brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.2 KiB · 83cf4d9 Raw
271 lines · cpp
1//===- PrettyFunctionDumper.cpp --------------------------------- *- C++ *-===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "PrettyFunctionDumper.h"10#include "PrettyBuiltinDumper.h"11 12#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"13#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"14#include "llvm/DebugInfo/PDB/IPDBSession.h"15#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"16#include "llvm/DebugInfo/PDB/PDBExtras.h"17#include "llvm/DebugInfo/PDB/PDBSymbolData.h"18#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"19#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"20#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"21#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"22#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"23#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"24#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"25#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"26#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"27#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"28#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"29#include "llvm/Support/Format.h"30#include "llvm/Support/FormatVariadic.h"31 32using namespace llvm;33using namespace llvm::codeview;34using namespace llvm::pdb;35 36namespace {37template <class T>38void dumpClassParentWithScopeOperator(const T &Symbol, LinePrinter &Printer,39                                      FunctionDumper &Dumper) {40  uint32_t ClassParentId = Symbol.getClassParentId();41  auto ClassParent =42      Symbol.getSession().template getConcreteSymbolById<PDBSymbolTypeUDT>(43          ClassParentId);44  if (!ClassParent)45    return;46 47  WithColor(Printer, PDB_ColorItem::Type).get() << ClassParent->getName();48  Printer << "::";49}50}51 52FunctionDumper::FunctionDumper(LinePrinter &P)53    : PDBSymDumper(true), Printer(P) {}54 55void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol,56                           const char *Name, PointerType Pointer) {57  auto ReturnType = Symbol.getReturnType();58  if (!ReturnType)59    Printer << "<unknown-type>";60  else61    ReturnType->dump(*this);62  Printer << " ";63  uint32_t ClassParentId = Symbol.getClassParentId();64  auto ClassParent =65      Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(66          ClassParentId);67 68  PDB_CallingConv CC = Symbol.getCallingConvention();69  bool ShouldDumpCallingConvention = true;70  if ((ClassParent && CC == CallingConvention::ThisCall) ||71      (!ClassParent && CC == CallingConvention::NearStdCall)) {72    ShouldDumpCallingConvention = false;73  }74 75  if (Pointer == PointerType::None) {76    if (ShouldDumpCallingConvention)77      WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";78    if (ClassParent) {79      Printer << "(";80      WithColor(Printer, PDB_ColorItem::Identifier).get()81          << ClassParent->getName();82      Printer << "::)";83    }84  } else {85    Printer << "(";86    if (ShouldDumpCallingConvention)87      WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";88    if (ClassParent) {89      WithColor(Printer, PDB_ColorItem::Identifier).get()90          << ClassParent->getName();91      Printer << "::";92    }93    if (Pointer == PointerType::Reference)94      Printer << "&";95    else96      Printer << "*";97    if (Name)98      WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;99    Printer << ")";100  }101 102  Printer << "(";103  if (auto ChildEnum = Symbol.getArguments()) {104    uint32_t Index = 0;105    while (auto Arg = ChildEnum->getNext()) {106      Arg->dump(*this);107      if (++Index < ChildEnum->getChildCount())108        Printer << ", ";109    }110  }111  Printer << ")";112 113  if (Symbol.isConstType())114    WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";115  if (Symbol.isVolatileType())116    WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";117}118 119void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer) {120  uint64_t FuncStart = Symbol.getVirtualAddress();121  uint64_t FuncEnd = FuncStart + Symbol.getLength();122 123  Printer << "func [";124  WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncStart, 10);125  if (auto DebugStart = Symbol.findOneChild<PDBSymbolFuncDebugStart>()) {126    uint64_t Prologue = DebugStart->getVirtualAddress() - FuncStart;127    WithColor(Printer, PDB_ColorItem::Offset).get()128        << formatv("+{0,2}", Prologue);129  }130  Printer << " - ";131  WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncEnd, 10);132  if (auto DebugEnd = Symbol.findOneChild<PDBSymbolFuncDebugEnd>()) {133    uint64_t Epilogue = FuncEnd - DebugEnd->getVirtualAddress();134    WithColor(Printer, PDB_ColorItem::Offset).get()135        << formatv("-{0,2}", Epilogue);136  }137 138  WithColor(Printer, PDB_ColorItem::Comment).get()139      << formatv(" | sizeof={0,3}", Symbol.getLength());140  Printer << "] (";141 142  if (Symbol.hasFramePointer()) {143    WithColor(Printer, PDB_ColorItem::Register).get()144        << CPURegister{Symbol.getRawSymbol().getPlatform(),145                       Symbol.getLocalBasePointerRegisterId()};146  } else {147    WithColor(Printer, PDB_ColorItem::Register).get() << "FPO";148  }149  Printer << ") ";150 151  if (Symbol.isVirtual() || Symbol.isPureVirtual())152    WithColor(Printer, PDB_ColorItem::Keyword).get() << "virtual ";153 154  auto Signature = Symbol.getSignature();155  if (!Signature) {156    WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();157    if (Pointer == PointerType::Pointer)158      Printer << "*";159    else if (Pointer == FunctionDumper::PointerType::Reference)160      Printer << "&";161    return;162  }163 164  auto ReturnType = Signature->getReturnType();165  ReturnType->dump(*this);166  Printer << " ";167 168  auto ClassParent = Symbol.getClassParent();169  CallingConvention CC = Signature->getCallingConvention();170  if (Pointer != FunctionDumper::PointerType::None)171    Printer << "(";172 173  if ((ClassParent && CC != CallingConvention::ThisCall) ||174      (!ClassParent && CC != CallingConvention::NearStdCall)) {175    WithColor(Printer, PDB_ColorItem::Keyword).get()176        << Signature->getCallingConvention() << " ";177  }178  WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();179  if (Pointer != FunctionDumper::PointerType::None) {180    if (Pointer == PointerType::Pointer)181      Printer << "*";182    else if (Pointer == FunctionDumper::PointerType::Reference)183      Printer << "&";184    Printer << ")";185  }186 187  Printer << "(";188  if (auto Arguments = Symbol.getArguments()) {189    uint32_t Index = 0;190    while (auto Arg = Arguments->getNext()) {191      auto ArgType = Arg->getType();192      ArgType->dump(*this);193      WithColor(Printer, PDB_ColorItem::Identifier).get() << " "194                                                          << Arg->getName();195      if (++Index < Arguments->getChildCount())196        Printer << ", ";197    }198    if (Signature->isCVarArgs())199      Printer << ", ...";200  }201  Printer << ")";202  if (Symbol.isConstType())203    WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";204  if (Symbol.isVolatileType())205    WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";206  if (Symbol.isPureVirtual())207    Printer << " = 0";208}209 210void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol) {211  auto ElementType = Symbol.getElementType();212 213  ElementType->dump(*this);214  Printer << "[";215  WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Symbol.getLength();216  Printer << "]";217}218 219void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {220  BuiltinDumper Dumper(Printer);221  Dumper.start(Symbol);222}223 224void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol) {225  dumpClassParentWithScopeOperator(Symbol, Printer, *this);226  WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();227}228 229void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) {230  // PDBSymbolTypeFunctionArg is just a shim over the real argument.  Just drill231  // through to the real thing and dump it.232  uint32_t TypeId = Symbol.getTypeId();233  auto Type = Symbol.getSession().getSymbolById(TypeId);234  if (Type)235    Type->dump(*this);236  else237    Printer << "<unknown-type>";238}239 240void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {241  dumpClassParentWithScopeOperator(Symbol, Printer, *this);242  WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();243}244 245void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol) {246  auto PointeeType = Symbol.getPointeeType();247  if (!PointeeType)248    return;249 250  if (auto FuncSig = unique_dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType)) {251    FunctionDumper NestedDumper(Printer);252    PointerType Pointer =253        Symbol.isReference() ? PointerType::Reference : PointerType::Pointer;254    NestedDumper.start(*FuncSig, nullptr, Pointer);255  } else {256    if (Symbol.isConstType())257      WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";258    if (Symbol.isVolatileType())259      WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";260    PointeeType->dump(*this);261    Printer << (Symbol.isReference() ? "&" : "*");262 263    if (Symbol.getRawSymbol().isRestrictedType())264      WithColor(Printer, PDB_ColorItem::Keyword).get() << " __restrict";265  }266}267 268void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol) {269  WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();270}271