blob: 24cf1e459f92aa9b51391a42fb12ec09a9a3a80a [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- PDBSymbol.h - base class for user-facing symbol types -----*- C++-*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
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) \
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020020 decltype(auto) MethodName() const { return RawSymbol->MethodName(); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010021
22#define FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(ConcreteType, PrivateName, \
23 PublicName) \
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020024 decltype(auto) PublicName##Id() const { \
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010025 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
39namespace llvm {
40
41class StringRef;
42class raw_ostream;
43
44namespace pdb {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010045class IPDBSession;
46
47#define DECLARE_PDB_SYMBOL_CONCRETE_TYPE(TagValue) \
Andrew Scull0372a572018-11-16 15:47:06 +000048private: \
49 using PDBSymbol::PDBSymbol; \
50 friend class PDBSymbol; \
51 \
52public: \
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010053 static const PDB_SymType Tag = TagValue; \
54 static bool classof(const PDBSymbol *S) { return S->getSymTag() == Tag; }
55
Andrew Scull0372a572018-11-16 15:47:06 +000056#define DECLARE_PDB_SYMBOL_CUSTOM_TYPE(Condition) \
57private: \
58 using PDBSymbol::PDBSymbol; \
59 friend class PDBSymbol; \
60 \
61public: \
62 static bool classof(const PDBSymbol *S) { return Condition; }
63
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010064/// 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
70class PDBSymbol {
Andrew Scull0372a572018-11-16 15:47:06 +000071 static std::unique_ptr<PDBSymbol> createSymbol(const IPDBSession &PDBSession,
72 PDB_SymType Tag);
73
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010074protected:
Andrew Scull0372a572018-11-16 15:47:06 +000075 explicit PDBSymbol(const IPDBSession &PDBSession);
76 PDBSymbol(PDBSymbol &&Other);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010077
78public:
79 static std::unique_ptr<PDBSymbol>
Andrew Scull0372a572018-11-16 15:47:06 +000080 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>
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>
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 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010098
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.
109 virtual void dumpRight(PDBSymDumper &Dumper) const {}
110
Andrew Scull0372a572018-11-16 15:47:06 +0000111 void defaultDump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowFlags,
112 PdbSymbolIdField RecurseFlags) const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100113 void dumpProperties() const;
114 void dumpChildStats() const;
115
116 PDB_SymType getSymTag() const;
117 uint32_t getSymIndexId() const;
118
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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100126 template <typename T>
127 std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const {
128 auto BaseIter = RawSymbol->findChildren(T::Tag);
129 if (!BaseIter)
130 return nullptr;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200131 return std::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter));
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100132 }
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;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200143 std::unique_ptr<IPDBEnumSymbols> findInlineFramesByVA(uint64_t VA) const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100144 std::unique_ptr<IPDBEnumSymbols> findInlineFramesByRVA(uint32_t RVA) const;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200145 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;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100151
152 const IPDBRawSymbol &getRawSymbol() const { return *RawSymbol; }
153 IPDBRawSymbol &getRawSymbol() { return *RawSymbol; }
154
155 const IPDBSession &getSession() const { return Session; }
156
157 std::unique_ptr<IPDBEnumSymbols> getChildStats(TagStats &Stats) const;
158
159protected:
160 std::unique_ptr<PDBSymbol> getSymbolByIdHelper(uint32_t Id) const;
161
162 template <typename ConcreteType>
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;
Andrew Scull0372a572018-11-16 15:47:06 +0000168 std::unique_ptr<IPDBRawSymbol> OwnedRawSymbol;
169 IPDBRawSymbol *RawSymbol = nullptr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100170};
171
172} // namespace llvm
173}
174
175#endif