From ba42b0bca2698ffb3a878c98017d494aba3ee5ff Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 14 Mar 2014 18:19:46 +0000 Subject: [PATCH] Objective-C. Allow objc_designated_initializer for private initializers; but only those declared in class extensions (not in implementations). // rdar://16305347 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203954 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Attr.td | 4 +++- include/clang/Basic/DiagnosticSemaKinds.td | 2 +- lib/Sema/SemaDeclAttr.cpp | 6 +++++- test/SemaObjC/attr-designated-init.m | 16 ++++++++-------- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index aae669db2f..f24d335df3 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -90,7 +90,9 @@ def ObjCInstanceMethod : SubsetSubjectgetMethodFamily() == OMF_init && - isa(S->getDeclContext())}]>; + (isa(S->getDeclContext()) || + (isa(S->getDeclContext()) && + cast(S->getDeclContext())->IsClassExtension()))}]>; def Struct : SubsetSubjectisUnion()}]>; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 727e229644..7ac2fc1ec9 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2088,7 +2088,7 @@ def warn_attribute_wrong_decl_type : Warning< "variables and fields|variables, data members and tag types|" "types and namespaces|Objective-C interfaces|methods and properties|" "struct or union|struct, union or class|types|" - "Objective-C instance methods|init methods of interface declarations|" + "Objective-C instance methods|init methods of interface or class extension declarations|" "variables, functions and classes|Objective-C protocols|" "functions and global variables}1">, InGroup; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 26fa4cddd3..38158eb133 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -3554,7 +3554,11 @@ static void handleObjCBridgeRelatedAttr(Sema &S, Scope *Sc, Decl *D, static void handleObjCDesignatedInitializer(Sema &S, Decl *D, const AttributeList &Attr) { - ObjCInterfaceDecl *IFace = cast(D->getDeclContext()); + ObjCInterfaceDecl *IFace; + if (ObjCCategoryDecl *CatDecl = dyn_cast(D->getDeclContext())) + IFace = CatDecl->getClassInterface(); + else + IFace = cast(D->getDeclContext()); IFace->setHasDesignatedInitializers(); D->addAttr(::new (S.Context) ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context, diff --git a/test/SemaObjC/attr-designated-init.m b/test/SemaObjC/attr-designated-init.m index d24c9c65cb..916be5d3bc 100644 --- a/test/SemaObjC/attr-designated-init.m +++ b/test/SemaObjC/attr-designated-init.m @@ -2,33 +2,33 @@ #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) -void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} +void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} @protocol P1 --(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} +-(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} @end __attribute__((objc_root_class)) @interface I1 --(void)meth NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} +-(void)meth NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} -(id)init NS_DESIGNATED_INITIALIZER; -+(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} ++(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} @end @interface I1(cat) --(id)init2 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} +-(id)init2 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} @end @interface I1() --(id)init3 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} +-(id)init3 NS_DESIGNATED_INITIALIZER; @end @implementation I1 -(void)meth {} --(id)init NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface declarations}} +-(id)init NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface or class extension declarations}} +(id)init { return 0; } -(id)init3 { return 0; } // expected-warning {{secondary initializer missing a 'self' call to another initializer}} --(id)init4 NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface declarations}} \ +-(id)init4 NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface or class extension declarations}} \ // expected-warning {{secondary initializer missing a 'self' call to another initializer}} @end -- 2.40.0