PDBSymbol.h 7.6 KB

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