1 //===- PDBSymbolTypeFunctionSig.cpp - --------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" 10 11 #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" 12 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 13 #include "llvm/DebugInfo/PDB/IPDBSession.h" 14 #include "llvm/DebugInfo/PDB/PDBSymDumper.h" 15 #include "llvm/DebugInfo/PDB/PDBSymbol.h" 16 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" 17 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" 18 19 #include <utility> 20 21 using namespace llvm; 22 using namespace llvm::pdb; 23 24 namespace { 25 class FunctionArgEnumerator : public IPDBEnumSymbols { 26 public: 27 typedef ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg> ArgEnumeratorType; 28 FunctionArgEnumerator(const IPDBSession & PDBSession,const PDBSymbolTypeFunctionSig & Sig)29 FunctionArgEnumerator(const IPDBSession &PDBSession, 30 const PDBSymbolTypeFunctionSig &Sig) 31 : Session(PDBSession), 32 Enumerator(Sig.findAllChildren<PDBSymbolTypeFunctionArg>()) {} 33 FunctionArgEnumerator(const IPDBSession & PDBSession,std::unique_ptr<ArgEnumeratorType> ArgEnumerator)34 FunctionArgEnumerator(const IPDBSession &PDBSession, 35 std::unique_ptr<ArgEnumeratorType> ArgEnumerator) 36 : Session(PDBSession), Enumerator(std::move(ArgEnumerator)) {} 37 getChildCount() const38 uint32_t getChildCount() const override { 39 return Enumerator->getChildCount(); 40 } 41 getChildAtIndex(uint32_t Index) const42 std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override { 43 auto FunctionArgSymbol = Enumerator->getChildAtIndex(Index); 44 if (!FunctionArgSymbol) 45 return nullptr; 46 return Session.getSymbolById(FunctionArgSymbol->getTypeId()); 47 } 48 getNext()49 std::unique_ptr<PDBSymbol> getNext() override { 50 auto FunctionArgSymbol = Enumerator->getNext(); 51 if (!FunctionArgSymbol) 52 return nullptr; 53 return Session.getSymbolById(FunctionArgSymbol->getTypeId()); 54 } 55 reset()56 void reset() override { Enumerator->reset(); } 57 58 private: 59 const IPDBSession &Session; 60 std::unique_ptr<ArgEnumeratorType> Enumerator; 61 }; 62 } 63 64 std::unique_ptr<IPDBEnumSymbols> getArguments() const65PDBSymbolTypeFunctionSig::getArguments() const { 66 return std::make_unique<FunctionArgEnumerator>(Session, *this); 67 } 68 dump(PDBSymDumper & Dumper) const69void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const { 70 Dumper.dump(*this); 71 } 72 dumpRight(PDBSymDumper & Dumper) const73void PDBSymbolTypeFunctionSig::dumpRight(PDBSymDumper &Dumper) const { 74 Dumper.dumpRight(*this); 75 } 76 isCVarArgs() const77bool PDBSymbolTypeFunctionSig::isCVarArgs() const { 78 auto SigArguments = getArguments(); 79 if (!SigArguments) 80 return false; 81 uint32_t NumArgs = SigArguments->getChildCount(); 82 if (NumArgs == 0) 83 return false; 84 auto Last = SigArguments->getChildAtIndex(NumArgs - 1); 85 if (auto Builtin = llvm::dyn_cast_or_null<PDBSymbolTypeBuiltin>(Last.get())) { 86 if (Builtin->getBuiltinType() == PDB_BuiltinType::None) 87 return true; 88 } 89 90 // Note that for a variadic template signature, this method always returns 91 // false since the parameters of the template are specialized. 92 return false; 93 } 94