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