1 //===- PDBSymbol.h - base class for user-facing symbol types -----*- C++-*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_DEBUGINFO_PDB_IPDBSYMBOL_H 11 #define LLVM_DEBUGINFO_PDB_IPDBSYMBOL_H 12 13 #include "ConcreteSymbolEnumerator.h" 14 #include "IPDBRawSymbol.h" 15 #include "PDBExtras.h" 16 #include "PDBTypes.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/Support/Casting.h" 19 20 #define FORWARD_SYMBOL_METHOD(MethodName) \ 21 auto MethodName() const->decltype(RawSymbol->MethodName()) { \ 22 return RawSymbol->MethodName(); \ 23 } 24 25 #define FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(ConcreteType, PrivateName, \ 26 PublicName) \ 27 auto PublicName##Id() const->decltype(RawSymbol->PrivateName##Id()) { \ 28 return RawSymbol->PrivateName##Id(); \ 29 } \ 30 std::unique_ptr<ConcreteType> PublicName() const { \ 31 uint32_t Id = PublicName##Id(); \ 32 return getConcreteSymbolByIdHelper<ConcreteType>(Id); \ 33 } 34 35 #define FORWARD_SYMBOL_ID_METHOD_WITH_NAME(PrivateName, PublicName) \ 36 FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(PDBSymbol, PrivateName, \ 37 PublicName) 38 39 #define FORWARD_SYMBOL_ID_METHOD(MethodName) \ 40 FORWARD_SYMBOL_ID_METHOD_WITH_NAME(MethodName, MethodName) 41 42 namespace llvm { 43 44 class StringRef; 45 class raw_ostream; 46 47 namespace pdb { 48 class IPDBRawSymbol; 49 class IPDBSession; 50 51 #define DECLARE_PDB_SYMBOL_CONCRETE_TYPE(TagValue) \ 52 static const PDB_SymType Tag = TagValue; \ 53 static bool classof(const PDBSymbol *S) { return S->getSymTag() == Tag; } 54 55 /// PDBSymbol defines the base of the inheritance hierarchy for concrete symbol 56 /// types (e.g. functions, executables, vtables, etc). All concrete symbol 57 /// types inherit from PDBSymbol and expose the exact set of methods that are 58 /// valid for that particular symbol type, as described in the Microsoft 59 /// reference "Lexical and Class Hierarchy of Symbol Types": 60 /// https://msdn.microsoft.com/en-us/library/370hs6k4.aspx 61 class PDBSymbol { 62 protected: 63 PDBSymbol(const IPDBSession &PDBSession, 64 std::unique_ptr<IPDBRawSymbol> Symbol); 65 66 public: 67 static std::unique_ptr<PDBSymbol> 68 create(const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol); 69 70 virtual ~PDBSymbol(); 71 72 /// Dumps the contents of a symbol a raw_ostream. By default this will just 73 /// call dump() on the underlying RawSymbol, which allows us to discover 74 /// unknown properties, but individual implementations of PDBSymbol may 75 /// override the behavior to only dump known fields. 76 virtual void dump(PDBSymDumper &Dumper) const = 0; 77 78 /// For certain PDBSymbolTypes, dumps additional information for the type that 79 /// normally goes on the right side of the symbol. 80 virtual void dumpRight(PDBSymDumper &Dumper) const {} 81 82 void defaultDump(raw_ostream &OS, int Indent) const; 83 void dumpProperties() const; 84 void dumpChildStats() const; 85 86 PDB_SymType getSymTag() const; 87 uint32_t getSymIndexId() const; 88 89 template <typename T> std::unique_ptr<T> findOneChild() const { 90 auto Enumerator(findAllChildren<T>()); 91 return Enumerator->getNext(); 92 } 93 94 template <typename T> T *cast() { return llvm::dyn_cast<T>(this); } 95 96 template <typename T> const T *cast() const { 97 return llvm::dyn_cast<T>(this); 98 } 99 100 std::unique_ptr<PDBSymbol> clone() const; 101 102 template <typename T> 103 std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const { 104 auto BaseIter = RawSymbol->findChildren(T::Tag); 105 return llvm::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter)); 106 } 107 std::unique_ptr<IPDBEnumSymbols> findAllChildren(PDB_SymType Type) const; 108 std::unique_ptr<IPDBEnumSymbols> findAllChildren() const; 109 110 std::unique_ptr<IPDBEnumSymbols> 111 findChildren(PDB_SymType Type, StringRef Name, 112 PDB_NameSearchFlags Flags) const; 113 std::unique_ptr<IPDBEnumSymbols> findChildrenByRVA(PDB_SymType Type, 114 StringRef Name, 115 PDB_NameSearchFlags Flags, 116 uint32_t RVA) const; 117 std::unique_ptr<IPDBEnumSymbols> findInlineFramesByRVA(uint32_t RVA) const; 118 119 const IPDBRawSymbol &getRawSymbol() const { return *RawSymbol; } 120 IPDBRawSymbol &getRawSymbol() { return *RawSymbol; } 121 122 const IPDBSession &getSession() const { return Session; } 123 124 std::unique_ptr<IPDBEnumSymbols> getChildStats(TagStats &Stats) const; 125 126 protected: 127 std::unique_ptr<PDBSymbol> getSymbolByIdHelper(uint32_t Id) const; 128 129 template <typename ConcreteType> 130 std::unique_ptr<ConcreteType> getConcreteSymbolByIdHelper(uint32_t Id) const { 131 auto Sym = getSymbolByIdHelper(Id); 132 if (!Sym) 133 return nullptr; 134 ConcreteType *Result = Sym->cast<ConcreteType>(); 135 if (!Result) 136 return nullptr; 137 Sym.release(); 138 return std::unique_ptr<ConcreteType>(Result); 139 } 140 141 const IPDBSession &Session; 142 const std::unique_ptr<IPDBRawSymbol> RawSymbol; 143 }; 144 145 } // namespace llvm 146 } 147 148 #endif 149