[clang] [llvm] [WIP] Advance the merger progress of #211963 (PR #216611)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 16 16:35:36 PDT 2026
https://github.com/zhangweize9-cyber updated https://github.com/llvm/llvm-project/pull/216611
>From 808122fa480b131a69276c594fcf6c0479aed2b5 Mon Sep 17 00:00:00 2001
From: pyxherb <codesbuilder at 163.com>
Date: Sat, 25 Jul 2026 07:29:53 +0800
Subject: [PATCH 1/3] [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 c17813140b10f..936dd777940bf 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3134,6 +3134,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 7aa394ac8768b7badb0e002c8448318a996beb8d Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Mon, 17 Aug 2026 06:19:33 +0800
Subject: [PATCH 2/3] fix: #211963
---
clang/lib/CodeGen/ItaniumCXXABI.cpp | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 936dd777940bf..e6d76d74bd9b2 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3131,8 +3131,6 @@ 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,
@@ -3140,10 +3138,11 @@ void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
// 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 (!CGM.getLangOpts().hasAtExit() && !D.isStaticLocal() &&
+ 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
>From 291b7bcbbdeea87f231440fa3ceef0671bd67ab9 Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Mon, 17 Aug 2026 06:47:35 +0800
Subject: [PATCH 3/3] refix: #211963
---
clang/lib/CodeGen/ItaniumCXXABI.cpp | 745 ++++++++++++------------
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 4 +-
2 files changed, 365 insertions(+), 384 deletions(-)
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index e6d76d74bd9b2..9b3f0b84dea39 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -63,12 +63,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;
@@ -130,12 +128,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,
@@ -157,14 +153,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,
@@ -261,9 +257,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;
@@ -369,17 +365,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,
@@ -392,14 +387,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;
@@ -446,43 +439,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()) {
@@ -502,9 +495,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; }
@@ -512,8 +505,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;
@@ -533,8 +525,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; }
@@ -557,8 +548,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,
@@ -570,7 +560,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()) {
@@ -641,8 +631,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 =
@@ -689,9 +679,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);
@@ -953,10 +942,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));
@@ -1009,15 +997,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.
@@ -1093,22 +1082,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);
@@ -1143,7 +1134,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);
}
@@ -1221,8 +1212,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>();
@@ -1239,9 +1230,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);
@@ -1265,7 +1256,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);
}
@@ -1273,12 +1264,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;
@@ -1335,8 +1323,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);
}
@@ -1347,17 +1335,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");
}
@@ -1373,8 +1359,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);
}
@@ -1409,8 +1395,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) {
@@ -1452,7 +1437,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");
@@ -1466,7 +1451,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");
}
@@ -1475,9 +1460,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");
}
@@ -1493,8 +1478,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,
@@ -1516,9 +1501,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);
}
@@ -1531,9 +1517,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);
@@ -1572,7 +1558,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;
@@ -1625,12 +1611,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.
@@ -1879,24 +1864,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");
@@ -2041,8 +2024,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);
@@ -2192,9 +2175,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
@@ -2228,13 +2211,15 @@ 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 PointerAuth = CGM.getVTablePointerAuthInfo(&CGF, VTableClass, VTT,
- /*IsVTTEntry=*/true))
- AP = CGF.EmitPointerAuthAuth(*PointerAuth, AP);
+ 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);
+ }
return AP;
}
@@ -2277,8 +2262,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;
@@ -2350,8 +2334,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;
@@ -2473,8 +2459,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.
@@ -2488,9 +2474,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());
@@ -2534,8 +2519,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);
@@ -2606,8 +2591,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);
@@ -2638,8 +2623,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) {
@@ -2650,8 +2634,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.
@@ -2669,8 +2653,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);
@@ -2681,9 +2665,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(),
@@ -2695,7 +2679,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(),
@@ -2707,7 +2691,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(),
@@ -2716,21 +2700,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;
@@ -2787,10 +2770,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());
@@ -2870,8 +2852,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))
@@ -2905,13 +2887,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);
@@ -2957,7 +2939,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
@@ -2978,7 +2960,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);
@@ -3132,13 +3114,13 @@ void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
// not strictly 1-to-1 with using `atexit` because we no longer tear down
// globals in reverse order of when they were constructed.
- // 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() && !D.isStaticLocal() &&
+ // 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 &&
@@ -3191,9 +3173,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;
{
@@ -3373,8 +3354,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
@@ -3562,9 +3542,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;
@@ -3624,7 +3604,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,
@@ -3653,13 +3633,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) {
@@ -3742,53 +3721,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"
@@ -3829,8 +3805,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
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!");
@@ -3838,7 +3813,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
case BuiltinType::ObjCClass:
case BuiltinType::ObjCSel:
llvm_unreachable("FIXME: Objective-C types are unsupported!");
- }
+ }
llvm_unreachable("Invalid BuiltinType Kind!");
}
@@ -3878,13 +3853,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 +3921,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 +3963,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 +4224,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 +4428,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 +4453,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 +4520,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 +4565,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 +4580,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 +4638,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 +4651,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 +4665,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 +4689,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 +4722,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 +4899,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 +4915,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 +4955,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 +4969,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 +5000,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 +5034,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 +5048,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 +5110,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 +5118,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();
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index d078117061677..d7c37a021169e 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -2173,8 +2173,8 @@ bool X86DAGToDAGISel::matchAdd(SDValue &N, X86ISelAddressMode &AM,
};
X86ISelAddressMode Backup = AM;
- if (!MatchOperand(N.getOperand(0)) &&
- !MatchOperand(Handle.getValue().getOperand(1)))
+ if (!matchAddressRecursively(N.getOperand(0), AM, Depth + 1) &&
+ !matchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth + 1))
return false;
AM = Backup;
More information about the llvm-commits
mailing list