blob: e392c5d0778ce5c3cf96b3f80fca6210a711c209 [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"
11
12#include "llvm/DebugInfo/PDB/IPDBSession.h"
13#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
14#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
15#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
16#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
17#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
18#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
19#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
20#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
21#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
22
Zachary Turneraea59922015-02-22 22:20:26 +000023using namespace llvm;
24
Zachary Turner9a818ad2015-02-22 22:03:38 +000025namespace {
26template <class T>
27void dumpClassParentWithScopeOperator(const T &Symbol, llvm::raw_ostream &OS,
28 llvm::FunctionDumper &Dumper) {
29 uint32_t ClassParentId = Symbol.getClassParentId();
30 auto ClassParent =
31 Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
32 ClassParentId);
33 if (!ClassParent)
34 return;
35
36 OS << ClassParent->getName() << "::";
37}
38}
39
Zachary Turner9a818ad2015-02-22 22:03:38 +000040FunctionDumper::FunctionDumper() : PDBSymDumper(true) {}
41
42void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol,
43 PointerType Pointer, raw_ostream &OS) {
44 auto ReturnType = Symbol.getReturnType();
45 ReturnType->dump(OS, 0, *this);
46 OS << " ";
47 uint32_t ClassParentId = Symbol.getClassParentId();
48 auto ClassParent =
49 Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
50 ClassParentId);
51
52 if (Pointer == PointerType::None) {
53 OS << Symbol.getCallingConvention() << " ";
54 if (ClassParent)
55 OS << "(" << ClassParent->getName() << "::)";
56 } else {
57 OS << "(" << Symbol.getCallingConvention() << " ";
58 if (ClassParent)
59 OS << ClassParent->getName() << "::";
60 if (Pointer == PointerType::Reference)
61 OS << "&";
62 else
63 OS << "*";
64 OS << ")";
65 }
66
67 OS << "(";
68 if (auto ChildEnum = Symbol.getArguments()) {
69 uint32_t Index = 0;
70 while (auto Arg = ChildEnum->getNext()) {
71 Arg->dump(OS, 0, *this);
72 if (++Index < ChildEnum->getChildCount())
73 OS << ", ";
74 }
75 }
76 OS << ")";
77
78 if (Symbol.isConstType())
79 OS << " const";
80 if (Symbol.isVolatileType())
81 OS << " volatile";
82}
83
84void FunctionDumper::start(const PDBSymbolFunc &Symbol, raw_ostream &OS) {
85 if (Symbol.isVirtual() || Symbol.isPureVirtual())
86 OS << "virtual ";
87
88 auto Signature = Symbol.getSignature();
89 if (!Signature) {
90 OS << Symbol.getName();
91 return;
92 }
93
94 auto ReturnType = Signature->getReturnType();
95 ReturnType->dump(OS, 0, *this);
96
97 OS << " " << Signature->getCallingConvention() << " ";
98 OS << Symbol.getName();
99
100 OS << "(";
101 if (auto ChildEnum = Signature->getArguments()) {
102 uint32_t Index = 0;
103 while (auto Arg = ChildEnum->getNext()) {
104 Arg->dump(OS, 0, *this);
105 if (++Index < ChildEnum->getChildCount())
106 OS << ", ";
107 }
108 }
109 OS << ")";
110
111 if (Symbol.isConstType())
112 OS << " const";
113 if (Symbol.isVolatileType())
114 OS << " volatile";
115 if (Symbol.isPureVirtual())
116 OS << " = 0";
117}
118
119void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS,
120 int Indent) {
121 uint32_t ElementTypeId = Symbol.getTypeId();
122 auto ElementType = Symbol.getSession().getSymbolById(ElementTypeId);
123 if (!ElementType)
124 return;
125
126 ElementType->dump(OS, 0, *this);
127 OS << "[" << Symbol.getLength() << "]";
128}
129
130void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS,
131 int Indent) {
132 PDB_BuiltinType Type = Symbol.getBuiltinType();
133 OS << Type;
134 if (Type == PDB_BuiltinType::UInt || Type == PDB_BuiltinType::Int)
135 OS << (8 * Symbol.getLength()) << "_t";
136}
137
138void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
139 int Indent) {
140 dumpClassParentWithScopeOperator(Symbol, OS, *this);
141 OS << Symbol.getName();
142}
143
144void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol,
145 raw_ostream &OS, int Indent) {
146 // PDBSymbolTypeFunctionArg is just a shim over the real argument. Just drill
147 // through to the
148 // real thing and dump it.
149 uint32_t TypeId = Symbol.getTypeId();
150 auto Type = Symbol.getSession().getSymbolById(TypeId);
151 if (!Type)
152 return;
153 Type->dump(OS, 0, *this);
154}
155
156void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
157 int Indent) {
158 dumpClassParentWithScopeOperator(Symbol, OS, *this);
159 OS << Symbol.getName();
160}
161
162void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS,
163 int Indent) {
164 uint32_t PointeeId = Symbol.getTypeId();
165 auto PointeeType = Symbol.getSession().getSymbolById(PointeeId);
166 if (!PointeeType)
167 return;
168
169 if (auto FuncSig = dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) {
170 FunctionDumper NestedDumper;
171 PointerType Pointer =
172 Symbol.isReference() ? PointerType::Reference : PointerType::Pointer;
173 NestedDumper.start(*FuncSig, Pointer, OS);
174 } else {
175 if (Symbol.isConstType())
176 OS << "const ";
177 if (Symbol.isVolatileType())
178 OS << "volatile ";
179 PointeeType->dump(OS, Indent, *this);
180 OS << (Symbol.isReference() ? "&" : "*");
181 }
182}
183
184void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
185 int Indent) {
186 OS << Symbol.getName();
187}