PDBSymbolTypeFunctionSig.cpp revision 360784
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(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(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>(Session, *this);
67}
68
69void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const {
70  Dumper.dump(*this);
71}
72
73void PDBSymbolTypeFunctionSig::dumpRight(PDBSymDumper &Dumper) const {
74  Dumper.dumpRight(*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(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