blob: 13df74f20d56c126e0ad68629bac1ef44c96112f [file] [log] [blame]
Zachary Turnera9054dd2017-01-11 00:35:43 +00001//===- PrettyFunctionDumper.cpp --------------------------------- *- C++ *-===//
Zachary Turner9a818ad2015-02-22 22:03:38 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Zachary Turnera9054dd2017-01-11 00:35:43 +000010#include "PrettyFunctionDumper.h"
Zachary Turner2d11c202015-02-27 09:15:59 +000011#include "LinePrinter.h"
Zachary Turnera9054dd2017-01-11 00:35:43 +000012#include "PrettyBuiltinDumper.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000013
14#include "llvm/DebugInfo/PDB/IPDBSession.h"
Zachary Turnerec28fc32016-05-04 20:32:13 +000015#include "llvm/DebugInfo/PDB/PDBExtras.h"
Zachary Turner29c69102015-02-23 05:58:34 +000016#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000017#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
Zachary Turner29c69102015-02-23 05:58:34 +000018#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
19#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000020#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000021#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
22#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
23#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
24#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
25#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
26#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
Zachary Turner29c69102015-02-23 05:58:34 +000027#include "llvm/Support/Format.h"
Zachary Turner0683be22017-05-14 01:13:40 +000028#include "llvm/Support/FormatVariadic.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000029
Zachary Turneraea59922015-02-22 22:20:26 +000030using namespace llvm;
Reid Kleckner72e2ba72016-01-13 19:32:35 +000031using namespace llvm::codeview;
Zachary Turnerec28fc32016-05-04 20:32:13 +000032using namespace llvm::pdb;
Zachary Turneraea59922015-02-22 22:20:26 +000033
Zachary Turner9a818ad2015-02-22 22:03:38 +000034namespace {
35template <class T>
Zachary Turner2d11c202015-02-27 09:15:59 +000036void dumpClassParentWithScopeOperator(const T &Symbol, LinePrinter &Printer,
Zachary Turnerec28fc32016-05-04 20:32:13 +000037 FunctionDumper &Dumper) {
Zachary Turner9a818ad2015-02-22 22:03:38 +000038 uint32_t ClassParentId = Symbol.getClassParentId();
39 auto ClassParent =
David Majnemer3f45d402015-02-22 22:33:57 +000040 Symbol.getSession().template getConcreteSymbolById<PDBSymbolTypeUDT>(
Zachary Turner9a818ad2015-02-22 22:03:38 +000041 ClassParentId);
42 if (!ClassParent)
43 return;
44
Zachary Turner2d11c202015-02-27 09:15:59 +000045 WithColor(Printer, PDB_ColorItem::Type).get() << ClassParent->getName();
46 Printer << "::";
Zachary Turner9a818ad2015-02-22 22:03:38 +000047}
48}
49
Zachary Turner2d11c202015-02-27 09:15:59 +000050FunctionDumper::FunctionDumper(LinePrinter &P)
51 : PDBSymDumper(true), Printer(P) {}
Zachary Turner9a818ad2015-02-22 22:03:38 +000052
53void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol,
Zachary Turnerb52d08d2015-03-01 06:51:29 +000054 const char *Name, PointerType Pointer) {
Zachary Turner9a818ad2015-02-22 22:03:38 +000055 auto ReturnType = Symbol.getReturnType();
Zachary Turnerb52d08d2015-03-01 06:51:29 +000056 ReturnType->dump(*this);
Zachary Turner2d11c202015-02-27 09:15:59 +000057 Printer << " ";
Zachary Turner9a818ad2015-02-22 22:03:38 +000058 uint32_t ClassParentId = Symbol.getClassParentId();
59 auto ClassParent =
60 Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
61 ClassParentId);
62
Zachary Turnerec28fc32016-05-04 20:32:13 +000063 PDB_CallingConv CC = Symbol.getCallingConvention();
Zachary Turner29c69102015-02-23 05:58:34 +000064 bool ShouldDumpCallingConvention = true;
Reid Kleckner72e2ba72016-01-13 19:32:35 +000065 if ((ClassParent && CC == CallingConvention::ThisCall) ||
66 (!ClassParent && CC == CallingConvention::NearStdCall)) {
Zachary Turner29c69102015-02-23 05:58:34 +000067 ShouldDumpCallingConvention = false;
68 }
69
Zachary Turner9a818ad2015-02-22 22:03:38 +000070 if (Pointer == PointerType::None) {
Zachary Turner29c69102015-02-23 05:58:34 +000071 if (ShouldDumpCallingConvention)
Zachary Turner2d11c202015-02-27 09:15:59 +000072 WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";
73 if (ClassParent) {
74 Printer << "(";
75 WithColor(Printer, PDB_ColorItem::Identifier).get()
76 << ClassParent->getName();
77 Printer << "::)";
78 }
Zachary Turner9a818ad2015-02-22 22:03:38 +000079 } else {
Zachary Turner2d11c202015-02-27 09:15:59 +000080 Printer << "(";
Zachary Turner29c69102015-02-23 05:58:34 +000081 if (ShouldDumpCallingConvention)
Zachary Turner2d11c202015-02-27 09:15:59 +000082 WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";
83 if (ClassParent) {
84 WithColor(Printer, PDB_ColorItem::Identifier).get()
85 << ClassParent->getName();
86 Printer << "::";
87 }
Zachary Turner9a818ad2015-02-22 22:03:38 +000088 if (Pointer == PointerType::Reference)
Zachary Turner2d11c202015-02-27 09:15:59 +000089 Printer << "&";
Zachary Turner9a818ad2015-02-22 22:03:38 +000090 else
Zachary Turner2d11c202015-02-27 09:15:59 +000091 Printer << "*";
Zachary Turnerd270d222015-02-26 23:49:23 +000092 if (Name)
Zachary Turner2d11c202015-02-27 09:15:59 +000093 WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;
94 Printer << ")";
Zachary Turner9a818ad2015-02-22 22:03:38 +000095 }
96
Zachary Turner2d11c202015-02-27 09:15:59 +000097 Printer << "(";
Zachary Turner9a818ad2015-02-22 22:03:38 +000098 if (auto ChildEnum = Symbol.getArguments()) {
99 uint32_t Index = 0;
100 while (auto Arg = ChildEnum->getNext()) {
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000101 Arg->dump(*this);
Zachary Turner9a818ad2015-02-22 22:03:38 +0000102 if (++Index < ChildEnum->getChildCount())
Zachary Turner2d11c202015-02-27 09:15:59 +0000103 Printer << ", ";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000104 }
105 }
Zachary Turner2d11c202015-02-27 09:15:59 +0000106 Printer << ")";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000107
108 if (Symbol.isConstType())
Zachary Turner2d11c202015-02-27 09:15:59 +0000109 WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000110 if (Symbol.isVolatileType())
Zachary Turner2d11c202015-02-27 09:15:59 +0000111 WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000112}
113
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000114void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer) {
Zachary Turnere5cb2692015-05-01 20:24:26 +0000115 uint64_t FuncStart = Symbol.getVirtualAddress();
116 uint64_t FuncEnd = FuncStart + Symbol.getLength();
Zachary Turner29c69102015-02-23 05:58:34 +0000117
Zachary Turner7797c722015-03-02 04:39:56 +0000118 Printer << "func [";
119 WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncStart, 10);
Zachary Turner2d11c202015-02-27 09:15:59 +0000120 if (auto DebugStart = Symbol.findOneChild<PDBSymbolFuncDebugStart>()) {
Zachary Turnere5cb2692015-05-01 20:24:26 +0000121 uint64_t Prologue = DebugStart->getVirtualAddress() - FuncStart;
Zachary Turner0683be22017-05-14 01:13:40 +0000122 WithColor(Printer, PDB_ColorItem::Offset).get()
123 << formatv("+{0,2}", Prologue);
Zachary Turner2d11c202015-02-27 09:15:59 +0000124 }
Zachary Turner7797c722015-03-02 04:39:56 +0000125 Printer << " - ";
126 WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncEnd, 10);
Zachary Turner2d11c202015-02-27 09:15:59 +0000127 if (auto DebugEnd = Symbol.findOneChild<PDBSymbolFuncDebugEnd>()) {
Zachary Turnere5cb2692015-05-01 20:24:26 +0000128 uint64_t Epilogue = FuncEnd - DebugEnd->getVirtualAddress();
Zachary Turner0683be22017-05-14 01:13:40 +0000129 WithColor(Printer, PDB_ColorItem::Offset).get()
130 << formatv("-{0,2}", Epilogue);
Zachary Turner2d11c202015-02-27 09:15:59 +0000131 }
Zachary Turner0683be22017-05-14 01:13:40 +0000132
133 WithColor(Printer, PDB_ColorItem::Comment).get()
134 << formatv(" | sizeof={0,3}", Symbol.getLength());
Zachary Turner7797c722015-03-02 04:39:56 +0000135 Printer << "] (";
Zachary Turner29c69102015-02-23 05:58:34 +0000136
Zachary Turner7797c722015-03-02 04:39:56 +0000137 if (Symbol.hasFramePointer()) {
138 WithColor(Printer, PDB_ColorItem::Register).get()
139 << Symbol.getLocalBasePointerRegisterId();
140 } else {
141 WithColor(Printer, PDB_ColorItem::Register).get() << "FPO";
142 }
143 Printer << ") ";
Zachary Turner29c69102015-02-23 05:58:34 +0000144
Zachary Turner9a818ad2015-02-22 22:03:38 +0000145 if (Symbol.isVirtual() || Symbol.isPureVirtual())
Zachary Turner2d11c202015-02-27 09:15:59 +0000146 WithColor(Printer, PDB_ColorItem::Keyword).get() << "virtual ";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000147
148 auto Signature = Symbol.getSignature();
149 if (!Signature) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000150 WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
Zachary Turner29c69102015-02-23 05:58:34 +0000151 if (Pointer == PointerType::Pointer)
Zachary Turner2d11c202015-02-27 09:15:59 +0000152 Printer << "*";
Zachary Turner29c69102015-02-23 05:58:34 +0000153 else if (Pointer == FunctionDumper::PointerType::Reference)
Zachary Turner2d11c202015-02-27 09:15:59 +0000154 Printer << "&";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000155 return;
156 }
157
158 auto ReturnType = Signature->getReturnType();
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000159 ReturnType->dump(*this);
Zachary Turner2d11c202015-02-27 09:15:59 +0000160 Printer << " ";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000161
Zachary Turner29c69102015-02-23 05:58:34 +0000162 auto ClassParent = Symbol.getClassParent();
Reid Kleckner72e2ba72016-01-13 19:32:35 +0000163 CallingConvention CC = Signature->getCallingConvention();
Zachary Turner29c69102015-02-23 05:58:34 +0000164 if (Pointer != FunctionDumper::PointerType::None)
Zachary Turner2d11c202015-02-27 09:15:59 +0000165 Printer << "(";
Zachary Turner29c69102015-02-23 05:58:34 +0000166
Reid Kleckner72e2ba72016-01-13 19:32:35 +0000167 if ((ClassParent && CC != CallingConvention::ThisCall) ||
168 (!ClassParent && CC != CallingConvention::NearStdCall)) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000169 WithColor(Printer, PDB_ColorItem::Keyword).get()
170 << Signature->getCallingConvention() << " ";
171 }
172 WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
Zachary Turner29c69102015-02-23 05:58:34 +0000173 if (Pointer != FunctionDumper::PointerType::None) {
174 if (Pointer == PointerType::Pointer)
Zachary Turner2d11c202015-02-27 09:15:59 +0000175 Printer << "*";
Zachary Turner29c69102015-02-23 05:58:34 +0000176 else if (Pointer == FunctionDumper::PointerType::Reference)
Zachary Turner2d11c202015-02-27 09:15:59 +0000177 Printer << "&";
178 Printer << ")";
Zachary Turner29c69102015-02-23 05:58:34 +0000179 }
Zachary Turner9a818ad2015-02-22 22:03:38 +0000180
Zachary Turner2d11c202015-02-27 09:15:59 +0000181 Printer << "(";
Zachary Turner29c69102015-02-23 05:58:34 +0000182 if (auto Arguments = Symbol.getArguments()) {
Zachary Turner9a818ad2015-02-22 22:03:38 +0000183 uint32_t Index = 0;
Zachary Turner29c69102015-02-23 05:58:34 +0000184 while (auto Arg = Arguments->getNext()) {
185 auto ArgType = Arg->getType();
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000186 ArgType->dump(*this);
Zachary Turner2d11c202015-02-27 09:15:59 +0000187 WithColor(Printer, PDB_ColorItem::Identifier).get() << " "
188 << Arg->getName();
Zachary Turner29c69102015-02-23 05:58:34 +0000189 if (++Index < Arguments->getChildCount())
Zachary Turner2d11c202015-02-27 09:15:59 +0000190 Printer << ", ";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000191 }
Aaron Smith53a1a162018-01-17 01:22:03 +0000192 if (Signature->isCVarArgs())
193 Printer << ", ...";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000194 }
Zachary Turner2d11c202015-02-27 09:15:59 +0000195 Printer << ")";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000196 if (Symbol.isConstType())
Zachary Turner2d11c202015-02-27 09:15:59 +0000197 WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000198 if (Symbol.isVolatileType())
Zachary Turner2d11c202015-02-27 09:15:59 +0000199 WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000200 if (Symbol.isPureVirtual())
Zachary Turner2d11c202015-02-27 09:15:59 +0000201 Printer << " = 0";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000202}
203
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000204void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol) {
Zachary Turner1b1a70f2017-04-10 06:14:09 +0000205 auto ElementType = Symbol.getElementType();
Zachary Turner9a818ad2015-02-22 22:03:38 +0000206
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000207 ElementType->dump(*this);
Zachary Turner2d11c202015-02-27 09:15:59 +0000208 Printer << "[";
209 WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Symbol.getLength();
210 Printer << "]";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000211}
212
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000213void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000214 BuiltinDumper Dumper(Printer);
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000215 Dumper.start(Symbol);
Zachary Turner9a818ad2015-02-22 22:03:38 +0000216}
217
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000218void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000219 dumpClassParentWithScopeOperator(Symbol, Printer, *this);
220 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
Zachary Turner9a818ad2015-02-22 22:03:38 +0000221}
222
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000223void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) {
Zachary Turner9a818ad2015-02-22 22:03:38 +0000224 // PDBSymbolTypeFunctionArg is just a shim over the real argument. Just drill
Zachary Turner29c69102015-02-23 05:58:34 +0000225 // through to the real thing and dump it.
Zachary Turner9a818ad2015-02-22 22:03:38 +0000226 uint32_t TypeId = Symbol.getTypeId();
227 auto Type = Symbol.getSession().getSymbolById(TypeId);
228 if (!Type)
229 return;
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000230 Type->dump(*this);
Zachary Turner9a818ad2015-02-22 22:03:38 +0000231}
232
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000233void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000234 dumpClassParentWithScopeOperator(Symbol, Printer, *this);
235 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
Zachary Turner9a818ad2015-02-22 22:03:38 +0000236}
237
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000238void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol) {
Zachary Turner1b1a70f2017-04-10 06:14:09 +0000239 auto PointeeType = Symbol.getPointeeType();
Zachary Turner9a818ad2015-02-22 22:03:38 +0000240 if (!PointeeType)
241 return;
242
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000243 if (auto FuncSig = unique_dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType)) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000244 FunctionDumper NestedDumper(Printer);
Zachary Turner9a818ad2015-02-22 22:03:38 +0000245 PointerType Pointer =
246 Symbol.isReference() ? PointerType::Reference : PointerType::Pointer;
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000247 NestedDumper.start(*FuncSig, nullptr, Pointer);
Zachary Turner9a818ad2015-02-22 22:03:38 +0000248 } else {
249 if (Symbol.isConstType())
Zachary Turner2d11c202015-02-27 09:15:59 +0000250 WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000251 if (Symbol.isVolatileType())
Zachary Turner2d11c202015-02-27 09:15:59 +0000252 WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000253 PointeeType->dump(*this);
254 Printer << (Symbol.isReference() ? "&" : "*");
Zachary Turner9a818ad2015-02-22 22:03:38 +0000255 }
256}
257
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000258void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000259 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
Zachary Turner9a818ad2015-02-22 22:03:38 +0000260}