aboutsummaryrefslogtreecommitdiffstats
path: root/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/DebugInfo/PDB/PDBSymbolFunc.cpp')
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolFunc.cpp104
1 files changed, 104 insertions, 0 deletions
diff --git a/lib/DebugInfo/PDB/PDBSymbolFunc.cpp b/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
new file mode 100644
index 0000000..e2d859f
--- /dev/null
+++ b/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
@@ -0,0 +1,104 @@
+//===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+
+#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> {
+public:
+ typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType;
+
+ FunctionArgEnumerator(const IPDBSession &PDBSession,
+ const PDBSymbolFunc &PDBFunc)
+ : Session(PDBSession), Func(PDBFunc) {
+ // Arguments can appear multiple times if they have live range
+ // information, so we only take the first occurrence.
+ std::unordered_set<std::string> SeenNames;
+ auto DataChildren = Func.findAllChildren<PDBSymbolData>();
+ while (auto Child = DataChildren->getNext()) {
+ if (Child->getDataKind() == PDB_DataKind::Param) {
+ std::string Name = Child->getName();
+ if (SeenNames.find(Name) != SeenNames.end())
+ continue;
+ Args.push_back(std::move(Child));
+ SeenNames.insert(Name);
+ }
+ }
+ reset();
+ }
+
+ uint32_t getChildCount() const { return Args.size(); }
+
+ std::unique_ptr<PDBSymbolData> getChildAtIndex(uint32_t Index) const {
+ if (Index >= Args.size())
+ return nullptr;
+
+ return Session.getConcreteSymbolById<PDBSymbolData>(
+ Args[Index]->getSymIndexId());
+ }
+
+ std::unique_ptr<PDBSymbolData> getNext() {
+ if (CurIter == Args.end())
+ return nullptr;
+ const auto &Result = **CurIter;
+ ++CurIter;
+ return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId());
+ }
+
+ void reset() { CurIter = Args.empty() ? Args.end() : Args.begin(); }
+
+ FunctionArgEnumerator *clone() const {
+ return new FunctionArgEnumerator(Session, Func);
+ }
+
+private:
+ typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType;
+ const IPDBSession &Session;
+ const PDBSymbolFunc &Func;
+ ArgListType Args;
+ ArgListType::const_iterator CurIter;
+};
+}
+
+PDBSymbolFunc::PDBSymbolFunc(const IPDBSession &PDBSession,
+ std::unique_ptr<IPDBRawSymbol> Symbol)
+ : PDBSymbol(PDBSession, std::move(Symbol)) {}
+
+std::unique_ptr<PDBSymbolTypeFunctionSig> PDBSymbolFunc::getSignature() const {
+ return Session.getConcreteSymbolById<PDBSymbolTypeFunctionSig>(getTypeId());
+}
+
+std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
+PDBSymbolFunc::getArguments() const {
+ return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
+}
+
+std::unique_ptr<PDBSymbolTypeUDT> PDBSymbolFunc::getClassParent() const {
+ return Session.getConcreteSymbolById<PDBSymbolTypeUDT>(getClassParentId());
+}
+
+void PDBSymbolFunc::dump(raw_ostream &OS, int Indent,
+ PDBSymDumper &Dumper) const {
+ Dumper.dump(*this, OS, Indent);
+}