diff options
author | Zachary Turner <zturner@google.com> | 2015-02-23 05:58:34 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2015-02-23 05:58:34 +0000 |
commit | 29c69105fb02de4aec7ad0e614bc299c807370cd (patch) | |
tree | 704e1f63cf99a214a6ff0d8a09ba8c40eabf2c2b /llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp | |
parent | 203540f2d6f54eec322ec7d4aeefa811ecb2335c (diff) | |
download | llvm-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.cpp | 74 |
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); |