annotate clang/lib/CodeGen/CGCXXABI.h @ 225:f7655407a6ba

remove unnecessary files
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 19 Jul 2021 03:48:36 +0900
parents 2e18cbf3894f
children c4bab56944e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===----- CGCXXABI.h - Interface to C++ ABIs -------------------*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 //
anatofuz
parents:
diff changeset
9 // This provides an abstract class for C++ code generation. Concrete subclasses
anatofuz
parents:
diff changeset
10 // of this implement code generation for specific C++ ABIs.
anatofuz
parents:
diff changeset
11 //
anatofuz
parents:
diff changeset
12 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 #ifndef LLVM_CLANG_LIB_CODEGEN_CGCXXABI_H
anatofuz
parents:
diff changeset
15 #define LLVM_CLANG_LIB_CODEGEN_CGCXXABI_H
anatofuz
parents:
diff changeset
16
anatofuz
parents:
diff changeset
17 #include "CodeGenFunction.h"
anatofuz
parents:
diff changeset
18 #include "clang/Basic/LLVM.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
19 #include "clang/CodeGen/CodeGenABITypes.h"
150
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 namespace llvm {
anatofuz
parents:
diff changeset
22 class Constant;
anatofuz
parents:
diff changeset
23 class Type;
anatofuz
parents:
diff changeset
24 class Value;
anatofuz
parents:
diff changeset
25 class CallInst;
anatofuz
parents:
diff changeset
26 }
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 namespace clang {
anatofuz
parents:
diff changeset
29 class CastExpr;
anatofuz
parents:
diff changeset
30 class CXXConstructorDecl;
anatofuz
parents:
diff changeset
31 class CXXDestructorDecl;
anatofuz
parents:
diff changeset
32 class CXXMethodDecl;
anatofuz
parents:
diff changeset
33 class CXXRecordDecl;
anatofuz
parents:
diff changeset
34 class FieldDecl;
anatofuz
parents:
diff changeset
35 class MangleContext;
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 namespace CodeGen {
anatofuz
parents:
diff changeset
38 class CGCallee;
anatofuz
parents:
diff changeset
39 class CodeGenFunction;
anatofuz
parents:
diff changeset
40 class CodeGenModule;
anatofuz
parents:
diff changeset
41 struct CatchTypeInfo;
anatofuz
parents:
diff changeset
42
anatofuz
parents:
diff changeset
43 /// Implements C++ ABI-specific code generation functions.
anatofuz
parents:
diff changeset
44 class CGCXXABI {
anatofuz
parents:
diff changeset
45 protected:
anatofuz
parents:
diff changeset
46 CodeGenModule &CGM;
anatofuz
parents:
diff changeset
47 std::unique_ptr<MangleContext> MangleCtx;
anatofuz
parents:
diff changeset
48
anatofuz
parents:
diff changeset
49 CGCXXABI(CodeGenModule &CGM)
anatofuz
parents:
diff changeset
50 : CGM(CGM), MangleCtx(CGM.getContext().createMangleContext()) {}
anatofuz
parents:
diff changeset
51
anatofuz
parents:
diff changeset
52 protected:
anatofuz
parents:
diff changeset
53 ImplicitParamDecl *getThisDecl(CodeGenFunction &CGF) {
anatofuz
parents:
diff changeset
54 return CGF.CXXABIThisDecl;
anatofuz
parents:
diff changeset
55 }
anatofuz
parents:
diff changeset
56 llvm::Value *getThisValue(CodeGenFunction &CGF) {
anatofuz
parents:
diff changeset
57 return CGF.CXXABIThisValue;
anatofuz
parents:
diff changeset
58 }
anatofuz
parents:
diff changeset
59 Address getThisAddress(CodeGenFunction &CGF) {
anatofuz
parents:
diff changeset
60 return Address(CGF.CXXABIThisValue, CGF.CXXABIThisAlignment);
anatofuz
parents:
diff changeset
61 }
anatofuz
parents:
diff changeset
62
anatofuz
parents:
diff changeset
63 /// Issue a diagnostic about unsupported features in the ABI.
anatofuz
parents:
diff changeset
64 void ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S);
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 /// Get a null value for unsupported member pointers.
anatofuz
parents:
diff changeset
67 llvm::Constant *GetBogusMemberPointer(QualType T);
anatofuz
parents:
diff changeset
68
anatofuz
parents:
diff changeset
69 ImplicitParamDecl *&getStructorImplicitParamDecl(CodeGenFunction &CGF) {
anatofuz
parents:
diff changeset
70 return CGF.CXXStructorImplicitParamDecl;
anatofuz
parents:
diff changeset
71 }
anatofuz
parents:
diff changeset
72 llvm::Value *&getStructorImplicitParamValue(CodeGenFunction &CGF) {
anatofuz
parents:
diff changeset
73 return CGF.CXXStructorImplicitParamValue;
anatofuz
parents:
diff changeset
74 }
anatofuz
parents:
diff changeset
75
anatofuz
parents:
diff changeset
76 /// Loads the incoming C++ this pointer as it was passed by the caller.
anatofuz
parents:
diff changeset
77 llvm::Value *loadIncomingCXXThis(CodeGenFunction &CGF);
anatofuz
parents:
diff changeset
78
anatofuz
parents:
diff changeset
79 void setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr);
anatofuz
parents:
diff changeset
80
anatofuz
parents:
diff changeset
81 ASTContext &getContext() const { return CGM.getContext(); }
anatofuz
parents:
diff changeset
82
anatofuz
parents:
diff changeset
83 virtual bool requiresArrayCookie(const CXXDeleteExpr *E, QualType eltType);
anatofuz
parents:
diff changeset
84 virtual bool requiresArrayCookie(const CXXNewExpr *E);
anatofuz
parents:
diff changeset
85
anatofuz
parents:
diff changeset
86 /// Determine whether there's something special about the rules of
anatofuz
parents:
diff changeset
87 /// the ABI tell us that 'this' is a complete object within the
anatofuz
parents:
diff changeset
88 /// given function. Obvious common logic like being defined on a
anatofuz
parents:
diff changeset
89 /// final class will have been taken care of by the caller.
anatofuz
parents:
diff changeset
90 virtual bool isThisCompleteObject(GlobalDecl GD) const = 0;
anatofuz
parents:
diff changeset
91
anatofuz
parents:
diff changeset
92 public:
anatofuz
parents:
diff changeset
93
anatofuz
parents:
diff changeset
94 virtual ~CGCXXABI();
anatofuz
parents:
diff changeset
95
anatofuz
parents:
diff changeset
96 /// Gets the mangle context.
anatofuz
parents:
diff changeset
97 MangleContext &getMangleContext() {
anatofuz
parents:
diff changeset
98 return *MangleCtx;
anatofuz
parents:
diff changeset
99 }
anatofuz
parents:
diff changeset
100
anatofuz
parents:
diff changeset
101 /// Returns true if the given constructor or destructor is one of the
anatofuz
parents:
diff changeset
102 /// kinds that the ABI says returns 'this' (only applies when called
anatofuz
parents:
diff changeset
103 /// non-virtually for destructors).
anatofuz
parents:
diff changeset
104 ///
anatofuz
parents:
diff changeset
105 /// There currently is no way to indicate if a destructor returns 'this'
anatofuz
parents:
diff changeset
106 /// when called virtually, and code generation does not support the case.
anatofuz
parents:
diff changeset
107 virtual bool HasThisReturn(GlobalDecl GD) const { return false; }
anatofuz
parents:
diff changeset
108
anatofuz
parents:
diff changeset
109 virtual bool hasMostDerivedReturn(GlobalDecl GD) const { return false; }
anatofuz
parents:
diff changeset
110
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
111 virtual bool useSinitAndSterm() const { return false; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
112
150
anatofuz
parents:
diff changeset
113 /// Returns true if the target allows calling a function through a pointer
anatofuz
parents:
diff changeset
114 /// with a different signature than the actual function (or equivalently,
anatofuz
parents:
diff changeset
115 /// bitcasting a function or function pointer to a different function type).
anatofuz
parents:
diff changeset
116 /// In principle in the most general case this could depend on the target, the
anatofuz
parents:
diff changeset
117 /// calling convention, and the actual types of the arguments and return
anatofuz
parents:
diff changeset
118 /// value. Here it just means whether the signature mismatch could *ever* be
anatofuz
parents:
diff changeset
119 /// allowed; in other words, does the target do strict checking of signatures
anatofuz
parents:
diff changeset
120 /// for all calls.
anatofuz
parents:
diff changeset
121 virtual bool canCallMismatchedFunctionType() const { return true; }
anatofuz
parents:
diff changeset
122
anatofuz
parents:
diff changeset
123 /// If the C++ ABI requires the given type be returned in a particular way,
anatofuz
parents:
diff changeset
124 /// this method sets RetAI and returns true.
anatofuz
parents:
diff changeset
125 virtual bool classifyReturnType(CGFunctionInfo &FI) const = 0;
anatofuz
parents:
diff changeset
126
anatofuz
parents:
diff changeset
127 /// Specify how one should pass an argument of a record type.
anatofuz
parents:
diff changeset
128 enum RecordArgABI {
anatofuz
parents:
diff changeset
129 /// Pass it using the normal C aggregate rules for the ABI, potentially
anatofuz
parents:
diff changeset
130 /// introducing extra copies and passing some or all of it in registers.
anatofuz
parents:
diff changeset
131 RAA_Default = 0,
anatofuz
parents:
diff changeset
132
anatofuz
parents:
diff changeset
133 /// Pass it on the stack using its defined layout. The argument must be
anatofuz
parents:
diff changeset
134 /// evaluated directly into the correct stack position in the arguments area,
anatofuz
parents:
diff changeset
135 /// and the call machinery must not move it or introduce extra copies.
anatofuz
parents:
diff changeset
136 RAA_DirectInMemory,
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 /// Pass it as a pointer to temporary memory.
anatofuz
parents:
diff changeset
139 RAA_Indirect
anatofuz
parents:
diff changeset
140 };
anatofuz
parents:
diff changeset
141
anatofuz
parents:
diff changeset
142 /// Returns how an argument of the given record type should be passed.
anatofuz
parents:
diff changeset
143 virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const = 0;
anatofuz
parents:
diff changeset
144
anatofuz
parents:
diff changeset
145 /// Returns true if the implicit 'sret' parameter comes after the implicit
anatofuz
parents:
diff changeset
146 /// 'this' parameter of C++ instance methods.
anatofuz
parents:
diff changeset
147 virtual bool isSRetParameterAfterThis() const { return false; }
anatofuz
parents:
diff changeset
148
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
149 /// Returns true if the ABI permits the argument to be a homogeneous
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
150 /// aggregate.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
151 virtual bool
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
152 isPermittedToBeHomogeneousAggregate(const CXXRecordDecl *RD) const {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
153 return true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
154 };
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
155
150
anatofuz
parents:
diff changeset
156 /// Find the LLVM type used to represent the given member pointer
anatofuz
parents:
diff changeset
157 /// type.
anatofuz
parents:
diff changeset
158 virtual llvm::Type *
anatofuz
parents:
diff changeset
159 ConvertMemberPointerType(const MemberPointerType *MPT);
anatofuz
parents:
diff changeset
160
anatofuz
parents:
diff changeset
161 /// Load a member function from an object and a member function
anatofuz
parents:
diff changeset
162 /// pointer. Apply the this-adjustment and set 'This' to the
anatofuz
parents:
diff changeset
163 /// adjusted value.
anatofuz
parents:
diff changeset
164 virtual CGCallee EmitLoadOfMemberFunctionPointer(
anatofuz
parents:
diff changeset
165 CodeGenFunction &CGF, const Expr *E, Address This,
anatofuz
parents:
diff changeset
166 llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
anatofuz
parents:
diff changeset
167 const MemberPointerType *MPT);
anatofuz
parents:
diff changeset
168
anatofuz
parents:
diff changeset
169 /// Calculate an l-value from an object and a data member pointer.
anatofuz
parents:
diff changeset
170 virtual llvm::Value *
anatofuz
parents:
diff changeset
171 EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
anatofuz
parents:
diff changeset
172 Address Base, llvm::Value *MemPtr,
anatofuz
parents:
diff changeset
173 const MemberPointerType *MPT);
anatofuz
parents:
diff changeset
174
anatofuz
parents:
diff changeset
175 /// Perform a derived-to-base, base-to-derived, or bitcast member
anatofuz
parents:
diff changeset
176 /// pointer conversion.
anatofuz
parents:
diff changeset
177 virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
178 const CastExpr *E,
anatofuz
parents:
diff changeset
179 llvm::Value *Src);
anatofuz
parents:
diff changeset
180
anatofuz
parents:
diff changeset
181 /// Perform a derived-to-base, base-to-derived, or bitcast member
anatofuz
parents:
diff changeset
182 /// pointer conversion on a constant value.
anatofuz
parents:
diff changeset
183 virtual llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
anatofuz
parents:
diff changeset
184 llvm::Constant *Src);
anatofuz
parents:
diff changeset
185
anatofuz
parents:
diff changeset
186 /// Return true if the given member pointer can be zero-initialized
anatofuz
parents:
diff changeset
187 /// (in the C++ sense) with an LLVM zeroinitializer.
anatofuz
parents:
diff changeset
188 virtual bool isZeroInitializable(const MemberPointerType *MPT);
anatofuz
parents:
diff changeset
189
anatofuz
parents:
diff changeset
190 /// Return whether or not a member pointers type is convertible to an IR type.
anatofuz
parents:
diff changeset
191 virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const {
anatofuz
parents:
diff changeset
192 return true;
anatofuz
parents:
diff changeset
193 }
anatofuz
parents:
diff changeset
194
anatofuz
parents:
diff changeset
195 /// Create a null member pointer of the given type.
anatofuz
parents:
diff changeset
196 virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
anatofuz
parents:
diff changeset
197
anatofuz
parents:
diff changeset
198 /// Create a member pointer for the given method.
anatofuz
parents:
diff changeset
199 virtual llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD);
anatofuz
parents:
diff changeset
200
anatofuz
parents:
diff changeset
201 /// Create a member pointer for the given field.
anatofuz
parents:
diff changeset
202 virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
anatofuz
parents:
diff changeset
203 CharUnits offset);
anatofuz
parents:
diff changeset
204
anatofuz
parents:
diff changeset
205 /// Create a member pointer for the given member pointer constant.
anatofuz
parents:
diff changeset
206 virtual llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT);
anatofuz
parents:
diff changeset
207
anatofuz
parents:
diff changeset
208 /// Emit a comparison between two member pointers. Returns an i1.
anatofuz
parents:
diff changeset
209 virtual llvm::Value *
anatofuz
parents:
diff changeset
210 EmitMemberPointerComparison(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
211 llvm::Value *L,
anatofuz
parents:
diff changeset
212 llvm::Value *R,
anatofuz
parents:
diff changeset
213 const MemberPointerType *MPT,
anatofuz
parents:
diff changeset
214 bool Inequality);
anatofuz
parents:
diff changeset
215
anatofuz
parents:
diff changeset
216 /// Determine if a member pointer is non-null. Returns an i1.
anatofuz
parents:
diff changeset
217 virtual llvm::Value *
anatofuz
parents:
diff changeset
218 EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
219 llvm::Value *MemPtr,
anatofuz
parents:
diff changeset
220 const MemberPointerType *MPT);
anatofuz
parents:
diff changeset
221
anatofuz
parents:
diff changeset
222 protected:
anatofuz
parents:
diff changeset
223 /// A utility method for computing the offset required for the given
anatofuz
parents:
diff changeset
224 /// base-to-derived or derived-to-base member-pointer conversion.
anatofuz
parents:
diff changeset
225 /// Does not handle virtual conversions (in case we ever fully
anatofuz
parents:
diff changeset
226 /// support an ABI that allows this). Returns null if no adjustment
anatofuz
parents:
diff changeset
227 /// is required.
anatofuz
parents:
diff changeset
228 llvm::Constant *getMemberPointerAdjustment(const CastExpr *E);
anatofuz
parents:
diff changeset
229
anatofuz
parents:
diff changeset
230 public:
anatofuz
parents:
diff changeset
231 virtual void emitVirtualObjectDelete(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
232 const CXXDeleteExpr *DE,
anatofuz
parents:
diff changeset
233 Address Ptr, QualType ElementType,
anatofuz
parents:
diff changeset
234 const CXXDestructorDecl *Dtor) = 0;
anatofuz
parents:
diff changeset
235 virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) = 0;
anatofuz
parents:
diff changeset
236 virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) = 0;
anatofuz
parents:
diff changeset
237 virtual llvm::GlobalVariable *getThrowInfo(QualType T) { return nullptr; }
anatofuz
parents:
diff changeset
238
anatofuz
parents:
diff changeset
239 /// Determine whether it's possible to emit a vtable for \p RD, even
anatofuz
parents:
diff changeset
240 /// though we do not know that the vtable has been marked as used by semantic
anatofuz
parents:
diff changeset
241 /// analysis.
anatofuz
parents:
diff changeset
242 virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const = 0;
anatofuz
parents:
diff changeset
243
anatofuz
parents:
diff changeset
244 virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) = 0;
anatofuz
parents:
diff changeset
245
anatofuz
parents:
diff changeset
246 virtual llvm::CallInst *
anatofuz
parents:
diff changeset
247 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
248 llvm::Value *Exn);
anatofuz
parents:
diff changeset
249
anatofuz
parents:
diff changeset
250 virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0;
anatofuz
parents:
diff changeset
251 virtual CatchTypeInfo
anatofuz
parents:
diff changeset
252 getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) = 0;
anatofuz
parents:
diff changeset
253 virtual CatchTypeInfo getCatchAllTypeInfo();
anatofuz
parents:
diff changeset
254
anatofuz
parents:
diff changeset
255 virtual bool shouldTypeidBeNullChecked(bool IsDeref,
anatofuz
parents:
diff changeset
256 QualType SrcRecordTy) = 0;
anatofuz
parents:
diff changeset
257 virtual void EmitBadTypeidCall(CodeGenFunction &CGF) = 0;
anatofuz
parents:
diff changeset
258 virtual llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
anatofuz
parents:
diff changeset
259 Address ThisPtr,
anatofuz
parents:
diff changeset
260 llvm::Type *StdTypeInfoPtrTy) = 0;
anatofuz
parents:
diff changeset
261
anatofuz
parents:
diff changeset
262 virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
anatofuz
parents:
diff changeset
263 QualType SrcRecordTy) = 0;
anatofuz
parents:
diff changeset
264
anatofuz
parents:
diff changeset
265 virtual llvm::Value *
anatofuz
parents:
diff changeset
266 EmitDynamicCastCall(CodeGenFunction &CGF, Address Value,
anatofuz
parents:
diff changeset
267 QualType SrcRecordTy, QualType DestTy,
anatofuz
parents:
diff changeset
268 QualType DestRecordTy, llvm::BasicBlock *CastEnd) = 0;
anatofuz
parents:
diff changeset
269
anatofuz
parents:
diff changeset
270 virtual llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
271 Address Value,
anatofuz
parents:
diff changeset
272 QualType SrcRecordTy,
anatofuz
parents:
diff changeset
273 QualType DestTy) = 0;
anatofuz
parents:
diff changeset
274
anatofuz
parents:
diff changeset
275 virtual bool EmitBadCastCall(CodeGenFunction &CGF) = 0;
anatofuz
parents:
diff changeset
276
anatofuz
parents:
diff changeset
277 virtual llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
278 Address This,
anatofuz
parents:
diff changeset
279 const CXXRecordDecl *ClassDecl,
anatofuz
parents:
diff changeset
280 const CXXRecordDecl *BaseClassDecl) = 0;
anatofuz
parents:
diff changeset
281
anatofuz
parents:
diff changeset
282 virtual llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
283 const CXXRecordDecl *RD);
anatofuz
parents:
diff changeset
284
anatofuz
parents:
diff changeset
285 /// Emit the code to initialize hidden members required
anatofuz
parents:
diff changeset
286 /// to handle virtual inheritance, if needed by the ABI.
anatofuz
parents:
diff changeset
287 virtual void
anatofuz
parents:
diff changeset
288 initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
289 const CXXRecordDecl *RD) {}
anatofuz
parents:
diff changeset
290
anatofuz
parents:
diff changeset
291 /// Emit constructor variants required by this ABI.
anatofuz
parents:
diff changeset
292 virtual void EmitCXXConstructors(const CXXConstructorDecl *D) = 0;
anatofuz
parents:
diff changeset
293
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
294 /// Additional implicit arguments to add to the beginning (Prefix) and end
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
295 /// (Suffix) of a constructor / destructor arg list.
150
anatofuz
parents:
diff changeset
296 ///
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
297 /// Note that Prefix should actually be inserted *after* the first existing
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
298 /// arg; `this` arguments always come first.
150
anatofuz
parents:
diff changeset
299 struct AddedStructorArgs {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
300 struct Arg {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
301 llvm::Value *Value;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
302 QualType Type;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
303 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
304 SmallVector<Arg, 1> Prefix;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
305 SmallVector<Arg, 1> Suffix;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
306 AddedStructorArgs() = default;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
307 AddedStructorArgs(SmallVector<Arg, 1> P, SmallVector<Arg, 1> S)
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
308 : Prefix(std::move(P)), Suffix(std::move(S)) {}
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
309 static AddedStructorArgs prefix(SmallVector<Arg, 1> Args) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
310 return {std::move(Args), {}};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
311 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
312 static AddedStructorArgs suffix(SmallVector<Arg, 1> Args) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
313 return {{}, std::move(Args)};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
314 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
315 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
316
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
317 /// Similar to AddedStructorArgs, but only notes the number of additional
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
318 /// arguments.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
319 struct AddedStructorArgCounts {
150
anatofuz
parents:
diff changeset
320 unsigned Prefix = 0;
anatofuz
parents:
diff changeset
321 unsigned Suffix = 0;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
322 AddedStructorArgCounts() = default;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
323 AddedStructorArgCounts(unsigned P, unsigned S) : Prefix(P), Suffix(S) {}
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
324 static AddedStructorArgCounts prefix(unsigned N) { return {N, 0}; }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
325 static AddedStructorArgCounts suffix(unsigned N) { return {0, N}; }
150
anatofuz
parents:
diff changeset
326 };
anatofuz
parents:
diff changeset
327
anatofuz
parents:
diff changeset
328 /// Build the signature of the given constructor or destructor variant by
anatofuz
parents:
diff changeset
329 /// adding any required parameters. For convenience, ArgTys has been
anatofuz
parents:
diff changeset
330 /// initialized with the type of 'this'.
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
331 virtual AddedStructorArgCounts
150
anatofuz
parents:
diff changeset
332 buildStructorSignature(GlobalDecl GD,
anatofuz
parents:
diff changeset
333 SmallVectorImpl<CanQualType> &ArgTys) = 0;
anatofuz
parents:
diff changeset
334
anatofuz
parents:
diff changeset
335 /// Returns true if the given destructor type should be emitted as a linkonce
anatofuz
parents:
diff changeset
336 /// delegating thunk, regardless of whether the dtor is defined in this TU or
anatofuz
parents:
diff changeset
337 /// not.
anatofuz
parents:
diff changeset
338 virtual bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
anatofuz
parents:
diff changeset
339 CXXDtorType DT) const = 0;
anatofuz
parents:
diff changeset
340
anatofuz
parents:
diff changeset
341 virtual void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
anatofuz
parents:
diff changeset
342 const CXXDestructorDecl *Dtor,
anatofuz
parents:
diff changeset
343 CXXDtorType DT) const;
anatofuz
parents:
diff changeset
344
anatofuz
parents:
diff changeset
345 virtual llvm::GlobalValue::LinkageTypes
anatofuz
parents:
diff changeset
346 getCXXDestructorLinkage(GVALinkage Linkage, const CXXDestructorDecl *Dtor,
anatofuz
parents:
diff changeset
347 CXXDtorType DT) const;
anatofuz
parents:
diff changeset
348
anatofuz
parents:
diff changeset
349 /// Emit destructor variants required by this ABI.
anatofuz
parents:
diff changeset
350 virtual void EmitCXXDestructors(const CXXDestructorDecl *D) = 0;
anatofuz
parents:
diff changeset
351
anatofuz
parents:
diff changeset
352 /// Get the type of the implicit "this" parameter used by a method. May return
anatofuz
parents:
diff changeset
353 /// zero if no specific type is applicable, e.g. if the ABI expects the "this"
anatofuz
parents:
diff changeset
354 /// parameter to point to some artificial offset in a complete object due to
anatofuz
parents:
diff changeset
355 /// vbases being reordered.
anatofuz
parents:
diff changeset
356 virtual const CXXRecordDecl *
anatofuz
parents:
diff changeset
357 getThisArgumentTypeForMethod(const CXXMethodDecl *MD) {
anatofuz
parents:
diff changeset
358 return MD->getParent();
anatofuz
parents:
diff changeset
359 }
anatofuz
parents:
diff changeset
360
anatofuz
parents:
diff changeset
361 /// Perform ABI-specific "this" argument adjustment required prior to
anatofuz
parents:
diff changeset
362 /// a call of a virtual function.
anatofuz
parents:
diff changeset
363 /// The "VirtualCall" argument is true iff the call itself is virtual.
anatofuz
parents:
diff changeset
364 virtual Address
anatofuz
parents:
diff changeset
365 adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD,
anatofuz
parents:
diff changeset
366 Address This, bool VirtualCall) {
anatofuz
parents:
diff changeset
367 return This;
anatofuz
parents:
diff changeset
368 }
anatofuz
parents:
diff changeset
369
anatofuz
parents:
diff changeset
370 /// Build a parameter variable suitable for 'this'.
anatofuz
parents:
diff changeset
371 void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params);
anatofuz
parents:
diff changeset
372
anatofuz
parents:
diff changeset
373 /// Insert any ABI-specific implicit parameters into the parameter list for a
anatofuz
parents:
diff changeset
374 /// function. This generally involves extra data for constructors and
anatofuz
parents:
diff changeset
375 /// destructors.
anatofuz
parents:
diff changeset
376 ///
anatofuz
parents:
diff changeset
377 /// ABIs may also choose to override the return type, which has been
anatofuz
parents:
diff changeset
378 /// initialized with the type of 'this' if HasThisReturn(CGF.CurGD) is true or
anatofuz
parents:
diff changeset
379 /// the formal return type of the function otherwise.
anatofuz
parents:
diff changeset
380 virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
anatofuz
parents:
diff changeset
381 FunctionArgList &Params) = 0;
anatofuz
parents:
diff changeset
382
anatofuz
parents:
diff changeset
383 /// Get the ABI-specific "this" parameter adjustment to apply in the prologue
anatofuz
parents:
diff changeset
384 /// of a virtual function.
anatofuz
parents:
diff changeset
385 virtual CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
anatofuz
parents:
diff changeset
386 return CharUnits::Zero();
anatofuz
parents:
diff changeset
387 }
anatofuz
parents:
diff changeset
388
anatofuz
parents:
diff changeset
389 /// Emit the ABI-specific prolog for the function.
anatofuz
parents:
diff changeset
390 virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF) = 0;
anatofuz
parents:
diff changeset
391
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
392 virtual AddedStructorArgs
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
393 getImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
394 CXXCtorType Type, bool ForVirtualBase,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
395 bool Delegating) = 0;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
396
150
anatofuz
parents:
diff changeset
397 /// Add any ABI-specific implicit arguments needed to call a constructor.
anatofuz
parents:
diff changeset
398 ///
anatofuz
parents:
diff changeset
399 /// \return The number of arguments added at the beginning and end of the
anatofuz
parents:
diff changeset
400 /// call, which is typically zero or one.
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
401 AddedStructorArgCounts
150
anatofuz
parents:
diff changeset
402 addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
anatofuz
parents:
diff changeset
403 CXXCtorType Type, bool ForVirtualBase,
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
404 bool Delegating, CallArgList &Args);
150
anatofuz
parents:
diff changeset
405
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
406 /// Get the implicit (second) parameter that comes after the "this" pointer,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
407 /// or nullptr if there is isn't one.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
408 virtual llvm::Value *
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
409 getCXXDestructorImplicitParam(CodeGenFunction &CGF,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
410 const CXXDestructorDecl *DD, CXXDtorType Type,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
411 bool ForVirtualBase, bool Delegating) = 0;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
412
150
anatofuz
parents:
diff changeset
413 /// Emit the destructor call.
anatofuz
parents:
diff changeset
414 virtual void EmitDestructorCall(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
415 const CXXDestructorDecl *DD, CXXDtorType Type,
anatofuz
parents:
diff changeset
416 bool ForVirtualBase, bool Delegating,
anatofuz
parents:
diff changeset
417 Address This, QualType ThisTy) = 0;
anatofuz
parents:
diff changeset
418
anatofuz
parents:
diff changeset
419 /// Emits the VTable definitions required for the given record type.
anatofuz
parents:
diff changeset
420 virtual void emitVTableDefinitions(CodeGenVTables &CGVT,
anatofuz
parents:
diff changeset
421 const CXXRecordDecl *RD) = 0;
anatofuz
parents:
diff changeset
422
anatofuz
parents:
diff changeset
423 /// Checks if ABI requires extra virtual offset for vtable field.
anatofuz
parents:
diff changeset
424 virtual bool
anatofuz
parents:
diff changeset
425 isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
426 CodeGenFunction::VPtr Vptr) = 0;
anatofuz
parents:
diff changeset
427
anatofuz
parents:
diff changeset
428 /// Checks if ABI requires to initialize vptrs for given dynamic class.
anatofuz
parents:
diff changeset
429 virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) = 0;
anatofuz
parents:
diff changeset
430
anatofuz
parents:
diff changeset
431 /// Get the address point of the vtable for the given base subobject.
anatofuz
parents:
diff changeset
432 virtual llvm::Constant *
anatofuz
parents:
diff changeset
433 getVTableAddressPoint(BaseSubobject Base,
anatofuz
parents:
diff changeset
434 const CXXRecordDecl *VTableClass) = 0;
anatofuz
parents:
diff changeset
435
anatofuz
parents:
diff changeset
436 /// Get the address point of the vtable for the given base subobject while
anatofuz
parents:
diff changeset
437 /// building a constructor or a destructor.
anatofuz
parents:
diff changeset
438 virtual llvm::Value *
anatofuz
parents:
diff changeset
439 getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD,
anatofuz
parents:
diff changeset
440 BaseSubobject Base,
anatofuz
parents:
diff changeset
441 const CXXRecordDecl *NearestVBase) = 0;
anatofuz
parents:
diff changeset
442
anatofuz
parents:
diff changeset
443 /// Get the address point of the vtable for the given base subobject while
anatofuz
parents:
diff changeset
444 /// building a constexpr.
anatofuz
parents:
diff changeset
445 virtual llvm::Constant *
anatofuz
parents:
diff changeset
446 getVTableAddressPointForConstExpr(BaseSubobject Base,
anatofuz
parents:
diff changeset
447 const CXXRecordDecl *VTableClass) = 0;
anatofuz
parents:
diff changeset
448
anatofuz
parents:
diff changeset
449 /// Get the address of the vtable for the given record decl which should be
anatofuz
parents:
diff changeset
450 /// used for the vptr at the given offset in RD.
anatofuz
parents:
diff changeset
451 virtual llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
anatofuz
parents:
diff changeset
452 CharUnits VPtrOffset) = 0;
anatofuz
parents:
diff changeset
453
anatofuz
parents:
diff changeset
454 /// Build a virtual function pointer in the ABI-specific way.
anatofuz
parents:
diff changeset
455 virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
456 GlobalDecl GD, Address This,
anatofuz
parents:
diff changeset
457 llvm::Type *Ty,
anatofuz
parents:
diff changeset
458 SourceLocation Loc) = 0;
anatofuz
parents:
diff changeset
459
anatofuz
parents:
diff changeset
460 using DeleteOrMemberCallExpr =
anatofuz
parents:
diff changeset
461 llvm::PointerUnion<const CXXDeleteExpr *, const CXXMemberCallExpr *>;
anatofuz
parents:
diff changeset
462
anatofuz
parents:
diff changeset
463 /// Emit the ABI-specific virtual destructor call.
anatofuz
parents:
diff changeset
464 virtual llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
465 const CXXDestructorDecl *Dtor,
anatofuz
parents:
diff changeset
466 CXXDtorType DtorType,
anatofuz
parents:
diff changeset
467 Address This,
anatofuz
parents:
diff changeset
468 DeleteOrMemberCallExpr E) = 0;
anatofuz
parents:
diff changeset
469
anatofuz
parents:
diff changeset
470 virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
471 GlobalDecl GD,
anatofuz
parents:
diff changeset
472 CallArgList &CallArgs) {}
anatofuz
parents:
diff changeset
473
anatofuz
parents:
diff changeset
474 /// Emit any tables needed to implement virtual inheritance. For Itanium,
anatofuz
parents:
diff changeset
475 /// this emits virtual table tables. For the MSVC++ ABI, this emits virtual
anatofuz
parents:
diff changeset
476 /// base tables.
anatofuz
parents:
diff changeset
477 virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0;
anatofuz
parents:
diff changeset
478
anatofuz
parents:
diff changeset
479 virtual bool exportThunk() = 0;
anatofuz
parents:
diff changeset
480 virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
anatofuz
parents:
diff changeset
481 GlobalDecl GD, bool ReturnAdjustment) = 0;
anatofuz
parents:
diff changeset
482
anatofuz
parents:
diff changeset
483 virtual llvm::Value *performThisAdjustment(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
484 Address This,
anatofuz
parents:
diff changeset
485 const ThisAdjustment &TA) = 0;
anatofuz
parents:
diff changeset
486
anatofuz
parents:
diff changeset
487 virtual llvm::Value *performReturnAdjustment(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
488 Address Ret,
anatofuz
parents:
diff changeset
489 const ReturnAdjustment &RA) = 0;
anatofuz
parents:
diff changeset
490
anatofuz
parents:
diff changeset
491 virtual void EmitReturnFromThunk(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
492 RValue RV, QualType ResultType);
anatofuz
parents:
diff changeset
493
anatofuz
parents:
diff changeset
494 virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *,
anatofuz
parents:
diff changeset
495 FunctionArgList &Args) const = 0;
anatofuz
parents:
diff changeset
496
anatofuz
parents:
diff changeset
497 /// Gets the offsets of all the virtual base pointers in a given class.
anatofuz
parents:
diff changeset
498 virtual std::vector<CharUnits> getVBPtrOffsets(const CXXRecordDecl *RD);
anatofuz
parents:
diff changeset
499
anatofuz
parents:
diff changeset
500 /// Gets the pure virtual member call function.
anatofuz
parents:
diff changeset
501 virtual StringRef GetPureVirtualCallName() = 0;
anatofuz
parents:
diff changeset
502
anatofuz
parents:
diff changeset
503 /// Gets the deleted virtual member call name.
anatofuz
parents:
diff changeset
504 virtual StringRef GetDeletedVirtualCallName() = 0;
anatofuz
parents:
diff changeset
505
anatofuz
parents:
diff changeset
506 /**************************** Array cookies ******************************/
anatofuz
parents:
diff changeset
507
anatofuz
parents:
diff changeset
508 /// Returns the extra size required in order to store the array
anatofuz
parents:
diff changeset
509 /// cookie for the given new-expression. May return 0 to indicate that no
anatofuz
parents:
diff changeset
510 /// array cookie is required.
anatofuz
parents:
diff changeset
511 ///
anatofuz
parents:
diff changeset
512 /// Several cases are filtered out before this method is called:
anatofuz
parents:
diff changeset
513 /// - non-array allocations never need a cookie
anatofuz
parents:
diff changeset
514 /// - calls to \::operator new(size_t, void*) never need a cookie
anatofuz
parents:
diff changeset
515 ///
anatofuz
parents:
diff changeset
516 /// \param expr - the new-expression being allocated.
anatofuz
parents:
diff changeset
517 virtual CharUnits GetArrayCookieSize(const CXXNewExpr *expr);
anatofuz
parents:
diff changeset
518
anatofuz
parents:
diff changeset
519 /// Initialize the array cookie for the given allocation.
anatofuz
parents:
diff changeset
520 ///
anatofuz
parents:
diff changeset
521 /// \param NewPtr - a char* which is the presumed-non-null
anatofuz
parents:
diff changeset
522 /// return value of the allocation function
anatofuz
parents:
diff changeset
523 /// \param NumElements - the computed number of elements,
anatofuz
parents:
diff changeset
524 /// potentially collapsed from the multidimensional array case;
anatofuz
parents:
diff changeset
525 /// always a size_t
anatofuz
parents:
diff changeset
526 /// \param ElementType - the base element allocated type,
anatofuz
parents:
diff changeset
527 /// i.e. the allocated type after stripping all array types
anatofuz
parents:
diff changeset
528 virtual Address InitializeArrayCookie(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
529 Address NewPtr,
anatofuz
parents:
diff changeset
530 llvm::Value *NumElements,
anatofuz
parents:
diff changeset
531 const CXXNewExpr *expr,
anatofuz
parents:
diff changeset
532 QualType ElementType);
anatofuz
parents:
diff changeset
533
anatofuz
parents:
diff changeset
534 /// Reads the array cookie associated with the given pointer,
anatofuz
parents:
diff changeset
535 /// if it has one.
anatofuz
parents:
diff changeset
536 ///
anatofuz
parents:
diff changeset
537 /// \param Ptr - a pointer to the first element in the array
anatofuz
parents:
diff changeset
538 /// \param ElementType - the base element type of elements of the array
anatofuz
parents:
diff changeset
539 /// \param NumElements - an out parameter which will be initialized
anatofuz
parents:
diff changeset
540 /// with the number of elements allocated, or zero if there is no
anatofuz
parents:
diff changeset
541 /// cookie
anatofuz
parents:
diff changeset
542 /// \param AllocPtr - an out parameter which will be initialized
anatofuz
parents:
diff changeset
543 /// with a char* pointing to the address returned by the allocation
anatofuz
parents:
diff changeset
544 /// function
anatofuz
parents:
diff changeset
545 /// \param CookieSize - an out parameter which will be initialized
anatofuz
parents:
diff changeset
546 /// with the size of the cookie, or zero if there is no cookie
anatofuz
parents:
diff changeset
547 virtual void ReadArrayCookie(CodeGenFunction &CGF, Address Ptr,
anatofuz
parents:
diff changeset
548 const CXXDeleteExpr *expr,
anatofuz
parents:
diff changeset
549 QualType ElementType, llvm::Value *&NumElements,
anatofuz
parents:
diff changeset
550 llvm::Value *&AllocPtr, CharUnits &CookieSize);
anatofuz
parents:
diff changeset
551
anatofuz
parents:
diff changeset
552 /// Return whether the given global decl needs a VTT parameter.
anatofuz
parents:
diff changeset
553 virtual bool NeedsVTTParameter(GlobalDecl GD);
anatofuz
parents:
diff changeset
554
anatofuz
parents:
diff changeset
555 protected:
anatofuz
parents:
diff changeset
556 /// Returns the extra size required in order to store the array
anatofuz
parents:
diff changeset
557 /// cookie for the given type. Assumes that an array cookie is
anatofuz
parents:
diff changeset
558 /// required.
anatofuz
parents:
diff changeset
559 virtual CharUnits getArrayCookieSizeImpl(QualType elementType);
anatofuz
parents:
diff changeset
560
anatofuz
parents:
diff changeset
561 /// Reads the array cookie for an allocation which is known to have one.
anatofuz
parents:
diff changeset
562 /// This is called by the standard implementation of ReadArrayCookie.
anatofuz
parents:
diff changeset
563 ///
anatofuz
parents:
diff changeset
564 /// \param ptr - a pointer to the allocation made for an array, as a char*
anatofuz
parents:
diff changeset
565 /// \param cookieSize - the computed cookie size of an array
anatofuz
parents:
diff changeset
566 ///
anatofuz
parents:
diff changeset
567 /// Other parameters are as above.
anatofuz
parents:
diff changeset
568 ///
anatofuz
parents:
diff changeset
569 /// \return a size_t
anatofuz
parents:
diff changeset
570 virtual llvm::Value *readArrayCookieImpl(CodeGenFunction &IGF, Address ptr,
anatofuz
parents:
diff changeset
571 CharUnits cookieSize);
anatofuz
parents:
diff changeset
572
anatofuz
parents:
diff changeset
573 public:
anatofuz
parents:
diff changeset
574
anatofuz
parents:
diff changeset
575 /*************************** Static local guards ****************************/
anatofuz
parents:
diff changeset
576
anatofuz
parents:
diff changeset
577 /// Emits the guarded initializer and destructor setup for the given
anatofuz
parents:
diff changeset
578 /// variable, given that it couldn't be emitted as a constant.
anatofuz
parents:
diff changeset
579 /// If \p PerformInit is false, the initialization has been folded to a
anatofuz
parents:
diff changeset
580 /// constant and should not be performed.
anatofuz
parents:
diff changeset
581 ///
anatofuz
parents:
diff changeset
582 /// The variable may be:
anatofuz
parents:
diff changeset
583 /// - a static local variable
anatofuz
parents:
diff changeset
584 /// - a static data member of a class template instantiation
anatofuz
parents:
diff changeset
585 virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
anatofuz
parents:
diff changeset
586 llvm::GlobalVariable *DeclPtr,
anatofuz
parents:
diff changeset
587 bool PerformInit) = 0;
anatofuz
parents:
diff changeset
588
anatofuz
parents:
diff changeset
589 /// Emit code to force the execution of a destructor during global
anatofuz
parents:
diff changeset
590 /// teardown. The default implementation of this uses atexit.
anatofuz
parents:
diff changeset
591 ///
anatofuz
parents:
diff changeset
592 /// \param Dtor - a function taking a single pointer argument
anatofuz
parents:
diff changeset
593 /// \param Addr - a pointer to pass to the destructor function.
anatofuz
parents:
diff changeset
594 virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
anatofuz
parents:
diff changeset
595 llvm::FunctionCallee Dtor,
anatofuz
parents:
diff changeset
596 llvm::Constant *Addr) = 0;
anatofuz
parents:
diff changeset
597
anatofuz
parents:
diff changeset
598 /*************************** thread_local initialization ********************/
anatofuz
parents:
diff changeset
599
anatofuz
parents:
diff changeset
600 /// Emits ABI-required functions necessary to initialize thread_local
anatofuz
parents:
diff changeset
601 /// variables in this translation unit.
anatofuz
parents:
diff changeset
602 ///
anatofuz
parents:
diff changeset
603 /// \param CXXThreadLocals - The thread_local declarations in this translation
anatofuz
parents:
diff changeset
604 /// unit.
anatofuz
parents:
diff changeset
605 /// \param CXXThreadLocalInits - If this translation unit contains any
anatofuz
parents:
diff changeset
606 /// non-constant initialization or non-trivial destruction for
anatofuz
parents:
diff changeset
607 /// thread_local variables, a list of functions to perform the
anatofuz
parents:
diff changeset
608 /// initialization.
anatofuz
parents:
diff changeset
609 virtual void EmitThreadLocalInitFuncs(
anatofuz
parents:
diff changeset
610 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
anatofuz
parents:
diff changeset
611 ArrayRef<llvm::Function *> CXXThreadLocalInits,
anatofuz
parents:
diff changeset
612 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) = 0;
anatofuz
parents:
diff changeset
613
anatofuz
parents:
diff changeset
614 // Determine if references to thread_local global variables can be made
anatofuz
parents:
diff changeset
615 // directly or require access through a thread wrapper function.
anatofuz
parents:
diff changeset
616 virtual bool usesThreadWrapperFunction(const VarDecl *VD) const = 0;
anatofuz
parents:
diff changeset
617
anatofuz
parents:
diff changeset
618 /// Emit a reference to a non-local thread_local variable (including
anatofuz
parents:
diff changeset
619 /// triggering the initialization of all thread_local variables in its
anatofuz
parents:
diff changeset
620 /// translation unit).
anatofuz
parents:
diff changeset
621 virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
anatofuz
parents:
diff changeset
622 const VarDecl *VD,
anatofuz
parents:
diff changeset
623 QualType LValType) = 0;
anatofuz
parents:
diff changeset
624
anatofuz
parents:
diff changeset
625 /// Emit a single constructor/destructor with the given type from a C++
anatofuz
parents:
diff changeset
626 /// constructor Decl.
anatofuz
parents:
diff changeset
627 virtual void emitCXXStructor(GlobalDecl GD) = 0;
anatofuz
parents:
diff changeset
628
anatofuz
parents:
diff changeset
629 /// Load a vtable from This, an object of polymorphic type RD, or from one of
anatofuz
parents:
diff changeset
630 /// its virtual bases if it does not have its own vtable. Returns the vtable
anatofuz
parents:
diff changeset
631 /// and the class from which the vtable was loaded.
anatofuz
parents:
diff changeset
632 virtual std::pair<llvm::Value *, const CXXRecordDecl *>
anatofuz
parents:
diff changeset
633 LoadVTablePtr(CodeGenFunction &CGF, Address This,
anatofuz
parents:
diff changeset
634 const CXXRecordDecl *RD) = 0;
anatofuz
parents:
diff changeset
635 };
anatofuz
parents:
diff changeset
636
anatofuz
parents:
diff changeset
637 // Create an instance of a C++ ABI class:
anatofuz
parents:
diff changeset
638
anatofuz
parents:
diff changeset
639 /// Creates an Itanium-family ABI.
anatofuz
parents:
diff changeset
640 CGCXXABI *CreateItaniumCXXABI(CodeGenModule &CGM);
anatofuz
parents:
diff changeset
641
anatofuz
parents:
diff changeset
642 /// Creates a Microsoft-family ABI.
anatofuz
parents:
diff changeset
643 CGCXXABI *CreateMicrosoftCXXABI(CodeGenModule &CGM);
anatofuz
parents:
diff changeset
644
anatofuz
parents:
diff changeset
645 struct CatchRetScope final : EHScopeStack::Cleanup {
anatofuz
parents:
diff changeset
646 llvm::CatchPadInst *CPI;
anatofuz
parents:
diff changeset
647
anatofuz
parents:
diff changeset
648 CatchRetScope(llvm::CatchPadInst *CPI) : CPI(CPI) {}
anatofuz
parents:
diff changeset
649
anatofuz
parents:
diff changeset
650 void Emit(CodeGenFunction &CGF, Flags flags) override {
anatofuz
parents:
diff changeset
651 llvm::BasicBlock *BB = CGF.createBasicBlock("catchret.dest");
anatofuz
parents:
diff changeset
652 CGF.Builder.CreateCatchRet(CPI, BB);
anatofuz
parents:
diff changeset
653 CGF.EmitBlock(BB);
anatofuz
parents:
diff changeset
654 }
anatofuz
parents:
diff changeset
655 };
anatofuz
parents:
diff changeset
656 }
anatofuz
parents:
diff changeset
657 }
anatofuz
parents:
diff changeset
658
anatofuz
parents:
diff changeset
659 #endif