1 //===-- PdbUtil.h -----------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H 11 #define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H 12 13 #include "lldb/Expression/DWARFExpression.h" 14 #include "lldb/Symbol/Variable.h" 15 #include "lldb/lldb-enumerations.h" 16 17 #include "llvm/ADT/Optional.h" 18 #include "llvm/DebugInfo/CodeView/CodeView.h" 19 #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 20 #include "llvm/DebugInfo/CodeView/TypeRecord.h" 21 #include "llvm/DebugInfo/PDB/PDBTypes.h" 22 23 #include "PdbSymUid.h" 24 25 #include <tuple> 26 #include <utility> 27 28 namespace llvm { 29 namespace pdb { 30 class TpiStream; 31 } 32 } // namespace llvm 33 34 namespace lldb_private { 35 namespace npdb { 36 37 class PdbIndex; 38 39 struct CVTagRecord { 40 enum Kind { Class, Struct, Union, Enum }; 41 42 static CVTagRecord create(llvm::codeview::CVType type); 43 44 Kind kind() const { return m_kind; } 45 46 const llvm::codeview::TagRecord &asTag() const { 47 if (m_kind == Struct || m_kind == Class) 48 return cvclass; 49 if (m_kind == Enum) 50 return cvenum; 51 return cvunion; 52 } 53 54 const llvm::codeview::ClassRecord &asClass() const { 55 assert(m_kind == Struct || m_kind == Class); 56 return cvclass; 57 } 58 59 const llvm::codeview::EnumRecord &asEnum() const { 60 assert(m_kind == Enum); 61 return cvenum; 62 } 63 64 const llvm::codeview::UnionRecord &asUnion() const { 65 assert(m_kind == Union); 66 return cvunion; 67 } 68 69 private: 70 CVTagRecord(llvm::codeview::ClassRecord &&c); 71 CVTagRecord(llvm::codeview::UnionRecord &&u); 72 CVTagRecord(llvm::codeview::EnumRecord &&e); 73 union { 74 llvm::codeview::ClassRecord cvclass; 75 llvm::codeview::EnumRecord cvenum; 76 llvm::codeview::UnionRecord cvunion; 77 }; 78 Kind m_kind; 79 }; 80 81 struct SegmentOffset { 82 SegmentOffset() = default; 83 SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {} 84 uint16_t segment = 0; 85 uint32_t offset = 0; 86 }; 87 88 struct SegmentOffsetLength { 89 SegmentOffsetLength() = default; 90 SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l) 91 : so(s, o), length(l) {} 92 SegmentOffset so; 93 uint32_t length = 0; 94 }; 95 96 struct VariableInfo { 97 llvm::StringRef name; 98 llvm::codeview::TypeIndex type; 99 llvm::Optional<DWARFExpression> location; 100 llvm::Optional<Variable::RangeList> ranges; 101 }; 102 103 llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind); 104 llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind); 105 106 bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym); 107 bool SymbolIsCode(const llvm::codeview::CVSymbol &sym); 108 109 SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym); 110 SegmentOffsetLength 111 GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym); 112 113 template <typename RecordT> bool IsValidRecord(const RecordT &sym) { 114 return true; 115 } 116 117 inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) { 118 // S_PROCREF symbols have 1-based module indices. 119 return sym.Module > 0; 120 } 121 122 bool IsForwardRefUdt(llvm::codeview::CVType cvt); 123 bool IsTagRecord(llvm::codeview::CVType cvt); 124 bool IsClassStructUnion(llvm::codeview::CVType cvt); 125 126 bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); 127 bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); 128 129 lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access); 130 llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt); 131 llvm::codeview::TypeIndex 132 LookThroughModifierRecord(llvm::codeview::CVType modifier); 133 134 llvm::StringRef DropNameScope(llvm::StringRef name); 135 136 VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol); 137 VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, 138 lldb::ModuleSP module); 139 140 size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind); 141 lldb::BasicType 142 GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind); 143 144 PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi); 145 146 size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi); 147 148 } // namespace npdb 149 } // namespace lldb_private 150 151 #endif 152