1*9880d681SAndroid Build Coastguard Worker //===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" 13*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 14*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/IPDBSession.h" 15*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBSymbolData.h" 16*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" 17*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBSymDumper.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBTypes.h" 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker #include <unordered_set> 22*9880d681SAndroid Build Coastguard Worker #include <utility> 23*9880d681SAndroid Build Coastguard Worker #include <vector> 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker using namespace llvm; 26*9880d681SAndroid Build Coastguard Worker using namespace llvm::pdb; 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker namespace { 29*9880d681SAndroid Build Coastguard Worker class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> { 30*9880d681SAndroid Build Coastguard Worker public: 31*9880d681SAndroid Build Coastguard Worker typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType; 32*9880d681SAndroid Build Coastguard Worker FunctionArgEnumerator(const IPDBSession & PDBSession,const PDBSymbolFunc & PDBFunc)33*9880d681SAndroid Build Coastguard Worker FunctionArgEnumerator(const IPDBSession &PDBSession, 34*9880d681SAndroid Build Coastguard Worker const PDBSymbolFunc &PDBFunc) 35*9880d681SAndroid Build Coastguard Worker : Session(PDBSession), Func(PDBFunc) { 36*9880d681SAndroid Build Coastguard Worker // Arguments can appear multiple times if they have live range 37*9880d681SAndroid Build Coastguard Worker // information, so we only take the first occurrence. 38*9880d681SAndroid Build Coastguard Worker std::unordered_set<std::string> SeenNames; 39*9880d681SAndroid Build Coastguard Worker auto DataChildren = Func.findAllChildren<PDBSymbolData>(); 40*9880d681SAndroid Build Coastguard Worker while (auto Child = DataChildren->getNext()) { 41*9880d681SAndroid Build Coastguard Worker if (Child->getDataKind() == PDB_DataKind::Param) { 42*9880d681SAndroid Build Coastguard Worker std::string Name = Child->getName(); 43*9880d681SAndroid Build Coastguard Worker if (SeenNames.find(Name) != SeenNames.end()) 44*9880d681SAndroid Build Coastguard Worker continue; 45*9880d681SAndroid Build Coastguard Worker Args.push_back(std::move(Child)); 46*9880d681SAndroid Build Coastguard Worker SeenNames.insert(Name); 47*9880d681SAndroid Build Coastguard Worker } 48*9880d681SAndroid Build Coastguard Worker } 49*9880d681SAndroid Build Coastguard Worker reset(); 50*9880d681SAndroid Build Coastguard Worker } 51*9880d681SAndroid Build Coastguard Worker getChildCount() const52*9880d681SAndroid Build Coastguard Worker uint32_t getChildCount() const override { return Args.size(); } 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker std::unique_ptr<PDBSymbolData> getChildAtIndex(uint32_t Index) const55*9880d681SAndroid Build Coastguard Worker getChildAtIndex(uint32_t Index) const override { 56*9880d681SAndroid Build Coastguard Worker if (Index >= Args.size()) 57*9880d681SAndroid Build Coastguard Worker return nullptr; 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker return Session.getConcreteSymbolById<PDBSymbolData>( 60*9880d681SAndroid Build Coastguard Worker Args[Index]->getSymIndexId()); 61*9880d681SAndroid Build Coastguard Worker } 62*9880d681SAndroid Build Coastguard Worker getNext()63*9880d681SAndroid Build Coastguard Worker std::unique_ptr<PDBSymbolData> getNext() override { 64*9880d681SAndroid Build Coastguard Worker if (CurIter == Args.end()) 65*9880d681SAndroid Build Coastguard Worker return nullptr; 66*9880d681SAndroid Build Coastguard Worker const auto &Result = **CurIter; 67*9880d681SAndroid Build Coastguard Worker ++CurIter; 68*9880d681SAndroid Build Coastguard Worker return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId()); 69*9880d681SAndroid Build Coastguard Worker } 70*9880d681SAndroid Build Coastguard Worker reset()71*9880d681SAndroid Build Coastguard Worker void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); } 72*9880d681SAndroid Build Coastguard Worker clone() const73*9880d681SAndroid Build Coastguard Worker FunctionArgEnumerator *clone() const override { 74*9880d681SAndroid Build Coastguard Worker return new FunctionArgEnumerator(Session, Func); 75*9880d681SAndroid Build Coastguard Worker } 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker private: 78*9880d681SAndroid Build Coastguard Worker typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType; 79*9880d681SAndroid Build Coastguard Worker const IPDBSession &Session; 80*9880d681SAndroid Build Coastguard Worker const PDBSymbolFunc &Func; 81*9880d681SAndroid Build Coastguard Worker ArgListType Args; 82*9880d681SAndroid Build Coastguard Worker ArgListType::const_iterator CurIter; 83*9880d681SAndroid Build Coastguard Worker }; 84*9880d681SAndroid Build Coastguard Worker } 85*9880d681SAndroid Build Coastguard Worker PDBSymbolFunc(const IPDBSession & PDBSession,std::unique_ptr<IPDBRawSymbol> Symbol)86*9880d681SAndroid Build Coastguard WorkerPDBSymbolFunc::PDBSymbolFunc(const IPDBSession &PDBSession, 87*9880d681SAndroid Build Coastguard Worker std::unique_ptr<IPDBRawSymbol> Symbol) 88*9880d681SAndroid Build Coastguard Worker : PDBSymbol(PDBSession, std::move(Symbol)) {} 89*9880d681SAndroid Build Coastguard Worker getSignature() const90*9880d681SAndroid Build Coastguard Workerstd::unique_ptr<PDBSymbolTypeFunctionSig> PDBSymbolFunc::getSignature() const { 91*9880d681SAndroid Build Coastguard Worker return Session.getConcreteSymbolById<PDBSymbolTypeFunctionSig>(getTypeId()); 92*9880d681SAndroid Build Coastguard Worker } 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Worker std::unique_ptr<IPDBEnumChildren<PDBSymbolData>> getArguments() const95*9880d681SAndroid Build Coastguard WorkerPDBSymbolFunc::getArguments() const { 96*9880d681SAndroid Build Coastguard Worker return llvm::make_unique<FunctionArgEnumerator>(Session, *this); 97*9880d681SAndroid Build Coastguard Worker } 98*9880d681SAndroid Build Coastguard Worker getClassParent() const99*9880d681SAndroid Build Coastguard Workerstd::unique_ptr<PDBSymbolTypeUDT> PDBSymbolFunc::getClassParent() const { 100*9880d681SAndroid Build Coastguard Worker return Session.getConcreteSymbolById<PDBSymbolTypeUDT>(getClassParentId()); 101*9880d681SAndroid Build Coastguard Worker } 102*9880d681SAndroid Build Coastguard Worker dump(PDBSymDumper & Dumper) const103*9880d681SAndroid Build Coastguard Workervoid PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); } 104