PDBSymbolFunc.cpp revision 283631
1//===- PDBSymbolFunc.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 "llvm/DebugInfo/PDB/PDBSymbolFunc.h" 11 12#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" 13#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 14#include "llvm/DebugInfo/PDB/IPDBSession.h" 15#include "llvm/DebugInfo/PDB/PDBSymbolData.h" 16#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" 17#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 18#include "llvm/DebugInfo/PDB/PDBSymDumper.h" 19#include "llvm/DebugInfo/PDB/PDBTypes.h" 20 21#include <unordered_set> 22#include <utility> 23#include <vector> 24 25using namespace llvm; 26 27namespace { 28class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> { 29public: 30 typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType; 31 32 FunctionArgEnumerator(const IPDBSession &PDBSession, 33 const PDBSymbolFunc &PDBFunc) 34 : Session(PDBSession), Func(PDBFunc) { 35 // Arguments can appear multiple times if they have live range 36 // information, so we only take the first occurrence. 37 std::unordered_set<std::string> SeenNames; 38 auto DataChildren = Func.findAllChildren<PDBSymbolData>(); 39 while (auto Child = DataChildren->getNext()) { 40 if (Child->getDataKind() == PDB_DataKind::Param) { 41 std::string Name = Child->getName(); 42 if (SeenNames.find(Name) != SeenNames.end()) 43 continue; 44 Args.push_back(std::move(Child)); 45 SeenNames.insert(Name); 46 } 47 } 48 reset(); 49 } 50 51 uint32_t getChildCount() const override { return Args.size(); } 52 53 std::unique_ptr<PDBSymbolData> 54 getChildAtIndex(uint32_t Index) const override { 55 if (Index >= Args.size()) 56 return nullptr; 57 58 return Session.getConcreteSymbolById<PDBSymbolData>( 59 Args[Index]->getSymIndexId()); 60 } 61 62 std::unique_ptr<PDBSymbolData> getNext() override { 63 if (CurIter == Args.end()) 64 return nullptr; 65 const auto &Result = **CurIter; 66 ++CurIter; 67 return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId()); 68 } 69 70 void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); } 71 72 FunctionArgEnumerator *clone() const override { 73 return new FunctionArgEnumerator(Session, Func); 74 } 75 76private: 77 typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType; 78 const IPDBSession &Session; 79 const PDBSymbolFunc &Func; 80 ArgListType Args; 81 ArgListType::const_iterator CurIter; 82}; 83} 84 85PDBSymbolFunc::PDBSymbolFunc(const IPDBSession &PDBSession, 86 std::unique_ptr<IPDBRawSymbol> Symbol) 87 : PDBSymbol(PDBSession, std::move(Symbol)) {} 88 89std::unique_ptr<PDBSymbolTypeFunctionSig> PDBSymbolFunc::getSignature() const { 90 return Session.getConcreteSymbolById<PDBSymbolTypeFunctionSig>(getTypeId()); 91} 92 93std::unique_ptr<IPDBEnumChildren<PDBSymbolData>> 94PDBSymbolFunc::getArguments() const { 95 return llvm::make_unique<FunctionArgEnumerator>(Session, *this); 96} 97 98std::unique_ptr<PDBSymbolTypeUDT> PDBSymbolFunc::getClassParent() const { 99 return Session.getConcreteSymbolById<PDBSymbolTypeUDT>(getClassParentId()); 100} 101 102void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); } 103