Path: blob/main/contrib/llvm-project/llvm/tools/llvm-pdbutil/PrettyFunctionDumper.cpp
35259 views
//===- PrettyFunctionDumper.cpp --------------------------------- *- 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 "PrettyFunctionDumper.h"9#include "PrettyBuiltinDumper.h"1011#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"12#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"13#include "llvm/DebugInfo/PDB/IPDBSession.h"14#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"15#include "llvm/DebugInfo/PDB/PDBExtras.h"16#include "llvm/DebugInfo/PDB/PDBSymbolData.h"17#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"18#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"19#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"20#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"21#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"22#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"23#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"24#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"25#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"26#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"27#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"28#include "llvm/Support/Format.h"29#include "llvm/Support/FormatVariadic.h"3031using namespace llvm;32using namespace llvm::codeview;33using namespace llvm::pdb;3435namespace {36template <class T>37void dumpClassParentWithScopeOperator(const T &Symbol, LinePrinter &Printer,38FunctionDumper &Dumper) {39uint32_t ClassParentId = Symbol.getClassParentId();40auto ClassParent =41Symbol.getSession().template getConcreteSymbolById<PDBSymbolTypeUDT>(42ClassParentId);43if (!ClassParent)44return;4546WithColor(Printer, PDB_ColorItem::Type).get() << ClassParent->getName();47Printer << "::";48}49}5051FunctionDumper::FunctionDumper(LinePrinter &P)52: PDBSymDumper(true), Printer(P) {}5354void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol,55const char *Name, PointerType Pointer) {56auto ReturnType = Symbol.getReturnType();57if (!ReturnType)58Printer << "<unknown-type>";59else60ReturnType->dump(*this);61Printer << " ";62uint32_t ClassParentId = Symbol.getClassParentId();63auto ClassParent =64Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(65ClassParentId);6667PDB_CallingConv CC = Symbol.getCallingConvention();68bool ShouldDumpCallingConvention = true;69if ((ClassParent && CC == CallingConvention::ThisCall) ||70(!ClassParent && CC == CallingConvention::NearStdCall)) {71ShouldDumpCallingConvention = false;72}7374if (Pointer == PointerType::None) {75if (ShouldDumpCallingConvention)76WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";77if (ClassParent) {78Printer << "(";79WithColor(Printer, PDB_ColorItem::Identifier).get()80<< ClassParent->getName();81Printer << "::)";82}83} else {84Printer << "(";85if (ShouldDumpCallingConvention)86WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";87if (ClassParent) {88WithColor(Printer, PDB_ColorItem::Identifier).get()89<< ClassParent->getName();90Printer << "::";91}92if (Pointer == PointerType::Reference)93Printer << "&";94else95Printer << "*";96if (Name)97WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;98Printer << ")";99}100101Printer << "(";102if (auto ChildEnum = Symbol.getArguments()) {103uint32_t Index = 0;104while (auto Arg = ChildEnum->getNext()) {105Arg->dump(*this);106if (++Index < ChildEnum->getChildCount())107Printer << ", ";108}109}110Printer << ")";111112if (Symbol.isConstType())113WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";114if (Symbol.isVolatileType())115WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";116}117118void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer) {119uint64_t FuncStart = Symbol.getVirtualAddress();120uint64_t FuncEnd = FuncStart + Symbol.getLength();121122Printer << "func [";123WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncStart, 10);124if (auto DebugStart = Symbol.findOneChild<PDBSymbolFuncDebugStart>()) {125uint64_t Prologue = DebugStart->getVirtualAddress() - FuncStart;126WithColor(Printer, PDB_ColorItem::Offset).get()127<< formatv("+{0,2}", Prologue);128}129Printer << " - ";130WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncEnd, 10);131if (auto DebugEnd = Symbol.findOneChild<PDBSymbolFuncDebugEnd>()) {132uint64_t Epilogue = FuncEnd - DebugEnd->getVirtualAddress();133WithColor(Printer, PDB_ColorItem::Offset).get()134<< formatv("-{0,2}", Epilogue);135}136137WithColor(Printer, PDB_ColorItem::Comment).get()138<< formatv(" | sizeof={0,3}", Symbol.getLength());139Printer << "] (";140141if (Symbol.hasFramePointer()) {142WithColor(Printer, PDB_ColorItem::Register).get()143<< CPURegister{Symbol.getRawSymbol().getPlatform(),144Symbol.getLocalBasePointerRegisterId()};145} else {146WithColor(Printer, PDB_ColorItem::Register).get() << "FPO";147}148Printer << ") ";149150if (Symbol.isVirtual() || Symbol.isPureVirtual())151WithColor(Printer, PDB_ColorItem::Keyword).get() << "virtual ";152153auto Signature = Symbol.getSignature();154if (!Signature) {155WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();156if (Pointer == PointerType::Pointer)157Printer << "*";158else if (Pointer == FunctionDumper::PointerType::Reference)159Printer << "&";160return;161}162163auto ReturnType = Signature->getReturnType();164ReturnType->dump(*this);165Printer << " ";166167auto ClassParent = Symbol.getClassParent();168CallingConvention CC = Signature->getCallingConvention();169if (Pointer != FunctionDumper::PointerType::None)170Printer << "(";171172if ((ClassParent && CC != CallingConvention::ThisCall) ||173(!ClassParent && CC != CallingConvention::NearStdCall)) {174WithColor(Printer, PDB_ColorItem::Keyword).get()175<< Signature->getCallingConvention() << " ";176}177WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();178if (Pointer != FunctionDumper::PointerType::None) {179if (Pointer == PointerType::Pointer)180Printer << "*";181else if (Pointer == FunctionDumper::PointerType::Reference)182Printer << "&";183Printer << ")";184}185186Printer << "(";187if (auto Arguments = Symbol.getArguments()) {188uint32_t Index = 0;189while (auto Arg = Arguments->getNext()) {190auto ArgType = Arg->getType();191ArgType->dump(*this);192WithColor(Printer, PDB_ColorItem::Identifier).get() << " "193<< Arg->getName();194if (++Index < Arguments->getChildCount())195Printer << ", ";196}197if (Signature->isCVarArgs())198Printer << ", ...";199}200Printer << ")";201if (Symbol.isConstType())202WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";203if (Symbol.isVolatileType())204WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";205if (Symbol.isPureVirtual())206Printer << " = 0";207}208209void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol) {210auto ElementType = Symbol.getElementType();211212ElementType->dump(*this);213Printer << "[";214WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Symbol.getLength();215Printer << "]";216}217218void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {219BuiltinDumper Dumper(Printer);220Dumper.start(Symbol);221}222223void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol) {224dumpClassParentWithScopeOperator(Symbol, Printer, *this);225WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();226}227228void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) {229// PDBSymbolTypeFunctionArg is just a shim over the real argument. Just drill230// through to the real thing and dump it.231uint32_t TypeId = Symbol.getTypeId();232auto Type = Symbol.getSession().getSymbolById(TypeId);233if (Type)234Type->dump(*this);235else236Printer << "<unknown-type>";237}238239void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {240dumpClassParentWithScopeOperator(Symbol, Printer, *this);241WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();242}243244void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol) {245auto PointeeType = Symbol.getPointeeType();246if (!PointeeType)247return;248249if (auto FuncSig = unique_dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType)) {250FunctionDumper NestedDumper(Printer);251PointerType Pointer =252Symbol.isReference() ? PointerType::Reference : PointerType::Pointer;253NestedDumper.start(*FuncSig, nullptr, Pointer);254} else {255if (Symbol.isConstType())256WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";257if (Symbol.isVolatileType())258WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";259PointeeType->dump(*this);260Printer << (Symbol.isReference() ? "&" : "*");261262if (Symbol.getRawSymbol().isRestrictedType())263WithColor(Printer, PDB_ColorItem::Keyword).get() << " __restrict";264}265}266267void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol) {268WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();269}270271272