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 llvm::StringRef name() const { 70 if (m_kind == Struct || m_kind == Union) 71 return cvclass.Name; 72 if (m_kind == Enum) 73 return cvenum.Name; 74 return cvunion.Name; 75 } 76 77 private: 78 CVTagRecord(llvm::codeview::ClassRecord &&c); 79 CVTagRecord(llvm::codeview::UnionRecord &&u); 80 CVTagRecord(llvm::codeview::EnumRecord &&e); 81 union { 82 llvm::codeview::ClassRecord cvclass; 83 llvm::codeview::EnumRecord cvenum; 84 llvm::codeview::UnionRecord cvunion; 85 }; 86 Kind m_kind; 87 }; 88 89 struct SegmentOffset { 90 SegmentOffset() = default; 91 SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {} 92 uint16_t segment = 0; 93 uint32_t offset = 0; 94 }; 95 96 struct SegmentOffsetLength { 97 SegmentOffsetLength() = default; 98 SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l) 99 : so(s, o), length(l) {} 100 SegmentOffset so; 101 uint32_t length = 0; 102 }; 103 104 struct VariableInfo { 105 llvm::StringRef name; 106 llvm::codeview::TypeIndex type; 107 llvm::Optional<DWARFExpression> location; 108 llvm::Optional<Variable::RangeList> ranges; 109 }; 110 111 llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind); 112 llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind); 113 114 bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym); 115 bool SymbolIsCode(const llvm::codeview::CVSymbol &sym); 116 117 SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym); 118 SegmentOffsetLength 119 GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym); 120 121 template <typename RecordT> bool IsValidRecord(const RecordT &sym) { 122 return true; 123 } 124 125 inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) { 126 // S_PROCREF symbols have 1-based module indices. 127 return sym.Module > 0; 128 } 129 130 bool IsForwardRefUdt(llvm::codeview::CVType cvt); 131 bool IsTagRecord(llvm::codeview::CVType cvt); 132 bool IsClassStructUnion(llvm::codeview::CVType cvt); 133 134 bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); 135 bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); 136 137 lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access); 138 llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt); 139 llvm::codeview::TypeIndex 140 LookThroughModifierRecord(llvm::codeview::CVType modifier); 141 142 llvm::StringRef DropNameScope(llvm::StringRef name); 143 144 VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol); 145 VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, 146 lldb::ModuleSP module); 147 148 size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind); 149 lldb::BasicType 150 GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind); 151 152 PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi); 153 154 size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi); 155 156 } // namespace npdb 157 } // namespace lldb_private 158 159 #endif 160