Line data Source code
1 : //===- NativeTypeFunctionSig.cpp - info about function signature -*- C++-*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
11 :
12 : #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
13 : #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
14 : #include "llvm/DebugInfo/PDB/PDBExtras.h"
15 : #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
16 : #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
17 :
18 : using namespace llvm;
19 : using namespace llvm::codeview;
20 : using namespace llvm::pdb;
21 :
22 : namespace {
23 : // This is kind of a silly class, hence why we keep it private to the file.
24 : // It's only purpose is to wrap the real type record. I guess this is so that
25 : // we can have the lexical parent point to the function instead of the global
26 : // scope.
27 0 : class NativeTypeFunctionArg : public NativeRawSymbol {
28 : public:
29 : NativeTypeFunctionArg(NativeSession &Session,
30 : std::unique_ptr<PDBSymbol> RealType)
31 51 : : NativeRawSymbol(Session, PDB_SymType::FunctionArg, 0),
32 51 : RealType(std::move(RealType)) {}
33 :
34 0 : void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
35 : PdbSymbolIdField RecurseIdFields) const override {
36 0 : NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
37 :
38 0 : dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
39 : PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
40 0 : }
41 :
42 102 : SymIndexId getTypeId() const override { return RealType->getSymIndexId(); }
43 :
44 : std::unique_ptr<PDBSymbol> RealType;
45 : };
46 :
47 : class NativeEnumFunctionArgs : public IPDBEnumChildren<PDBSymbol> {
48 : public:
49 : NativeEnumFunctionArgs(NativeSession &Session,
50 : std::unique_ptr<NativeEnumTypes> TypeEnumerator)
51 61 : : Session(Session), TypeEnumerator(std::move(TypeEnumerator)) {}
52 :
53 51 : uint32_t getChildCount() const override {
54 51 : return TypeEnumerator->getChildCount();
55 : }
56 0 : std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override {
57 0 : return wrap(TypeEnumerator->getChildAtIndex(Index));
58 : }
59 112 : std::unique_ptr<PDBSymbol> getNext() override {
60 112 : return wrap(TypeEnumerator->getNext());
61 : }
62 :
63 0 : void reset() override { TypeEnumerator->reset(); }
64 :
65 : private:
66 0 : std::unique_ptr<PDBSymbol> wrap(std::unique_ptr<PDBSymbol> S) const {
67 0 : if (!S)
68 : return nullptr;
69 0 : auto NTFA = llvm::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
70 0 : return PDBSymbol::create(Session, std::move(NTFA));
71 : }
72 : NativeSession &Session;
73 : std::unique_ptr<NativeEnumTypes> TypeEnumerator;
74 : };
75 : } // namespace
76 :
77 36 : NativeTypeFunctionSig::NativeTypeFunctionSig(NativeSession &Session,
78 : SymIndexId Id,
79 : codeview::TypeIndex Index,
80 36 : codeview::ProcedureRecord Proc)
81 : : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
82 36 : Proc(std::move(Proc)), Index(Index), IsMemberFunction(false) {}
83 :
84 86 : NativeTypeFunctionSig::NativeTypeFunctionSig(
85 : NativeSession &Session, SymIndexId Id, codeview::TypeIndex Index,
86 86 : codeview::MemberFunctionRecord MemberFunc)
87 : : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
88 86 : MemberFunc(std::move(MemberFunc)), Index(Index), IsMemberFunction(true) {}
89 :
90 122 : void NativeTypeFunctionSig::initialize() {
91 122 : if (IsMemberFunction) {
92 86 : ClassParentId =
93 172 : Session.getSymbolCache().findSymbolByTypeIndex(MemberFunc.ClassType);
94 86 : initializeArgList(MemberFunc.ArgumentList);
95 : } else {
96 36 : initializeArgList(Proc.ArgumentList);
97 : }
98 122 : }
99 :
100 244 : NativeTypeFunctionSig::~NativeTypeFunctionSig() {}
101 :
102 122 : void NativeTypeFunctionSig::initializeArgList(codeview::TypeIndex ArgListTI) {
103 366 : TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
104 122 : CVType CVT = Tpi.typeCollection().getType(ArgListTI);
105 :
106 122 : cantFail(TypeDeserializer::deserializeAs<ArgListRecord>(CVT, ArgList));
107 122 : }
108 :
109 58 : void NativeTypeFunctionSig::dump(raw_ostream &OS, int Indent,
110 : PdbSymbolIdField ShowIdFields,
111 : PdbSymbolIdField RecurseIdFields) const {
112 :
113 58 : NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
114 :
115 116 : dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
116 : PdbSymbolIdField::LexicalParent, ShowIdFields,
117 : RecurseIdFields);
118 :
119 58 : dumpSymbolField(OS, "callingConvention", getCallingConvention(), Indent);
120 58 : dumpSymbolField(OS, "count", getCount(), Indent);
121 58 : dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
122 : PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
123 58 : if (IsMemberFunction)
124 41 : dumpSymbolField(OS, "thisAdjust", getThisAdjust(), Indent);
125 58 : dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
126 58 : dumpSymbolField(OS, "constType", isConstType(), Indent);
127 58 : dumpSymbolField(OS, "isConstructorVirtualBase", isConstructorVirtualBase(),
128 : Indent);
129 58 : dumpSymbolField(OS, "isCxxReturnUdt", isCxxReturnUdt(), Indent);
130 58 : dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
131 58 : dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
132 58 : }
133 :
134 : std::unique_ptr<IPDBEnumSymbols>
135 61 : NativeTypeFunctionSig::findChildren(PDB_SymType Type) const {
136 61 : if (Type != PDB_SymType::FunctionArg)
137 : return llvm::make_unique<NullEnumerator<PDBSymbol>>();
138 :
139 : auto NET = llvm::make_unique<NativeEnumTypes>(Session,
140 61 : /* copy */ ArgList.ArgIndices);
141 : return std::unique_ptr<IPDBEnumSymbols>(
142 61 : new NativeEnumFunctionArgs(Session, std::move(NET)));
143 : }
144 :
145 61 : SymIndexId NativeTypeFunctionSig::getClassParentId() const {
146 61 : if (!IsMemberFunction)
147 : return 0;
148 :
149 43 : return ClassParentId;
150 : }
151 :
152 119 : PDB_CallingConv NativeTypeFunctionSig::getCallingConvention() const {
153 119 : return IsMemberFunction ? MemberFunc.CallConv : Proc.CallConv;
154 : }
155 :
156 58 : uint32_t NativeTypeFunctionSig::getCount() const {
157 58 : return IsMemberFunction ? (1 + MemberFunc.getParameterCount())
158 17 : : Proc.getParameterCount();
159 : }
160 :
161 119 : SymIndexId NativeTypeFunctionSig::getTypeId() const {
162 : TypeIndex ReturnTI =
163 119 : IsMemberFunction ? MemberFunc.getReturnType() : Proc.getReturnType();
164 :
165 238 : SymIndexId Result = Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI);
166 119 : return Result;
167 : }
168 :
169 41 : int32_t NativeTypeFunctionSig::getThisAdjust() const {
170 41 : return IsMemberFunction ? MemberFunc.getThisPointerAdjustment() : 0;
171 : }
172 :
173 58 : bool NativeTypeFunctionSig::hasConstructor() const {
174 58 : if (!IsMemberFunction)
175 : return false;
176 :
177 41 : return (MemberFunc.getOptions() & FunctionOptions::Constructor) !=
178 41 : FunctionOptions::None;
179 : }
180 :
181 119 : bool NativeTypeFunctionSig::isConstType() const { return false; }
182 :
183 58 : bool NativeTypeFunctionSig::isConstructorVirtualBase() const {
184 58 : if (!IsMemberFunction)
185 : return false;
186 :
187 41 : return (MemberFunc.getOptions() &
188 : FunctionOptions::ConstructorWithVirtualBases) !=
189 41 : FunctionOptions::None;
190 : }
191 :
192 58 : bool NativeTypeFunctionSig::isCxxReturnUdt() const {
193 : FunctionOptions Options =
194 58 : IsMemberFunction ? MemberFunc.getOptions() : Proc.getOptions();
195 58 : return (Options & FunctionOptions::CxxReturnUdt) != FunctionOptions::None;
196 : }
197 :
198 58 : bool NativeTypeFunctionSig::isUnalignedType() const { return false; }
199 :
200 119 : bool NativeTypeFunctionSig::isVolatileType() const { return false; }
|