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