PDBSymbol.cpp revision 344779
10SN/A//===- PDBSymbol.cpp - base class for user-facing symbol types --*- C++ -*-===// 22362SN/A// 30SN/A// The LLVM Compiler Infrastructure 40SN/A// 50SN/A// This file is distributed under the University of Illinois Open Source 60SN/A// License. See LICENSE.TXT for details. 72362SN/A// 80SN/A//===----------------------------------------------------------------------===// 92362SN/A 100SN/A#include "llvm/DebugInfo/PDB/PDBSymbol.h" 110SN/A#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 120SN/A#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" 130SN/A#include "llvm/DebugInfo/PDB/IPDBSession.h" 140SN/A#include "llvm/DebugInfo/PDB/PDBExtras.h" 150SN/A#include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h" 160SN/A#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h" 170SN/A#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 180SN/A#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h" 190SN/A#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h" 200SN/A#include "llvm/DebugInfo/PDB/PDBSymbolCustom.h" 212362SN/A#include "llvm/DebugInfo/PDB/PDBSymbolData.h" 222362SN/A#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" 232362SN/A#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" 240SN/A#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" 250SN/A#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h" 260SN/A#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h" 270SN/A#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" 280SN/A#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" 290SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" 300SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" 310SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" 320SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h" 330SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h" 340SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" 3513629Savstepan#include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h" 3613629Savstepan#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" 3713629Savstepan#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" 380SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h" 390SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" 400SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" 4113629Savstepan#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 420SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" 430SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h" 440SN/A#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h" 450SN/A#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h" 460SN/A#include "llvm/DebugInfo/PDB/PDBTypes.h" 470SN/A#include <algorithm> 480SN/A#include <memory> 4913629Savstepan 500SN/Ausing namespace llvm; 510SN/Ausing namespace llvm::pdb; 520SN/A 530SN/APDBSymbol::PDBSymbol(const IPDBSession &PDBSession) : Session(PDBSession) {} 5413629Savstepan 5513629SavstepanPDBSymbol::PDBSymbol(PDBSymbol &&Other) 560SN/A : Session(Other.Session), RawSymbol(std::move(Other.RawSymbol)) {} 570SN/A 580SN/APDBSymbol::~PDBSymbol() = default; 590SN/A 600SN/A#define FACTORY_SYMTAG_CASE(Tag, Type) \ 619458SN/A case PDB_SymType::Tag: \ 620SN/A return std::unique_ptr<PDBSymbol>(new Type(PDBSession)); 630SN/A 640SN/Astd::unique_ptr<PDBSymbol> 650SN/APDBSymbol::createSymbol(const IPDBSession &PDBSession, PDB_SymType Tag) { 660SN/A switch (Tag) { 670SN/A FACTORY_SYMTAG_CASE(Exe, PDBSymbolExe) 680SN/A FACTORY_SYMTAG_CASE(Compiland, PDBSymbolCompiland) 690SN/A FACTORY_SYMTAG_CASE(CompilandDetails, PDBSymbolCompilandDetails) 700SN/A FACTORY_SYMTAG_CASE(CompilandEnv, PDBSymbolCompilandEnv) 710SN/A FACTORY_SYMTAG_CASE(Function, PDBSymbolFunc) 720SN/A FACTORY_SYMTAG_CASE(Block, PDBSymbolBlock) 730SN/A FACTORY_SYMTAG_CASE(Data, PDBSymbolData) 740SN/A FACTORY_SYMTAG_CASE(Annotation, PDBSymbolAnnotation) 750SN/A FACTORY_SYMTAG_CASE(Label, PDBSymbolLabel) 760SN/A FACTORY_SYMTAG_CASE(PublicSymbol, PDBSymbolPublicSymbol) 779458SN/A FACTORY_SYMTAG_CASE(UDT, PDBSymbolTypeUDT) 780SN/A FACTORY_SYMTAG_CASE(Enum, PDBSymbolTypeEnum) 790SN/A FACTORY_SYMTAG_CASE(FunctionSig, PDBSymbolTypeFunctionSig) 800SN/A FACTORY_SYMTAG_CASE(PointerType, PDBSymbolTypePointer) 8113629Savstepan FACTORY_SYMTAG_CASE(ArrayType, PDBSymbolTypeArray) 820SN/A FACTORY_SYMTAG_CASE(BuiltinType, PDBSymbolTypeBuiltin) 8313629Savstepan FACTORY_SYMTAG_CASE(Typedef, PDBSymbolTypeTypedef) 840SN/A FACTORY_SYMTAG_CASE(BaseClass, PDBSymbolTypeBaseClass) 8510735Syan FACTORY_SYMTAG_CASE(Friend, PDBSymbolTypeFriend) 8610735Syan FACTORY_SYMTAG_CASE(FunctionArg, PDBSymbolTypeFunctionArg) 870SN/A FACTORY_SYMTAG_CASE(FuncDebugStart, PDBSymbolFuncDebugStart) 880SN/A FACTORY_SYMTAG_CASE(FuncDebugEnd, PDBSymbolFuncDebugEnd) 890SN/A FACTORY_SYMTAG_CASE(UsingNamespace, PDBSymbolUsingNamespace) 900SN/A FACTORY_SYMTAG_CASE(VTableShape, PDBSymbolTypeVTableShape) 910SN/A FACTORY_SYMTAG_CASE(VTable, PDBSymbolTypeVTable) 920SN/A FACTORY_SYMTAG_CASE(Custom, PDBSymbolCustom) 930SN/A FACTORY_SYMTAG_CASE(Thunk, PDBSymbolThunk) 940SN/A FACTORY_SYMTAG_CASE(CustomType, PDBSymbolTypeCustom) 950SN/A FACTORY_SYMTAG_CASE(ManagedType, PDBSymbolTypeManaged) 960SN/A FACTORY_SYMTAG_CASE(Dimension, PDBSymbolTypeDimension) 970SN/A default: 980SN/A return std::unique_ptr<PDBSymbol>(new PDBSymbolUnknown(PDBSession)); 990SN/A } 1000SN/A} 1010SN/A 1020SN/Astd::unique_ptr<PDBSymbol> 1030SN/APDBSymbol::create(const IPDBSession &PDBSession, 1040SN/A std::unique_ptr<IPDBRawSymbol> RawSymbol) { 1050SN/A auto SymbolPtr = createSymbol(PDBSession, RawSymbol->getSymTag()); 1060SN/A SymbolPtr->RawSymbol = RawSymbol.get(); 1070SN/A SymbolPtr->OwnedRawSymbol = std::move(RawSymbol); 1080SN/A return SymbolPtr; 1090SN/A} 1100SN/A 1110SN/Astd::unique_ptr<PDBSymbol> PDBSymbol::create(const IPDBSession &PDBSession, 1120SN/A IPDBRawSymbol &RawSymbol) { 1130SN/A auto SymbolPtr = createSymbol(PDBSession, RawSymbol.getSymTag()); 1140SN/A SymbolPtr->RawSymbol = &RawSymbol; 1150SN/A return SymbolPtr; 1160SN/A} 1170SN/A 1180SN/Avoid PDBSymbol::defaultDump(raw_ostream &OS, int Indent, 1190SN/A PdbSymbolIdField ShowFlags, 1200SN/A PdbSymbolIdField RecurseFlags) const { 1210SN/A RawSymbol->dump(OS, Indent, ShowFlags, RecurseFlags); 1220SN/A} 1230SN/A 1240SN/Avoid PDBSymbol::dumpProperties() const { 1250SN/A outs() << "\n"; 1260SN/A defaultDump(outs(), 0, PdbSymbolIdField::All, PdbSymbolIdField::None); 1270SN/A outs().flush(); 1280SN/A} 1290SN/A 1300SN/Avoid PDBSymbol::dumpChildStats() const { 1310SN/A TagStats Stats; 1320SN/A getChildStats(Stats); 1330SN/A outs() << "\n"; 1340SN/A for (auto &Stat : Stats) { 1350SN/A outs() << Stat.first << ": " << Stat.second << "\n"; 1360SN/A } 1370SN/A outs().flush(); 1380SN/A} 13913629Savstepan 1400SN/APDB_SymType PDBSymbol::getSymTag() const { return RawSymbol->getSymTag(); } 1410SN/Auint32_t PDBSymbol::getSymIndexId() const { return RawSymbol->getSymIndexId(); } 14213629Savstepan 1430SN/Astd::unique_ptr<IPDBEnumSymbols> PDBSymbol::findAllChildren() const { 1440SN/A return findAllChildren(PDB_SymType::None); 14513629Savstepan} 14613629Savstepan 14713629Savstepanstd::unique_ptr<IPDBEnumSymbols> 14810735SyanPDBSymbol::findAllChildren(PDB_SymType Type) const { 14910735Syan return RawSymbol->findChildren(Type); 1500SN/A} 1510SN/A 1520SN/Astd::unique_ptr<IPDBEnumSymbols> 1530SN/APDBSymbol::findChildren(PDB_SymType Type, StringRef Name, 1540SN/A PDB_NameSearchFlags Flags) const { 1550SN/A return RawSymbol->findChildren(Type, Name, Flags); 1560SN/A} 1570SN/A 1580SN/Astd::unique_ptr<IPDBEnumSymbols> 1590SN/APDBSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name, 1600SN/A PDB_NameSearchFlags Flags, uint32_t RVA) const { 1610SN/A return RawSymbol->findChildrenByRVA(Type, Name, Flags, RVA); 1620SN/A} 1630SN/A 1640SN/Astd::unique_ptr<IPDBEnumSymbols> 1650SN/APDBSymbol::findInlineFramesByRVA(uint32_t RVA) const { 1660SN/A return RawSymbol->findInlineFramesByRVA(RVA); 1670SN/A} 1680SN/A 1690SN/Astd::unique_ptr<IPDBEnumSymbols> 1700SN/APDBSymbol::getChildStats(TagStats &Stats) const { 1710SN/A std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren()); 1720SN/A if (!Result) 1730SN/A return nullptr; 1740SN/A Stats.clear(); 1750SN/A while (auto Child = Result->getNext()) { 1760SN/A ++Stats[Child->getSymTag()]; 1770SN/A } 1780SN/A Result->reset(); 1790SN/A return Result; 1800SN/A} 1810SN/A 1820SN/Astd::unique_ptr<PDBSymbol> PDBSymbol::getSymbolByIdHelper(uint32_t Id) const { 1830SN/A return Session.getSymbolById(Id); 18410735Syan} 18510735Syan 1860SN/Avoid llvm::pdb::dumpSymbolIdField(raw_ostream &OS, StringRef Name, 1870SN/A SymIndexId Value, int Indent, 1880SN/A const IPDBSession &Session, 1890SN/A PdbSymbolIdField FieldId, 1900SN/A PdbSymbolIdField ShowFlags, 1910SN/A PdbSymbolIdField RecurseFlags) { 1920SN/A if ((FieldId & ShowFlags) == PdbSymbolIdField::None) 1930SN/A return; 1940SN/A 1950SN/A OS << "\n"; 1960SN/A OS.indent(Indent); 1970SN/A OS << Name << ": " << Value; 1980SN/A // Don't recurse unless the user requested it. 1990SN/A if ((FieldId & RecurseFlags) == PdbSymbolIdField::None) 2000SN/A return; 2010SN/A // And obviously don't recurse on the symbol itself. 2020SN/A if (FieldId == PdbSymbolIdField::SymIndexId) 2030SN/A return; 2040SN/A 2050SN/A auto Child = Session.getSymbolById(Value); 20610735Syan 2070SN/A // It could have been a placeholder symbol for a type we don't yet support, 2080SN/A // so just exit in that case. 2090SN/A if (!Child) 21013629Savstepan return; 21113629Savstepan 21213629Savstepan // Don't recurse more than once, so pass PdbSymbolIdField::None) for the 21313629Savstepan // recurse flags. 21410735Syan Child->defaultDump(OS, Indent + 2, ShowFlags, PdbSymbolIdField::None); 2150SN/A} 2160SN/A