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 | |
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 | |
58 | private: |
59 | const IPDBSession &Session; |
60 | std::unique_ptr<ArgEnumeratorType> Enumerator; |
61 | }; |
62 | } |
63 | |
64 | std::unique_ptr<IPDBEnumSymbols> |
65 | PDBSymbolTypeFunctionSig::getArguments() const { |
66 | return std::make_unique<FunctionArgEnumerator>(args: Session, args: *this); |
67 | } |
68 | |
69 | void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const { |
70 | Dumper.dump(Symbol: *this); |
71 | } |
72 | |
73 | void PDBSymbolTypeFunctionSig::dumpRight(PDBSymDumper &Dumper) const { |
74 | Dumper.dumpRight(Symbol: *this); |
75 | } |
76 | |
77 | bool 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 |