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