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