Author: joseph_daniels Date: Mon Feb 4 15:32:55 2019 New Revision: 353116 URL: http://llvm.org/viewvc/llvm-project?rev=353116&view=rev Log: [OBJC] Add attribute to mark Objective C class as non-lazy
A non-lazy class will be initialized eagerly when the Objective-C runtime is loaded. This is required for certain system classes which have instances allocated in non-standard ways, such as the classes for blocks and constant strings. Adding this attribute is essentially equivalent to providing a trivial +load method but avoids the (fairly small) load-time overheads associated with defining and calling such a method. Differential Revision: https://reviews.llvm.org/D56555 Added: cfe/trunk/test/SemaObjC/attr-objc-non-lazy.m Modified: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Basic/AttrDocs.td cfe/trunk/lib/CodeGen/CGObjCMac.cpp cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/CodeGenObjC/non-lazy-classes.m cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test Modified: cfe/trunk/include/clang/Basic/Attr.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=353116&r1=353115&r2=353116&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Attr.td (original) +++ cfe/trunk/include/clang/Basic/Attr.td Mon Feb 4 15:32:55 2019 @@ -1758,6 +1758,13 @@ def ObjCRootClass : InheritableAttr { let Documentation = [Undocumented]; } +def ObjCNonLazyClass : Attr { + let Spellings = [Clang<"objc_nonlazy_class">]; + let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; + let LangOpts = [ObjC]; + let Documentation = [ObjCNonLazyClassDocs]; +} + def ObjCSubclassingRestricted : InheritableAttr { let Spellings = [Clang<"objc_subclassing_restricted">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; Modified: cfe/trunk/include/clang/Basic/AttrDocs.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=353116&r1=353115&r2=353116&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/AttrDocs.td (original) +++ cfe/trunk/include/clang/Basic/AttrDocs.td Mon Feb 4 15:32:55 2019 @@ -3699,6 +3699,19 @@ ensure that this class cannot be subclas }]; } +def ObjCNonLazyClassDocs : Documentation { + let Category = DocCatType; + let Content = [{ +This attribute can be added to an Objective-C ``@interface`` declaration to +add the class to the list of non-lazily initialized classes. A non-lazy class +will be initialized eagerly when the Objective-C runtime is loaded. This is +required for certain system classes which have instances allocated in +non-standard ways, such as the classes for blocks and constant strings. Adding +this attribute is essentially equivalent to providing a trivial `+load` method +but avoids the (fairly small) load-time overheads associated with defining and +calling such a method. + }]; +} def SelectAnyDocs : Documentation { let Category = DocCatType; Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=353116&r1=353115&r2=353116&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original) +++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Mon Feb 4 15:32:55 2019 @@ -6261,9 +6261,10 @@ CGObjCNonFragileABIMac::BuildClassObject return GV; } -bool -CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const { - return OD->getClassMethod(GetNullarySelector("load")) != nullptr; +bool CGObjCNonFragileABIMac::ImplementationIsNonLazy( + const ObjCImplDecl *OD) const { + return OD->getClassMethod(GetNullarySelector("load")) != nullptr || + OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>(); } void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=353116&r1=353115&r2=353116&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Feb 4 15:32:55 2019 @@ -6832,6 +6832,9 @@ static void ProcessDeclAttribute(Sema &S case ParsedAttr::AT_ObjCRootClass: handleSimpleAttribute<ObjCRootClassAttr>(S, D, AL); break; + case ParsedAttr::AT_ObjCNonLazyClass: + handleSimpleAttribute<ObjCNonLazyClassAttr>(S, D, AL); + break; case ParsedAttr::AT_ObjCSubclassingRestricted: handleSimpleAttribute<ObjCSubclassingRestrictedAttr>(S, D, AL); break; Modified: cfe/trunk/test/CodeGenObjC/non-lazy-classes.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/non-lazy-classes.m?rev=353116&r1=353115&r2=353116&view=diff ============================================================================== --- cfe/trunk/test/CodeGenObjC/non-lazy-classes.m (original) +++ cfe/trunk/test/CodeGenObjC/non-lazy-classes.m Mon Feb 4 15:32:55 2019 @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wno-objc-root-class -emit-llvm -o - %s | \ // RUN: FileCheck %s -// CHECK: @"OBJC_LABEL_NONLAZY_CLASS_$" = private global [1 x {{.*}}] {{.*}}@"OBJC_CLASS_$_A"{{.*}}, section "__DATA,__objc_nlclslist,regular,no_dead_strip", align 8 +// CHECK: @"OBJC_LABEL_NONLAZY_CLASS_$" = private global [2 x {{.*}}]{{.*}}@"OBJC_CLASS_$_A"{{.*}},{{.*}}@"OBJC_CLASS_$_D"{{.*}} section "__DATA,__objc_nlclslist,regular,no_dead_strip", align 8 // CHECK: @"OBJC_LABEL_NONLAZY_CATEGORY_$" = private global [1 x {{.*}}] {{.*}}@"\01l_OBJC_$_CATEGORY_A_$_Cat"{{.*}}, section "__DATA,__objc_nlcatlist,regular,no_dead_strip", align 8 @interface A @end @@ -30,3 +30,8 @@ @interface C : A @end @implementation C @end + +__attribute__((objc_nonlazy_class)) +@interface D @end + +@implementation D @end Modified: cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test?rev=353116&r1=353115&r2=353116&view=diff ============================================================================== --- cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test (original) +++ cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test Mon Feb 4 15:32:55 2019 @@ -100,6 +100,7 @@ // CHECK-NEXT: ObjCExplicitProtocolImpl (SubjectMatchRule_objc_protocol) // CHECK-NEXT: ObjCExternallyRetained (SubjectMatchRule_variable_not_is_parameter, SubjectMatchRule_function, SubjectMatchRule_block, SubjectMatchRule_objc_method) // CHECK-NEXT: ObjCMethodFamily (SubjectMatchRule_objc_method) +// CHECK-NEXT: ObjCNonLazyClass (SubjectMatchRule_objc_interface) // CHECK-NEXT: ObjCPreciseLifetime (SubjectMatchRule_variable) // CHECK-NEXT: ObjCRequiresPropertyDefs (SubjectMatchRule_objc_interface) // CHECK-NEXT: ObjCRequiresSuper (SubjectMatchRule_objc_method) Added: cfe/trunk/test/SemaObjC/attr-objc-non-lazy.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-objc-non-lazy.m?rev=353116&view=auto ============================================================================== --- cfe/trunk/test/SemaObjC/attr-objc-non-lazy.m (added) +++ cfe/trunk/test/SemaObjC/attr-objc-non-lazy.m Mon Feb 4 15:32:55 2019 @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class -fsyntax-only %s + +__attribute__((objc_nonlazy_class)) +@interface A +@end +@implementation A +@end + +__attribute__((objc_nonlazy_class)) int X; // expected-error {{'objc_nonlazy_class' attribute only applies to Objective-C interfaces}} + +__attribute__((objc_nonlazy_class())) +@interface B +@end +@implementation B +@end + +__attribute__((objc_nonlazy_class("foo"))) // expected-error{{'objc_nonlazy_class' attribute takes no arguments}} +@interface C +@end +@implementation C +@end + +__attribute__((objc_nonlazy_class)) // expected-error {{'objc_nonlazy_class' attribute only applies to Objective-C interfaces}} +@protocol B +@end + +__attribute__((objc_nonlazy_class)) // expected-error {{'objc_nonlazy_class' attribute only applies to Objective-C interfaces}} +void foo(); + +@interface E +@end +__attribute__((objc_nonlazy_class)) +@implementation E // expected-error {{prefix attribute must be followed by an interface or protocol}} +@end _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits