]> granicus.if.org Git - clang/commitdiff
Add a SubsetSubject in Attr.td to automate checking of where the objc_designated_init...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 7 Dec 2013 06:08:04 +0000 (06:08 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 7 Dec 2013 06:08:04 +0000 (06:08 +0000)
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
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/AttributeList.h
lib/Sema/SemaDeclAttr.cpp
test/SemaObjC/attr-designated-init.m

index ac6bbf63ef3ca68aa0571208085bc32a792aabfc..96d71c747f1588694dc7215e2267dc3c2d501f70 100644 (file)
@@ -40,6 +40,10 @@ def NonBitField : SubsetSubject<Field,
 def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
                                        [{S->isInstanceMethod()}]>;
 
+def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
+                               [{S->getMethodFamily() == OMF_init &&
+                                 isa<ObjCInterfaceDecl>(S->getDeclContext())}]>;
+
 def Struct : SubsetSubject<Record,
                            [{!S->isUnion()}]>;
 
@@ -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 {
index 76738d0ef37b95aeb711f3f0b0814a5283791790..cf75c868f4c64427a6e7763815b22a95947d4528 100644 (file)
@@ -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<IgnoredAttributes>;
 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<ObjCDesignatedInit>;
index a0059b5e833e094a2b0b66d7edba55cff9a57ee9..f661dd08739217b78b310a5e244af47f3e06998c 100644 (file)
@@ -909,6 +909,7 @@ enum AttributeDeclKind {
   ExpectedStructOrUnionOrClass,
   ExpectedType,
   ExpectedObjCInstanceMethod,
+  ExpectedObjCInterfaceDeclInitMethod,
   ExpectedFunctionVariableOrClass
 };
 
index f5a36542185ba252fd31e9e6b7f9761a372c0a45..6d7bc0346580fbcc4aff8696160c04e2560012ed 100644 (file)
@@ -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<ObjCMethodDecl>(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<ObjCInterfaceDecl>(Method->getDeclContext());
-  if (!IFace) {
-    S.Diag(D->getLocStart(), diag::err_attr_objc_designated_not_interface)
-    << SourceRange(Loc, Loc);
-    return;
-  }
-
+  ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D->getDeclContext());
   IFace->setHasDesignatedInitializers();
-  Method->addAttr(::new (S.Context)
+  D->addAttr(::new (S.Context)
                   ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context,
                                          Attr.getAttributeSpellingListIndex()));
 }
index dd908854a396cafe2a2fea7466728b9f8d81d617..9b8e5d13a50d8523a88bc85f8aba8a1ada5ecc0a 100644 (file)
@@ -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