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 IPDBRawSymbol; 46 class IPDBSession; 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> findInlineFramesByRVA(uint32_t RVA) const; 145 getRawSymbol()146 const IPDBRawSymbol &getRawSymbol() const { return *RawSymbol; } getRawSymbol()147 IPDBRawSymbol &getRawSymbol() { return *RawSymbol; } 148 getSession()149 const IPDBSession &getSession() const { return Session; } 150 151 std::unique_ptr<IPDBEnumSymbols> getChildStats(TagStats &Stats) const; 152 153 protected: 154 std::unique_ptr<PDBSymbol> getSymbolByIdHelper(uint32_t Id) const; 155 156 template <typename ConcreteType> getConcreteSymbolByIdHelper(uint32_t Id)157 std::unique_ptr<ConcreteType> getConcreteSymbolByIdHelper(uint32_t Id) const { 158 return unique_dyn_cast_or_null<ConcreteType>(getSymbolByIdHelper(Id)); 159 } 160 161 const IPDBSession &Session; 162 std::unique_ptr<IPDBRawSymbol> OwnedRawSymbol; 163 IPDBRawSymbol *RawSymbol = nullptr; 164 }; 165 166 } // namespace llvm 167 } 168 169 #endif 170