| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 1 | //===- PDBSymbol.cpp - base class for user-facing symbol types --*- C++ -*-===// | 
|  | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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 | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 |  | 
| Zachary Turner | 52c9f88 | 2015-02-14 03:53:56 +0000 | [diff] [blame] | 9 | #include "llvm/DebugInfo/PDB/PDBSymbol.h" | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 10 | #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" | 
|  | 11 | #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" | 
| Zachary Turner | 1b1a70f | 2017-04-10 06:14:09 +0000 | [diff] [blame] | 12 | #include "llvm/DebugInfo/PDB/IPDBSession.h" | 
| Eugene Zelenko | 570e39a | 2016-11-23 23:16:32 +0000 | [diff] [blame] | 13 | #include "llvm/DebugInfo/PDB/PDBExtras.h" | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 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" | 
| Eugene Zelenko | 570e39a | 2016-11-23 23:16:32 +0000 | [diff] [blame] | 45 | #include "llvm/DebugInfo/PDB/PDBTypes.h" | 
|  | 46 | #include <algorithm> | 
| Chandler Carruth | 71f308a | 2015-02-13 09:09:03 +0000 | [diff] [blame] | 47 | #include <memory> | 
| Zachary Turner | 52c9f88 | 2015-02-14 03:53:56 +0000 | [diff] [blame] | 48 |  | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 49 | using namespace llvm; | 
| Zachary Turner | ec28fc3 | 2016-05-04 20:32:13 +0000 | [diff] [blame] | 50 | using namespace llvm::pdb; | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 51 |  | 
| Zachary Turner | 7999b4f | 2018-09-05 23:30:38 +0000 | [diff] [blame] | 52 | PDBSymbol::PDBSymbol(const IPDBSession &PDBSession) : Session(PDBSession) {} | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 53 |  | 
| Zachary Turner | 7999b4f | 2018-09-05 23:30:38 +0000 | [diff] [blame] | 54 | PDBSymbol::PDBSymbol(PDBSymbol &&Other) | 
|  | 55 | : Session(Other.Session), RawSymbol(std::move(Other.RawSymbol)) {} | 
| Zachary Turner | c883a8c | 2017-04-12 23:18:21 +0000 | [diff] [blame] | 56 |  | 
| Eugene Zelenko | 570e39a | 2016-11-23 23:16:32 +0000 | [diff] [blame] | 57 | PDBSymbol::~PDBSymbol() = default; | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 58 |  | 
|  | 59 | #define FACTORY_SYMTAG_CASE(Tag, Type)                                         \ | 
|  | 60 | case PDB_SymType::Tag:                                                       \ | 
| Zachary Turner | 7999b4f | 2018-09-05 23:30:38 +0000 | [diff] [blame] | 61 | return std::unique_ptr<PDBSymbol>(new Type(PDBSession)); | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 62 |  | 
|  | 63 | std::unique_ptr<PDBSymbol> | 
| Zachary Turner | 7999b4f | 2018-09-05 23:30:38 +0000 | [diff] [blame] | 64 | PDBSymbol::createSymbol(const IPDBSession &PDBSession, PDB_SymType Tag) { | 
|  | 65 | switch (Tag) { | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 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) | 
|  | 96 | default: | 
| Zachary Turner | 7999b4f | 2018-09-05 23:30:38 +0000 | [diff] [blame] | 97 | return std::unique_ptr<PDBSymbol>(new PDBSymbolUnknown(PDBSession)); | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 98 | } | 
|  | 99 | } | 
|  | 100 |  | 
| Zachary Turner | 7999b4f | 2018-09-05 23:30:38 +0000 | [diff] [blame] | 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); | 
| Zachary Turner | 5cda1b8 | 2018-09-06 00:06:20 +0000 | [diff] [blame] | 107 | return SymbolPtr; | 
| Zachary Turner | 7999b4f | 2018-09-05 23:30:38 +0000 | [diff] [blame] | 108 | } | 
|  | 109 |  | 
|  | 110 | std::unique_ptr<PDBSymbol> PDBSymbol::create(const IPDBSession &PDBSession, | 
|  | 111 | IPDBRawSymbol &RawSymbol) { | 
|  | 112 | auto SymbolPtr = createSymbol(PDBSession, RawSymbol.getSymTag()); | 
|  | 113 | SymbolPtr->RawSymbol = &RawSymbol; | 
| Zachary Turner | 5cda1b8 | 2018-09-06 00:06:20 +0000 | [diff] [blame] | 114 | return SymbolPtr; | 
| Zachary Turner | 7999b4f | 2018-09-05 23:30:38 +0000 | [diff] [blame] | 115 | } | 
|  | 116 |  | 
| Zachary Turner | c41ce83 | 2018-09-18 16:35:05 +0000 | [diff] [blame] | 117 | void PDBSymbol::defaultDump(raw_ostream &OS, int Indent, | 
|  | 118 | PdbSymbolIdField ShowFlags, | 
|  | 119 | PdbSymbolIdField RecurseFlags) const { | 
|  | 120 | RawSymbol->dump(OS, Indent, ShowFlags, RecurseFlags); | 
| Zachary Turner | a554917 | 2015-02-10 22:43:25 +0000 | [diff] [blame] | 121 | } | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 122 |  | 
| Zachary Turner | 1b1a70f | 2017-04-10 06:14:09 +0000 | [diff] [blame] | 123 | void PDBSymbol::dumpProperties() const { | 
|  | 124 | outs() << "\n"; | 
| Zachary Turner | c41ce83 | 2018-09-18 16:35:05 +0000 | [diff] [blame] | 125 | defaultDump(outs(), 0, PdbSymbolIdField::All, PdbSymbolIdField::None); | 
| Zachary Turner | 1b1a70f | 2017-04-10 06:14:09 +0000 | [diff] [blame] | 126 | outs().flush(); | 
|  | 127 | } | 
|  | 128 |  | 
|  | 129 | void PDBSymbol::dumpChildStats() const { | 
|  | 130 | TagStats Stats; | 
|  | 131 | getChildStats(Stats); | 
|  | 132 | outs() << "\n"; | 
|  | 133 | for (auto &Stat : Stats) { | 
|  | 134 | outs() << Stat.first << ": " << Stat.second << "\n"; | 
|  | 135 | } | 
|  | 136 | outs().flush(); | 
|  | 137 | } | 
|  | 138 |  | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 139 | PDB_SymType PDBSymbol::getSymTag() const { return RawSymbol->getSymTag(); } | 
| Zachary Turner | 0cdb055 | 2016-02-17 21:13:34 +0000 | [diff] [blame] | 140 | uint32_t PDBSymbol::getSymIndexId() const { return RawSymbol->getSymIndexId(); } | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 141 |  | 
| Zachary Turner | c074de0 | 2015-02-12 21:09:24 +0000 | [diff] [blame] | 142 | std::unique_ptr<IPDBEnumSymbols> PDBSymbol::findAllChildren() const { | 
| Zachary Turner | 26ebe3f | 2015-02-14 03:54:28 +0000 | [diff] [blame] | 143 | return findAllChildren(PDB_SymType::None); | 
|  | 144 | } | 
|  | 145 |  | 
|  | 146 | std::unique_ptr<IPDBEnumSymbols> | 
|  | 147 | PDBSymbol::findAllChildren(PDB_SymType Type) const { | 
|  | 148 | return RawSymbol->findChildren(Type); | 
| Zachary Turner | a554917 | 2015-02-10 22:43:25 +0000 | [diff] [blame] | 149 | } | 
|  | 150 |  | 
| Zachary Turner | 0e9e663 | 2015-02-06 20:30:52 +0000 | [diff] [blame] | 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); | 
|  | 155 | } | 
|  | 156 |  | 
|  | 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); | 
|  | 161 | } | 
|  | 162 |  | 
|  | 163 | std::unique_ptr<IPDBEnumSymbols> | 
|  | 164 | PDBSymbol::findInlineFramesByRVA(uint32_t RVA) const { | 
|  | 165 | return RawSymbol->findInlineFramesByRVA(RVA); | 
|  | 166 | } | 
| Zachary Turner | a554917 | 2015-02-10 22:43:25 +0000 | [diff] [blame] | 167 |  | 
|  | 168 | std::unique_ptr<IPDBEnumSymbols> | 
|  | 169 | PDBSymbol::getChildStats(TagStats &Stats) const { | 
| Zachary Turner | c074de0 | 2015-02-12 21:09:24 +0000 | [diff] [blame] | 170 | std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren()); | 
| Zachary Turner | 4dc4f01 | 2017-04-13 21:11:00 +0000 | [diff] [blame] | 171 | if (!Result) | 
|  | 172 | return nullptr; | 
| Zachary Turner | a554917 | 2015-02-10 22:43:25 +0000 | [diff] [blame] | 173 | Stats.clear(); | 
|  | 174 | while (auto Child = Result->getNext()) { | 
|  | 175 | ++Stats[Child->getSymTag()]; | 
|  | 176 | } | 
|  | 177 | Result->reset(); | 
|  | 178 | return Result; | 
|  | 179 | } | 
| Zachary Turner | 1b1a70f | 2017-04-10 06:14:09 +0000 | [diff] [blame] | 180 |  | 
|  | 181 | std::unique_ptr<PDBSymbol> PDBSymbol::getSymbolByIdHelper(uint32_t Id) const { | 
|  | 182 | return Session.getSymbolById(Id); | 
|  | 183 | } | 
| Zachary Turner | c41ce83 | 2018-09-18 16:35:05 +0000 | [diff] [blame] | 184 |  | 
|  | 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) | 
|  | 192 | return; | 
|  | 193 |  | 
|  | 194 | OS << "\n"; | 
|  | 195 | OS.indent(Indent); | 
|  | 196 | OS << Name << ": " << Value; | 
|  | 197 | // Don't recurse unless the user requested it. | 
|  | 198 | if ((FieldId & RecurseFlags) == PdbSymbolIdField::None) | 
|  | 199 | return; | 
|  | 200 | // And obviously don't recurse on the symbol itself. | 
|  | 201 | if (FieldId == PdbSymbolIdField::SymIndexId) | 
|  | 202 | return; | 
|  | 203 |  | 
|  | 204 | auto Child = Session.getSymbolById(Value); | 
|  | 205 |  | 
|  | 206 | // It could have been a placeholder symbol for a type we don't yet support, | 
|  | 207 | // so just exit in that case. | 
|  | 208 | if (!Child) | 
|  | 209 | return; | 
|  | 210 |  | 
|  | 211 | // Don't recurse more than once, so pass PdbSymbolIdField::None) for the | 
|  | 212 | // recurse flags. | 
|  | 213 | Child->defaultDump(OS, Indent + 2, ShowFlags, PdbSymbolIdField::None); | 
|  | 214 | } |