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
21using namespace llvm;
22using namespace llvm::pdb;
23
24namespace {
25class FunctionArgEnumerator : public IPDBEnumSymbols {
26public:
27 typedef ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg> ArgEnumeratorType;
28
29 FunctionArgEnumerator(const IPDBSession &PDBSession,
30 const PDBSymbolTypeFunctionSig &Sig)
31 : Session(PDBSession),
32 Enumerator(Sig.findAllChildren<PDBSymbolTypeFunctionArg>()) {}
33
34 FunctionArgEnumerator(const IPDBSession &PDBSession,
35 std::unique_ptr<ArgEnumeratorType> ArgEnumerator)
36 : Session(PDBSession), Enumerator(std::move(ArgEnumerator)) {}
37
38 uint32_t getChildCount() const override {
39 return Enumerator->getChildCount();
40 }
41
42 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(SymbolId: FunctionArgSymbol->getTypeId());
47 }
48
49 std::unique_ptr<PDBSymbol> getNext() override {
50 auto FunctionArgSymbol = Enumerator->getNext();
51 if (!FunctionArgSymbol)
52 return nullptr;
53 return Session.getSymbolById(SymbolId: FunctionArgSymbol->getTypeId());
54 }
55
56 void reset() override { Enumerator->reset(); }
57
58private:
59 const IPDBSession &Session;
60 std::unique_ptr<ArgEnumeratorType> Enumerator;
61};
62}
63
64std::unique_ptr<IPDBEnumSymbols>
65PDBSymbolTypeFunctionSig::getArguments() const {
66 return std::make_unique<FunctionArgEnumerator>(args: Session, args: *this);
67}
68
69void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const {
70 Dumper.dump(Symbol: *this);
71}
72
73void PDBSymbolTypeFunctionSig::dumpRight(PDBSymDumper &Dumper) const {
74 Dumper.dumpRight(Symbol: *this);
75}
76
77bool 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(Index: NumArgs - 1);
85 if (auto Builtin = llvm::dyn_cast_or_null<PDBSymbolTypeBuiltin>(Val: 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