851fa1f773ebdbfa9eccd5454e7793a1fc9ecd28
[oota-llvm.git] / tools / llvm-pdbdump / FunctionDumper.cpp
1 //===- 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
23 namespace {
24 template <class T>
25 void dumpClassParentWithScopeOperator(const T &Symbol, llvm::raw_ostream &OS,
26                                       llvm::FunctionDumper &Dumper) {
27   uint32_t ClassParentId = Symbol.getClassParentId();
28   auto ClassParent =
29       Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
30           ClassParentId);
31   if (!ClassParent)
32     return;
33
34   OS << ClassParent->getName() << "::";
35 }
36 }
37
38 using namespace llvm;
39
40 FunctionDumper::FunctionDumper() : PDBSymDumper(true) {}
41
42 void 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
84 void 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
119 void 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
130 void 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
138 void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
139                           int Indent) {
140   dumpClassParentWithScopeOperator(Symbol, OS, *this);
141   OS << Symbol.getName();
142 }
143
144 void 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
156 void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
157                           int Indent) {
158   dumpClassParentWithScopeOperator(Symbol, OS, *this);
159   OS << Symbol.getName();
160 }
161
162 void 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
184 void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
185                           int Indent) {
186   OS << Symbol.getName();
187 }