Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp
35266 views
//===- PDBSymbol.cpp - base class for user-facing symbol types --*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/DebugInfo/PDB/PDBSymbol.h"9#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"10#include "llvm/DebugInfo/PDB/IPDBLineNumber.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"46#include <memory>4748using namespace llvm;49using namespace llvm::pdb;5051PDBSymbol::PDBSymbol(const IPDBSession &PDBSession) : Session(PDBSession) {}5253PDBSymbol::PDBSymbol(PDBSymbol &&Other)54: Session(Other.Session), RawSymbol(std::move(Other.RawSymbol)) {}5556PDBSymbol::~PDBSymbol() = default;5758#define FACTORY_SYMTAG_CASE(Tag, Type) \59case PDB_SymType::Tag: \60return std::unique_ptr<PDBSymbol>(new Type(PDBSession));6162std::unique_ptr<PDBSymbol>63PDBSymbol::createSymbol(const IPDBSession &PDBSession, PDB_SymType Tag) {64switch (Tag) {65FACTORY_SYMTAG_CASE(Exe, PDBSymbolExe)66FACTORY_SYMTAG_CASE(Compiland, PDBSymbolCompiland)67FACTORY_SYMTAG_CASE(CompilandDetails, PDBSymbolCompilandDetails)68FACTORY_SYMTAG_CASE(CompilandEnv, PDBSymbolCompilandEnv)69FACTORY_SYMTAG_CASE(Function, PDBSymbolFunc)70FACTORY_SYMTAG_CASE(Block, PDBSymbolBlock)71FACTORY_SYMTAG_CASE(Data, PDBSymbolData)72FACTORY_SYMTAG_CASE(Annotation, PDBSymbolAnnotation)73FACTORY_SYMTAG_CASE(Label, PDBSymbolLabel)74FACTORY_SYMTAG_CASE(PublicSymbol, PDBSymbolPublicSymbol)75FACTORY_SYMTAG_CASE(UDT, PDBSymbolTypeUDT)76FACTORY_SYMTAG_CASE(Enum, PDBSymbolTypeEnum)77FACTORY_SYMTAG_CASE(FunctionSig, PDBSymbolTypeFunctionSig)78FACTORY_SYMTAG_CASE(PointerType, PDBSymbolTypePointer)79FACTORY_SYMTAG_CASE(ArrayType, PDBSymbolTypeArray)80FACTORY_SYMTAG_CASE(BuiltinType, PDBSymbolTypeBuiltin)81FACTORY_SYMTAG_CASE(Typedef, PDBSymbolTypeTypedef)82FACTORY_SYMTAG_CASE(BaseClass, PDBSymbolTypeBaseClass)83FACTORY_SYMTAG_CASE(Friend, PDBSymbolTypeFriend)84FACTORY_SYMTAG_CASE(FunctionArg, PDBSymbolTypeFunctionArg)85FACTORY_SYMTAG_CASE(FuncDebugStart, PDBSymbolFuncDebugStart)86FACTORY_SYMTAG_CASE(FuncDebugEnd, PDBSymbolFuncDebugEnd)87FACTORY_SYMTAG_CASE(UsingNamespace, PDBSymbolUsingNamespace)88FACTORY_SYMTAG_CASE(VTableShape, PDBSymbolTypeVTableShape)89FACTORY_SYMTAG_CASE(VTable, PDBSymbolTypeVTable)90FACTORY_SYMTAG_CASE(Custom, PDBSymbolCustom)91FACTORY_SYMTAG_CASE(Thunk, PDBSymbolThunk)92FACTORY_SYMTAG_CASE(CustomType, PDBSymbolTypeCustom)93FACTORY_SYMTAG_CASE(ManagedType, PDBSymbolTypeManaged)94FACTORY_SYMTAG_CASE(Dimension, PDBSymbolTypeDimension)95default:96return std::unique_ptr<PDBSymbol>(new PDBSymbolUnknown(PDBSession));97}98}99100std::unique_ptr<PDBSymbol>101PDBSymbol::create(const IPDBSession &PDBSession,102std::unique_ptr<IPDBRawSymbol> RawSymbol) {103auto SymbolPtr = createSymbol(PDBSession, RawSymbol->getSymTag());104SymbolPtr->RawSymbol = RawSymbol.get();105SymbolPtr->OwnedRawSymbol = std::move(RawSymbol);106return SymbolPtr;107}108109std::unique_ptr<PDBSymbol> PDBSymbol::create(const IPDBSession &PDBSession,110IPDBRawSymbol &RawSymbol) {111auto SymbolPtr = createSymbol(PDBSession, RawSymbol.getSymTag());112SymbolPtr->RawSymbol = &RawSymbol;113return SymbolPtr;114}115116void PDBSymbol::defaultDump(raw_ostream &OS, int Indent,117PdbSymbolIdField ShowFlags,118PdbSymbolIdField RecurseFlags) const {119RawSymbol->dump(OS, Indent, ShowFlags, RecurseFlags);120}121122void PDBSymbol::dumpProperties() const {123outs() << "\n";124defaultDump(outs(), 0, PdbSymbolIdField::All, PdbSymbolIdField::None);125outs().flush();126}127128void PDBSymbol::dumpChildStats() const {129TagStats Stats;130getChildStats(Stats);131outs() << "\n";132for (auto &Stat : Stats) {133outs() << Stat.first << ": " << Stat.second << "\n";134}135outs().flush();136}137138PDB_SymType PDBSymbol::getSymTag() const { return RawSymbol->getSymTag(); }139uint32_t PDBSymbol::getSymIndexId() const { return RawSymbol->getSymIndexId(); }140141std::unique_ptr<IPDBEnumSymbols> PDBSymbol::findAllChildren() const {142return findAllChildren(PDB_SymType::None);143}144145std::unique_ptr<IPDBEnumSymbols>146PDBSymbol::findAllChildren(PDB_SymType Type) const {147return RawSymbol->findChildren(Type);148}149150std::unique_ptr<IPDBEnumSymbols>151PDBSymbol::findChildren(PDB_SymType Type, StringRef Name,152PDB_NameSearchFlags Flags) const {153return RawSymbol->findChildren(Type, Name, Flags);154}155156std::unique_ptr<IPDBEnumSymbols>157PDBSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,158PDB_NameSearchFlags Flags, uint32_t RVA) const {159return RawSymbol->findChildrenByRVA(Type, Name, Flags, RVA);160}161162std::unique_ptr<IPDBEnumSymbols>163PDBSymbol::findInlineFramesByVA(uint64_t VA) const {164return RawSymbol->findInlineFramesByVA(VA);165}166167std::unique_ptr<IPDBEnumSymbols>168PDBSymbol::findInlineFramesByRVA(uint32_t RVA) const {169return RawSymbol->findInlineFramesByRVA(RVA);170}171172std::unique_ptr<IPDBEnumLineNumbers>173PDBSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {174return RawSymbol->findInlineeLinesByVA(VA, Length);175}176177std::unique_ptr<IPDBEnumLineNumbers>178PDBSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {179return RawSymbol->findInlineeLinesByRVA(RVA, Length);180}181182std::string PDBSymbol::getName() const { return RawSymbol->getName(); }183184std::unique_ptr<IPDBEnumSymbols>185PDBSymbol::getChildStats(TagStats &Stats) const {186std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren());187if (!Result)188return nullptr;189Stats.clear();190while (auto Child = Result->getNext()) {191++Stats[Child->getSymTag()];192}193Result->reset();194return Result;195}196197std::unique_ptr<PDBSymbol> PDBSymbol::getSymbolByIdHelper(uint32_t Id) const {198return Session.getSymbolById(Id);199}200201void llvm::pdb::dumpSymbolIdField(raw_ostream &OS, StringRef Name,202SymIndexId Value, int Indent,203const IPDBSession &Session,204PdbSymbolIdField FieldId,205PdbSymbolIdField ShowFlags,206PdbSymbolIdField RecurseFlags) {207if ((FieldId & ShowFlags) == PdbSymbolIdField::None)208return;209210OS << "\n";211OS.indent(Indent);212OS << Name << ": " << Value;213// Don't recurse unless the user requested it.214if ((FieldId & RecurseFlags) == PdbSymbolIdField::None)215return;216// And obviously don't recurse on the symbol itself.217if (FieldId == PdbSymbolIdField::SymIndexId)218return;219220auto Child = Session.getSymbolById(Value);221222// It could have been a placeholder symbol for a type we don't yet support,223// so just exit in that case.224if (!Child)225return;226227// Don't recurse more than once, so pass PdbSymbolIdField::None) for the228// recurse flags.229Child->defaultDump(OS, Indent + 2, ShowFlags, PdbSymbolIdField::None);230}231232233