1 //===- PDBSymbol.cpp - base class for user-facing symbol types --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
10 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
11 #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
12 #include "llvm/DebugInfo/PDB/IPDBSession.h"
13 #include "llvm/DebugInfo/PDB/PDBExtras.h"
14 #include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
15 #include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
16 #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
17 #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
18 #include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
19 #include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
20 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
21 #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
22 #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
23 #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
24 #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
25 #include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
26 #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
27 #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
28 #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
29 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
30 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
31 #include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
32 #include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
33 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
34 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
35 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
36 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
37 #include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
38 #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
39 #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
40 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
41 #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
42 #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
43 #include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
44 #include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
45 #include "llvm/DebugInfo/PDB/PDBTypes.h"
50 using namespace llvm::pdb
;
52 PDBSymbol::PDBSymbol(const IPDBSession
&PDBSession
) : Session(PDBSession
) {}
54 PDBSymbol::PDBSymbol(PDBSymbol
&&Other
)
55 : Session(Other
.Session
), RawSymbol(std::move(Other
.RawSymbol
)) {}
57 PDBSymbol::~PDBSymbol() = default;
59 #define FACTORY_SYMTAG_CASE(Tag, Type) \
60 case PDB_SymType::Tag: \
61 return std::unique_ptr<PDBSymbol>(new Type(PDBSession));
63 std::unique_ptr
<PDBSymbol
>
64 PDBSymbol::createSymbol(const IPDBSession
&PDBSession
, PDB_SymType Tag
) {
66 FACTORY_SYMTAG_CASE(Exe
, PDBSymbolExe
)
67 FACTORY_SYMTAG_CASE(Compiland
, PDBSymbolCompiland
)
68 FACTORY_SYMTAG_CASE(CompilandDetails
, PDBSymbolCompilandDetails
)
69 FACTORY_SYMTAG_CASE(CompilandEnv
, PDBSymbolCompilandEnv
)
70 FACTORY_SYMTAG_CASE(Function
, PDBSymbolFunc
)
71 FACTORY_SYMTAG_CASE(Block
, PDBSymbolBlock
)
72 FACTORY_SYMTAG_CASE(Data
, PDBSymbolData
)
73 FACTORY_SYMTAG_CASE(Annotation
, PDBSymbolAnnotation
)
74 FACTORY_SYMTAG_CASE(Label
, PDBSymbolLabel
)
75 FACTORY_SYMTAG_CASE(PublicSymbol
, PDBSymbolPublicSymbol
)
76 FACTORY_SYMTAG_CASE(UDT
, PDBSymbolTypeUDT
)
77 FACTORY_SYMTAG_CASE(Enum
, PDBSymbolTypeEnum
)
78 FACTORY_SYMTAG_CASE(FunctionSig
, PDBSymbolTypeFunctionSig
)
79 FACTORY_SYMTAG_CASE(PointerType
, PDBSymbolTypePointer
)
80 FACTORY_SYMTAG_CASE(ArrayType
, PDBSymbolTypeArray
)
81 FACTORY_SYMTAG_CASE(BuiltinType
, PDBSymbolTypeBuiltin
)
82 FACTORY_SYMTAG_CASE(Typedef
, PDBSymbolTypeTypedef
)
83 FACTORY_SYMTAG_CASE(BaseClass
, PDBSymbolTypeBaseClass
)
84 FACTORY_SYMTAG_CASE(Friend
, PDBSymbolTypeFriend
)
85 FACTORY_SYMTAG_CASE(FunctionArg
, PDBSymbolTypeFunctionArg
)
86 FACTORY_SYMTAG_CASE(FuncDebugStart
, PDBSymbolFuncDebugStart
)
87 FACTORY_SYMTAG_CASE(FuncDebugEnd
, PDBSymbolFuncDebugEnd
)
88 FACTORY_SYMTAG_CASE(UsingNamespace
, PDBSymbolUsingNamespace
)
89 FACTORY_SYMTAG_CASE(VTableShape
, PDBSymbolTypeVTableShape
)
90 FACTORY_SYMTAG_CASE(VTable
, PDBSymbolTypeVTable
)
91 FACTORY_SYMTAG_CASE(Custom
, PDBSymbolCustom
)
92 FACTORY_SYMTAG_CASE(Thunk
, PDBSymbolThunk
)
93 FACTORY_SYMTAG_CASE(CustomType
, PDBSymbolTypeCustom
)
94 FACTORY_SYMTAG_CASE(ManagedType
, PDBSymbolTypeManaged
)
95 FACTORY_SYMTAG_CASE(Dimension
, PDBSymbolTypeDimension
)
97 return std::unique_ptr
<PDBSymbol
>(new PDBSymbolUnknown(PDBSession
));
101 std::unique_ptr
<PDBSymbol
>
102 PDBSymbol::create(const IPDBSession
&PDBSession
,
103 std::unique_ptr
<IPDBRawSymbol
> RawSymbol
) {
104 auto SymbolPtr
= createSymbol(PDBSession
, RawSymbol
->getSymTag());
105 SymbolPtr
->RawSymbol
= RawSymbol
.get();
106 SymbolPtr
->OwnedRawSymbol
= std::move(RawSymbol
);
110 std::unique_ptr
<PDBSymbol
> PDBSymbol::create(const IPDBSession
&PDBSession
,
111 IPDBRawSymbol
&RawSymbol
) {
112 auto SymbolPtr
= createSymbol(PDBSession
, RawSymbol
.getSymTag());
113 SymbolPtr
->RawSymbol
= &RawSymbol
;
117 void PDBSymbol::defaultDump(raw_ostream
&OS
, int Indent
,
118 PdbSymbolIdField ShowFlags
,
119 PdbSymbolIdField RecurseFlags
) const {
120 RawSymbol
->dump(OS
, Indent
, ShowFlags
, RecurseFlags
);
123 void PDBSymbol::dumpProperties() const {
125 defaultDump(outs(), 0, PdbSymbolIdField::All
, PdbSymbolIdField::None
);
129 void PDBSymbol::dumpChildStats() const {
131 getChildStats(Stats
);
133 for (auto &Stat
: Stats
) {
134 outs() << Stat
.first
<< ": " << Stat
.second
<< "\n";
139 PDB_SymType
PDBSymbol::getSymTag() const { return RawSymbol
->getSymTag(); }
140 uint32_t PDBSymbol::getSymIndexId() const { return RawSymbol
->getSymIndexId(); }
142 std::unique_ptr
<IPDBEnumSymbols
> PDBSymbol::findAllChildren() const {
143 return findAllChildren(PDB_SymType::None
);
146 std::unique_ptr
<IPDBEnumSymbols
>
147 PDBSymbol::findAllChildren(PDB_SymType Type
) const {
148 return RawSymbol
->findChildren(Type
);
151 std::unique_ptr
<IPDBEnumSymbols
>
152 PDBSymbol::findChildren(PDB_SymType Type
, StringRef Name
,
153 PDB_NameSearchFlags Flags
) const {
154 return RawSymbol
->findChildren(Type
, Name
, Flags
);
157 std::unique_ptr
<IPDBEnumSymbols
>
158 PDBSymbol::findChildrenByRVA(PDB_SymType Type
, StringRef Name
,
159 PDB_NameSearchFlags Flags
, uint32_t RVA
) const {
160 return RawSymbol
->findChildrenByRVA(Type
, Name
, Flags
, RVA
);
163 std::unique_ptr
<IPDBEnumSymbols
>
164 PDBSymbol::findInlineFramesByRVA(uint32_t RVA
) const {
165 return RawSymbol
->findInlineFramesByRVA(RVA
);
168 std::unique_ptr
<IPDBEnumSymbols
>
169 PDBSymbol::getChildStats(TagStats
&Stats
) const {
170 std::unique_ptr
<IPDBEnumSymbols
> Result(findAllChildren());
174 while (auto Child
= Result
->getNext()) {
175 ++Stats
[Child
->getSymTag()];
181 std::unique_ptr
<PDBSymbol
> PDBSymbol::getSymbolByIdHelper(uint32_t Id
) const {
182 return Session
.getSymbolById(Id
);
185 void llvm::pdb::dumpSymbolIdField(raw_ostream
&OS
, StringRef Name
,
186 SymIndexId Value
, int Indent
,
187 const IPDBSession
&Session
,
188 PdbSymbolIdField FieldId
,
189 PdbSymbolIdField ShowFlags
,
190 PdbSymbolIdField RecurseFlags
) {
191 if ((FieldId
& ShowFlags
) == PdbSymbolIdField::None
)
196 OS
<< Name
<< ": " << Value
;
197 // Don't recurse unless the user requested it.
198 if ((FieldId
& RecurseFlags
) == PdbSymbolIdField::None
)
200 // And obviously don't recurse on the symbol itself.
201 if (FieldId
== PdbSymbolIdField::SymIndexId
)
204 auto Child
= Session
.getSymbolById(Value
);
206 // It could have been a placeholder symbol for a type we don't yet support,
207 // so just exit in that case.
211 // Don't recurse more than once, so pass PdbSymbolIdField::None) for the
213 Child
->defaultDump(OS
, Indent
+ 2, ShowFlags
, PdbSymbolIdField::None
);