1 //===------- ItaniumCXXABI.cpp - Emit LLVM Code from ASTs for a Module ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This provides C++ code generation targetting the Itanium C++ ABI. The class
11 // in this file generates structures that follow the Itanium C++ ABI, which is
13 // http://www.codesourcery.com/public/cxx-abi/abi.html
14 // http://www.codesourcery.com/public/cxx-abi/abi-eh.html
16 // It also supports the closely-related ARM ABI, documented at:
17 // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
19 //===----------------------------------------------------------------------===//
22 #include "CGRecordLayout.h"
23 #include "CodeGenFunction.h"
24 #include "CodeGenModule.h"
25 #include <clang/AST/Mangle.h>
26 #include <clang/AST/Type.h>
27 #include <llvm/Target/TargetData.h>
28 #include <llvm/Value.h>
30 using namespace clang
;
31 using namespace CodeGen
;
34 class ItaniumCXXABI
: public CodeGen::CGCXXABI
{
36 const llvm::IntegerType
*PtrDiffTy
;
40 // It's a little silly for us to cache this.
41 const llvm::IntegerType
*getPtrDiffTy() {
43 QualType T
= getContext().getPointerDiffType();
44 const llvm::Type
*Ty
= CGM
.getTypes().ConvertTypeRecursive(T
);
45 PtrDiffTy
= cast
<llvm::IntegerType
>(Ty
);
50 bool NeedsArrayCookie(const CXXNewExpr
*expr
);
51 bool NeedsArrayCookie(const CXXDeleteExpr
*expr
,
52 QualType elementType
);
55 ItaniumCXXABI(CodeGen::CodeGenModule
&CGM
, bool IsARM
= false) :
56 CGCXXABI(CGM
), PtrDiffTy(0), IsARM(IsARM
) { }
58 bool isZeroInitializable(const MemberPointerType
*MPT
);
60 const llvm::Type
*ConvertMemberPointerType(const MemberPointerType
*MPT
);
62 llvm::Value
*EmitLoadOfMemberFunctionPointer(CodeGenFunction
&CGF
,
64 llvm::Value
*MemFnPtr
,
65 const MemberPointerType
*MPT
);
67 llvm::Value
*EmitMemberDataPointerAddress(CodeGenFunction
&CGF
,
70 const MemberPointerType
*MPT
);
72 llvm::Value
*EmitMemberPointerConversion(CodeGenFunction
&CGF
,
76 llvm::Constant
*EmitMemberPointerConversion(llvm::Constant
*C
,
79 llvm::Constant
*EmitNullMemberPointer(const MemberPointerType
*MPT
);
81 llvm::Constant
*EmitMemberPointer(const CXXMethodDecl
*MD
);
82 llvm::Constant
*EmitMemberPointer(const FieldDecl
*FD
);
84 llvm::Value
*EmitMemberPointerComparison(CodeGenFunction
&CGF
,
87 const MemberPointerType
*MPT
,
90 llvm::Value
*EmitMemberPointerIsNotNull(CodeGenFunction
&CGF
,
92 const MemberPointerType
*MPT
);
94 void BuildConstructorSignature(const CXXConstructorDecl
*Ctor
,
97 llvm::SmallVectorImpl
<CanQualType
> &ArgTys
);
99 void BuildDestructorSignature(const CXXDestructorDecl
*Dtor
,
102 llvm::SmallVectorImpl
<CanQualType
> &ArgTys
);
104 void BuildInstanceFunctionParams(CodeGenFunction
&CGF
,
106 FunctionArgList
&Params
);
108 void EmitInstanceFunctionProlog(CodeGenFunction
&CGF
);
110 CharUnits
GetArrayCookieSize(const CXXNewExpr
*expr
);
111 llvm::Value
*InitializeArrayCookie(CodeGenFunction
&CGF
,
113 llvm::Value
*NumElements
,
114 const CXXNewExpr
*expr
,
115 QualType ElementType
);
116 void ReadArrayCookie(CodeGenFunction
&CGF
, llvm::Value
*Ptr
,
117 const CXXDeleteExpr
*expr
,
118 QualType ElementType
, llvm::Value
*&NumElements
,
119 llvm::Value
*&AllocPtr
, CharUnits
&CookieSize
);
121 void EmitGuardedInit(CodeGenFunction
&CGF
, const VarDecl
&D
,
122 llvm::GlobalVariable
*DeclPtr
);
125 class ARMCXXABI
: public ItaniumCXXABI
{
127 ARMCXXABI(CodeGen::CodeGenModule
&CGM
) : ItaniumCXXABI(CGM
, /*ARM*/ true) {}
129 void BuildConstructorSignature(const CXXConstructorDecl
*Ctor
,
132 llvm::SmallVectorImpl
<CanQualType
> &ArgTys
);
134 void BuildDestructorSignature(const CXXDestructorDecl
*Dtor
,
137 llvm::SmallVectorImpl
<CanQualType
> &ArgTys
);
139 void BuildInstanceFunctionParams(CodeGenFunction
&CGF
,
141 FunctionArgList
&Params
);
143 void EmitInstanceFunctionProlog(CodeGenFunction
&CGF
);
145 void EmitReturnFromThunk(CodeGenFunction
&CGF
, RValue RV
, QualType ResTy
);
147 CharUnits
GetArrayCookieSize(const CXXNewExpr
*expr
);
148 llvm::Value
*InitializeArrayCookie(CodeGenFunction
&CGF
,
150 llvm::Value
*NumElements
,
151 const CXXNewExpr
*expr
,
152 QualType ElementType
);
153 void ReadArrayCookie(CodeGenFunction
&CGF
, llvm::Value
*Ptr
,
154 const CXXDeleteExpr
*expr
,
155 QualType ElementType
, llvm::Value
*&NumElements
,
156 llvm::Value
*&AllocPtr
, CharUnits
&CookieSize
);
159 /// \brief Returns true if the given instance method is one of the
160 /// kinds that the ARM ABI says returns 'this'.
161 static bool HasThisReturn(GlobalDecl GD
) {
162 const CXXMethodDecl
*MD
= cast
<CXXMethodDecl
>(GD
.getDecl());
163 return ((isa
<CXXDestructorDecl
>(MD
) && GD
.getDtorType() != Dtor_Deleting
) ||
164 (isa
<CXXConstructorDecl
>(MD
)));
169 CodeGen::CGCXXABI
*CodeGen::CreateItaniumCXXABI(CodeGenModule
&CGM
) {
170 return new ItaniumCXXABI(CGM
);
173 CodeGen::CGCXXABI
*CodeGen::CreateARMCXXABI(CodeGenModule
&CGM
) {
174 return new ARMCXXABI(CGM
);
178 ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType
*MPT
) {
179 if (MPT
->isMemberDataPointer())
180 return getPtrDiffTy();
182 return llvm::StructType::get(CGM
.getLLVMContext(),
183 getPtrDiffTy(), getPtrDiffTy(), NULL
);
186 /// In the Itanium and ARM ABIs, method pointers have the form:
187 /// struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
189 /// In the Itanium ABI:
190 /// - method pointers are virtual if (memptr.ptr & 1) is nonzero
191 /// - the this-adjustment is (memptr.adj)
192 /// - the virtual offset is (memptr.ptr - 1)
195 /// - method pointers are virtual if (memptr.adj & 1) is nonzero
196 /// - the this-adjustment is (memptr.adj >> 1)
197 /// - the virtual offset is (memptr.ptr)
198 /// ARM uses 'adj' for the virtual flag because Thumb functions
199 /// may be only single-byte aligned.
201 /// If the member is virtual, the adjusted 'this' pointer points
202 /// to a vtable pointer from which the virtual offset is applied.
204 /// If the member is non-virtual, memptr.ptr is the address of
205 /// the function to call.
207 ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction
&CGF
,
209 llvm::Value
*MemFnPtr
,
210 const MemberPointerType
*MPT
) {
211 CGBuilderTy
&Builder
= CGF
.Builder
;
213 const FunctionProtoType
*FPT
=
214 MPT
->getPointeeType()->getAs
<FunctionProtoType
>();
215 const CXXRecordDecl
*RD
=
216 cast
<CXXRecordDecl
>(MPT
->getClass()->getAs
<RecordType
>()->getDecl());
218 const llvm::FunctionType
*FTy
=
219 CGM
.getTypes().GetFunctionType(CGM
.getTypes().getFunctionInfo(RD
, FPT
),
222 const llvm::IntegerType
*ptrdiff
= getPtrDiffTy();
223 llvm::Constant
*ptrdiff_1
= llvm::ConstantInt::get(ptrdiff
, 1);
225 llvm::BasicBlock
*FnVirtual
= CGF
.createBasicBlock("memptr.virtual");
226 llvm::BasicBlock
*FnNonVirtual
= CGF
.createBasicBlock("memptr.nonvirtual");
227 llvm::BasicBlock
*FnEnd
= CGF
.createBasicBlock("memptr.end");
229 // Extract memptr.adj, which is in the second field.
230 llvm::Value
*RawAdj
= Builder
.CreateExtractValue(MemFnPtr
, 1, "memptr.adj");
232 // Compute the true adjustment.
233 llvm::Value
*Adj
= RawAdj
;
235 Adj
= Builder
.CreateAShr(Adj
, ptrdiff_1
, "memptr.adj.shifted");
237 // Apply the adjustment and cast back to the original struct type
239 llvm::Value
*Ptr
= Builder
.CreateBitCast(This
, Builder
.getInt8PtrTy());
240 Ptr
= Builder
.CreateInBoundsGEP(Ptr
, Adj
);
241 This
= Builder
.CreateBitCast(Ptr
, This
->getType(), "this.adjusted");
243 // Load the function pointer.
244 llvm::Value
*FnAsInt
= Builder
.CreateExtractValue(MemFnPtr
, 0, "memptr.ptr");
246 // If the LSB in the function pointer is 1, the function pointer points to
247 // a virtual function.
248 llvm::Value
*IsVirtual
;
250 IsVirtual
= Builder
.CreateAnd(RawAdj
, ptrdiff_1
);
252 IsVirtual
= Builder
.CreateAnd(FnAsInt
, ptrdiff_1
);
253 IsVirtual
= Builder
.CreateIsNotNull(IsVirtual
, "memptr.isvirtual");
254 Builder
.CreateCondBr(IsVirtual
, FnVirtual
, FnNonVirtual
);
256 // In the virtual path, the adjustment left 'This' pointing to the
257 // vtable of the correct base subobject. The "function pointer" is an
258 // offset within the vtable (+1 for the virtual flag on non-ARM).
259 CGF
.EmitBlock(FnVirtual
);
261 // Cast the adjusted this to a pointer to vtable pointer and load.
262 const llvm::Type
*VTableTy
= Builder
.getInt8PtrTy();
263 llvm::Value
*VTable
= Builder
.CreateBitCast(This
, VTableTy
->getPointerTo());
264 VTable
= Builder
.CreateLoad(VTable
, "memptr.vtable");
267 llvm::Value
*VTableOffset
= FnAsInt
;
268 if (!IsARM
) VTableOffset
= Builder
.CreateSub(VTableOffset
, ptrdiff_1
);
269 VTable
= Builder
.CreateGEP(VTable
, VTableOffset
);
271 // Load the virtual function to call.
272 VTable
= Builder
.CreateBitCast(VTable
, FTy
->getPointerTo()->getPointerTo());
273 llvm::Value
*VirtualFn
= Builder
.CreateLoad(VTable
, "memptr.virtualfn");
274 CGF
.EmitBranch(FnEnd
);
276 // In the non-virtual path, the function pointer is actually a
278 CGF
.EmitBlock(FnNonVirtual
);
279 llvm::Value
*NonVirtualFn
=
280 Builder
.CreateIntToPtr(FnAsInt
, FTy
->getPointerTo(), "memptr.nonvirtualfn");
283 CGF
.EmitBlock(FnEnd
);
284 llvm::PHINode
*Callee
= Builder
.CreatePHI(FTy
->getPointerTo());
285 Callee
->reserveOperandSpace(2);
286 Callee
->addIncoming(VirtualFn
, FnVirtual
);
287 Callee
->addIncoming(NonVirtualFn
, FnNonVirtual
);
291 /// Compute an l-value by applying the given pointer-to-member to a
293 llvm::Value
*ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction
&CGF
,
296 const MemberPointerType
*MPT
) {
297 assert(MemPtr
->getType() == getPtrDiffTy());
299 CGBuilderTy
&Builder
= CGF
.Builder
;
301 unsigned AS
= cast
<llvm::PointerType
>(Base
->getType())->getAddressSpace();
304 Base
= Builder
.CreateBitCast(Base
, Builder
.getInt8Ty()->getPointerTo(AS
));
306 // Apply the offset, which we assume is non-null.
307 llvm::Value
*Addr
= Builder
.CreateInBoundsGEP(Base
, MemPtr
, "memptr.offset");
309 // Cast the address to the appropriate pointer type, adopting the
310 // address space of the base pointer.
311 const llvm::Type
*PType
312 = CGF
.ConvertTypeForMem(MPT
->getPointeeType())->getPointerTo(AS
);
313 return Builder
.CreateBitCast(Addr
, PType
);
316 /// Perform a derived-to-base or base-to-derived member pointer conversion.
318 /// Obligatory offset/adjustment diagram:
319 /// <-- offset --> <-- adjustment -->
320 /// |--------------------------|----------------------|--------------------|
321 /// ^Derived address point ^Base address point ^Member address point
323 /// So when converting a base member pointer to a derived member pointer,
324 /// we add the offset to the adjustment because the address point has
325 /// decreased; and conversely, when converting a derived MP to a base MP
326 /// we subtract the offset from the adjustment because the address point
329 /// The standard forbids (at compile time) conversion to and from
330 /// virtual bases, which is why we don't have to consider them here.
332 /// The standard forbids (at run time) casting a derived MP to a base
333 /// MP when the derived MP does not point to a member of the base.
334 /// This is why -1 is a reasonable choice for null data member
337 ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction
&CGF
,
340 assert(E
->getCastKind() == CK_DerivedToBaseMemberPointer
||
341 E
->getCastKind() == CK_BaseToDerivedMemberPointer
);
343 if (isa
<llvm::Constant
>(Src
))
344 return EmitMemberPointerConversion(cast
<llvm::Constant
>(Src
), E
);
346 CGBuilderTy
&Builder
= CGF
.Builder
;
348 const MemberPointerType
*SrcTy
=
349 E
->getSubExpr()->getType()->getAs
<MemberPointerType
>();
350 const MemberPointerType
*DestTy
= E
->getType()->getAs
<MemberPointerType
>();
352 const CXXRecordDecl
*SrcDecl
= SrcTy
->getClass()->getAsCXXRecordDecl();
353 const CXXRecordDecl
*DestDecl
= DestTy
->getClass()->getAsCXXRecordDecl();
356 E
->getCastKind() == CK_DerivedToBaseMemberPointer
;
358 const CXXRecordDecl
*DerivedDecl
;
360 DerivedDecl
= SrcDecl
;
362 DerivedDecl
= DestDecl
;
364 llvm::Constant
*Adj
=
365 CGF
.CGM
.GetNonVirtualBaseClassOffset(DerivedDecl
,
368 if (!Adj
) return Src
;
370 // For member data pointers, this is just a matter of adding the
371 // offset if the source is non-null.
372 if (SrcTy
->isMemberDataPointer()) {
375 Dst
= Builder
.CreateNSWSub(Src
, Adj
, "adj");
377 Dst
= Builder
.CreateNSWAdd(Src
, Adj
, "adj");
380 llvm::Value
*Null
= llvm::Constant::getAllOnesValue(Src
->getType());
381 llvm::Value
*IsNull
= Builder
.CreateICmpEQ(Src
, Null
, "memptr.isnull");
382 return Builder
.CreateSelect(IsNull
, Src
, Dst
);
385 // The this-adjustment is left-shifted by 1 on ARM.
387 uint64_t Offset
= cast
<llvm::ConstantInt
>(Adj
)->getZExtValue();
389 Adj
= llvm::ConstantInt::get(Adj
->getType(), Offset
);
392 llvm::Value
*SrcAdj
= Builder
.CreateExtractValue(Src
, 1, "src.adj");
395 DstAdj
= Builder
.CreateNSWSub(SrcAdj
, Adj
, "adj");
397 DstAdj
= Builder
.CreateNSWAdd(SrcAdj
, Adj
, "adj");
399 return Builder
.CreateInsertValue(Src
, DstAdj
, 1);
403 ItaniumCXXABI::EmitMemberPointerConversion(llvm::Constant
*C
,
405 const MemberPointerType
*SrcTy
=
406 E
->getSubExpr()->getType()->getAs
<MemberPointerType
>();
407 const MemberPointerType
*DestTy
=
408 E
->getType()->getAs
<MemberPointerType
>();
411 E
->getCastKind() == CK_DerivedToBaseMemberPointer
;
413 const CXXRecordDecl
*DerivedDecl
;
415 DerivedDecl
= SrcTy
->getClass()->getAsCXXRecordDecl();
417 DerivedDecl
= DestTy
->getClass()->getAsCXXRecordDecl();
419 // Calculate the offset to the base class.
420 llvm::Constant
*Offset
=
421 CGM
.GetNonVirtualBaseClassOffset(DerivedDecl
,
424 // If there's no offset, we're done.
425 if (!Offset
) return C
;
427 // If the source is a member data pointer, we have to do a null
428 // check and then add the offset. In the common case, we can fold
430 if (SrcTy
->isMemberDataPointer()) {
431 assert(C
->getType() == getPtrDiffTy());
433 // If it's a constant int, just create a new constant int.
434 if (llvm::ConstantInt
*CI
= dyn_cast
<llvm::ConstantInt
>(C
)) {
435 int64_t Src
= CI
->getSExtValue();
437 // Null converts to null.
438 if (Src
== -1) return CI
;
440 // Otherwise, just add the offset.
441 int64_t OffsetV
= cast
<llvm::ConstantInt
>(Offset
)->getSExtValue();
442 int64_t Dst
= (DerivedToBase
? Src
- OffsetV
: Src
+ OffsetV
);
443 return llvm::ConstantInt::get(CI
->getType(), Dst
, /*signed*/ true);
446 // Otherwise, we have to form a constant select expression.
447 llvm::Constant
*Null
= llvm::Constant::getAllOnesValue(C
->getType());
449 llvm::Constant
*IsNull
=
450 llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_EQ
, C
, Null
);
454 Dst
= llvm::ConstantExpr::getNSWSub(C
, Offset
);
456 Dst
= llvm::ConstantExpr::getNSWAdd(C
, Offset
);
458 return llvm::ConstantExpr::getSelect(IsNull
, Null
, Dst
);
461 // The this-adjustment is left-shifted by 1 on ARM.
463 int64_t OffsetV
= cast
<llvm::ConstantInt
>(Offset
)->getSExtValue();
465 Offset
= llvm::ConstantInt::get(Offset
->getType(), OffsetV
);
468 llvm::ConstantStruct
*CS
= cast
<llvm::ConstantStruct
>(C
);
470 llvm::Constant
*Values
[2] = { CS
->getOperand(0), 0 };
472 Values
[1] = llvm::ConstantExpr::getSub(CS
->getOperand(1), Offset
);
474 Values
[1] = llvm::ConstantExpr::getAdd(CS
->getOperand(1), Offset
);
476 return llvm::ConstantStruct::get(CGM
.getLLVMContext(), Values
, 2,
482 ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType
*MPT
) {
483 const llvm::Type
*ptrdiff_t = getPtrDiffTy();
485 // Itanium C++ ABI 2.3:
486 // A NULL pointer is represented as -1.
487 if (MPT
->isMemberDataPointer())
488 return llvm::ConstantInt::get(ptrdiff_t, -1ULL, /*isSigned=*/true);
490 llvm::Constant
*Zero
= llvm::ConstantInt::get(ptrdiff_t, 0);
491 llvm::Constant
*Values
[2] = { Zero
, Zero
};
492 return llvm::ConstantStruct::get(CGM
.getLLVMContext(), Values
, 2,
496 static uint64_t getFieldOffset(const FieldDecl
*FD
, CodeGenModule
&CGM
) {
497 const CGRecordLayout
&RL
= CGM
.getTypes().getCGRecordLayout(FD
->getParent());
498 const llvm::StructType
*ClassLTy
= RL
.getLLVMType();
500 unsigned FieldNo
= RL
.getLLVMFieldNo(FD
);
502 CGM
.getTargetData().getStructLayout(ClassLTy
)->getElementOffset(FieldNo
);
505 llvm::Constant
*ItaniumCXXABI::EmitMemberPointer(const FieldDecl
*FD
) {
506 // Itanium C++ ABI 2.3:
507 // A pointer to data member is an offset from the base address of
508 // the class object containing it, represented as a ptrdiff_t
510 const RecordDecl
*parent
= FD
->getParent();
511 if (!parent
->isAnonymousStructOrUnion())
512 return llvm::ConstantInt::get(getPtrDiffTy(), getFieldOffset(FD
, CGM
));
514 // Handle a field injected from an anonymous struct or union.
516 assert(FD
->getDeclName() && "Requested pointer to member with no name!");
518 // Find the record which the field was injected into.
519 while (parent
->isAnonymousStructOrUnion())
520 parent
= cast
<RecordDecl
>(parent
->getParent());
522 RecordDecl::lookup_const_result lookup
= parent
->lookup(FD
->getDeclName());
523 assert(lookup
.first
!= lookup
.second
&& "Didn't find the field!");
524 const IndirectFieldDecl
*indirectFD
= cast
<IndirectFieldDecl
>(*lookup
.first
);
527 for (IndirectFieldDecl::chain_iterator
528 I
= indirectFD
->chain_begin(), E
= indirectFD
->chain_end(); I
!=E
; ++I
) {
529 Offset
+= getFieldOffset(cast
<FieldDecl
>(*I
), CGM
);
532 return llvm::ConstantInt::get(getPtrDiffTy(), Offset
);
535 llvm::Constant
*ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl
*MD
) {
536 assert(MD
->isInstance() && "Member function must not be static!");
537 MD
= MD
->getCanonicalDecl();
539 CodeGenTypes
&Types
= CGM
.getTypes();
540 const llvm::Type
*ptrdiff_t = getPtrDiffTy();
542 // Get the function pointer (or index if this is a virtual function).
543 llvm::Constant
*MemPtr
[2];
544 if (MD
->isVirtual()) {
545 uint64_t Index
= CGM
.getVTables().getMethodVTableIndex(MD
);
547 // FIXME: We shouldn't use / 8 here.
548 uint64_t PointerWidthInBytes
=
549 getContext().Target
.getPointerWidth(0) / 8;
550 uint64_t VTableOffset
= (Index
* PointerWidthInBytes
);
553 // ARM C++ ABI 3.2.1:
554 // This ABI specifies that adj contains twice the this
555 // adjustment, plus 1 if the member function is virtual. The
556 // least significant bit of adj then makes exactly the same
557 // discrimination as the least significant bit of ptr does for
559 MemPtr
[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset
);
560 MemPtr
[1] = llvm::ConstantInt::get(ptrdiff_t, 1);
562 // Itanium C++ ABI 2.3:
563 // For a virtual function, [the pointer field] is 1 plus the
564 // virtual table offset (in bytes) of the function,
565 // represented as a ptrdiff_t.
566 MemPtr
[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset
+ 1);
567 MemPtr
[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
570 const FunctionProtoType
*FPT
= MD
->getType()->getAs
<FunctionProtoType
>();
571 const llvm::Type
*Ty
;
572 // Check whether the function has a computable LLVM signature.
573 if (!CodeGenTypes::VerifyFuncTypeComplete(FPT
)) {
574 // The function has a computable LLVM signature; use the correct type.
575 Ty
= Types
.GetFunctionType(Types
.getFunctionInfo(MD
), FPT
->isVariadic());
577 // Use an arbitrary non-function type to tell GetAddrOfFunction that the
578 // function type is incomplete.
582 llvm::Constant
*Addr
= CGM
.GetAddrOfFunction(MD
, Ty
);
583 MemPtr
[0] = llvm::ConstantExpr::getPtrToInt(Addr
, ptrdiff_t);
584 MemPtr
[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
587 return llvm::ConstantStruct::get(CGM
.getLLVMContext(),
588 MemPtr
, 2, /*Packed=*/false);
591 /// The comparison algorithm is pretty easy: the member pointers are
592 /// the same if they're either bitwise identical *or* both null.
594 /// ARM is different here only because null-ness is more complicated.
596 ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction
&CGF
,
599 const MemberPointerType
*MPT
,
601 CGBuilderTy
&Builder
= CGF
.Builder
;
603 llvm::ICmpInst::Predicate Eq
;
604 llvm::Instruction::BinaryOps And
, Or
;
606 Eq
= llvm::ICmpInst::ICMP_NE
;
607 And
= llvm::Instruction::Or
;
608 Or
= llvm::Instruction::And
;
610 Eq
= llvm::ICmpInst::ICMP_EQ
;
611 And
= llvm::Instruction::And
;
612 Or
= llvm::Instruction::Or
;
615 // Member data pointers are easy because there's a unique null
616 // value, so it just comes down to bitwise equality.
617 if (MPT
->isMemberDataPointer())
618 return Builder
.CreateICmp(Eq
, L
, R
);
620 // For member function pointers, the tautologies are more complex.
621 // The Itanium tautology is:
622 // (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
623 // The ARM tautology is:
624 // (L == R) <==> (L.ptr == R.ptr &&
625 // (L.adj == R.adj ||
626 // (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
627 // The inequality tautologies have exactly the same structure, except
628 // applying De Morgan's laws.
630 llvm::Value
*LPtr
= Builder
.CreateExtractValue(L
, 0, "lhs.memptr.ptr");
631 llvm::Value
*RPtr
= Builder
.CreateExtractValue(R
, 0, "rhs.memptr.ptr");
633 // This condition tests whether L.ptr == R.ptr. This must always be
634 // true for equality to hold.
635 llvm::Value
*PtrEq
= Builder
.CreateICmp(Eq
, LPtr
, RPtr
, "cmp.ptr");
637 // This condition, together with the assumption that L.ptr == R.ptr,
638 // tests whether the pointers are both null. ARM imposes an extra
640 llvm::Value
*Zero
= llvm::Constant::getNullValue(LPtr
->getType());
641 llvm::Value
*EqZero
= Builder
.CreateICmp(Eq
, LPtr
, Zero
, "cmp.ptr.null");
643 // This condition tests whether L.adj == R.adj. If this isn't
644 // true, the pointers are unequal unless they're both null.
645 llvm::Value
*LAdj
= Builder
.CreateExtractValue(L
, 1, "lhs.memptr.adj");
646 llvm::Value
*RAdj
= Builder
.CreateExtractValue(R
, 1, "rhs.memptr.adj");
647 llvm::Value
*AdjEq
= Builder
.CreateICmp(Eq
, LAdj
, RAdj
, "cmp.adj");
649 // Null member function pointers on ARM clear the low bit of Adj,
650 // so the zero condition has to check that neither low bit is set.
652 llvm::Value
*One
= llvm::ConstantInt::get(LPtr
->getType(), 1);
654 // Compute (l.adj | r.adj) & 1 and test it against zero.
655 llvm::Value
*OrAdj
= Builder
.CreateOr(LAdj
, RAdj
, "or.adj");
656 llvm::Value
*OrAdjAnd1
= Builder
.CreateAnd(OrAdj
, One
);
657 llvm::Value
*OrAdjAnd1EqZero
= Builder
.CreateICmp(Eq
, OrAdjAnd1
, Zero
,
659 EqZero
= Builder
.CreateBinOp(And
, EqZero
, OrAdjAnd1EqZero
);
662 // Tie together all our conditions.
663 llvm::Value
*Result
= Builder
.CreateBinOp(Or
, EqZero
, AdjEq
);
664 Result
= Builder
.CreateBinOp(And
, PtrEq
, Result
,
665 Inequality
? "memptr.ne" : "memptr.eq");
670 ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction
&CGF
,
672 const MemberPointerType
*MPT
) {
673 CGBuilderTy
&Builder
= CGF
.Builder
;
675 /// For member data pointers, this is just a check against -1.
676 if (MPT
->isMemberDataPointer()) {
677 assert(MemPtr
->getType() == getPtrDiffTy());
678 llvm::Value
*NegativeOne
=
679 llvm::Constant::getAllOnesValue(MemPtr
->getType());
680 return Builder
.CreateICmpNE(MemPtr
, NegativeOne
, "memptr.tobool");
683 // In Itanium, a member function pointer is null if 'ptr' is null.
684 llvm::Value
*Ptr
= Builder
.CreateExtractValue(MemPtr
, 0, "memptr.ptr");
686 llvm::Constant
*Zero
= llvm::ConstantInt::get(Ptr
->getType(), 0);
687 llvm::Value
*Result
= Builder
.CreateICmpNE(Ptr
, Zero
, "memptr.tobool");
689 // In ARM, it's that, plus the low bit of 'adj' must be zero.
691 llvm::Constant
*One
= llvm::ConstantInt::get(Ptr
->getType(), 1);
692 llvm::Value
*Adj
= Builder
.CreateExtractValue(MemPtr
, 1, "memptr.adj");
693 llvm::Value
*VirtualBit
= Builder
.CreateAnd(Adj
, One
, "memptr.virtualbit");
694 llvm::Value
*IsNotVirtual
= Builder
.CreateICmpEQ(VirtualBit
, Zero
,
695 "memptr.notvirtual");
696 Result
= Builder
.CreateAnd(Result
, IsNotVirtual
);
702 /// The Itanium ABI requires non-zero initialization only for data
703 /// member pointers, for which '0' is a valid offset.
704 bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType
*MPT
) {
705 return MPT
->getPointeeType()->isFunctionType();
708 /// The generic ABI passes 'this', plus a VTT if it's initializing a
710 void ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl
*Ctor
,
713 llvm::SmallVectorImpl
<CanQualType
> &ArgTys
) {
714 ASTContext
&Context
= getContext();
716 // 'this' is already there.
718 // Check if we need to add a VTT parameter (which has type void **).
719 if (Type
== Ctor_Base
&& Ctor
->getParent()->getNumVBases() != 0)
720 ArgTys
.push_back(Context
.getPointerType(Context
.VoidPtrTy
));
723 /// The ARM ABI does the same as the Itanium ABI, but returns 'this'.
724 void ARMCXXABI::BuildConstructorSignature(const CXXConstructorDecl
*Ctor
,
727 llvm::SmallVectorImpl
<CanQualType
> &ArgTys
) {
728 ItaniumCXXABI::BuildConstructorSignature(Ctor
, Type
, ResTy
, ArgTys
);
732 /// The generic ABI passes 'this', plus a VTT if it's destroying a
734 void ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl
*Dtor
,
737 llvm::SmallVectorImpl
<CanQualType
> &ArgTys
) {
738 ASTContext
&Context
= getContext();
740 // 'this' is already there.
742 // Check if we need to add a VTT parameter (which has type void **).
743 if (Type
== Dtor_Base
&& Dtor
->getParent()->getNumVBases() != 0)
744 ArgTys
.push_back(Context
.getPointerType(Context
.VoidPtrTy
));
747 /// The ARM ABI does the same as the Itanium ABI, but returns 'this'
748 /// for non-deleting destructors.
749 void ARMCXXABI::BuildDestructorSignature(const CXXDestructorDecl
*Dtor
,
752 llvm::SmallVectorImpl
<CanQualType
> &ArgTys
) {
753 ItaniumCXXABI::BuildDestructorSignature(Dtor
, Type
, ResTy
, ArgTys
);
755 if (Type
!= Dtor_Deleting
)
759 void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction
&CGF
,
761 FunctionArgList
&Params
) {
762 /// Create the 'this' variable.
763 BuildThisParam(CGF
, Params
);
765 const CXXMethodDecl
*MD
= cast
<CXXMethodDecl
>(CGF
.CurGD
.getDecl());
766 assert(MD
->isInstance());
768 // Check if we need a VTT parameter as well.
769 if (CodeGenVTables::needsVTTParameter(CGF
.CurGD
)) {
770 ASTContext
&Context
= getContext();
772 // FIXME: avoid the fake decl
773 QualType T
= Context
.getPointerType(Context
.VoidPtrTy
);
774 ImplicitParamDecl
*VTTDecl
775 = ImplicitParamDecl::Create(Context
, 0, MD
->getLocation(),
776 &Context
.Idents
.get("vtt"), T
);
777 Params
.push_back(std::make_pair(VTTDecl
, VTTDecl
->getType()));
778 getVTTDecl(CGF
) = VTTDecl
;
782 void ARMCXXABI::BuildInstanceFunctionParams(CodeGenFunction
&CGF
,
784 FunctionArgList
&Params
) {
785 ItaniumCXXABI::BuildInstanceFunctionParams(CGF
, ResTy
, Params
);
787 // Return 'this' from certain constructors and destructors.
788 if (HasThisReturn(CGF
.CurGD
))
789 ResTy
= Params
[0].second
;
792 void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction
&CGF
) {
793 /// Initialize the 'this' slot.
796 /// Initialize the 'vtt' slot if needed.
797 if (getVTTDecl(CGF
)) {
799 = CGF
.Builder
.CreateLoad(CGF
.GetAddrOfLocalVar(getVTTDecl(CGF
)),
804 void ARMCXXABI::EmitInstanceFunctionProlog(CodeGenFunction
&CGF
) {
805 ItaniumCXXABI::EmitInstanceFunctionProlog(CGF
);
807 /// Initialize the return slot to 'this' at the start of the
809 if (HasThisReturn(CGF
.CurGD
))
810 CGF
.Builder
.CreateStore(CGF
.LoadCXXThis(), CGF
.ReturnValue
);
813 void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction
&CGF
,
814 RValue RV
, QualType ResultType
) {
815 if (!isa
<CXXDestructorDecl
>(CGF
.CurGD
.getDecl()))
816 return ItaniumCXXABI::EmitReturnFromThunk(CGF
, RV
, ResultType
);
818 // Destructor thunks in the ARM ABI have indeterminate results.
819 const llvm::Type
*T
=
820 cast
<llvm::PointerType
>(CGF
.ReturnValue
->getType())->getElementType();
821 RValue Undef
= RValue::get(llvm::UndefValue::get(T
));
822 return ItaniumCXXABI::EmitReturnFromThunk(CGF
, Undef
, ResultType
);
825 /************************** Array allocation cookies **************************/
827 bool ItaniumCXXABI::NeedsArrayCookie(const CXXNewExpr
*expr
) {
828 // If the class's usual deallocation function takes two arguments,
829 // it needs a cookie.
830 if (expr
->doesUsualArrayDeleteWantSize())
833 // Otherwise, if the class has a non-trivial destructor, it always
835 const CXXRecordDecl
*record
=
836 expr
->getAllocatedType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
837 return (record
&& !record
->hasTrivialDestructor());
840 bool ItaniumCXXABI::NeedsArrayCookie(const CXXDeleteExpr
*expr
,
841 QualType elementType
) {
842 // If the class's usual deallocation function takes two arguments,
843 // it needs a cookie.
844 if (expr
->doesUsualArrayDeleteWantSize())
847 // Otherwise, if the class has a non-trivial destructor, it always
849 const CXXRecordDecl
*record
=
850 elementType
->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
851 return (record
&& !record
->hasTrivialDestructor());
854 CharUnits
ItaniumCXXABI::GetArrayCookieSize(const CXXNewExpr
*expr
) {
855 if (!NeedsArrayCookie(expr
))
856 return CharUnits::Zero();
858 // Padding is the maximum of sizeof(size_t) and alignof(elementType)
859 ASTContext
&Ctx
= getContext();
860 return std::max(Ctx
.getTypeSizeInChars(Ctx
.getSizeType()),
861 Ctx
.getTypeAlignInChars(expr
->getAllocatedType()));
864 llvm::Value
*ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction
&CGF
,
866 llvm::Value
*NumElements
,
867 const CXXNewExpr
*expr
,
868 QualType ElementType
) {
869 assert(NeedsArrayCookie(expr
));
871 unsigned AS
= cast
<llvm::PointerType
>(NewPtr
->getType())->getAddressSpace();
873 ASTContext
&Ctx
= getContext();
874 QualType SizeTy
= Ctx
.getSizeType();
875 CharUnits SizeSize
= Ctx
.getTypeSizeInChars(SizeTy
);
877 // The size of the cookie.
878 CharUnits CookieSize
=
879 std::max(SizeSize
, Ctx
.getTypeAlignInChars(ElementType
));
881 // Compute an offset to the cookie.
882 llvm::Value
*CookiePtr
= NewPtr
;
883 CharUnits CookieOffset
= CookieSize
- SizeSize
;
884 if (!CookieOffset
.isZero())
885 CookiePtr
= CGF
.Builder
.CreateConstInBoundsGEP1_64(CookiePtr
,
886 CookieOffset
.getQuantity());
888 // Write the number of elements into the appropriate slot.
889 llvm::Value
*NumElementsPtr
890 = CGF
.Builder
.CreateBitCast(CookiePtr
,
891 CGF
.ConvertType(SizeTy
)->getPointerTo(AS
));
892 CGF
.Builder
.CreateStore(NumElements
, NumElementsPtr
);
894 // Finally, compute a pointer to the actual data buffer by skipping
895 // over the cookie completely.
896 return CGF
.Builder
.CreateConstInBoundsGEP1_64(NewPtr
,
897 CookieSize
.getQuantity());
900 void ItaniumCXXABI::ReadArrayCookie(CodeGenFunction
&CGF
,
902 const CXXDeleteExpr
*expr
,
903 QualType ElementType
,
904 llvm::Value
*&NumElements
,
905 llvm::Value
*&AllocPtr
,
906 CharUnits
&CookieSize
) {
907 // Derive a char* in the same address space as the pointer.
908 unsigned AS
= cast
<llvm::PointerType
>(Ptr
->getType())->getAddressSpace();
909 const llvm::Type
*CharPtrTy
= CGF
.Builder
.getInt8Ty()->getPointerTo(AS
);
911 // If we don't need an array cookie, bail out early.
912 if (!NeedsArrayCookie(expr
, ElementType
)) {
913 AllocPtr
= CGF
.Builder
.CreateBitCast(Ptr
, CharPtrTy
);
915 CookieSize
= CharUnits::Zero();
919 QualType SizeTy
= getContext().getSizeType();
920 CharUnits SizeSize
= getContext().getTypeSizeInChars(SizeTy
);
921 const llvm::Type
*SizeLTy
= CGF
.ConvertType(SizeTy
);
924 = std::max(SizeSize
, getContext().getTypeAlignInChars(ElementType
));
926 CharUnits NumElementsOffset
= CookieSize
- SizeSize
;
928 // Compute the allocated pointer.
929 AllocPtr
= CGF
.Builder
.CreateBitCast(Ptr
, CharPtrTy
);
930 AllocPtr
= CGF
.Builder
.CreateConstInBoundsGEP1_64(AllocPtr
,
931 -CookieSize
.getQuantity());
933 llvm::Value
*NumElementsPtr
= AllocPtr
;
934 if (!NumElementsOffset
.isZero())
936 CGF
.Builder
.CreateConstInBoundsGEP1_64(NumElementsPtr
,
937 NumElementsOffset
.getQuantity());
939 CGF
.Builder
.CreateBitCast(NumElementsPtr
, SizeLTy
->getPointerTo(AS
));
940 NumElements
= CGF
.Builder
.CreateLoad(NumElementsPtr
);
943 CharUnits
ARMCXXABI::GetArrayCookieSize(const CXXNewExpr
*expr
) {
944 if (!NeedsArrayCookie(expr
))
945 return CharUnits::Zero();
947 // On ARM, the cookie is always:
948 // struct array_cookie {
949 // std::size_t element_size; // element_size != 0
950 // std::size_t element_count;
952 // TODO: what should we do if the allocated type actually wants
953 // greater alignment?
954 return getContext().getTypeSizeInChars(getContext().getSizeType()) * 2;
957 llvm::Value
*ARMCXXABI::InitializeArrayCookie(CodeGenFunction
&CGF
,
959 llvm::Value
*NumElements
,
960 const CXXNewExpr
*expr
,
961 QualType ElementType
) {
962 assert(NeedsArrayCookie(expr
));
964 // NewPtr is a char*.
966 unsigned AS
= cast
<llvm::PointerType
>(NewPtr
->getType())->getAddressSpace();
968 ASTContext
&Ctx
= getContext();
969 CharUnits SizeSize
= Ctx
.getTypeSizeInChars(Ctx
.getSizeType());
970 const llvm::IntegerType
*SizeTy
=
971 cast
<llvm::IntegerType
>(CGF
.ConvertType(Ctx
.getSizeType()));
973 // The cookie is always at the start of the buffer.
974 llvm::Value
*CookiePtr
= NewPtr
;
976 // The first element is the element size.
977 CookiePtr
= CGF
.Builder
.CreateBitCast(CookiePtr
, SizeTy
->getPointerTo(AS
));
978 llvm::Value
*ElementSize
= llvm::ConstantInt::get(SizeTy
,
979 Ctx
.getTypeSizeInChars(ElementType
).getQuantity());
980 CGF
.Builder
.CreateStore(ElementSize
, CookiePtr
);
982 // The second element is the element count.
983 CookiePtr
= CGF
.Builder
.CreateConstInBoundsGEP1_32(CookiePtr
, 1);
984 CGF
.Builder
.CreateStore(NumElements
, CookiePtr
);
986 // Finally, compute a pointer to the actual data buffer by skipping
987 // over the cookie completely.
988 CharUnits CookieSize
= 2 * SizeSize
;
989 return CGF
.Builder
.CreateConstInBoundsGEP1_64(NewPtr
,
990 CookieSize
.getQuantity());
993 void ARMCXXABI::ReadArrayCookie(CodeGenFunction
&CGF
,
995 const CXXDeleteExpr
*expr
,
996 QualType ElementType
,
997 llvm::Value
*&NumElements
,
998 llvm::Value
*&AllocPtr
,
999 CharUnits
&CookieSize
) {
1000 // Derive a char* in the same address space as the pointer.
1001 unsigned AS
= cast
<llvm::PointerType
>(Ptr
->getType())->getAddressSpace();
1002 const llvm::Type
*CharPtrTy
= CGF
.Builder
.getInt8Ty()->getPointerTo(AS
);
1004 // If we don't need an array cookie, bail out early.
1005 if (!NeedsArrayCookie(expr
, ElementType
)) {
1006 AllocPtr
= CGF
.Builder
.CreateBitCast(Ptr
, CharPtrTy
);
1008 CookieSize
= CharUnits::Zero();
1012 QualType SizeTy
= getContext().getSizeType();
1013 CharUnits SizeSize
= getContext().getTypeSizeInChars(SizeTy
);
1014 const llvm::Type
*SizeLTy
= CGF
.ConvertType(SizeTy
);
1016 // The cookie size is always 2 * sizeof(size_t).
1017 CookieSize
= 2 * SizeSize
;
1019 // The allocated pointer is the input ptr, minus that amount.
1020 AllocPtr
= CGF
.Builder
.CreateBitCast(Ptr
, CharPtrTy
);
1021 AllocPtr
= CGF
.Builder
.CreateConstInBoundsGEP1_64(AllocPtr
,
1022 -CookieSize
.getQuantity());
1024 // The number of elements is at offset sizeof(size_t) relative to that.
1025 llvm::Value
*NumElementsPtr
1026 = CGF
.Builder
.CreateConstInBoundsGEP1_64(AllocPtr
,
1027 SizeSize
.getQuantity());
1029 CGF
.Builder
.CreateBitCast(NumElementsPtr
, SizeLTy
->getPointerTo(AS
));
1030 NumElements
= CGF
.Builder
.CreateLoad(NumElementsPtr
);
1033 /*********************** Static local initialization **************************/
1035 static llvm::Constant
*getGuardAcquireFn(CodeGenModule
&CGM
,
1036 const llvm::PointerType
*GuardPtrTy
) {
1037 // int __cxa_guard_acquire(__guard *guard_object);
1039 std::vector
<const llvm::Type
*> Args(1, GuardPtrTy
);
1040 const llvm::FunctionType
*FTy
=
1041 llvm::FunctionType::get(CGM
.getTypes().ConvertType(CGM
.getContext().IntTy
),
1042 Args
, /*isVarArg=*/false);
1044 return CGM
.CreateRuntimeFunction(FTy
, "__cxa_guard_acquire");
1047 static llvm::Constant
*getGuardReleaseFn(CodeGenModule
&CGM
,
1048 const llvm::PointerType
*GuardPtrTy
) {
1049 // void __cxa_guard_release(__guard *guard_object);
1051 std::vector
<const llvm::Type
*> Args(1, GuardPtrTy
);
1053 const llvm::FunctionType
*FTy
=
1054 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM
.getLLVMContext()),
1055 Args
, /*isVarArg=*/false);
1057 return CGM
.CreateRuntimeFunction(FTy
, "__cxa_guard_release");
1060 static llvm::Constant
*getGuardAbortFn(CodeGenModule
&CGM
,
1061 const llvm::PointerType
*GuardPtrTy
) {
1062 // void __cxa_guard_abort(__guard *guard_object);
1064 std::vector
<const llvm::Type
*> Args(1, GuardPtrTy
);
1066 const llvm::FunctionType
*FTy
=
1067 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM
.getLLVMContext()),
1068 Args
, /*isVarArg=*/false);
1070 return CGM
.CreateRuntimeFunction(FTy
, "__cxa_guard_abort");
1074 struct CallGuardAbort
: EHScopeStack::Cleanup
{
1075 llvm::GlobalVariable
*Guard
;
1076 CallGuardAbort(llvm::GlobalVariable
*Guard
) : Guard(Guard
) {}
1078 void Emit(CodeGenFunction
&CGF
, bool IsForEH
) {
1079 CGF
.Builder
.CreateCall(getGuardAbortFn(CGF
.CGM
, Guard
->getType()), Guard
)
1080 ->setDoesNotThrow();
1085 /// The ARM code here follows the Itanium code closely enough that we
1086 /// just special-case it at particular places.
1087 void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction
&CGF
,
1089 llvm::GlobalVariable
*GV
) {
1090 CGBuilderTy
&Builder
= CGF
.Builder
;
1092 // We only need to use thread-safe statics for local variables;
1093 // global initialization is always single-threaded.
1094 bool ThreadsafeStatics
= (getContext().getLangOptions().ThreadsafeStatics
&&
1095 D
.isLocalVarDecl());
1097 // Guard variables are 64 bits in the generic ABI and 32 bits on ARM.
1098 const llvm::IntegerType
*GuardTy
1099 = (IsARM
? Builder
.getInt32Ty() : Builder
.getInt64Ty());
1100 const llvm::PointerType
*GuardPtrTy
= GuardTy
->getPointerTo();
1102 // Create the guard variable.
1103 llvm::SmallString
<256> GuardVName
;
1104 getMangleContext().mangleItaniumGuardVariable(&D
, GuardVName
);
1106 // Just absorb linkage and visibility from the variable.
1107 llvm::GlobalVariable
*GuardVariable
=
1108 new llvm::GlobalVariable(CGM
.getModule(), GuardTy
,
1109 false, GV
->getLinkage(),
1110 llvm::ConstantInt::get(GuardTy
, 0),
1112 GuardVariable
->setVisibility(GV
->getVisibility());
1114 // Test whether the variable has completed initialization.
1115 llvm::Value
*IsInitialized
;
1117 // ARM C++ ABI 3.2.3.1:
1118 // To support the potential use of initialization guard variables
1119 // as semaphores that are the target of ARM SWP and LDREX/STREX
1120 // synchronizing instructions we define a static initialization
1121 // guard variable to be a 4-byte aligned, 4- byte word with the
1122 // following inline access protocol.
1123 // #define INITIALIZED 1
1124 // if ((obj_guard & INITIALIZED) != INITIALIZED) {
1125 // if (__cxa_guard_acquire(&obj_guard))
1129 llvm::Value
*V
= Builder
.CreateLoad(GuardVariable
);
1130 V
= Builder
.CreateAnd(V
, Builder
.getInt32(1));
1131 IsInitialized
= Builder
.CreateIsNull(V
, "guard.uninitialized");
1133 // Itanium C++ ABI 3.3.2:
1134 // The following is pseudo-code showing how these functions can be used:
1135 // if (obj_guard.first_byte == 0) {
1136 // if ( __cxa_guard_acquire (&obj_guard) ) {
1138 // ... initialize the object ...;
1140 // __cxa_guard_abort (&obj_guard);
1143 // ... queue object destructor with __cxa_atexit() ...;
1144 // __cxa_guard_release (&obj_guard);
1148 // Load the first byte of the guard variable.
1149 const llvm::Type
*PtrTy
= Builder
.getInt8PtrTy();
1151 Builder
.CreateLoad(Builder
.CreateBitCast(GuardVariable
, PtrTy
), "tmp");
1153 IsInitialized
= Builder
.CreateIsNull(V
, "guard.uninitialized");
1156 llvm::BasicBlock
*InitCheckBlock
= CGF
.createBasicBlock("init.check");
1157 llvm::BasicBlock
*EndBlock
= CGF
.createBasicBlock("init.end");
1159 // Check if the first byte of the guard variable is zero.
1160 Builder
.CreateCondBr(IsInitialized
, InitCheckBlock
, EndBlock
);
1162 CGF
.EmitBlock(InitCheckBlock
);
1164 // Variables used when coping with thread-safe statics and exceptions.
1165 if (ThreadsafeStatics
) {
1166 // Call __cxa_guard_acquire.
1168 = Builder
.CreateCall(getGuardAcquireFn(CGM
, GuardPtrTy
), GuardVariable
);
1170 llvm::BasicBlock
*InitBlock
= CGF
.createBasicBlock("init");
1172 Builder
.CreateCondBr(Builder
.CreateIsNotNull(V
, "tobool"),
1173 InitBlock
, EndBlock
);
1175 // Call __cxa_guard_abort along the exceptional edge.
1176 CGF
.EHStack
.pushCleanup
<CallGuardAbort
>(EHCleanup
, GuardVariable
);
1178 CGF
.EmitBlock(InitBlock
);
1181 // Emit the initializer and add a global destructor if appropriate.
1182 CGF
.EmitCXXGlobalVarDeclInit(D
, GV
);
1184 if (ThreadsafeStatics
) {
1185 // Pop the guard-abort cleanup if we pushed one.
1186 CGF
.PopCleanupBlock();
1188 // Call __cxa_guard_release. This cannot throw.
1189 Builder
.CreateCall(getGuardReleaseFn(CGM
, GuardPtrTy
), GuardVariable
);
1191 Builder
.CreateStore(llvm::ConstantInt::get(GuardTy
, 1), GuardVariable
);
1194 CGF
.EmitBlock(EndBlock
);