xref: /freebsd-src/contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
10b57cec5SDimitry Andric //===- PDBSymbol.cpp - base class for user-facing symbol types --*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbol.h"
100b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
11*81ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
120b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
130b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBSession.h"
140b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBExtras.h"
150b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
160b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
170b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
180b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
190b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
200b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
210b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
220b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
230b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
240b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
250b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
260b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
270b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
280b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
290b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
300b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
310b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
320b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
330b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
340b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
350b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
360b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
370b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
380b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
390b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
400b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
410b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
420b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
430b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
440b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
450b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
460b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBTypes.h"
470b57cec5SDimitry Andric #include <memory>
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric using namespace llvm;
500b57cec5SDimitry Andric using namespace llvm::pdb;
510b57cec5SDimitry Andric 
PDBSymbol(const IPDBSession & PDBSession)520b57cec5SDimitry Andric PDBSymbol::PDBSymbol(const IPDBSession &PDBSession) : Session(PDBSession) {}
530b57cec5SDimitry Andric 
PDBSymbol(PDBSymbol && Other)540b57cec5SDimitry Andric PDBSymbol::PDBSymbol(PDBSymbol &&Other)
550b57cec5SDimitry Andric     : Session(Other.Session), RawSymbol(std::move(Other.RawSymbol)) {}
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric PDBSymbol::~PDBSymbol() = default;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric #define FACTORY_SYMTAG_CASE(Tag, Type)                                         \
600b57cec5SDimitry Andric   case PDB_SymType::Tag:                                                       \
610b57cec5SDimitry Andric     return std::unique_ptr<PDBSymbol>(new Type(PDBSession));
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric std::unique_ptr<PDBSymbol>
createSymbol(const IPDBSession & PDBSession,PDB_SymType Tag)640b57cec5SDimitry Andric PDBSymbol::createSymbol(const IPDBSession &PDBSession, PDB_SymType Tag) {
650b57cec5SDimitry Andric   switch (Tag) {
660b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Exe, PDBSymbolExe)
670b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Compiland, PDBSymbolCompiland)
680b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(CompilandDetails, PDBSymbolCompilandDetails)
690b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(CompilandEnv, PDBSymbolCompilandEnv)
700b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Function, PDBSymbolFunc)
710b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Block, PDBSymbolBlock)
720b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Data, PDBSymbolData)
730b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Annotation, PDBSymbolAnnotation)
740b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Label, PDBSymbolLabel)
750b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(PublicSymbol, PDBSymbolPublicSymbol)
760b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(UDT, PDBSymbolTypeUDT)
770b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Enum, PDBSymbolTypeEnum)
780b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(FunctionSig, PDBSymbolTypeFunctionSig)
790b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(PointerType, PDBSymbolTypePointer)
800b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(ArrayType, PDBSymbolTypeArray)
810b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(BuiltinType, PDBSymbolTypeBuiltin)
820b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Typedef, PDBSymbolTypeTypedef)
830b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(BaseClass, PDBSymbolTypeBaseClass)
840b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Friend, PDBSymbolTypeFriend)
850b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(FunctionArg, PDBSymbolTypeFunctionArg)
860b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(FuncDebugStart, PDBSymbolFuncDebugStart)
870b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(FuncDebugEnd, PDBSymbolFuncDebugEnd)
880b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(UsingNamespace, PDBSymbolUsingNamespace)
890b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(VTableShape, PDBSymbolTypeVTableShape)
900b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(VTable, PDBSymbolTypeVTable)
910b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Custom, PDBSymbolCustom)
920b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Thunk, PDBSymbolThunk)
930b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(CustomType, PDBSymbolTypeCustom)
940b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(ManagedType, PDBSymbolTypeManaged)
950b57cec5SDimitry Andric     FACTORY_SYMTAG_CASE(Dimension, PDBSymbolTypeDimension)
960b57cec5SDimitry Andric   default:
970b57cec5SDimitry Andric     return std::unique_ptr<PDBSymbol>(new PDBSymbolUnknown(PDBSession));
980b57cec5SDimitry Andric   }
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric std::unique_ptr<PDBSymbol>
create(const IPDBSession & PDBSession,std::unique_ptr<IPDBRawSymbol> RawSymbol)1020b57cec5SDimitry Andric PDBSymbol::create(const IPDBSession &PDBSession,
1030b57cec5SDimitry Andric                   std::unique_ptr<IPDBRawSymbol> RawSymbol) {
1040b57cec5SDimitry Andric   auto SymbolPtr = createSymbol(PDBSession, RawSymbol->getSymTag());
1050b57cec5SDimitry Andric   SymbolPtr->RawSymbol = RawSymbol.get();
1060b57cec5SDimitry Andric   SymbolPtr->OwnedRawSymbol = std::move(RawSymbol);
1070b57cec5SDimitry Andric   return SymbolPtr;
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
create(const IPDBSession & PDBSession,IPDBRawSymbol & RawSymbol)1100b57cec5SDimitry Andric std::unique_ptr<PDBSymbol> PDBSymbol::create(const IPDBSession &PDBSession,
1110b57cec5SDimitry Andric                                              IPDBRawSymbol &RawSymbol) {
1120b57cec5SDimitry Andric   auto SymbolPtr = createSymbol(PDBSession, RawSymbol.getSymTag());
1130b57cec5SDimitry Andric   SymbolPtr->RawSymbol = &RawSymbol;
1140b57cec5SDimitry Andric   return SymbolPtr;
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric 
defaultDump(raw_ostream & OS,int Indent,PdbSymbolIdField ShowFlags,PdbSymbolIdField RecurseFlags) const1170b57cec5SDimitry Andric void PDBSymbol::defaultDump(raw_ostream &OS, int Indent,
1180b57cec5SDimitry Andric                             PdbSymbolIdField ShowFlags,
1190b57cec5SDimitry Andric                             PdbSymbolIdField RecurseFlags) const {
1200b57cec5SDimitry Andric   RawSymbol->dump(OS, Indent, ShowFlags, RecurseFlags);
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric 
dumpProperties() const1230b57cec5SDimitry Andric void PDBSymbol::dumpProperties() const {
1240b57cec5SDimitry Andric   outs() << "\n";
1250b57cec5SDimitry Andric   defaultDump(outs(), 0, PdbSymbolIdField::All, PdbSymbolIdField::None);
1260b57cec5SDimitry Andric   outs().flush();
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric 
dumpChildStats() const1290b57cec5SDimitry Andric void PDBSymbol::dumpChildStats() const {
1300b57cec5SDimitry Andric   TagStats Stats;
1310b57cec5SDimitry Andric   getChildStats(Stats);
1320b57cec5SDimitry Andric   outs() << "\n";
1330b57cec5SDimitry Andric   for (auto &Stat : Stats) {
1340b57cec5SDimitry Andric     outs() << Stat.first << ": " << Stat.second << "\n";
1350b57cec5SDimitry Andric   }
1360b57cec5SDimitry Andric   outs().flush();
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric 
getSymTag() const1390b57cec5SDimitry Andric PDB_SymType PDBSymbol::getSymTag() const { return RawSymbol->getSymTag(); }
getSymIndexId() const1400b57cec5SDimitry Andric uint32_t PDBSymbol::getSymIndexId() const { return RawSymbol->getSymIndexId(); }
1410b57cec5SDimitry Andric 
findAllChildren() const1420b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSymbols> PDBSymbol::findAllChildren() const {
1430b57cec5SDimitry Andric   return findAllChildren(PDB_SymType::None);
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSymbols>
findAllChildren(PDB_SymType Type) const1470b57cec5SDimitry Andric PDBSymbol::findAllChildren(PDB_SymType Type) const {
1480b57cec5SDimitry Andric   return RawSymbol->findChildren(Type);
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSymbols>
findChildren(PDB_SymType Type,StringRef Name,PDB_NameSearchFlags Flags) const1520b57cec5SDimitry Andric PDBSymbol::findChildren(PDB_SymType Type, StringRef Name,
1530b57cec5SDimitry Andric                         PDB_NameSearchFlags Flags) const {
1540b57cec5SDimitry Andric   return RawSymbol->findChildren(Type, Name, Flags);
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSymbols>
findChildrenByRVA(PDB_SymType Type,StringRef Name,PDB_NameSearchFlags Flags,uint32_t RVA) const1580b57cec5SDimitry Andric PDBSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
1590b57cec5SDimitry Andric                              PDB_NameSearchFlags Flags, uint32_t RVA) const {
1600b57cec5SDimitry Andric   return RawSymbol->findChildrenByRVA(Type, Name, Flags, RVA);
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSymbols>
findInlineFramesByVA(uint64_t VA) const164e8d8bef9SDimitry Andric PDBSymbol::findInlineFramesByVA(uint64_t VA) const {
165e8d8bef9SDimitry Andric   return RawSymbol->findInlineFramesByVA(VA);
166e8d8bef9SDimitry Andric }
167e8d8bef9SDimitry Andric 
168e8d8bef9SDimitry Andric std::unique_ptr<IPDBEnumSymbols>
findInlineFramesByRVA(uint32_t RVA) const1690b57cec5SDimitry Andric PDBSymbol::findInlineFramesByRVA(uint32_t RVA) const {
1700b57cec5SDimitry Andric   return RawSymbol->findInlineFramesByRVA(RVA);
1710b57cec5SDimitry Andric }
1720b57cec5SDimitry Andric 
173e8d8bef9SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers>
findInlineeLinesByVA(uint64_t VA,uint32_t Length) const174e8d8bef9SDimitry Andric PDBSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
175e8d8bef9SDimitry Andric   return RawSymbol->findInlineeLinesByVA(VA, Length);
176e8d8bef9SDimitry Andric }
177e8d8bef9SDimitry Andric 
178e8d8bef9SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers>
findInlineeLinesByRVA(uint32_t RVA,uint32_t Length) const179e8d8bef9SDimitry Andric PDBSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
180e8d8bef9SDimitry Andric   return RawSymbol->findInlineeLinesByRVA(RVA, Length);
181e8d8bef9SDimitry Andric }
182e8d8bef9SDimitry Andric 
getName() const183e8d8bef9SDimitry Andric std::string PDBSymbol::getName() const { return RawSymbol->getName(); }
184e8d8bef9SDimitry Andric 
1850b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSymbols>
getChildStats(TagStats & Stats) const1860b57cec5SDimitry Andric PDBSymbol::getChildStats(TagStats &Stats) const {
1870b57cec5SDimitry Andric   std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren());
1880b57cec5SDimitry Andric   if (!Result)
1890b57cec5SDimitry Andric     return nullptr;
1900b57cec5SDimitry Andric   Stats.clear();
1910b57cec5SDimitry Andric   while (auto Child = Result->getNext()) {
1920b57cec5SDimitry Andric     ++Stats[Child->getSymTag()];
1930b57cec5SDimitry Andric   }
1940b57cec5SDimitry Andric   Result->reset();
1950b57cec5SDimitry Andric   return Result;
1960b57cec5SDimitry Andric }
1970b57cec5SDimitry Andric 
getSymbolByIdHelper(uint32_t Id) const1980b57cec5SDimitry Andric std::unique_ptr<PDBSymbol> PDBSymbol::getSymbolByIdHelper(uint32_t Id) const {
1990b57cec5SDimitry Andric   return Session.getSymbolById(Id);
2000b57cec5SDimitry Andric }
2010b57cec5SDimitry Andric 
dumpSymbolIdField(raw_ostream & OS,StringRef Name,SymIndexId Value,int Indent,const IPDBSession & Session,PdbSymbolIdField FieldId,PdbSymbolIdField ShowFlags,PdbSymbolIdField RecurseFlags)2020b57cec5SDimitry Andric void llvm::pdb::dumpSymbolIdField(raw_ostream &OS, StringRef Name,
2030b57cec5SDimitry Andric                                   SymIndexId Value, int Indent,
2040b57cec5SDimitry Andric                                   const IPDBSession &Session,
2050b57cec5SDimitry Andric                                   PdbSymbolIdField FieldId,
2060b57cec5SDimitry Andric                                   PdbSymbolIdField ShowFlags,
2070b57cec5SDimitry Andric                                   PdbSymbolIdField RecurseFlags) {
2080b57cec5SDimitry Andric   if ((FieldId & ShowFlags) == PdbSymbolIdField::None)
2090b57cec5SDimitry Andric     return;
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   OS << "\n";
2120b57cec5SDimitry Andric   OS.indent(Indent);
2130b57cec5SDimitry Andric   OS << Name << ": " << Value;
2140b57cec5SDimitry Andric   // Don't recurse unless the user requested it.
2150b57cec5SDimitry Andric   if ((FieldId & RecurseFlags) == PdbSymbolIdField::None)
2160b57cec5SDimitry Andric     return;
2170b57cec5SDimitry Andric   // And obviously don't recurse on the symbol itself.
2180b57cec5SDimitry Andric   if (FieldId == PdbSymbolIdField::SymIndexId)
2190b57cec5SDimitry Andric     return;
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   auto Child = Session.getSymbolById(Value);
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric   // It could have been a placeholder symbol for a type we don't yet support,
2240b57cec5SDimitry Andric   // so just exit in that case.
2250b57cec5SDimitry Andric   if (!Child)
2260b57cec5SDimitry Andric     return;
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   // Don't recurse more than once, so pass PdbSymbolIdField::None) for the
2290b57cec5SDimitry Andric   // recurse flags.
2300b57cec5SDimitry Andric   Child->defaultDump(OS, Indent + 2, ShowFlags, PdbSymbolIdField::None);
2310b57cec5SDimitry Andric }
232