summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp30
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp4
2 files changed, 28 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 01179cca6b9..99548517430 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -2367,7 +2367,10 @@ enum NonFragileClassFlags {
NonFragileABI_Class_HasIvarReleaser = 0x00040,
/// Class implementation was compiled under ARC.
- NonFragileABI_Class_CompiledByARC = 0x00080
+ NonFragileABI_Class_CompiledByARC = 0x00080,
+
+ /// Class has non-trivial destructors, but zero-initialization is okay.
+ NonFragileABI_Class_HasCXXDestructorOnly = 0x00100
};
/*
@@ -2401,7 +2404,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Interface->all_referenced_protocol_begin(),
Interface->all_referenced_protocol_end());
unsigned Flags = FragileABI_Class_Factory;
- if (ID->hasCXXStructors())
+ if (ID->hasNonZeroConstructors() || ID->hasDestructors())
Flags |= FragileABI_Class_HasCXXStructors;
unsigned Size =
CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
@@ -5154,12 +5157,20 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
llvm::GlobalVariable *SuperClassGV, *IsAGV;
+ // Build the flags for the metaclass.
bool classIsHidden =
ID->getClassInterface()->getVisibility() == HiddenVisibility;
if (classIsHidden)
flags |= NonFragileABI_Class_Hidden;
- if (ID->hasCXXStructors())
+
+ // FIXME: why is this flag set on the metaclass?
+ // ObjC metaclasses have no fields and don't really get constructed.
+ if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
flags |= NonFragileABI_Class_HasCXXStructors;
+ if (!ID->hasNonZeroConstructors())
+ flags |= NonFragileABI_Class_HasCXXDestructorOnly;
+ }
+
if (!ID->getClassInterface()->getSuperClass()) {
// class is root
flags |= NonFragileABI_Class_Root;
@@ -5194,9 +5205,20 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
flags = 0;
if (classIsHidden)
flags |= NonFragileABI_Class_Hidden;
- if (ID->hasCXXStructors())
+
+ if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
flags |= NonFragileABI_Class_HasCXXStructors;
+ // Set a flag to enable a runtime optimization when a class has
+ // fields that require destruction but which don't require
+ // anything except zero-initialization during construction. This
+ // is most notably true of __strong and __weak types, but you can
+ // also imagine there being C++ types with non-trivial default
+ // constructors that merely set all fields to null.
+ if (!ID->hasNonZeroConstructors())
+ flags |= NonFragileABI_Class_HasCXXDestructorOnly;
+ }
+
if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
flags |= NonFragileABI_Class_Exception;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index e9344a1351b..95753d540e7 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2541,7 +2541,7 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {
/*isDefined=*/false, ObjCMethodDecl::Required);
D->addInstanceMethod(DTORMethod);
CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, DTORMethod, false);
- D->setHasCXXStructors(true);
+ D->setHasDestructors(true);
}
// If the implementation doesn't have any ivar initializers, we don't need
@@ -2565,7 +2565,7 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {
ObjCMethodDecl::Required);
D->addInstanceMethod(CTORMethod);
CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, CTORMethod, true);
- D->setHasCXXStructors(true);
+ D->setHasNonZeroConstructors(true);
}
/// EmitNamespace - Emit all declarations in a namespace.
OpenPOWER on IntegriCloud