From c1905867bf85ab97793a250870fbfb39db8a7210 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Sat, 7 Dec 2013 06:08:04 +0000 Subject: [PATCH] Add a SubsetSubject in Attr.td to automate checking of where the objc_designated_initializer attribute is acceptable. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196644 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Attr.td | 7 ++++++- include/clang/Basic/DiagnosticSemaKinds.td | 10 ++++------ include/clang/Sema/AttributeList.h | 1 + lib/Sema/SemaDeclAttr.cpp | 19 ++----------------- test/SemaObjC/attr-designated-init.m | 16 ++++++++-------- 5 files changed, 21 insertions(+), 32 deletions(-) diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index ac6bbf63ef..96d71c747f 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -40,6 +40,10 @@ def NonBitField : SubsetSubjectisInstanceMethod()}]>; +def ObjCInterfaceDeclInitMethod : SubsetSubjectgetMethodFamily() == OMF_init && + isa(S->getDeclContext())}]>; + def Struct : SubsetSubjectisUnion()}]>; @@ -699,7 +703,8 @@ def ObjCSuppressProtocol : InheritableAttr { def ObjCDesignatedInitializer : Attr { let Spellings = [GNU<"objc_designated_initializer">]; - let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; + let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag, + "ExpectedObjCInterfaceDeclInitMethod">; } def Overloadable : Attr { diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 76738d0ef3..cf75c868f4 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2037,7 +2037,8 @@ 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|variables, functions and classes}1">, + "Objective-C instance methods|init methods of interface declarations|" + "variables, functions and classes}1">, InGroup; def err_attribute_wrong_decl_type : Error< "%0 attribute only applies to %select{functions|unions|" @@ -2049,7 +2050,8 @@ def err_attribute_wrong_decl_type : Error< "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|variables, functions and classes}1">; + "Objective-C instance methods|init methods of interface declarations|" + "variables, functions and classes}1">; def warn_type_attribute_wrong_type : Warning< "'%0' only applies to %select{function|pointer|" "Objective-C object or block pointer}1 types; type here is %2">, @@ -2428,10 +2430,6 @@ def note_protocol_decl : Note< "protocol is declared here">; // objc_designated_initializer attribute diagnostics. -def err_attr_objc_designated_not_init_family : Error< - "'objc_designated_initializer' only applies to methods of the init family">; -def err_attr_objc_designated_not_interface : Error< - "'objc_designated_initializer' only applies to methods of interface declarations">; def warn_objc_designated_init_missing_super_call : Warning< "designated initializer missing a 'super' call to a designated initializer of the super class">, InGroup; diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index a0059b5e83..f661dd0873 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -909,6 +909,7 @@ enum AttributeDeclKind { ExpectedStructOrUnionOrClass, ExpectedType, ExpectedObjCInstanceMethod, + ExpectedObjCInterfaceDeclInitMethod, ExpectedFunctionVariableOrClass }; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index f5a3654218..6d7bc03465 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -3733,24 +3733,9 @@ static void handleObjCBridgeRelatedAttr(Sema &S, Scope *Sc, Decl *D, static void handleObjCDesignatedInitializer(Sema &S, Decl *D, const AttributeList &Attr) { - SourceLocation Loc = Attr.getLoc(); - ObjCMethodDecl *Method = cast(D); - - if (Method->getMethodFamily() != OMF_init) { - S.Diag(D->getLocStart(), diag::err_attr_objc_designated_not_init_family) - << SourceRange(Loc, Loc); - return; - } - ObjCInterfaceDecl *IFace = - dyn_cast(Method->getDeclContext()); - if (!IFace) { - S.Diag(D->getLocStart(), diag::err_attr_objc_designated_not_interface) - << SourceRange(Loc, Loc); - return; - } - + ObjCInterfaceDecl *IFace = cast(D->getDeclContext()); IFace->setHasDesignatedInitializers(); - Method->addAttr(::new (S.Context) + D->addAttr(::new (S.Context) ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); } diff --git a/test/SemaObjC/attr-designated-init.m b/test/SemaObjC/attr-designated-init.m index dd908854a3..9b8e5d13a5 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 methods}} +void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} @protocol P1 --(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of interface declarations}} +-(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} @end __attribute__((objc_root_class)) @interface I1 --(void)meth NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of the init family}} +-(void)meth NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} -(id)init NS_DESIGNATED_INITIALIZER; -+(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of the init family}} ++(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} @end @interface I1(cat) --(id)init2 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of interface declarations}} +-(id)init2 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} @end @interface I1() --(id)init3 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of interface declarations}} +-(id)init3 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface declarations}} @end @implementation I1 -(void)meth {} --(id)init NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to methods of interface declarations}} +-(id)init NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface 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 methods of interface declarations}} \ +-(id)init4 NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface declarations}} \ // expected-warning {{secondary initializer missing a 'self' call to another initializer}} @end -- 2.40.0