diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp | 334 |
1 files changed, 174 insertions, 160 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp b/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp index c3f635a..98f67f3 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -73,15 +73,17 @@ public: llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src); - - llvm::Constant *EmitMemberPointerConversion(llvm::Constant *C, - const CastExpr *E); + llvm::Constant *EmitMemberPointerConversion(const CastExpr *E, + llvm::Constant *Src); llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD); llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset); + llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT); + llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD, + CharUnits ThisAdjustment); llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, @@ -121,7 +123,7 @@ public: llvm::Value *&AllocPtr, CharUnits &CookieSize); void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, - llvm::GlobalVariable *DeclPtr); + llvm::GlobalVariable *DeclPtr, bool PerformInit); }; class ARMCXXABI : public ItaniumCXXABI { @@ -216,8 +218,8 @@ ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl()); llvm::FunctionType *FTy = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT), - FPT->isVariadic()); + CGM.getTypes().GetFunctionType( + CGM.getTypes().arrangeCXXMethodType(RD, FPT)); llvm::IntegerType *ptrdiff = getPtrDiffTy(); llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(ptrdiff, 1); @@ -312,7 +314,10 @@ llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, return Builder.CreateBitCast(Addr, PType); } -/// Perform a derived-to-base or base-to-derived member pointer conversion. +/// Perform a bitcast, derived-to-base, or base-to-derived member pointer +/// conversion. +/// +/// Bitcast conversions are always a no-op under Itanium. /// /// Obligatory offset/adjustment diagram: /// <-- offset --> <-- adjustment --> @@ -335,146 +340,106 @@ llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, llvm::Value * ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, - llvm::Value *Src) { + llvm::Value *src) { assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || - E->getCastKind() == CK_BaseToDerivedMemberPointer); - - if (isa<llvm::Constant>(Src)) - return EmitMemberPointerConversion(cast<llvm::Constant>(Src), E); - - CGBuilderTy &Builder = CGF.Builder; + E->getCastKind() == CK_BaseToDerivedMemberPointer || + E->getCastKind() == CK_ReinterpretMemberPointer); - const MemberPointerType *SrcTy = - E->getSubExpr()->getType()->getAs<MemberPointerType>(); - const MemberPointerType *DestTy = E->getType()->getAs<MemberPointerType>(); + // Under Itanium, reinterprets don't require any additional processing. + if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; - const CXXRecordDecl *SrcDecl = SrcTy->getClass()->getAsCXXRecordDecl(); - const CXXRecordDecl *DestDecl = DestTy->getClass()->getAsCXXRecordDecl(); + // Use constant emission if we can. + if (isa<llvm::Constant>(src)) + return EmitMemberPointerConversion(E, cast<llvm::Constant>(src)); - bool DerivedToBase = - E->getCastKind() == CK_DerivedToBaseMemberPointer; + llvm::Constant *adj = getMemberPointerAdjustment(E); + if (!adj) return src; - const CXXRecordDecl *DerivedDecl; - if (DerivedToBase) - DerivedDecl = SrcDecl; - else - DerivedDecl = DestDecl; + CGBuilderTy &Builder = CGF.Builder; + bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); - llvm::Constant *Adj = - CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, - E->path_begin(), - E->path_end()); - if (!Adj) return Src; + const MemberPointerType *destTy = + E->getType()->castAs<MemberPointerType>(); // For member data pointers, this is just a matter of adding the // offset if the source is non-null. - if (SrcTy->isMemberDataPointer()) { - llvm::Value *Dst; - if (DerivedToBase) - Dst = Builder.CreateNSWSub(Src, Adj, "adj"); + if (destTy->isMemberDataPointer()) { + llvm::Value *dst; + if (isDerivedToBase) + dst = Builder.CreateNSWSub(src, adj, "adj"); else - Dst = Builder.CreateNSWAdd(Src, Adj, "adj"); + dst = Builder.CreateNSWAdd(src, adj, "adj"); // Null check. - llvm::Value *Null = llvm::Constant::getAllOnesValue(Src->getType()); - llvm::Value *IsNull = Builder.CreateICmpEQ(Src, Null, "memptr.isnull"); - return Builder.CreateSelect(IsNull, Src, Dst); + llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType()); + llvm::Value *isNull = Builder.CreateICmpEQ(src, null, "memptr.isnull"); + return Builder.CreateSelect(isNull, src, dst); } // The this-adjustment is left-shifted by 1 on ARM. if (IsARM) { - uint64_t Offset = cast<llvm::ConstantInt>(Adj)->getZExtValue(); - Offset <<= 1; - Adj = llvm::ConstantInt::get(Adj->getType(), Offset); + uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue(); + offset <<= 1; + adj = llvm::ConstantInt::get(adj->getType(), offset); } - llvm::Value *SrcAdj = Builder.CreateExtractValue(Src, 1, "src.adj"); - llvm::Value *DstAdj; - if (DerivedToBase) - DstAdj = Builder.CreateNSWSub(SrcAdj, Adj, "adj"); + llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, "src.adj"); + llvm::Value *dstAdj; + if (isDerivedToBase) + dstAdj = Builder.CreateNSWSub(srcAdj, adj, "adj"); else - DstAdj = Builder.CreateNSWAdd(SrcAdj, Adj, "adj"); + dstAdj = Builder.CreateNSWAdd(srcAdj, adj, "adj"); - return Builder.CreateInsertValue(Src, DstAdj, 1); + return Builder.CreateInsertValue(src, dstAdj, 1); } llvm::Constant * -ItaniumCXXABI::EmitMemberPointerConversion(llvm::Constant *C, - const CastExpr *E) { - const MemberPointerType *SrcTy = - E->getSubExpr()->getType()->getAs<MemberPointerType>(); - const MemberPointerType *DestTy = - E->getType()->getAs<MemberPointerType>(); - - bool DerivedToBase = - E->getCastKind() == CK_DerivedToBaseMemberPointer; - - const CXXRecordDecl *DerivedDecl; - if (DerivedToBase) - DerivedDecl = SrcTy->getClass()->getAsCXXRecordDecl(); - else - DerivedDecl = DestTy->getClass()->getAsCXXRecordDecl(); - - // Calculate the offset to the base class. - llvm::Constant *Offset = - CGM.GetNonVirtualBaseClassOffset(DerivedDecl, - E->path_begin(), - E->path_end()); - // If there's no offset, we're done. - if (!Offset) return C; - - // If the source is a member data pointer, we have to do a null - // check and then add the offset. In the common case, we can fold - // away the offset. - if (SrcTy->isMemberDataPointer()) { - assert(C->getType() == getPtrDiffTy()); - - // If it's a constant int, just create a new constant int. - if (llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C)) { - int64_t Src = CI->getSExtValue(); - - // Null converts to null. - if (Src == -1) return CI; - - // Otherwise, just add the offset. - int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue(); - int64_t Dst = (DerivedToBase ? Src - OffsetV : Src + OffsetV); - return llvm::ConstantInt::get(CI->getType(), Dst, /*signed*/ true); - } +ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E, + llvm::Constant *src) { + assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || + E->getCastKind() == CK_BaseToDerivedMemberPointer || + E->getCastKind() == CK_ReinterpretMemberPointer); - // Otherwise, we have to form a constant select expression. - llvm::Constant *Null = llvm::Constant::getAllOnesValue(C->getType()); + // Under Itanium, reinterprets don't require any additional processing. + if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; - llvm::Constant *IsNull = - llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_EQ, C, Null); + // If the adjustment is trivial, we don't need to do anything. + llvm::Constant *adj = getMemberPointerAdjustment(E); + if (!adj) return src; - llvm::Constant *Dst; - if (DerivedToBase) - Dst = llvm::ConstantExpr::getNSWSub(C, Offset); - else - Dst = llvm::ConstantExpr::getNSWAdd(C, Offset); + bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); + + const MemberPointerType *destTy = + E->getType()->castAs<MemberPointerType>(); + + // For member data pointers, this is just a matter of adding the + // offset if the source is non-null. + if (destTy->isMemberDataPointer()) { + // null maps to null. + if (src->isAllOnesValue()) return src; - return llvm::ConstantExpr::getSelect(IsNull, Null, Dst); + if (isDerivedToBase) + return llvm::ConstantExpr::getNSWSub(src, adj); + else + return llvm::ConstantExpr::getNSWAdd(src, adj); } // The this-adjustment is left-shifted by 1 on ARM. if (IsARM) { - int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue(); - OffsetV <<= 1; - Offset = llvm::ConstantInt::get(Offset->getType(), OffsetV); + uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue(); + offset <<= 1; + adj = llvm::ConstantInt::get(adj->getType(), offset); } - llvm::ConstantStruct *CS = cast<llvm::ConstantStruct>(C); - - llvm::Constant *Values[2] = { CS->getOperand(0), 0 }; - if (DerivedToBase) - Values[1] = llvm::ConstantExpr::getSub(CS->getOperand(1), Offset); + llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1); + llvm::Constant *dstAdj; + if (isDerivedToBase) + dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj); else - Values[1] = llvm::ConstantExpr::getAdd(CS->getOperand(1), Offset); - - return llvm::ConstantStruct::get(CS->getType(), Values); -} + dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj); + return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1); +} llvm::Constant * ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { @@ -500,6 +465,11 @@ ItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, } llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { + return BuildMemberPointer(MD, CharUnits::Zero()); +} + +llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, + CharUnits ThisAdjustment) { assert(MD->isInstance() && "Member function must not be static!"); MD = MD->getCanonicalDecl(); @@ -524,14 +494,16 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { // discrimination as the least significant bit of ptr does for // Itanium. MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset); - MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 1); + MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, + 2 * ThisAdjustment.getQuantity() + 1); } else { // Itanium C++ ABI 2.3: // For a virtual function, [the pointer field] is 1 plus the // virtual table offset (in bytes) of the function, // represented as a ptrdiff_t. MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset + 1); - MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0); + MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, + ThisAdjustment.getQuantity()); } } else { const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); @@ -539,8 +511,7 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { // Check whether the function has a computable LLVM signature. if (Types.isFuncTypeConvertible(FPT)) { // The function has a computable LLVM signature; use the correct type. - Ty = Types.GetFunctionType(Types.getFunctionInfo(MD), - FPT->isVariadic()); + Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD)); } else { // Use an arbitrary non-function type to tell GetAddrOfFunction that the // function type is incomplete. @@ -549,12 +520,45 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty); MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, ptrdiff_t); - MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0); + MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, (IsARM ? 2 : 1) * + ThisAdjustment.getQuantity()); } return llvm::ConstantStruct::getAnon(MemPtr); } +llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP, + QualType MPType) { + const MemberPointerType *MPT = MPType->castAs<MemberPointerType>(); + const ValueDecl *MPD = MP.getMemberPointerDecl(); + if (!MPD) + return EmitNullMemberPointer(MPT); + + // Compute the this-adjustment. + CharUnits ThisAdjustment = CharUnits::Zero(); + ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath(); + bool DerivedMember = MP.isMemberPointerToDerivedMember(); + const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext()); + for (unsigned I = 0, N = Path.size(); I != N; ++I) { + const CXXRecordDecl *Base = RD; + const CXXRecordDecl *Derived = Path[I]; + if (DerivedMember) + std::swap(Base, Derived); + ThisAdjustment += + getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base); + RD = Path[I]; + } + if (DerivedMember) + ThisAdjustment = -ThisAdjustment; + + if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) + return BuildMemberPointer(MD, ThisAdjustment); + + CharUnits FieldOffset = + getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); + return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset); +} + /// The comparison algorithm is pretty easy: the member pointers are /// the same if they're either bitwise identical *or* both null. /// @@ -775,7 +779,7 @@ void ARMCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) { /// Initialize the return slot to 'this' at the start of the /// function. if (HasThisReturn(CGF.CurGD)) - CGF.Builder.CreateStore(CGF.LoadCXXThis(), CGF.ReturnValue); + CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue); } void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, @@ -801,7 +805,7 @@ bool ItaniumCXXABI::NeedsArrayCookie(const CXXNewExpr *expr) { // Automatic Reference Counting: // We need an array cookie for pointers with strong or weak lifetime. QualType AllocatedType = expr->getAllocatedType(); - if (getContext().getLangOptions().ObjCAutoRefCount && + if (getContext().getLangOpts().ObjCAutoRefCount && AllocatedType->isObjCLifetimeType()) { switch (AllocatedType.getObjCLifetime()) { case Qualifiers::OCL_None: @@ -1020,27 +1024,28 @@ static llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM, llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy), GuardPtrTy, /*isVarArg=*/false); - return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire"); + return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire", + llvm::Attribute::NoUnwind); } static llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy) { // void __cxa_guard_release(__guard *guard_object); llvm::FunctionType *FTy = - llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()), - GuardPtrTy, /*isVarArg=*/false); + llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false); - return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release"); + return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release", + llvm::Attribute::NoUnwind); } static llvm::Constant *getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy) { // void __cxa_guard_abort(__guard *guard_object); llvm::FunctionType *FTy = - llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()), - GuardPtrTy, /*isVarArg=*/false); + llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false); - return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort"); + return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort", + llvm::Attribute::NoUnwind); } namespace { @@ -1059,43 +1064,53 @@ namespace { /// just special-case it at particular places. void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, - llvm::GlobalVariable *GV) { + llvm::GlobalVariable *var, + bool shouldPerformInit) { CGBuilderTy &Builder = CGF.Builder; // We only need to use thread-safe statics for local variables; // global initialization is always single-threaded. bool threadsafe = - (getContext().getLangOptions().ThreadsafeStatics && D.isLocalVarDecl()); - - llvm::IntegerType *GuardTy; + (getContext().getLangOpts().ThreadsafeStatics && D.isLocalVarDecl()); // If we have a global variable with internal linkage and thread-safe statics // are disabled, we can just let the guard variable be of type i8. - bool useInt8GuardVariable = !threadsafe && GV->hasInternalLinkage(); + bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage(); + + llvm::IntegerType *guardTy; if (useInt8GuardVariable) { - GuardTy = CGF.Int8Ty; + guardTy = CGF.Int8Ty; } else { // Guard variables are 64 bits in the generic ABI and 32 bits on ARM. - GuardTy = (IsARM ? CGF.Int32Ty : CGF.Int64Ty); + guardTy = (IsARM ? CGF.Int32Ty : CGF.Int64Ty); + } + llvm::PointerType *guardPtrTy = guardTy->getPointerTo(); + + // Create the guard variable if we don't already have it (as we + // might if we're double-emitting this function body). + llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D); + if (!guard) { + // Mangle the name for the guard. + SmallString<256> guardName; + { + llvm::raw_svector_ostream out(guardName); + getMangleContext().mangleItaniumGuardVariable(&D, out); + out.flush(); + } + + // Create the guard variable with a zero-initializer. + // Just absorb linkage and visibility from the guarded variable. + guard = new llvm::GlobalVariable(CGM.getModule(), guardTy, + false, var->getLinkage(), + llvm::ConstantInt::get(guardTy, 0), + guardName.str()); + guard->setVisibility(var->getVisibility()); + + CGM.setStaticLocalDeclGuardAddress(&D, guard); } - llvm::PointerType *GuardPtrTy = GuardTy->getPointerTo(); - - // Create the guard variable. - llvm::SmallString<256> GuardVName; - llvm::raw_svector_ostream Out(GuardVName); - getMangleContext().mangleItaniumGuardVariable(&D, Out); - Out.flush(); - - // Just absorb linkage and visibility from the variable. - llvm::GlobalVariable *GuardVariable = - new llvm::GlobalVariable(CGM.getModule(), GuardTy, - false, GV->getLinkage(), - llvm::ConstantInt::get(GuardTy, 0), - GuardVName.str()); - GuardVariable->setVisibility(GV->getVisibility()); // Test whether the variable has completed initialization. - llvm::Value *IsInitialized; + llvm::Value *isInitialized; // ARM C++ ABI 3.2.3.1: // To support the potential use of initialization guard variables @@ -1109,9 +1124,9 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, // ... // } if (IsARM && !useInt8GuardVariable) { - llvm::Value *V = Builder.CreateLoad(GuardVariable); + llvm::Value *V = Builder.CreateLoad(guard); V = Builder.CreateAnd(V, Builder.getInt32(1)); - IsInitialized = Builder.CreateIsNull(V, "guard.uninitialized"); + isInitialized = Builder.CreateIsNull(V, "guard.uninitialized"); // Itanium C++ ABI 3.3.2: // The following is pseudo-code showing how these functions can be used: @@ -1129,9 +1144,8 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, // } } else { // Load the first byte of the guard variable. - llvm::Type *PtrTy = Builder.getInt8PtrTy(); llvm::LoadInst *LI = - Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy)); + Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy)); LI->setAlignment(1); // Itanium ABI: @@ -1143,14 +1157,14 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, if (threadsafe) LI->setAtomic(llvm::Acquire); - IsInitialized = Builder.CreateIsNull(LI, "guard.uninitialized"); + isInitialized = Builder.CreateIsNull(LI, "guard.uninitialized"); } llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check"); llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end"); // Check if the first byte of the guard variable is zero. - Builder.CreateCondBr(IsInitialized, InitCheckBlock, EndBlock); + Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock); CGF.EmitBlock(InitCheckBlock); @@ -1158,7 +1172,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, if (threadsafe) { // Call __cxa_guard_acquire. llvm::Value *V - = Builder.CreateCall(getGuardAcquireFn(CGM, GuardPtrTy), GuardVariable); + = Builder.CreateCall(getGuardAcquireFn(CGM, guardPtrTy), guard); llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init"); @@ -1166,22 +1180,22 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, InitBlock, EndBlock); // Call __cxa_guard_abort along the exceptional edge. - CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, GuardVariable); + CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard); CGF.EmitBlock(InitBlock); } // Emit the initializer and add a global destructor if appropriate. - CGF.EmitCXXGlobalVarDeclInit(D, GV); + CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit); if (threadsafe) { // Pop the guard-abort cleanup if we pushed one. CGF.PopCleanupBlock(); // Call __cxa_guard_release. This cannot throw. - Builder.CreateCall(getGuardReleaseFn(CGM, GuardPtrTy), GuardVariable); + Builder.CreateCall(getGuardReleaseFn(CGM, guardPtrTy), guard); } else { - Builder.CreateStore(llvm::ConstantInt::get(GuardTy, 1), GuardVariable); + Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard); } CGF.EmitBlock(EndBlock); |