1 //===- PDBSymbol.h - base class for user-facing symbol types -----*- C++-*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_DEBUGINFO_PDB_PDBSYMBOL_H 10 #define LLVM_DEBUGINFO_PDB_PDBSYMBOL_H 11 12 #include "IPDBRawSymbol.h" 13 #include "PDBExtras.h" 14 #include "PDBTypes.h" 15 #include "llvm/Support/Casting.h" 16 #include "llvm/Support/Compiler.h" 17 18 #define FORWARD_SYMBOL_METHOD(MethodName) \ 19 decltype(auto) MethodName() const { return RawSymbol->MethodName(); } 20 21 #define FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(ConcreteType, PrivateName, \ 22 PublicName) \ 23 decltype(auto) PublicName##Id() const { \ 24 return RawSymbol->PrivateName##Id(); \ 25 } \ 26 std::unique_ptr<ConcreteType> PublicName() const { \ 27 uint32_t Id = PublicName##Id(); \ 28 return getConcreteSymbolByIdHelper<ConcreteType>(Id); \ 29 } 30 31 #define FORWARD_SYMBOL_ID_METHOD_WITH_NAME(PrivateName, PublicName) \ 32 FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(PDBSymbol, PrivateName, \ 33 PublicName) 34 35 #define FORWARD_SYMBOL_ID_METHOD(MethodName) \ 36 FORWARD_SYMBOL_ID_METHOD_WITH_NAME(MethodName, MethodName) 37 38 namespace llvm { 39 40 class StringRef; 41 class raw_ostream; 42 43 namespace pdb { 44 class IPDBSession; 45 class PDBSymDumper; 46 class PDBSymbol; 47 template <typename ChildType> class ConcreteSymbolEnumerator; 48 49 #define DECLARE_PDB_SYMBOL_CONCRETE_TYPE(TagValue) \ 50 private: \ 51 using PDBSymbol::PDBSymbol; \ 52 friend class PDBSymbol; \ 53 \ 54 public: \ 55 static const PDB_SymType Tag = TagValue; \ 56 static bool classof(const PDBSymbol *S) { return S->getSymTag() == Tag; } 57 58 #define DECLARE_PDB_SYMBOL_CUSTOM_TYPE(Condition) \ 59 private: \ 60 using PDBSymbol::PDBSymbol; \ 61 friend class PDBSymbol; \ 62 \ 63 public: \ 64 static bool classof(const PDBSymbol *S) { return Condition; } 65 66 /// PDBSymbol defines the base of the inheritance hierarchy for concrete symbol 67 /// types (e.g. functions, executables, vtables, etc). All concrete symbol 68 /// types inherit from PDBSymbol and expose the exact set of methods that are 69 /// valid for that particular symbol type, as described in the Microsoft 70 /// reference "Lexical and Class Hierarchy of Symbol Types": 71 /// https://msdn.microsoft.com/en-us/library/370hs6k4.aspx 72 class LLVM_ABI PDBSymbol { 73 static std::unique_ptr<PDBSymbol> createSymbol(const IPDBSession &PDBSession, 74 PDB_SymType Tag); 75 76 protected: 77 explicit PDBSymbol(const IPDBSession &PDBSession); 78 PDBSymbol(PDBSymbol &&Other); 79 80 public: 81 static std::unique_ptr<PDBSymbol> 82 create(const IPDBSession &PDBSession, 83 std::unique_ptr<IPDBRawSymbol> RawSymbol); 84 static std::unique_ptr<PDBSymbol> create(const IPDBSession &PDBSession, 85 IPDBRawSymbol &RawSymbol); 86 87 template <typename ConcreteT> 88 static std::unique_ptr<ConcreteT> createAs(const IPDBSession & PDBSession,std::unique_ptr<IPDBRawSymbol> RawSymbol)89 createAs(const IPDBSession &PDBSession, 90 std::unique_ptr<IPDBRawSymbol> RawSymbol) { 91 std::unique_ptr<PDBSymbol> S = create(PDBSession, std::move(RawSymbol)); 92 return unique_dyn_cast_or_null<ConcreteT>(std::move(S)); 93 } 94 template <typename ConcreteT> createAs(const IPDBSession & PDBSession,IPDBRawSymbol & RawSymbol)95 static std::unique_ptr<ConcreteT> createAs(const IPDBSession &PDBSession, 96 IPDBRawSymbol &RawSymbol) { 97 std::unique_ptr<PDBSymbol> S = create(PDBSession, RawSymbol); 98 return unique_dyn_cast_or_null<ConcreteT>(std::move(S)); 99 } 100 101 virtual ~PDBSymbol(); 102 103 /// Dumps the contents of a symbol a raw_ostream. By default this will just 104 /// call dump() on the underlying RawSymbol, which allows us to discover 105 /// unknown properties, but individual implementations of PDBSymbol may 106 /// override the behavior to only dump known fields. 107 virtual void dump(PDBSymDumper &Dumper) const = 0; 108 109 /// For certain PDBSymbolTypes, dumps additional information for the type that 110 /// normally goes on the right side of the symbol. dumpRight(PDBSymDumper & Dumper)111 virtual void dumpRight(PDBSymDumper &Dumper) const {} 112 113 void defaultDump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowFlags, 114 PdbSymbolIdField RecurseFlags) const; 115 void dumpProperties() const; 116 void dumpChildStats() const; 117 118 PDB_SymType getSymTag() const; 119 uint32_t getSymIndexId() const; 120 findOneChild()121 template <typename T> std::unique_ptr<T> findOneChild() const { 122 auto Enumerator(findAllChildren<T>()); 123 if (!Enumerator) 124 return nullptr; 125 return Enumerator->getNext(); 126 } 127 128 template <typename T> findAllChildren()129 std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const { 130 auto BaseIter = RawSymbol->findChildren(T::Tag); 131 if (!BaseIter) 132 return nullptr; 133 return std::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter)); 134 } 135 std::unique_ptr<IPDBEnumSymbols> findAllChildren(PDB_SymType Type) const; 136 std::unique_ptr<IPDBEnumSymbols> findAllChildren() const; 137 138 std::unique_ptr<IPDBEnumSymbols> 139 findChildren(PDB_SymType Type, StringRef Name, 140 PDB_NameSearchFlags Flags) const; 141 std::unique_ptr<IPDBEnumSymbols> findChildrenByRVA(PDB_SymType Type, 142 StringRef Name, 143 PDB_NameSearchFlags Flags, 144 uint32_t RVA) const; 145 std::unique_ptr<IPDBEnumSymbols> findInlineFramesByVA(uint64_t VA) const; 146 std::unique_ptr<IPDBEnumSymbols> findInlineFramesByRVA(uint32_t RVA) const; 147 std::unique_ptr<IPDBEnumLineNumbers> 148 findInlineeLinesByVA(uint64_t VA, uint32_t Length) const; 149 std::unique_ptr<IPDBEnumLineNumbers> 150 findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const; 151 152 std::string getName() const; 153 getRawSymbol()154 const IPDBRawSymbol &getRawSymbol() const { return *RawSymbol; } getRawSymbol()155 IPDBRawSymbol &getRawSymbol() { return *RawSymbol; } 156 getSession()157 const IPDBSession &getSession() const { return Session; } 158 159 std::unique_ptr<IPDBEnumSymbols> getChildStats(TagStats &Stats) const; 160 161 protected: 162 std::unique_ptr<PDBSymbol> getSymbolByIdHelper(uint32_t Id) const; 163 164 template <typename ConcreteType> getConcreteSymbolByIdHelper(uint32_t Id)165 std::unique_ptr<ConcreteType> getConcreteSymbolByIdHelper(uint32_t Id) const { 166 return unique_dyn_cast_or_null<ConcreteType>(getSymbolByIdHelper(Id)); 167 } 168 169 const IPDBSession &Session; 170 std::unique_ptr<IPDBRawSymbol> OwnedRawSymbol; 171 IPDBRawSymbol *RawSymbol = nullptr; 172 }; 173 174 } // namespace llvm 175 } 176 177 #endif 178