1104964Sjeff//===- PDBSymbolTypeFunctionSig.cpp - --------------------------*- C++ -*-===// 2164185Strhodes// 3164185Strhodes// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4164185Strhodes// See https://llvm.org/LICENSE.txt for license information. 5164185Strhodes// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6164185Strhodes// 7164185Strhodes//===----------------------------------------------------------------------===// 8164185Strhodes 9164185Strhodes#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" 10164185Strhodes 11164185Strhodes#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" 12164185Strhodes#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 13164185Strhodes#include "llvm/DebugInfo/PDB/IPDBSession.h" 14164185Strhodes#include "llvm/DebugInfo/PDB/PDBSymDumper.h" 15164185Strhodes#include "llvm/DebugInfo/PDB/PDBSymbol.h" 16164185Strhodes#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" 17164185Strhodes#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" 18164185Strhodes 19164185Strhodes#include <utility> 20164185Strhodes 21164185Strhodesusing namespace llvm; 22164185Strhodesusing namespace llvm::pdb; 23164185Strhodes 24164185Strhodesnamespace { 25164185Strhodesclass FunctionArgEnumerator : public IPDBEnumSymbols { 26164185Strhodespublic: 27164185Strhodes typedef ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg> ArgEnumeratorType; 28164185Strhodes 29164185Strhodes FunctionArgEnumerator(const IPDBSession &PDBSession, 30164185Strhodes const PDBSymbolTypeFunctionSig &Sig) 31164185Strhodes : Session(PDBSession), 32164185Strhodes Enumerator(Sig.findAllChildren<PDBSymbolTypeFunctionArg>()) {} 33164185Strhodes 34164185Strhodes FunctionArgEnumerator(const IPDBSession &PDBSession, 35176729Sjeff std::unique_ptr<ArgEnumeratorType> ArgEnumerator) 36104964Sjeff : Session(PDBSession), Enumerator(std::move(ArgEnumerator)) {} 37104964Sjeff 38104964Sjeff uint32_t getChildCount() const override { 39104964Sjeff return Enumerator->getChildCount(); 40104964Sjeff } 41104964Sjeff 42104964Sjeff std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override { 43104964Sjeff auto FunctionArgSymbol = Enumerator->getChildAtIndex(Index); 44104964Sjeff if (!FunctionArgSymbol) 45104964Sjeff return nullptr; 46104964Sjeff return Session.getSymbolById(FunctionArgSymbol->getTypeId()); 47104964Sjeff } 48104964Sjeff 49104964Sjeff std::unique_ptr<PDBSymbol> getNext() override { 50104964Sjeff auto FunctionArgSymbol = Enumerator->getNext(); 51104964Sjeff if (!FunctionArgSymbol) 52104964Sjeff return nullptr; 53104964Sjeff return Session.getSymbolById(FunctionArgSymbol->getTypeId()); 54104964Sjeff } 55104964Sjeff 56104964Sjeff void reset() override { Enumerator->reset(); } 57104964Sjeff 58104964Sjeffprivate: 59104964Sjeff const IPDBSession &Session; 60104964Sjeff std::unique_ptr<ArgEnumeratorType> Enumerator; 61104964Sjeff}; 62164185Strhodes} 63164185Strhodes 64104964Sjeffstd::unique_ptr<IPDBEnumSymbols> 65164185StrhodesPDBSymbolTypeFunctionSig::getArguments() const { 66104964Sjeff return std::make_unique<FunctionArgEnumerator>(Session, *this); 67104964Sjeff} 68125287Sjeff 69125287Sjeffvoid PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const { 70125287Sjeff Dumper.dump(*this); 71125287Sjeff} 72125287Sjeff 73125287Sjeffvoid PDBSymbolTypeFunctionSig::dumpRight(PDBSymDumper &Dumper) const { 74104964Sjeff Dumper.dumpRight(*this); 75125287Sjeff} 76104964Sjeff 77104964Sjeffbool PDBSymbolTypeFunctionSig::isCVarArgs() const { 78104964Sjeff auto SigArguments = getArguments(); 79113355Sjeff if (!SigArguments) 80113355Sjeff return false; 81113355Sjeff uint32_t NumArgs = SigArguments->getChildCount(); 82132372Sjulian if (NumArgs == 0) 83134791Sjulian return false; 84170293Sjeff auto Last = SigArguments->getChildAtIndex(NumArgs - 1); 85163709Sjb if (auto Builtin = llvm::dyn_cast_or_null<PDBSymbolTypeBuiltin>(Last.get())) { 86130551Sjulian if (Builtin->getBuiltinType() == PDB_BuiltinType::None) 87104964Sjeff return true; 88104964Sjeff } 89122036Sjeff 90164936Sjulian // Note that for a variadic template signature, this method always returns 91104964Sjeff // false since the parameters of the template are specialized. 92113355Sjeff return false; 93113355Sjeff} 94161599Sdavidxu