https://github.com/zhangweize9-cyber updated https://github.com/llvm/llvm-project/pull/216611
>From 70c8c59840424b3d10aac1b78cc57db1fd7ab1d3 Mon Sep 17 00:00:00 2001 From: pyxherb <[email protected]> Date: Sat, 25 Jul 2026 07:29:53 +0800 Subject: [PATCH 1/2] [Clang] Ensure that .fini_array is also available while __cxa_atexit() and atexit() are available This conservative PR fixes the inconsistency of behaviors of '-fno-use-cxa-atexit' to GCC, which blocks user to use .fini_array instead of __cxa_atexit() and atexit() on ELF-based platforms. This PR currently fixes this bug on the ELF-based platforms only, but perhaps also applicable on COFF. --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 5c5fefe32c06c..59374b13abe0f 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3136,6 +3136,18 @@ void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, if (!CGM.getLangOpts().hasAtExit() && !D.isStaticLocal()) return CGF.registerGlobalDtorWithLLVM(D, dtor, addr); + // If '-fno-use-cxa-atexit' and '-fno-register-global-dtors-with-atexit' are also sepcified, + // this means the user does not want any invocation to __cxa_atexit or atexit, + // but we still have to check if the declaration is static-local or thread-local, + // which should not be supported by this case. + // As we investigated, ELF has its .fini_array section to support the global destructors. + // So we can safely apply this to ELF. + if (CGM.getTarget().getTriple().isOSBinFormatELF() && + !CGM.getCodeGenOpts().CXAAtExit && + !CGM.getCodeGenOpts().RegisterGlobalDtorsWithAtExit && + !D.isStaticLocal() && !D.getTLSKind()) + return CGF.registerGlobalDtorWithLLVM(D, dtor, addr); + // emitGlobalDtorWithCXAAtExit will emit a call to either __cxa_thread_atexit // or __cxa_atexit depending on whether this VarDecl is a thread-local storage // or not. CXAAtExit controls only __cxa_atexit, so use it if it is enabled. >From de8fbda6f2ab46c71b08bf885dd7c455190bce0b Mon Sep 17 00:00:00 2001 From: zhangweize9-cyber <[email protected]> Date: Mon, 17 Aug 2026 07:58:10 +0800 Subject: [PATCH 2/2] refix: #211963 --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 815 ++++++++++++++-------------- 1 file changed, 396 insertions(+), 419 deletions(-) diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 59374b13abe0f..dbd4df150503d 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -62,12 +62,10 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { } public: - ItaniumCXXABI(CodeGen::CodeGenModule &CGM, - bool UseARMMethodPtrABI = false, - bool UseARMGuardVarABI = false) : - CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI), - UseARMGuardVarABI(UseARMGuardVarABI), - Use32BitVTableOffsetABI(false) { } + ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool UseARMMethodPtrABI = false, + bool UseARMGuardVarABI = false) + : CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI), + UseARMGuardVarABI(UseARMGuardVarABI), Use32BitVTableOffsetABI(false) {} bool classifyReturnType(CGFunctionInfo &FI) const override; @@ -129,12 +127,10 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override; CGCallee - EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, - const Expr *E, - Address This, - llvm::Value *&ThisPtrForCall, - llvm::Value *MemFnPtr, - const MemberPointerType *MPT) override; + EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, + Address This, llvm::Value *&ThisPtrForCall, + llvm::Value *MemFnPtr, + const MemberPointerType *MPT) override; llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, @@ -156,14 +152,14 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD, CharUnits ThisAdjustment); - llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, - llvm::Value *L, llvm::Value *R, + llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, + llvm::Value *R, const MemberPointerType *MPT, bool Inequality) override; - llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF, - llvm::Value *Addr, - const MemberPointerType *MPT) override; + llvm::Value * + EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *Addr, + const MemberPointerType *MPT) override; void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, @@ -260,9 +256,9 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { bool EmitBadCastCall(CodeGenFunction &CGF) override; llvm::Value * - GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, - const CXXRecordDecl *ClassDecl, - const CXXRecordDecl *BaseClassDecl) override; + GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, + const CXXRecordDecl *ClassDecl, + const CXXRecordDecl *BaseClassDecl) override; void EmitCXXConstructors(const CXXConstructorDecl *D) override; @@ -368,17 +364,16 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { } StringRef GetPureVirtualCallName() override { return "__cxa_pure_virtual"; } - StringRef GetDeletedVirtualCallName() override - { return "__cxa_deleted_virtual"; } + StringRef GetDeletedVirtualCallName() override { + return "__cxa_deleted_virtual"; + } CharUnits getArrayCookieSizeImpl(QualType elementType) override; - Address InitializeArrayCookie(CodeGenFunction &CGF, - Address NewPtr, + Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType) override; - llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, - Address allocPtr, + llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr, CharUnits cookieSize) override; void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, @@ -391,14 +386,12 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD, llvm::Value *Val); void EmitThreadLocalInitFuncs( - CodeGenModule &CGM, - ArrayRef<const VarDecl *> CXXThreadLocals, + CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals, ArrayRef<llvm::Function *> CXXThreadLocalInits, ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override; bool usesThreadWrapperFunction(const VarDecl *VD) const override { - return !isEmittedWithConstantInitializer(VD) || - mayNeedDestruction(VD); + return !isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD); } LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType) override; @@ -445,43 +438,43 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD) override; - private: - llvm::Constant * - getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD); - - bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const { - const auto &VtableLayout = - CGM.getItaniumVTableContext().getVTableLayout(RD); - - for (const auto &VtableComponent : VtableLayout.vtable_components()) { - // Skip empty slot. - if (!VtableComponent.isUsedFunctionPointerKind()) - continue; - - const CXXMethodDecl *Method = VtableComponent.getFunctionDecl(); - const FunctionDecl *FD = Method->getDefinition(); - const bool IsInlined = - Method->getCanonicalDecl()->isInlined() || (FD && FD->isInlined()); - if (!IsInlined) - continue; - - StringRef Name = CGM.getMangledName( - VtableComponent.getGlobalDecl(/*HasVectorDeletingDtors=*/false)); - auto *Entry = CGM.GetGlobalValue(Name); - // This checks if virtual inline function has already been emitted. - // Note that it is possible that this inline function would be emitted - // after trying to emit vtable speculatively. Because of this we do - // an extra pass after emitting all deferred vtables to find and emit - // these vtables opportunistically. - if (!Entry || Entry->isDeclaration()) - return true; - } - return false; +private: + llvm::Constant * + getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD); + + bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const { + const auto &VtableLayout = + CGM.getItaniumVTableContext().getVTableLayout(RD); + + for (const auto &VtableComponent : VtableLayout.vtable_components()) { + // Skip empty slot. + if (!VtableComponent.isUsedFunctionPointerKind()) + continue; + + const CXXMethodDecl *Method = VtableComponent.getFunctionDecl(); + const FunctionDecl *FD = Method->getDefinition(); + const bool IsInlined = + Method->getCanonicalDecl()->isInlined() || (FD && FD->isInlined()); + if (!IsInlined) + continue; + + StringRef Name = CGM.getMangledName( + VtableComponent.getGlobalDecl(/*HasVectorDeletingDtors=*/false)); + auto *Entry = CGM.GetGlobalValue(Name); + // This checks if virtual inline function has already been emitted. + // Note that it is possible that this inline function would be emitted + // after trying to emit vtable speculatively. Because of this we do + // an extra pass after emitting all deferred vtables to find and emit + // these vtables opportunistically. + if (!Entry || Entry->isDeclaration()) + return true; + } + return false; } bool isVTableHidden(const CXXRecordDecl *RD) const { const auto &VtableLayout = - CGM.getItaniumVTableContext().getVTableLayout(RD); + CGM.getItaniumVTableContext().getVTableLayout(RD); for (const auto &VtableComponent : VtableLayout.vtable_components()) { if (VtableComponent.isRTTIKind()) { @@ -501,9 +494,9 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { class ARMCXXABI : public ItaniumCXXABI { public: - ARMCXXABI(CodeGen::CodeGenModule &CGM) : - ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true, - /*UseARMGuardVarABI=*/true) {} + ARMCXXABI(CodeGen::CodeGenModule &CGM) + : ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true, + /*UseARMGuardVarABI=*/true) {} bool constructorsAndDestructorsReturnThis() const override { return true; } @@ -511,8 +504,7 @@ class ARMCXXABI : public ItaniumCXXABI { QualType ResTy) override; CharUnits getArrayCookieSizeImpl(QualType elementType) override; - Address InitializeArrayCookie(CodeGenFunction &CGF, - Address NewPtr, + Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType) override; @@ -532,8 +524,7 @@ class AppleARM64CXXABI : public ARMCXXABI { class FuchsiaCXXABI final : public ItaniumCXXABI { public: - explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM) - : ItaniumCXXABI(CGM) {} + explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM) {} private: bool constructorsAndDestructorsReturnThis() const override { return true; } @@ -556,8 +547,7 @@ class WebAssemblyCXXABI final : public ItaniumCXXABI { class XLCXXABI final : public ItaniumCXXABI { public: - explicit XLCXXABI(CodeGen::CodeGenModule &CGM) - : ItaniumCXXABI(CGM) {} + explicit XLCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM) {} void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee dtor, @@ -569,7 +559,7 @@ class XLCXXABI final : public ItaniumCXXABI { void emitCXXStermFinalizer(const VarDecl &D, llvm::Function *dtorStub, llvm::Constant *addr); }; -} +} // namespace CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) { switch (CGM.getContext().getCXXABIKind()) { @@ -640,8 +630,8 @@ ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { /// the function to call. CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( CodeGenFunction &CGF, const Expr *E, Address ThisAddr, - llvm::Value *&ThisPtrForCall, - llvm::Value *MemFnPtr, const MemberPointerType *MPT) { + llvm::Value *&ThisPtrForCall, llvm::Value *MemFnPtr, + const MemberPointerType *MPT) { CGBuilderTy &Builder = CGF.Builder; const FunctionProtoType *FPT = @@ -688,9 +678,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( // Cast the adjusted this to a pointer to vtable pointer and load. llvm::Type *VTableTy = CGF.CGM.GlobalsInt8PtrTy; - CharUnits VTablePtrAlign = - CGF.CGM.getDynamicOffsetAlignment(ThisAddr.getAlignment(), RD, - CGF.getPointerAlign()); + CharUnits VTablePtrAlign = CGF.CGM.getDynamicOffsetAlignment( + ThisAddr.getAlignment(), RD, CGF.getPointerAlign()); llvm::Value *VTable = CGF.GetVTablePtr( Address(This, ThisAddr.getElementType(), VTablePtrAlign), VTableTy, RD); @@ -952,10 +941,9 @@ static llvm::Constant *pointerAuthResignConstant( /// MP when the derived MP does not point to a member of the base. /// This is why -1 is a reasonable choice for null data member /// pointers. -llvm::Value * -ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, - const CastExpr *E, - llvm::Value *src) { +llvm::Value *ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, + const CastExpr *E, + llvm::Value *src) { // Use constant emission if we can. if (isa<llvm::Constant>(src)) return EmitMemberPointerConversion(E, cast<llvm::Constant>(src)); @@ -1008,15 +996,16 @@ ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, } // Under Itanium, reinterprets don't require any additional processing. - if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; + if (E->getCastKind() == CK_ReinterpretMemberPointer) + return src; llvm::Constant *adj = getMemberPointerAdjustment(E); - if (!adj) return src; + if (!adj) + return src; bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); - const MemberPointerType *destTy = - E->getType()->castAs<MemberPointerType>(); + 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. @@ -1092,22 +1081,24 @@ ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E, src, DstType, E->getSubExpr()->getType(), CGM); // Under Itanium, reinterprets don't require any additional processing. - if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; + if (E->getCastKind() == CK_ReinterpretMemberPointer) + return src; // If the adjustment is trivial, we don't need to do anything. llvm::Constant *adj = getMemberPointerAdjustment(E); - if (!adj) return src; + if (!adj) + return src; bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); - const MemberPointerType *destTy = - E->getType()->castAs<MemberPointerType>(); + 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; + if (src->isAllOnesValue()) + return src; if (isDerivedToBase) return llvm::ConstantExpr::getNSWSub(src, adj); @@ -1142,7 +1133,7 @@ ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true); llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0); - llvm::Constant *Values[2] = { Zero, Zero }; + llvm::Constant *Values[2] = {Zero, Zero}; return llvm::ConstantStruct::getAnon(Values); } @@ -1220,8 +1211,8 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, // virtual table offset (in bytes) of the function, // represented as a ptrdiff_t. MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1); - MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, - ThisAdjustment.getQuantity()); + MemPtr[1] = + llvm::ConstantInt::get(CGM.PtrDiffTy, ThisAdjustment.getQuantity()); } } else { const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); @@ -1238,9 +1229,9 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty); MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy); - MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, - (UseARMMethodPtrABI ? 2 : 1) * - ThisAdjustment.getQuantity()); + MemPtr[1] = + llvm::ConstantInt::get(CGM.PtrDiffTy, (UseARMMethodPtrABI ? 2 : 1) * + ThisAdjustment.getQuantity()); } return llvm::ConstantStruct::getAnon(MemPtr); @@ -1264,7 +1255,7 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP, getContext().recordMemberDataPointerEvaluation(MPD); CharUnits FieldOffset = - getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); + getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset); } @@ -1272,12 +1263,9 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP, /// the same if they're either bitwise identical *or* both null. /// /// ARM is different here only because null-ness is more complicated. -llvm::Value * -ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, - llvm::Value *L, - llvm::Value *R, - const MemberPointerType *MPT, - bool Inequality) { +llvm::Value *ItaniumCXXABI::EmitMemberPointerComparison( + CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, + const MemberPointerType *MPT, bool Inequality) { CGBuilderTy &Builder = CGF.Builder; llvm::ICmpInst::Predicate Eq; @@ -1334,8 +1322,8 @@ ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, // Compute (l.adj | r.adj) & 1 and test it against zero. llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj"); llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One); - llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero, - "cmp.or.adj"); + llvm::Value *OrAdjAnd1EqZero = + Builder.CreateICmp(Eq, OrAdjAnd1, Zero, "cmp.or.adj"); EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero); } @@ -1346,17 +1334,15 @@ ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, return Result; } -llvm::Value * -ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, - llvm::Value *MemPtr, - const MemberPointerType *MPT) { +llvm::Value *ItaniumCXXABI::EmitMemberPointerIsNotNull( + CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT) { CGBuilderTy &Builder = CGF.Builder; /// For member data pointers, this is just a check against -1. if (MPT->isMemberDataPointer()) { assert(MemPtr->getType() == CGM.PtrDiffTy); llvm::Value *NegativeOne = - llvm::Constant::getAllOnesValue(MemPtr->getType()); + llvm::Constant::getAllOnesValue(MemPtr->getType()); return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool"); } @@ -1372,8 +1358,8 @@ ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1); llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj"); llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit"); - llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero, - "memptr.isvirtual"); + llvm::Value *IsVirtual = + Builder.CreateICmpNE(VirtualBit, Zero, "memptr.isvirtual"); Result = Builder.CreateOr(Result, IsVirtual); } @@ -1408,8 +1394,7 @@ bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) { /// at entry -2 in the vtable. void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, - Address Ptr, - QualType ElementType, + Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor) { bool UseGlobalDelete = DE->isGlobalDelete(); if (UseGlobalDelete) { @@ -1451,7 +1436,7 @@ void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) { // void __cxa_rethrow(); llvm::FunctionType *FTy = - llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); + llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow"); @@ -1465,7 +1450,7 @@ static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM) { // void *__cxa_allocate_exception(size_t thrown_size); llvm::FunctionType *FTy = - llvm::FunctionType::get(CGM.Int8PtrTy, CGM.SizeTy, /*isVarArg=*/false); + llvm::FunctionType::get(CGM.Int8PtrTy, CGM.SizeTy, /*isVarArg=*/false); return CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception"); } @@ -1474,9 +1459,9 @@ static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM) { // void __cxa_throw(void *thrown_exception, std::type_info *tinfo, // void (*dest) (void *)); - llvm::Type *Args[3] = { CGM.Int8PtrTy, CGM.GlobalsInt8PtrTy, CGM.Int8PtrTy }; + llvm::Type *Args[3] = {CGM.Int8PtrTy, CGM.GlobalsInt8PtrTy, CGM.Int8PtrTy}; llvm::FunctionType *FTy = - llvm::FunctionType::get(CGM.VoidTy, Args, /*isVarArg=*/false); + llvm::FunctionType::get(CGM.VoidTy, Args, /*isVarArg=*/false); return CGM.CreateRuntimeFunction(FTy, "__cxa_throw"); } @@ -1492,8 +1477,8 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) { AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize), "exception"); CharUnits ExnAlign = CGF.getContext().getExnObjectAlignment(); - CGF.EmitAnyExprToExn( - E->getSubExpr(), Address(ExceptionPtr, CGM.Int8Ty, ExnAlign)); + CGF.EmitAnyExprToExn(E->getSubExpr(), + Address(ExceptionPtr, CGM.Int8Ty, ExnAlign)); // Now throw the exception. llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType, @@ -1515,9 +1500,10 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) { Dtor = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, Dtor_Complete)); Dtor = CGM.getFunctionPointer(Dtor, DtorTy); } - if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy); + if (!Dtor) + Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy); - llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor }; + llvm::Value *args[] = {ExceptionPtr, TypeInfo, Dtor}; CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(CGM), args); } @@ -1530,9 +1516,9 @@ static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF) { llvm::Type *Int8PtrTy = CGF.Int8PtrTy; llvm::Type *GlobInt8PtrTy = CGF.GlobalsInt8PtrTy; llvm::Type *PtrDiffTy = - CGF.ConvertType(CGF.getContext().getPointerDiffType()); + CGF.ConvertType(CGF.getContext().getPointerDiffType()); - llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy }; + llvm::Type *Args[4] = {Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy}; llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false); @@ -1571,7 +1557,7 @@ static CharUnits computeOffsetHint(ASTContext &Context, // Now walk all possible inheritance paths. for (const CXXBasePath &Path : Paths) { - if (Path.Access != AS_public) // Ignore non-public inheritance. + if (Path.Access != AS_public) // Ignore non-public inheritance. continue; ++NumPublicPaths; @@ -1624,12 +1610,11 @@ void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) { } llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF, - QualType SrcRecordTy, - Address ThisPtr, + QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy) { auto *ClassDecl = SrcRecordTy->castAsCXXRecordDecl(); - llvm::Value *Value = CGF.GetVTablePtr(ThisPtr, CGM.GlobalsInt8PtrTy, - ClassDecl); + llvm::Value *Value = + CGF.GetVTablePtr(ThisPtr, CGM.GlobalsInt8PtrTy, ClassDecl); if (CGM.getLangOpts().RelativeCXXABIVTables) { // Load the type info. @@ -1878,24 +1863,22 @@ bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) { } llvm::Value * -ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, - Address This, +ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl) { llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl); CharUnits VBaseOffsetOffset = CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl); - llvm::Value *VBaseOffsetPtr = - CGF.Builder.CreateConstGEP1_64( - CGF.Int8Ty, VTablePtr, VBaseOffsetOffset.getQuantity(), - "vbase.offset.ptr"); + llvm::Value *VBaseOffsetPtr = CGF.Builder.CreateConstGEP1_64( + CGF.Int8Ty, VTablePtr, VBaseOffsetOffset.getQuantity(), + "vbase.offset.ptr"); llvm::Value *VBaseOffset; if (CGM.getLangOpts().RelativeCXXABIVTables) { - VBaseOffset = CGF.Builder.CreateAlignedLoad( - CGF.Int32Ty, VBaseOffsetPtr, CharUnits::fromQuantity(4), - "vbase.offset"); + VBaseOffset = CGF.Builder.CreateAlignedLoad(CGF.Int32Ty, VBaseOffsetPtr, + CharUnits::fromQuantity(4), + "vbase.offset"); } else { VBaseOffset = CGF.Builder.CreateAlignedLoad( CGM.PtrDiffTy, VBaseOffsetPtr, CGF.getPointerAlign(), "vbase.offset"); @@ -2040,8 +2023,8 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF, QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy); CGCallee Callee; - if (getContext().getLangOpts().AppleKext && - Type != Dtor_Base && DD->isVirtual()) + if (getContext().getLangOpts().AppleKext && Type != Dtor_Base && + DD->isVirtual()) Callee = CGF.BuildAppleKextVirtualDestructorCall(DD, Type, DD->getParent()); else Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD); @@ -2191,9 +2174,9 @@ ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base, VTableLayout::AddressPointLocation AddressPoint = Layout.getAddressPoint(Base); llvm::Value *Indices[] = { - llvm::ConstantInt::get(CGM.Int32Ty, 0), - llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.VTableIndex), - llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.AddressPointIndex), + llvm::ConstantInt::get(CGM.Int32Ty, 0), + llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.VTableIndex), + llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.AddressPointIndex), }; // Add inrange attribute to indicate that only the VTableIndex can be @@ -2227,14 +2210,13 @@ llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT( VirtualPointerIndex); // And load the address point from the VTT. - llvm::Value *AP = - CGF.Builder.CreateAlignedLoad(CGF.GlobalsVoidPtrTy, VTT, - CGF.getPointerAlign()); - - if (auto &Schema = CGF.CGM.getCodeGenOpts().PointerAuth.CXXVTTVTablePointers) { - CGPointerAuthInfo PointerAuth = CGF.EmitPointerAuthInfo(Schema, VTT, - GlobalDecl(), - QualType()); + llvm::Value *AP = CGF.Builder.CreateAlignedLoad(CGF.GlobalsVoidPtrTy, VTT, + CGF.getPointerAlign()); + + if (auto &Schema = + CGF.CGM.getCodeGenOpts().PointerAuth.CXXVTTVTablePointers) { + CGPointerAuthInfo PointerAuth = + CGF.EmitPointerAuthInfo(Schema, VTT, GlobalDecl(), QualType()); AP = CGF.EmitPointerAuthAuth(PointerAuth, AP); } @@ -2279,8 +2261,7 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, } CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, - GlobalDecl GD, - Address This, + GlobalDecl GD, Address This, llvm::Type *Ty, SourceLocation Loc) { llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy; @@ -2352,8 +2333,10 @@ CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, CGPointerAuthInfo PointerAuth; if (Schema) { assert(VTableSlotPtr && "virtual function pointer not set"); - GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.getCanonicalDecl()); - PointerAuth = CGF.EmitPointerAuthInfo(Schema, VTableSlotPtr, GD, QualType()); + GD = + CGM.getItaniumVTableContext().findOriginalMethod(GD.getCanonicalDecl()); + PointerAuth = + CGF.EmitPointerAuthInfo(Schema, VTableSlotPtr, GD, QualType()); } CGCallee Callee(GD, VFunc, PointerAuth); return Callee; @@ -2475,8 +2458,8 @@ static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, // In a base-to-derived cast, the non-virtual adjustment is applied first. if (NonVirtualAdjustment && !IsReturnAdjustment) { - V = CGF.Builder.CreateConstInBoundsByteGEP(V, - CharUnits::fromQuantity(NonVirtualAdjustment)); + V = CGF.Builder.CreateConstInBoundsByteGEP( + V, CharUnits::fromQuantity(NonVirtualAdjustment)); } // Perform the virtual adjustment if we have one. @@ -2490,9 +2473,8 @@ static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, CGF.Int8Ty, VTablePtr, VirtualAdjustment); if (CGF.CGM.getLangOpts().RelativeCXXABIVTables) { // Load the adjustment offset from the vtable as a 32-bit int. - Offset = - CGF.Builder.CreateAlignedLoad(CGF.Int32Ty, OffsetPtr, - CharUnits::fromQuantity(4)); + Offset = CGF.Builder.CreateAlignedLoad(CGF.Int32Ty, OffsetPtr, + CharUnits::fromQuantity(4)); } else { llvm::Type *PtrDiffTy = CGF.ConvertType(CGF.getContext().getPointerDiffType()); @@ -2536,8 +2518,8 @@ ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret, /*IsReturnAdjustment=*/true); } -void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, - RValue RV, QualType ResultType) { +void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, + QualType ResultType) { if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl())) return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType); @@ -2608,8 +2590,8 @@ llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, Address numElementsPtr = allocPtr; CharUnits numElementsOffset = cookieSize - CGF.getSizeSize(); if (!numElementsOffset.isZero()) - numElementsPtr = - CGF.Builder.CreateConstInBoundsByteGEP(numElementsPtr, numElementsOffset); + numElementsPtr = CGF.Builder.CreateConstInBoundsByteGEP(numElementsPtr, + numElementsOffset); unsigned AS = allocPtr.getAddressSpace(); numElementsPtr = numElementsPtr.withElementType(CGF.SizeTy); @@ -2640,8 +2622,7 @@ CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) { CGM.getContext().getTypeAlignInChars(elementType)); } -Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, - Address newPtr, +Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, Address newPtr, llvm::Value *numElements, const CXXNewExpr *expr, QualType elementType) { @@ -2652,8 +2633,8 @@ Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, // The first element is the element size. cookie = cookie.withElementType(CGF.SizeTy); - llvm::Value *elementSize = llvm::ConstantInt::get(CGF.SizeTy, - getContext().getTypeSizeInChars(elementType).getQuantity()); + llvm::Value *elementSize = llvm::ConstantInt::get( + CGF.SizeTy, getContext().getTypeSizeInChars(elementType).getQuantity()); CGF.Builder.CreateStore(elementSize, cookie); // The second element is the element count. @@ -2671,8 +2652,8 @@ llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, CharUnits cookieSize) { // The number of elements is at offset sizeof(size_t) relative to // the allocated pointer. - Address numElementsPtr - = CGF.Builder.CreateConstInBoundsByteGEP(allocPtr, CGF.getSizeSize()); + Address numElementsPtr = + CGF.Builder.CreateConstInBoundsByteGEP(allocPtr, CGF.getSizeSize()); numElementsPtr = numElementsPtr.withElementType(CGF.SizeTy); return CGF.Builder.CreateLoad(numElementsPtr); @@ -2683,9 +2664,9 @@ llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, static llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy) { // int __cxa_guard_acquire(__guard *guard_object); - llvm::FunctionType *FTy = - llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy), - GuardPtrTy, /*isVarArg=*/false); + llvm::FunctionType *FTy = llvm::FunctionType::get( + CGM.getTypes().ConvertType(CGM.getContext().IntTy), GuardPtrTy, + /*isVarArg=*/false); return CGM.CreateRuntimeFunction( FTy, "__cxa_guard_acquire", llvm::AttributeList::get(CGM.getLLVMContext(), @@ -2697,7 +2678,7 @@ static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy) { // void __cxa_guard_release(__guard *guard_object); llvm::FunctionType *FTy = - llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false); + llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false); return CGM.CreateRuntimeFunction( FTy, "__cxa_guard_release", llvm::AttributeList::get(CGM.getLLVMContext(), @@ -2709,7 +2690,7 @@ static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy) { // void __cxa_guard_abort(__guard *guard_object); llvm::FunctionType *FTy = - llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false); + llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false); return CGM.CreateRuntimeFunction( FTy, "__cxa_guard_abort", llvm::AttributeList::get(CGM.getLLVMContext(), @@ -2718,21 +2699,20 @@ static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM, } namespace { - struct CallGuardAbort final : EHScopeStack::Cleanup { - llvm::GlobalVariable *Guard; - CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {} +struct CallGuardAbort final : EHScopeStack::Cleanup { + llvm::GlobalVariable *Guard; + CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {} - void Emit(CodeGenFunction &CGF, Flags flags) override { - CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()), - Guard); - } - }; -} + void Emit(CodeGenFunction &CGF, Flags flags) override { + CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()), + Guard); + } +}; +} // namespace /// The ARM code here follows the Itanium code closely enough that we /// just special-case it at particular places. -void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, - const VarDecl &D, +void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, llvm::GlobalVariable *var, bool shouldPerformInit) { CGBuilderTy &Builder = CGF.Builder; @@ -2789,10 +2769,9 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, // Create the guard variable with a zero-initializer. // Just absorb linkage, visibility and dll storage class from the guarded // variable. - guard = new llvm::GlobalVariable(CGM.getModule(), guardTy, - false, var->getLinkage(), - llvm::ConstantInt::get(guardTy, 0), - guardName.str()); + guard = new llvm::GlobalVariable( + CGM.getModule(), guardTy, false, var->getLinkage(), + llvm::ConstantInt::get(guardTy, 0), guardName.str()); guard->setDSOLocal(var->isDSOLocal()); guard->setVisibility(var->getVisibility()); guard->setDLLStorageClass(var->getDLLStorageClass()); @@ -2872,8 +2851,8 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, // // ARM64 C++ ABI 3.2.2: // This ABI instead only specifies the value bit 0 of the static guard - // variable; all other bits are platform defined. Bit 0 shall be 0 when the - // variable is not initialized and 1 when it is. + // variable; all other bits are platform defined. Bit 0 shall be 0 when + // the variable is not initialized and 1 when it is. llvm::Value *V = (UseARMGuardVarABI && !useInt8GuardVariable) ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1)) @@ -2907,13 +2886,13 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, // Variables used when coping with thread-safe statics and exceptions. if (threadsafe) { // Call __cxa_guard_acquire. - llvm::Value *V - = CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard); + llvm::Value *V = + CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard); llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init"); - Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"), - InitBlock, EndBlock); + Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"), InitBlock, + EndBlock); // Call __cxa_guard_abort along the exceptional edge. CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard); @@ -2959,7 +2938,7 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, const char *Name = "__cxa_atexit"; if (TLS) { const llvm::Triple &T = CGF.getTarget().getTriple(); - Name = T.isOSDarwin() ? "_tlv_atexit" : "__cxa_thread_atexit"; + Name = T.isOSDarwin() ? "_tlv_atexit" : "__cxa_thread_atexit"; } // We're assuming that the destructor function is something we can @@ -2980,7 +2959,7 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, // extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d); llvm::Type *paramTys[] = {dtorTy, AddrPtrTy, handle->getType()}; llvm::FunctionType *atexitTy = - llvm::FunctionType::get(CGF.IntTy, paramTys, false); + llvm::FunctionType::get(CGF.IntTy, paramTys, false); // Fetch the actual function. llvm::FunctionCallee atexit = CGF.CGM.CreateRuntimeFunction(atexitTy, Name); @@ -3133,19 +3112,18 @@ void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, // destructors which we can handle directly in the runtime. Note that this is // not strictly 1-to-1 with using `atexit` because we no longer tear down // globals in reverse order of when they were constructed. - if (!CGM.getLangOpts().hasAtExit() && !D.isStaticLocal()) - return CGF.registerGlobalDtorWithLLVM(D, dtor, addr); - // If '-fno-use-cxa-atexit' and '-fno-register-global-dtors-with-atexit' are also sepcified, - // this means the user does not want any invocation to __cxa_atexit or atexit, - // but we still have to check if the declaration is static-local or thread-local, - // which should not be supported by this case. - // As we investigated, ELF has its .fini_array section to support the global destructors. - // So we can safely apply this to ELF. - if (CGM.getTarget().getTriple().isOSBinFormatELF() && - !CGM.getCodeGenOpts().CXAAtExit && - !CGM.getCodeGenOpts().RegisterGlobalDtorsWithAtExit && - !D.isStaticLocal() && !D.getTLSKind()) + // If '-fno-use-cxa-atexit' and '-fno-register-global-dtors-with-atexit' are + // also sepcified, this means the user does not want any invocation to + // __cxa_atexit or atexit, but we still have to check if the declaration is + // static-local or thread-local, which should not be supported by this case. + // As we investigated, ELF has its .fini_array section to support the global + // destructors. So we can safely apply this to ELF. + if (!CGM.getLangOpts().hasAtExit() && + CGM.getTarget().getTriple().isOSBinFormatELF() && + !CGM.getCodeGenOpts().CXAAtExit && + !CGM.getCodeGenOpts().RegisterGlobalDtorsWithAtExit && + !D.isStaticLocal() && !D.getTLSKind()) return CGF.registerGlobalDtorWithLLVM(D, dtor, addr); // emitGlobalDtorWithCXAAtExit will emit a call to either __cxa_thread_atexit @@ -3194,9 +3172,8 @@ getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) { return llvm::GlobalValue::WeakODRLinkage; } -llvm::Function * -ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD, - llvm::Value *Val) { +llvm::Function *ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD, + llvm::Value *Val) { // Mangle the name for the thread_local wrapper function. SmallString<256> WrapperName; { @@ -3376,8 +3353,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs( // This is needed whenever a thread wrapper function is not used, and // also when the symbol is weak. if (CGM.getTriple().isOSAIX() && VD->hasDefinition() && - isEmittedWithConstantInitializer(VD, true) && - !mayNeedDestruction(VD)) { + isEmittedWithConstantInitializer(VD, true) && !mayNeedDestruction(VD)) { // Init should be null. If it were non-null, then the logic above would // either be defining the function to be an alias or declaring the // function with the expectation that the definition of the variable @@ -3564,9 +3540,9 @@ ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(const CXXMethodDecl *MD) { namespace { class ItaniumRTTIBuilder { - CodeGenModule &CGM; // Per-module state. + CodeGenModule &CGM; // Per-module state. llvm::LLVMContext &VMContext; - const ItaniumCXXABI &CXXABI; // Per-module state. + const ItaniumCXXABI &CXXABI; // Per-module state. /// Fields - The fields of the RTTI descriptor currently being built. SmallVector<llvm::Constant *, 16> Fields; @@ -3626,7 +3602,7 @@ class ItaniumRTTIBuilder { PTI_ContainingClassIncomplete = 0x10, /// PTI_TransactionSafe - Pointee is transaction_safe function (C++ TM TS). - //PTI_TransactionSafe = 0x20, + // PTI_TransactionSafe = 0x20, /// PTI_Noexcept - Pointee is noexcept function (C++1z). PTI_Noexcept = 0x40, @@ -3655,13 +3631,12 @@ class ItaniumRTTIBuilder { llvm::Constant *BuildTypeInfo(QualType Ty); /// BuildTypeInfo - Build the RTTI type info struct for the given type. - llvm::Constant *BuildTypeInfo( - QualType Ty, - llvm::GlobalVariable::LinkageTypes Linkage, - llvm::GlobalValue::VisibilityTypes Visibility, - llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass); + llvm::Constant * + BuildTypeInfo(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage, + llvm::GlobalValue::VisibilityTypes Visibility, + llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass); }; -} +} // namespace llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName( QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) { @@ -3744,53 +3719,50 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) { // Types added here must also be added to EmitFundamentalRTTIDescriptors. switch (Ty->getKind()) { - case BuiltinType::Void: - case BuiltinType::NullPtr: - case BuiltinType::Bool: - case BuiltinType::WChar_S: - case BuiltinType::WChar_U: - case BuiltinType::Char_U: - case BuiltinType::Char_S: - case BuiltinType::UChar: - case BuiltinType::SChar: - case BuiltinType::Short: - case BuiltinType::UShort: - case BuiltinType::Int: - case BuiltinType::UInt: - case BuiltinType::Long: - case BuiltinType::ULong: - case BuiltinType::LongLong: - case BuiltinType::ULongLong: - case BuiltinType::Half: - case BuiltinType::Float: - case BuiltinType::Double: - case BuiltinType::LongDouble: - case BuiltinType::Float16: - case BuiltinType::Float128: - case BuiltinType::Ibm128: - case BuiltinType::Char8: - case BuiltinType::Char16: - case BuiltinType::Char32: - case BuiltinType::Int128: - case BuiltinType::UInt128: - return true; + case BuiltinType::Void: + case BuiltinType::NullPtr: + case BuiltinType::Bool: + case BuiltinType::WChar_S: + case BuiltinType::WChar_U: + case BuiltinType::Char_U: + case BuiltinType::Char_S: + case BuiltinType::UChar: + case BuiltinType::SChar: + case BuiltinType::Short: + case BuiltinType::UShort: + case BuiltinType::Int: + case BuiltinType::UInt: + case BuiltinType::Long: + case BuiltinType::ULong: + case BuiltinType::LongLong: + case BuiltinType::ULongLong: + case BuiltinType::Half: + case BuiltinType::Float: + case BuiltinType::Double: + case BuiltinType::LongDouble: + case BuiltinType::Float16: + case BuiltinType::Float128: + case BuiltinType::Ibm128: + case BuiltinType::Char8: + case BuiltinType::Char16: + case BuiltinType::Char32: + case BuiltinType::Int128: + case BuiltinType::UInt128: + return true; -#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ - case BuiltinType::Id: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) + case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" -#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ - case BuiltinType::Id: +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id: #include "clang/Basic/OpenCLExtensionTypes.def" - case BuiltinType::OCLSampler: - case BuiltinType::OCLEvent: - case BuiltinType::OCLClkEvent: - case BuiltinType::OCLQueue: - case BuiltinType::OCLReserveID: -#define SVE_TYPE(Name, Id, SingletonId) \ - case BuiltinType::Id: + case BuiltinType::OCLSampler: + case BuiltinType::OCLEvent: + case BuiltinType::OCLClkEvent: + case BuiltinType::OCLQueue: + case BuiltinType::OCLReserveID: +#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id: #include "clang/Basic/AArch64ACLETypes.def" -#define PPC_VECTOR_TYPE(Name, Id, Size) \ - case BuiltinType::Id: +#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id: #include "clang/Basic/PPCTypes.def" #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id: #include "clang/Basic/RISCVVTypes.def" @@ -3800,44 +3772,43 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) { #include "clang/Basic/AMDGPUTypes.def" #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id: #include "clang/Basic/HLSLIntangibleTypes.def" - case BuiltinType::ShortAccum: - case BuiltinType::Accum: - case BuiltinType::LongAccum: - case BuiltinType::UShortAccum: - case BuiltinType::UAccum: - case BuiltinType::ULongAccum: - case BuiltinType::ShortFract: - case BuiltinType::Fract: - case BuiltinType::LongFract: - case BuiltinType::UShortFract: - case BuiltinType::UFract: - case BuiltinType::ULongFract: - case BuiltinType::SatShortAccum: - case BuiltinType::SatAccum: - case BuiltinType::SatLongAccum: - case BuiltinType::SatUShortAccum: - case BuiltinType::SatUAccum: - case BuiltinType::SatULongAccum: - case BuiltinType::SatShortFract: - case BuiltinType::SatFract: - case BuiltinType::SatLongFract: - case BuiltinType::SatUShortFract: - case BuiltinType::SatUFract: - case BuiltinType::SatULongFract: - case BuiltinType::BFloat16: - return false; + case BuiltinType::ShortAccum: + case BuiltinType::Accum: + case BuiltinType::LongAccum: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: + case BuiltinType::ShortFract: + case BuiltinType::Fract: + case BuiltinType::LongFract: + case BuiltinType::UShortFract: + case BuiltinType::UFract: + case BuiltinType::ULongFract: + case BuiltinType::SatShortAccum: + case BuiltinType::SatAccum: + case BuiltinType::SatLongAccum: + case BuiltinType::SatUShortAccum: + case BuiltinType::SatUAccum: + case BuiltinType::SatULongAccum: + case BuiltinType::SatShortFract: + case BuiltinType::SatFract: + case BuiltinType::SatLongFract: + case BuiltinType::SatUShortFract: + case BuiltinType::SatUFract: + case BuiltinType::SatULongFract: + case BuiltinType::BFloat16: + return false; - case BuiltinType::Dependent: + case BuiltinType::Dependent: #define BUILTIN_TYPE(Id, SingletonId) -#define PLACEHOLDER_TYPE(Id, SingletonId) \ - case BuiltinType::Id: +#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: #include "clang/AST/BuiltinTypes.def" - llvm_unreachable("asking for RRTI for a placeholder type!"); + llvm_unreachable("asking for RRTI for a placeholder type!"); - case BuiltinType::ObjCId: - case BuiltinType::ObjCClass: - case BuiltinType::ObjCSel: - llvm_unreachable("FIXME: Objective-C types are unsupported!"); + case BuiltinType::ObjCId: + case BuiltinType::ObjCClass: + case BuiltinType::ObjCSel: + llvm_unreachable("FIXME: Objective-C types are unsupported!"); } llvm_unreachable("Invalid BuiltinType Kind!"); @@ -3878,13 +3849,13 @@ static bool IsStandardLibraryRTTIDescriptor(QualType Ty) { /// the given type exists somewhere else, and that we should not emit the type /// information in this translation unit. Assumes that it is not a /// standard-library type. -static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, - QualType Ty) { +static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty) { ASTContext &Context = CGM.getContext(); // If RTTI is disabled, assume it might be disabled in the // translation unit that defines any potential key function, too. - if (!Context.getLangOpts().RTTI) return false; + if (!Context.getLangOpts().RTTI) + return false; if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { const CXXRecordDecl *RD = @@ -3946,7 +3917,7 @@ static bool ContainsIncompleteClassType(QualType Ty) { return ContainsIncompleteClassType(PointerTy->getPointeeType()); if (const MemberPointerType *MemberPointerTy = - dyn_cast<MemberPointerType>(Ty)) { + dyn_cast<MemberPointerType>(Ty)) { // Check if the class type is incomplete. if (!MemberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition()) return true; @@ -3988,14 +3959,14 @@ static bool CanUseSingleInheritance(const CXXRecordDecl *RD) { void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty, llvm::Constant *StorageAddress) { // abi::__class_type_info. - static const char * const ClassTypeInfo = - "_ZTVN10__cxxabiv117__class_type_infoE"; + static const char *const ClassTypeInfo = + "_ZTVN10__cxxabiv117__class_type_infoE"; // abi::__si_class_type_info. - static const char * const SIClassTypeInfo = - "_ZTVN10__cxxabiv120__si_class_type_infoE"; + static const char *const SIClassTypeInfo = + "_ZTVN10__cxxabiv120__si_class_type_infoE"; // abi::__vmi_class_type_info. - static const char * const VMIClassTypeInfo = - "_ZTVN10__cxxabiv121__vmi_class_type_infoE"; + static const char *const VMIClassTypeInfo = + "_ZTVN10__cxxabiv121__vmi_class_type_infoE"; const char *VTableName = nullptr; @@ -4249,10 +4220,9 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) { } llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( - QualType Ty, - llvm::GlobalVariable::LinkageTypes Linkage, - llvm::GlobalValue::VisibilityTypes Visibility, - llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) { + QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage, + llvm::GlobalValue::VisibilityTypes Visibility, + llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) { SmallString<256> Name; llvm::raw_svector_ostream Out(Name); CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out); @@ -4454,13 +4424,15 @@ void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) { // The builtin types are abi::__class_type_infos and don't require // extra fields. - if (isa<BuiltinType>(T)) return; + if (isa<BuiltinType>(T)) + return; ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl(); ObjCInterfaceDecl *Super = Class->getSuperClass(); // Root classes are also __class_type_info. - if (!Super) return; + if (!Super) + return; QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super); @@ -4477,18 +4449,18 @@ void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) { // It adds to abi::__class_type_info a single member pointing to the // type_info structure for the base type, llvm::Constant *BaseTypeInfo = - ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(RD->bases_begin()->getType()); + ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(RD->bases_begin()->getType()); Fields.push_back(BaseTypeInfo); } namespace { - /// SeenBases - Contains virtual and non-virtual bases seen when traversing - /// a class hierarchy. - struct SeenBases { - llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases; - llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases; - }; -} +/// SeenBases - Contains virtual and non-virtual bases seen when traversing +/// a class hierarchy. +struct SeenBases { + llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases; + llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases; +}; +} // namespace /// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in /// abi::__vmi_class_type_info. @@ -4544,7 +4516,7 @@ static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) { /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c. void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { llvm::Type *UnsignedIntLTy = - CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy); + CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy); // Itanium C++ ABI 2.9.5p6c: // __flags is a word with flags describing details about the class @@ -4589,8 +4561,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { if (TI.getTriple().isOSCygMing() && TI.getPointerWidth(LangAS::Default) > TI.getLongWidth()) OffsetFlagsTy = CGM.getContext().LongLongTy; - llvm::Type *OffsetFlagsLTy = - CGM.getTypes().ConvertType(OffsetFlagsTy); + llvm::Type *OffsetFlagsLTy = CGM.getTypes().ConvertType(OffsetFlagsTy); for (const auto &Base : RD->bases()) { // The __base_type member points to the RTTI for the base type. @@ -4605,8 +4576,8 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { // the virtual base offset for the virtual base referenced (negative). CharUnits Offset; if (Base.isVirtual()) - Offset = - CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl); + Offset = CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset( + RD, BaseDecl); else { const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); Offset = Layout.getBaseClassOffset(BaseDecl); @@ -4663,7 +4634,7 @@ void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) { unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy); llvm::Type *UnsignedIntLTy = - CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy); + CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy); Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags)); // Itanium C++ ABI 2.9.5p7: @@ -4676,8 +4647,8 @@ void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) { /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info /// struct, used for member pointer types. -void -ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) { +void ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo( + const MemberPointerType *Ty) { QualType PointeeTy = Ty->getPointeeType(); // Itanium C++ ABI 2.9.5p7: @@ -4690,7 +4661,7 @@ ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) { Flags |= PTI_ContainingClassIncomplete; llvm::Type *UnsignedIntLTy = - CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy); + CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy); Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags)); // Itanium C++ ABI 2.9.5p7: @@ -4714,21 +4685,31 @@ llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) { void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(const CXXRecordDecl *RD) { // Types added here must also be added to TypeInfoIsInStandardLibrary. - QualType FundamentalTypes[] = { - getContext().VoidTy, getContext().NullPtrTy, - getContext().BoolTy, getContext().WCharTy, - getContext().CharTy, getContext().UnsignedCharTy, - getContext().SignedCharTy, getContext().ShortTy, - getContext().UnsignedShortTy, getContext().IntTy, - getContext().UnsignedIntTy, getContext().LongTy, - getContext().UnsignedLongTy, getContext().LongLongTy, - getContext().UnsignedLongLongTy, getContext().Int128Ty, - getContext().UnsignedInt128Ty, getContext().HalfTy, - getContext().FloatTy, getContext().DoubleTy, - getContext().LongDoubleTy, getContext().Float128Ty, - getContext().Char8Ty, getContext().Char16Ty, - getContext().Char32Ty - }; + QualType FundamentalTypes[] = {getContext().VoidTy, + getContext().NullPtrTy, + getContext().BoolTy, + getContext().WCharTy, + getContext().CharTy, + getContext().UnsignedCharTy, + getContext().SignedCharTy, + getContext().ShortTy, + getContext().UnsignedShortTy, + getContext().IntTy, + getContext().UnsignedIntTy, + getContext().LongTy, + getContext().UnsignedLongTy, + getContext().LongLongTy, + getContext().UnsignedLongLongTy, + getContext().Int128Ty, + getContext().UnsignedInt128Ty, + getContext().HalfTy, + getContext().FloatTy, + getContext().DoubleTy, + getContext().LongDoubleTy, + getContext().Float128Ty, + getContext().Char8Ty, + getContext().Char16Ty, + getContext().Char32Ty}; llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass = RD->hasAttr<DLLExportAttr>() || CGM.shouldMapVisibilityToDLLExport(RD) ? llvm::GlobalValue::DLLExportStorageClass @@ -4737,12 +4718,12 @@ void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(const CXXRecordDecl *RD) { CodeGenModule::GetLLVMVisibility(RD->getVisibility()); for (const QualType &FundamentalType : FundamentalTypes) { QualType PointerType = getContext().getPointerType(FundamentalType); - QualType PointerTypeConst = getContext().getPointerType( - FundamentalType.withConst()); + QualType PointerTypeConst = + getContext().getPointerType(FundamentalType.withConst()); for (QualType Type : {FundamentalType, PointerType, PointerTypeConst}) ItaniumRTTIBuilder(*this).BuildTypeInfo( - Type, llvm::GlobalValue::ExternalLinkage, - Visibility, DLLStorageClass); + Type, llvm::GlobalValue::ExternalLinkage, Visibility, + DLLStorageClass); } } @@ -4914,8 +4895,8 @@ void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) { static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM) { // void *__cxa_begin_catch(void*); - llvm::FunctionType *FTy = llvm::FunctionType::get( - CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false); + llvm::FunctionType *FTy = + llvm::FunctionType::get(CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false); return CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch"); } @@ -4930,39 +4911,39 @@ static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM) { static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM) { // void *__cxa_get_exception_ptr(void*); - llvm::FunctionType *FTy = llvm::FunctionType::get( - CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false); + llvm::FunctionType *FTy = + llvm::FunctionType::get(CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false); return CGM.CreateRuntimeFunction(FTy, "__cxa_get_exception_ptr"); } namespace { - /// A cleanup to call __cxa_end_catch. In many cases, the caught - /// exception type lets us state definitively that the thrown exception - /// type does not have a destructor. In particular: - /// - Catch-alls tell us nothing, so we have to conservatively - /// assume that the thrown exception might have a destructor. - /// - Catches by reference behave according to their base types. - /// - Catches of non-record types will only trigger for exceptions - /// of non-record types, which never have destructors. - /// - Catches of record types can trigger for arbitrary subclasses - /// of the caught type, so we have to assume the actual thrown - /// exception type might have a throwing destructor, even if the - /// caught type's destructor is trivial or nothrow. - struct CallEndCatch final : EHScopeStack::Cleanup { - CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {} - bool MightThrow; - - void Emit(CodeGenFunction &CGF, Flags flags) override { - if (!MightThrow) { - CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM)); - return; - } - - CGF.EmitRuntimeCallOrInvoke(getEndCatchFn(CGF.CGM)); +/// A cleanup to call __cxa_end_catch. In many cases, the caught +/// exception type lets us state definitively that the thrown exception +/// type does not have a destructor. In particular: +/// - Catch-alls tell us nothing, so we have to conservatively +/// assume that the thrown exception might have a destructor. +/// - Catches by reference behave according to their base types. +/// - Catches of non-record types will only trigger for exceptions +/// of non-record types, which never have destructors. +/// - Catches of record types can trigger for arbitrary subclasses +/// of the caught type, so we have to assume the actual thrown +/// exception type might have a throwing destructor, even if the +/// caught type's destructor is trivial or nothrow. +struct CallEndCatch final : EHScopeStack::Cleanup { + CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {} + bool MightThrow; + + void Emit(CodeGenFunction &CGF, Flags flags) override { + if (!MightThrow) { + CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM)); + return; } - }; -} + + CGF.EmitRuntimeCallOrInvoke(getEndCatchFn(CGF.CGM)); + } +}; +} // namespace /// Emits a call to __cxa_begin_catch and enters a cleanup to call /// __cxa_end_catch. If -fassume-nothrow-exception-dtor is specified, we assume @@ -4970,11 +4951,10 @@ namespace { /// call can be marked as nounwind even if EndMightThrow is true. /// /// \param EndMightThrow - true if __cxa_end_catch might throw -static llvm::Value *CallBeginCatch(CodeGenFunction &CGF, - llvm::Value *Exn, +static llvm::Value *CallBeginCatch(CodeGenFunction &CGF, llvm::Value *Exn, bool EndMightThrow) { llvm::CallInst *call = - CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM), Exn); + CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM), Exn); CGF.EHStack.pushCleanup<CallEndCatch>( NormalAndEHCleanup, @@ -4985,15 +4965,13 @@ static llvm::Value *CallBeginCatch(CodeGenFunction &CGF, /// A "special initializer" callback for initializing a catch /// parameter during catch initialization. -static void InitCatchParam(CodeGenFunction &CGF, - const VarDecl &CatchParam, - Address ParamAddr, - SourceLocation Loc) { +static void InitCatchParam(CodeGenFunction &CGF, const VarDecl &CatchParam, + Address ParamAddr, SourceLocation Loc) { // Load the exception from where the landing pad saved it. llvm::Value *Exn = CGF.getExceptionFromSlot(); CanQualType CatchType = - CGF.CGM.getContext().getCanonicalType(CatchParam.getType()); + CGF.CGM.getContext().getCanonicalType(CatchParam.getType()); llvm::Type *LLVMCatchTy = CGF.ConvertTypeForMem(CatchType); // If we're catching by reference, we can just cast the object @@ -5018,31 +4996,31 @@ static void InitCatchParam(CodeGenFunction &CGF, // Exn points to the struct _Unwind_Exception header, which // we have to skip past in order to reach the exception data. unsigned HeaderSize = - CGF.CGM.getTargetCodeGenInfo().getSizeOfUnwindException(); + CGF.CGM.getTargetCodeGenInfo().getSizeOfUnwindException(); AdjustedExn = CGF.Builder.CreateConstGEP1_32(CGF.Int8Ty, Exn, HeaderSize); - // However, if we're catching a pointer-to-record type that won't - // work, because the personality function might have adjusted - // the pointer. There's actually no way for us to fully satisfy - // the language/ABI contract here: we can't use Exn because it - // might have the wrong adjustment, but we can't use the by-value - // pointer because it's off by a level of abstraction. - // - // The current solution is to dump the adjusted pointer into an - // alloca, which breaks language semantics (because changing the - // pointer doesn't change the exception) but at least works. - // The better solution would be to filter out non-exact matches - // and rethrow them, but this is tricky because the rethrow - // really needs to be catchable by other sites at this landing - // pad. The best solution is to fix the personality function. + // However, if we're catching a pointer-to-record type that won't + // work, because the personality function might have adjusted + // the pointer. There's actually no way for us to fully satisfy + // the language/ABI contract here: we can't use Exn because it + // might have the wrong adjustment, but we can't use the by-value + // pointer because it's off by a level of abstraction. + // + // The current solution is to dump the adjusted pointer into an + // alloca, which breaks language semantics (because changing the + // pointer doesn't change the exception) but at least works. + // The better solution would be to filter out non-exact matches + // and rethrow them, but this is tricky because the rethrow + // really needs to be catchable by other sites at this landing + // pad. The best solution is to fix the personality function. } else { // Pull the pointer for the reference type off. llvm::Type *PtrTy = CGF.ConvertTypeForMem(CaughtType); // Create the temporary and write the adjusted pointer into it. Address ExnPtrTmp = - CGF.CreateTempAlloca(PtrTy, CGF.getPointerAlign(), "exn.byref.tmp"); + CGF.CreateTempAlloca(PtrTy, CGF.getPointerAlign(), "exn.byref.tmp"); llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy); CGF.Builder.CreateStore(Casted, ExnPtrTmp); @@ -5052,7 +5030,7 @@ static void InitCatchParam(CodeGenFunction &CGF, } llvm::Value *ExnCast = - CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref"); + CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref"); CGF.Builder.CreateStore(ExnCast, ParamAddr); return; } @@ -5066,7 +5044,7 @@ static void InitCatchParam(CodeGenFunction &CGF, // the pointer by value. if (CatchType->hasPointerRepresentation()) { llvm::Value *CastExn = - CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted"); + CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted"); switch (CatchType.getQualifiers().getObjCLifetime()) { case Qualifiers::OCL_Strong: @@ -5128,7 +5106,7 @@ static void InitCatchParam(CodeGenFunction &CGF, // We have to call __cxa_get_exception_ptr to get the adjusted // pointer before copying. llvm::CallInst *rawAdjustedExn = - CGF.EmitNounwindRuntimeCall(getGetExceptionPtrFn(CGF.CGM), Exn); + CGF.EmitNounwindRuntimeCall(getGetExceptionPtrFn(CGF.CGM), Exn); // Cast that to the appropriate type. Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy), @@ -5136,20 +5114,19 @@ static void InitCatchParam(CodeGenFunction &CGF, // The copy expression is defined in terms of an OpaqueValueExpr. // Find it and map it to the adjusted expression. - CodeGenFunction::OpaqueValueMapping - opaque(CGF, OpaqueValueExpr::findInCopyConstruct(copyExpr), - CGF.MakeAddrLValue(adjustedExn, CatchParam.getType())); + CodeGenFunction::OpaqueValueMapping opaque( + CGF, OpaqueValueExpr::findInCopyConstruct(copyExpr), + CGF.MakeAddrLValue(adjustedExn, CatchParam.getType())); // Call the copy ctor in a terminate scope. CGF.EHStack.pushTerminate(); // Perform the copy construction. - CGF.EmitAggExpr(copyExpr, - AggValueSlot::forAddr(ParamAddr, Qualifiers(), - AggValueSlot::IsNotDestructed, - AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsNotAliased, - AggValueSlot::DoesNotOverlap)); + CGF.EmitAggExpr( + copyExpr, AggValueSlot::forAddr( + ParamAddr, Qualifiers(), AggValueSlot::IsNotDestructed, + AggValueSlot::DoesNotNeedGCBarriers, + AggValueSlot::IsNotAliased, AggValueSlot::DoesNotOverlap)); // Leave the terminate scope. CGF.EHStack.popTerminate(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
