r205065 - [SemaObjC] For the semantics of the designated-initializer attribute, consider that the ObjC interface of the class

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Mar 28 15:45:38 PDT 2014


Author: akirtzidis
Date: Fri Mar 28 17:45:38 2014
New Revision: 205065

URL: http://llvm.org/viewvc/llvm-project?rev=205065&view=rev
Log:
[SemaObjC] For the semantics of the designated-initializer attribute, consider that the ObjC interface of the class
includes its class extensions.

This is follow-up for rdar://16305347

Modified:
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/test/SemaObjC/attr-designated-init.m

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=205065&r1=205064&r2=205065&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Fri Mar 28 17:45:38 2014
@@ -353,6 +353,20 @@ ObjCInterfaceDecl::findInterfaceWithDesi
   return 0;
 }
 
+static bool isIntroducingInitializers(const ObjCInterfaceDecl *D) {
+  for (const auto *MD : D->instance_methods()) {
+    if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
+      return true;
+  }
+  for (const auto *Ext : D->visible_extensions()) {
+    for (const auto *MD : Ext->instance_methods()) {
+      if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
+        return true;
+    }
+  }
+  return false;
+}
+
 bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
   switch (data().InheritedDesignatedInitializers) {
   case DefinitionData::IDI_Inherited:
@@ -360,17 +374,10 @@ bool ObjCInterfaceDecl::inheritsDesignat
   case DefinitionData::IDI_NotInherited:
     return false;
   case DefinitionData::IDI_Unknown: {
-    bool isIntroducingInitializers = false;
-    for (const auto *MD : instance_methods()) {
-      if (MD->getMethodFamily() == OMF_init && !MD->isOverriding()) {
-        isIntroducingInitializers = true;
-        break;
-      }
-    }
     // If the class introduced initializers we conservatively assume that we
     // don't know if any of them is a designated initializer to avoid possible
     // misleading warnings.
-    if (isIntroducingInitializers) {
+    if (isIntroducingInitializers(this)) {
       data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;
       return false;
     } else {
@@ -398,6 +405,11 @@ void ObjCInterfaceDecl::getDesignatedIni
   for (const auto *MD : IFace->instance_methods())
     if (MD->isThisDeclarationADesignatedInitializer())
       Methods.push_back(MD);
+  for (const auto *Ext : IFace->visible_extensions()) {
+    for (const auto *MD : Ext->instance_methods())
+      if (MD->isThisDeclarationADesignatedInitializer())
+        Methods.push_back(MD);
+  }
 }
 
 bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
@@ -412,13 +424,22 @@ bool ObjCInterfaceDecl::isDesignatedInit
   if (!IFace)
     return false;
 
-  if (const ObjCMethodDecl *MD = IFace->getMethod(Sel, /*isInstance=*/true)) {
+  if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) {
     if (MD->isThisDeclarationADesignatedInitializer()) {
       if (InitMethod)
         *InitMethod = MD;
       return true;
     }
   }
+  for (const auto *Ext : IFace->visible_extensions()) {
+    if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) {
+      if (MD->isThisDeclarationADesignatedInitializer()) {
+        if (InitMethod)
+          *InitMethod = MD;
+        return true;
+      }
+    }
+  }
   return false;
 }
 

Modified: cfe/trunk/test/SemaObjC/attr-designated-init.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-designated-init.m?rev=205065&r1=205064&r2=205065&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-designated-init.m (original)
+++ cfe/trunk/test/SemaObjC/attr-designated-init.m Fri Mar 28 17:45:38 2014
@@ -27,7 +27,7 @@ __attribute__((objc_root_class))
 -(void)meth {}
 -(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)init3 { return 0; }
 -(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
@@ -36,9 +36,12 @@ __attribute__((objc_root_class))
 @interface B1
 -(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 6 {{method marked as designated initializer of the class here}}
 -(id)initB2;
--(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
 @end
 
+ at interface B1()
+-(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
+ at end;
+
 @implementation B1
 -(id)initB1 { return 0; }
 -(id)initB2 { return 0; } // expected-warning {{secondary initializer missing a 'self' call to another initializer}}
@@ -49,10 +52,13 @@ __attribute__((objc_root_class))
 -(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
 -(id)initS2 NS_DESIGNATED_INITIALIZER;
 -(id)initS3 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
--(id)initS4 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
 -(id)initB1;
 @end
 
+ at interface S1()
+-(id)initS4 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
+ at end
+
 @implementation S1
 -(id)initS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
   return 0;





More information about the cfe-commits mailing list