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