summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-pdbdump/FunctionDumper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-pdbdump/FunctionDumper.cpp')
-rw-r--r--llvm/tools/llvm-pdbdump/FunctionDumper.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/llvm/tools/llvm-pdbdump/FunctionDumper.cpp b/llvm/tools/llvm-pdbdump/FunctionDumper.cpp
new file mode 100644
index 00000000000..851fa1f773e
--- /dev/null
+++ b/llvm/tools/llvm-pdbdump/FunctionDumper.cpp
@@ -0,0 +1,187 @@
+//===- FunctionDumper.cpp ------------------------------------ *- C++ *-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "FunctionDumper.h"
+
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+
+namespace {
+template <class T>
+void dumpClassParentWithScopeOperator(const T &Symbol, llvm::raw_ostream &OS,
+ llvm::FunctionDumper &Dumper) {
+ uint32_t ClassParentId = Symbol.getClassParentId();
+ auto ClassParent =
+ Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
+ ClassParentId);
+ if (!ClassParent)
+ return;
+
+ OS << ClassParent->getName() << "::";
+}
+}
+
+using namespace llvm;
+
+FunctionDumper::FunctionDumper() : PDBSymDumper(true) {}
+
+void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol,
+ PointerType Pointer, raw_ostream &OS) {
+ auto ReturnType = Symbol.getReturnType();
+ ReturnType->dump(OS, 0, *this);
+ OS << " ";
+ uint32_t ClassParentId = Symbol.getClassParentId();
+ auto ClassParent =
+ Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
+ ClassParentId);
+
+ if (Pointer == PointerType::None) {
+ OS << Symbol.getCallingConvention() << " ";
+ if (ClassParent)
+ OS << "(" << ClassParent->getName() << "::)";
+ } else {
+ OS << "(" << Symbol.getCallingConvention() << " ";
+ if (ClassParent)
+ OS << ClassParent->getName() << "::";
+ if (Pointer == PointerType::Reference)
+ OS << "&";
+ else
+ OS << "*";
+ OS << ")";
+ }
+
+ OS << "(";
+ if (auto ChildEnum = Symbol.getArguments()) {
+ uint32_t Index = 0;
+ while (auto Arg = ChildEnum->getNext()) {
+ Arg->dump(OS, 0, *this);
+ if (++Index < ChildEnum->getChildCount())
+ OS << ", ";
+ }
+ }
+ OS << ")";
+
+ if (Symbol.isConstType())
+ OS << " const";
+ if (Symbol.isVolatileType())
+ OS << " volatile";
+}
+
+void FunctionDumper::start(const PDBSymbolFunc &Symbol, raw_ostream &OS) {
+ if (Symbol.isVirtual() || Symbol.isPureVirtual())
+ OS << "virtual ";
+
+ auto Signature = Symbol.getSignature();
+ if (!Signature) {
+ OS << Symbol.getName();
+ return;
+ }
+
+ auto ReturnType = Signature->getReturnType();
+ ReturnType->dump(OS, 0, *this);
+
+ OS << " " << Signature->getCallingConvention() << " ";
+ OS << Symbol.getName();
+
+ OS << "(";
+ if (auto ChildEnum = Signature->getArguments()) {
+ uint32_t Index = 0;
+ while (auto Arg = ChildEnum->getNext()) {
+ Arg->dump(OS, 0, *this);
+ if (++Index < ChildEnum->getChildCount())
+ OS << ", ";
+ }
+ }
+ OS << ")";
+
+ if (Symbol.isConstType())
+ OS << " const";
+ if (Symbol.isVolatileType())
+ OS << " volatile";
+ if (Symbol.isPureVirtual())
+ OS << " = 0";
+}
+
+void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS,
+ int Indent) {
+ uint32_t ElementTypeId = Symbol.getTypeId();
+ auto ElementType = Symbol.getSession().getSymbolById(ElementTypeId);
+ if (!ElementType)
+ return;
+
+ ElementType->dump(OS, 0, *this);
+ OS << "[" << Symbol.getLength() << "]";
+}
+
+void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS,
+ int Indent) {
+ PDB_BuiltinType Type = Symbol.getBuiltinType();
+ OS << Type;
+ if (Type == PDB_BuiltinType::UInt || Type == PDB_BuiltinType::Int)
+ OS << (8 * Symbol.getLength()) << "_t";
+}
+
+void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
+ int Indent) {
+ dumpClassParentWithScopeOperator(Symbol, OS, *this);
+ OS << Symbol.getName();
+}
+
+void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol,
+ raw_ostream &OS, int Indent) {
+ // PDBSymbolTypeFunctionArg is just a shim over the real argument. Just drill
+ // through to the
+ // real thing and dump it.
+ uint32_t TypeId = Symbol.getTypeId();
+ auto Type = Symbol.getSession().getSymbolById(TypeId);
+ if (!Type)
+ return;
+ Type->dump(OS, 0, *this);
+}
+
+void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
+ int Indent) {
+ dumpClassParentWithScopeOperator(Symbol, OS, *this);
+ OS << Symbol.getName();
+}
+
+void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS,
+ int Indent) {
+ uint32_t PointeeId = Symbol.getTypeId();
+ auto PointeeType = Symbol.getSession().getSymbolById(PointeeId);
+ if (!PointeeType)
+ return;
+
+ if (auto FuncSig = dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) {
+ FunctionDumper NestedDumper;
+ PointerType Pointer =
+ Symbol.isReference() ? PointerType::Reference : PointerType::Pointer;
+ NestedDumper.start(*FuncSig, Pointer, OS);
+ } else {
+ if (Symbol.isConstType())
+ OS << "const ";
+ if (Symbol.isVolatileType())
+ OS << "volatile ";
+ PointeeType->dump(OS, Indent, *this);
+ OS << (Symbol.isReference() ? "&" : "*");
+ }
+}
+
+void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
+ int Indent) {
+ OS << Symbol.getName();
+}
OpenPOWER on IntegriCloud