]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / DebugInfo / PDB / Native / NativeTypeFunctionSig.cpp
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 class NativeTypeFunctionArg : public NativeRawSymbol {
28 public:
29   NativeTypeFunctionArg(NativeSession &Session,
30                         std::unique_ptr<PDBSymbol> RealType)
31       : NativeRawSymbol(Session, PDB_SymType::FunctionArg, 0),
32         RealType(std::move(RealType)) {}
33
34   void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
35             PdbSymbolIdField RecurseIdFields) const override {
36     NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
37
38     dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
39                       PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
40   }
41
42   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       : Session(Session), TypeEnumerator(std::move(TypeEnumerator)) {}
52
53   uint32_t getChildCount() const override {
54     return TypeEnumerator->getChildCount();
55   }
56   std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override {
57     return wrap(TypeEnumerator->getChildAtIndex(Index));
58   }
59   std::unique_ptr<PDBSymbol> getNext() override {
60     return wrap(TypeEnumerator->getNext());
61   }
62
63   void reset() override { TypeEnumerator->reset(); }
64
65 private:
66   std::unique_ptr<PDBSymbol> wrap(std::unique_ptr<PDBSymbol> S) const {
67     if (!S)
68       return nullptr;
69     auto NTFA = llvm::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
70     return PDBSymbol::create(Session, std::move(NTFA));
71   }
72   NativeSession &Session;
73   std::unique_ptr<NativeEnumTypes> TypeEnumerator;
74 };
75 } // namespace
76
77 NativeTypeFunctionSig::NativeTypeFunctionSig(NativeSession &Session,
78                                              SymIndexId Id,
79                                              codeview::TypeIndex Index,
80                                              codeview::ProcedureRecord Proc)
81     : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
82       Proc(std::move(Proc)), Index(Index), IsMemberFunction(false) {}
83
84 NativeTypeFunctionSig::NativeTypeFunctionSig(
85     NativeSession &Session, SymIndexId Id, codeview::TypeIndex Index,
86     codeview::MemberFunctionRecord MemberFunc)
87     : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
88       MemberFunc(std::move(MemberFunc)), Index(Index), IsMemberFunction(true) {}
89
90 void NativeTypeFunctionSig::initialize() {
91   if (IsMemberFunction) {
92     ClassParentId =
93         Session.getSymbolCache().findSymbolByTypeIndex(MemberFunc.ClassType);
94     initializeArgList(MemberFunc.ArgumentList);
95   } else {
96     initializeArgList(Proc.ArgumentList);
97   }
98 }
99
100 NativeTypeFunctionSig::~NativeTypeFunctionSig() {}
101
102 void NativeTypeFunctionSig::initializeArgList(codeview::TypeIndex ArgListTI) {
103   TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
104   CVType CVT = Tpi.typeCollection().getType(ArgListTI);
105
106   cantFail(TypeDeserializer::deserializeAs<ArgListRecord>(CVT, ArgList));
107 }
108
109 void NativeTypeFunctionSig::dump(raw_ostream &OS, int Indent,
110                                  PdbSymbolIdField ShowIdFields,
111                                  PdbSymbolIdField RecurseIdFields) const {
112
113   NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
114
115   dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
116                     PdbSymbolIdField::LexicalParent, ShowIdFields,
117                     RecurseIdFields);
118
119   dumpSymbolField(OS, "callingConvention", getCallingConvention(), Indent);
120   dumpSymbolField(OS, "count", getCount(), Indent);
121   dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
122                     PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
123   if (IsMemberFunction)
124     dumpSymbolField(OS, "thisAdjust", getThisAdjust(), Indent);
125   dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
126   dumpSymbolField(OS, "constType", isConstType(), Indent);
127   dumpSymbolField(OS, "isConstructorVirtualBase", isConstructorVirtualBase(),
128                   Indent);
129   dumpSymbolField(OS, "isCxxReturnUdt", isCxxReturnUdt(), Indent);
130   dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
131   dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
132 }
133
134 std::unique_ptr<IPDBEnumSymbols>
135 NativeTypeFunctionSig::findChildren(PDB_SymType Type) const {
136   if (Type != PDB_SymType::FunctionArg)
137     return llvm::make_unique<NullEnumerator<PDBSymbol>>();
138
139   auto NET = llvm::make_unique<NativeEnumTypes>(Session,
140                                                 /* copy */ ArgList.ArgIndices);
141   return std::unique_ptr<IPDBEnumSymbols>(
142       new NativeEnumFunctionArgs(Session, std::move(NET)));
143 }
144
145 SymIndexId NativeTypeFunctionSig::getClassParentId() const {
146   if (!IsMemberFunction)
147     return 0;
148
149   return ClassParentId;
150 }
151
152 PDB_CallingConv NativeTypeFunctionSig::getCallingConvention() const {
153   return IsMemberFunction ? MemberFunc.CallConv : Proc.CallConv;
154 }
155
156 uint32_t NativeTypeFunctionSig::getCount() const {
157   return IsMemberFunction ? (1 + MemberFunc.getParameterCount())
158                           : Proc.getParameterCount();
159 }
160
161 SymIndexId NativeTypeFunctionSig::getTypeId() const {
162   TypeIndex ReturnTI =
163       IsMemberFunction ? MemberFunc.getReturnType() : Proc.getReturnType();
164
165   SymIndexId Result = Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI);
166   return Result;
167 }
168
169 int32_t NativeTypeFunctionSig::getThisAdjust() const {
170   return IsMemberFunction ? MemberFunc.getThisPointerAdjustment() : 0;
171 }
172
173 bool NativeTypeFunctionSig::hasConstructor() const {
174   if (!IsMemberFunction)
175     return false;
176
177   return (MemberFunc.getOptions() & FunctionOptions::Constructor) !=
178          FunctionOptions::None;
179 }
180
181 bool NativeTypeFunctionSig::isConstType() const { return false; }
182
183 bool NativeTypeFunctionSig::isConstructorVirtualBase() const {
184   if (!IsMemberFunction)
185     return false;
186
187   return (MemberFunc.getOptions() &
188           FunctionOptions::ConstructorWithVirtualBases) !=
189          FunctionOptions::None;
190 }
191
192 bool NativeTypeFunctionSig::isCxxReturnUdt() const {
193   FunctionOptions Options =
194       IsMemberFunction ? MemberFunc.getOptions() : Proc.getOptions();
195   return (Options & FunctionOptions::CxxReturnUdt) != FunctionOptions::None;
196 }
197
198 bool NativeTypeFunctionSig::isUnalignedType() const { return false; }
199
200 bool NativeTypeFunctionSig::isVolatileType() const { return false; }