aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2015-02-23 05:58:34 +0000
committerZachary Turner <zturner@google.com>2015-02-23 05:58:34 +0000
commit29c69105fb02de4aec7ad0e614bc299c807370cd (patch)
tree704e1f63cf99a214a6ff0d8a09ba8c40eabf2c2b /llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
parent203540f2d6f54eec322ec7d4aeefa811ecb2335c (diff)
downloadllvm-29c69105fb02de4aec7ad0e614bc299c807370cd.zip
llvm-29c69105fb02de4aec7ad0e614bc299c807370cd.tar.gz
llvm-29c69105fb02de4aec7ad0e614bc299c807370cd.tar.bz2
[llvm-pdbdump] Add an option to dump full class definitions.
This adds the --class-definitions flag. If specified, when dumping types, instead of "class Foo" you will see the full class definition, with member functions, constructors, access specifiers. NOTE: Using this option can be very slow, as generating a full class definition requires accessing many different parts of the PDB. llvm-svn: 230203
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp')
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
index 4702d6d..e2d859f 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
@@ -9,13 +9,78 @@
#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)) {}
@@ -24,6 +89,15 @@ 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);