1 //===- PDBSymbolTypeFunctionSig.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/PDBSymbolTypeFunctionSig.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/PDBSymDumper.h" 16 #include "llvm/DebugInfo/PDB/PDBSymbol.h" 17 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" 18 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" 19 20 #include <utility> 21 22 using namespace llvm; 23 using namespace llvm::pdb; 24 25 namespace { 26 class FunctionArgEnumerator : public IPDBEnumSymbols { 27 public: 28 typedef ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg> ArgEnumeratorType; 29 FunctionArgEnumerator(const IPDBSession & PDBSession,const PDBSymbolTypeFunctionSig & Sig)30 FunctionArgEnumerator(const IPDBSession &PDBSession, 31 const PDBSymbolTypeFunctionSig &Sig) 32 : Session(PDBSession), 33 Enumerator(Sig.findAllChildren<PDBSymbolTypeFunctionArg>()) {} 34 FunctionArgEnumerator(const IPDBSession & PDBSession,std::unique_ptr<ArgEnumeratorType> ArgEnumerator)35 FunctionArgEnumerator(const IPDBSession &PDBSession, 36 std::unique_ptr<ArgEnumeratorType> ArgEnumerator) 37 : Session(PDBSession), Enumerator(std::move(ArgEnumerator)) {} 38 getChildCount() const39 uint32_t getChildCount() const override { 40 return Enumerator->getChildCount(); 41 } 42 getChildAtIndex(uint32_t Index) const43 std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override { 44 auto FunctionArgSymbol = Enumerator->getChildAtIndex(Index); 45 if (!FunctionArgSymbol) 46 return nullptr; 47 return Session.getSymbolById(FunctionArgSymbol->getTypeId()); 48 } 49 getNext()50 std::unique_ptr<PDBSymbol> getNext() override { 51 auto FunctionArgSymbol = Enumerator->getNext(); 52 if (!FunctionArgSymbol) 53 return nullptr; 54 return Session.getSymbolById(FunctionArgSymbol->getTypeId()); 55 } 56 reset()57 void reset() override { Enumerator->reset(); } 58 59 private: 60 const IPDBSession &Session; 61 std::unique_ptr<ArgEnumeratorType> Enumerator; 62 }; 63 } 64 65 std::unique_ptr<IPDBEnumSymbols> getArguments() const66PDBSymbolTypeFunctionSig::getArguments() const { 67 return llvm::make_unique<FunctionArgEnumerator>(Session, *this); 68 } 69 dump(PDBSymDumper & Dumper) const70void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const { 71 Dumper.dump(*this); 72 } 73 dumpRight(PDBSymDumper & Dumper) const74void PDBSymbolTypeFunctionSig::dumpRight(PDBSymDumper &Dumper) const { 75 Dumper.dumpRight(*this); 76 } 77 isCVarArgs() const78bool PDBSymbolTypeFunctionSig::isCVarArgs() const { 79 auto SigArguments = getArguments(); 80 if (!SigArguments) 81 return false; 82 uint32_t NumArgs = SigArguments->getChildCount(); 83 if (NumArgs == 0) 84 return false; 85 auto Last = SigArguments->getChildAtIndex(NumArgs - 1); 86 if (auto Builtin = llvm::dyn_cast_or_null<PDBSymbolTypeBuiltin>(Last.get())) { 87 if (Builtin->getBuiltinType() == PDB_BuiltinType::None) 88 return true; 89 } 90 91 // Note that for a variadic template signature, this method always returns 92 // false since the parameters of the template are specialized. 93 return false; 94 } 95