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