blob: 29ba15d521f0e213b0bc63efa3e9917730c9dba1 [file] [log] [blame]
Zachary Turner9a818ad2015-02-22 22:03:38 +00001//===- FunctionDumper.cpp ------------------------------------ *- C++ *-===//
2//
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
10#include "FunctionDumper.h"
Zachary Turnerd270d222015-02-26 23:49:23 +000011#include "BuiltinDumper.h"
Zachary Turner2d11c202015-02-27 09:15:59 +000012#include "LinePrinter.h"
Zachary Turner29c69102015-02-23 05:58:34 +000013#include "llvm-pdbdump.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000014
15#include "llvm/DebugInfo/PDB/IPDBSession.h"
Zachary Turnerec28fc32016-05-04 20:32:13 +000016#include "llvm/DebugInfo/PDB/PDBExtras.h"
Zachary Turner29c69102015-02-23 05:58:34 +000017#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000018#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
Zachary Turner29c69102015-02-23 05:58:34 +000019#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
20#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000021#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000022#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"
Zachary Turner29c69102015-02-23 05:58:34 +000028#include "llvm/Support/Format.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 Turner2d11c202015-02-27 09:15:59 +0000122 WithColor(Printer, PDB_ColorItem::Offset).get() << "+" << Prologue;
123 }
Zachary Turner7797c722015-03-02 04:39:56 +0000124 Printer << " - ";
125 WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncEnd, 10);
Zachary Turner2d11c202015-02-27 09:15:59 +0000126 if (auto DebugEnd = Symbol.findOneChild<PDBSymbolFuncDebugEnd>()) {
Zachary Turnere5cb2692015-05-01 20:24:26 +0000127 uint64_t Epilogue = FuncEnd - DebugEnd->getVirtualAddress();
Zachary Turner2d11c202015-02-27 09:15:59 +0000128 WithColor(Printer, PDB_ColorItem::Offset).get() << "-" << Epilogue;
129 }
Zachary Turner7797c722015-03-02 04:39:56 +0000130 Printer << "] (";
Zachary Turner29c69102015-02-23 05:58:34 +0000131
Zachary Turner7797c722015-03-02 04:39:56 +0000132 if (Symbol.hasFramePointer()) {
133 WithColor(Printer, PDB_ColorItem::Register).get()
134 << Symbol.getLocalBasePointerRegisterId();
135 } else {
136 WithColor(Printer, PDB_ColorItem::Register).get() << "FPO";
137 }
138 Printer << ") ";
Zachary Turner29c69102015-02-23 05:58:34 +0000139
Zachary Turner9a818ad2015-02-22 22:03:38 +0000140 if (Symbol.isVirtual() || Symbol.isPureVirtual())
Zachary Turner2d11c202015-02-27 09:15:59 +0000141 WithColor(Printer, PDB_ColorItem::Keyword).get() << "virtual ";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000142
143 auto Signature = Symbol.getSignature();
144 if (!Signature) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000145 WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
Zachary Turner29c69102015-02-23 05:58:34 +0000146 if (Pointer == PointerType::Pointer)
Zachary Turner2d11c202015-02-27 09:15:59 +0000147 Printer << "*";
Zachary Turner29c69102015-02-23 05:58:34 +0000148 else if (Pointer == FunctionDumper::PointerType::Reference)
Zachary Turner2d11c202015-02-27 09:15:59 +0000149 Printer << "&";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000150 return;
151 }
152
153 auto ReturnType = Signature->getReturnType();
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000154 ReturnType->dump(*this);
Zachary Turner2d11c202015-02-27 09:15:59 +0000155 Printer << " ";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000156
Zachary Turner29c69102015-02-23 05:58:34 +0000157 auto ClassParent = Symbol.getClassParent();
Reid Kleckner72e2ba72016-01-13 19:32:35 +0000158 CallingConvention CC = Signature->getCallingConvention();
Zachary Turner29c69102015-02-23 05:58:34 +0000159 if (Pointer != FunctionDumper::PointerType::None)
Zachary Turner2d11c202015-02-27 09:15:59 +0000160 Printer << "(";
Zachary Turner29c69102015-02-23 05:58:34 +0000161
Reid Kleckner72e2ba72016-01-13 19:32:35 +0000162 if ((ClassParent && CC != CallingConvention::ThisCall) ||
163 (!ClassParent && CC != CallingConvention::NearStdCall)) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000164 WithColor(Printer, PDB_ColorItem::Keyword).get()
165 << Signature->getCallingConvention() << " ";
166 }
167 WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
Zachary Turner29c69102015-02-23 05:58:34 +0000168 if (Pointer != FunctionDumper::PointerType::None) {
169 if (Pointer == PointerType::Pointer)
Zachary Turner2d11c202015-02-27 09:15:59 +0000170 Printer << "*";
Zachary Turner29c69102015-02-23 05:58:34 +0000171 else if (Pointer == FunctionDumper::PointerType::Reference)
Zachary Turner2d11c202015-02-27 09:15:59 +0000172 Printer << "&";
173 Printer << ")";
Zachary Turner29c69102015-02-23 05:58:34 +0000174 }
Zachary Turner9a818ad2015-02-22 22:03:38 +0000175
Zachary Turner2d11c202015-02-27 09:15:59 +0000176 Printer << "(";
Zachary Turner29c69102015-02-23 05:58:34 +0000177 if (auto Arguments = Symbol.getArguments()) {
Zachary Turner9a818ad2015-02-22 22:03:38 +0000178 uint32_t Index = 0;
Zachary Turner29c69102015-02-23 05:58:34 +0000179 while (auto Arg = Arguments->getNext()) {
180 auto ArgType = Arg->getType();
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000181 ArgType->dump(*this);
Zachary Turner2d11c202015-02-27 09:15:59 +0000182 WithColor(Printer, PDB_ColorItem::Identifier).get() << " "
183 << Arg->getName();
Zachary Turner29c69102015-02-23 05:58:34 +0000184 if (++Index < Arguments->getChildCount())
Zachary Turner2d11c202015-02-27 09:15:59 +0000185 Printer << ", ";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000186 }
187 }
Zachary Turner2d11c202015-02-27 09:15:59 +0000188 Printer << ")";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000189 if (Symbol.isConstType())
Zachary Turner2d11c202015-02-27 09:15:59 +0000190 WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000191 if (Symbol.isVolatileType())
Zachary Turner2d11c202015-02-27 09:15:59 +0000192 WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000193 if (Symbol.isPureVirtual())
Zachary Turner2d11c202015-02-27 09:15:59 +0000194 Printer << " = 0";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000195}
196
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000197void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol) {
Zachary Turner9a818ad2015-02-22 22:03:38 +0000198 uint32_t ElementTypeId = Symbol.getTypeId();
199 auto ElementType = Symbol.getSession().getSymbolById(ElementTypeId);
200 if (!ElementType)
201 return;
202
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000203 ElementType->dump(*this);
Zachary Turner2d11c202015-02-27 09:15:59 +0000204 Printer << "[";
205 WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Symbol.getLength();
206 Printer << "]";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000207}
208
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000209void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000210 BuiltinDumper Dumper(Printer);
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000211 Dumper.start(Symbol);
Zachary Turner9a818ad2015-02-22 22:03:38 +0000212}
213
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000214void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000215 dumpClassParentWithScopeOperator(Symbol, Printer, *this);
216 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
Zachary Turner9a818ad2015-02-22 22:03:38 +0000217}
218
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000219void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) {
Zachary Turner9a818ad2015-02-22 22:03:38 +0000220 // PDBSymbolTypeFunctionArg is just a shim over the real argument. Just drill
Zachary Turner29c69102015-02-23 05:58:34 +0000221 // through to the real thing and dump it.
Zachary Turner9a818ad2015-02-22 22:03:38 +0000222 uint32_t TypeId = Symbol.getTypeId();
223 auto Type = Symbol.getSession().getSymbolById(TypeId);
224 if (!Type)
225 return;
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000226 Type->dump(*this);
Zachary Turner9a818ad2015-02-22 22:03:38 +0000227}
228
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000229void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000230 dumpClassParentWithScopeOperator(Symbol, Printer, *this);
231 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
Zachary Turner9a818ad2015-02-22 22:03:38 +0000232}
233
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000234void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol) {
Zachary Turner9a818ad2015-02-22 22:03:38 +0000235 uint32_t PointeeId = Symbol.getTypeId();
236 auto PointeeType = Symbol.getSession().getSymbolById(PointeeId);
237 if (!PointeeType)
238 return;
239
240 if (auto FuncSig = dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000241 FunctionDumper NestedDumper(Printer);
Zachary Turner9a818ad2015-02-22 22:03:38 +0000242 PointerType Pointer =
243 Symbol.isReference() ? PointerType::Reference : PointerType::Pointer;
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000244 NestedDumper.start(*FuncSig, nullptr, Pointer);
Zachary Turner9a818ad2015-02-22 22:03:38 +0000245 } else {
246 if (Symbol.isConstType())
Zachary Turner2d11c202015-02-27 09:15:59 +0000247 WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000248 if (Symbol.isVolatileType())
Zachary Turner2d11c202015-02-27 09:15:59 +0000249 WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000250 PointeeType->dump(*this);
251 Printer << (Symbol.isReference() ? "&" : "*");
Zachary Turner9a818ad2015-02-22 22:03:38 +0000252 }
253}
254
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000255void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000256 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
Zachary Turner9a818ad2015-02-22 22:03:38 +0000257}