def warn_objc_secondary_init_missing_init_call : Warning<
"secondary initializer missing a 'self' call to another initializer">,
InGroup<ObjCDesignatedInit>;
+def warn_objc_implementation_missing_designated_init_override : Warning<
+ "method override for the designated initializer of the superclass %objcinstance0 not found">,
+ InGroup<ObjCDesignatedInit>;
def err_ns_bridged_not_interface : Error<
"parameter of 'ns_bridged' attribute does not name an Objective-C class">;
void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D);
+ void DiagnoseMissingDesignatedInitOverrides(
+ const ObjCImplementationDecl *ImplD,
+ const ObjCInterfaceDecl *IFD);
+
void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
enum MethodMatchStrategy {
ImplMethodsVsClassMethods(S, IC, IDecl);
AtomicPropertySetterGetterRules(IC, IDecl);
DiagnoseOwningPropertyGetterSynthesis(IC);
-
+ if (IDecl->hasDesignatedInitializers())
+ DiagnoseMissingDesignatedInitOverrides(IC, IDecl);
+
bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>();
if (IDecl->getSuperClass() == NULL) {
// This class has no superclass, so check that it has been marked with
}
}
+void Sema::DiagnoseMissingDesignatedInitOverrides(
+ const ObjCImplementationDecl *ImplD,
+ const ObjCInterfaceDecl *IFD) {
+ assert(IFD->hasDesignatedInitializers());
+ const ObjCInterfaceDecl *SuperD = IFD->getSuperClass();
+ if (!SuperD)
+ return;
+
+ SelectorSet InitSelSet;
+ for (ObjCImplementationDecl::instmeth_iterator
+ I = ImplD->instmeth_begin(), E = ImplD->instmeth_end(); I!=E; ++I)
+ if ((*I)->getMethodFamily() == OMF_init)
+ InitSelSet.insert((*I)->getSelector());
+
+ SmallVector<const ObjCMethodDecl *, 8> DesignatedInits;
+ SuperD->getDesignatedInitializers(DesignatedInits);
+ for (SmallVector<const ObjCMethodDecl *, 8>::iterator
+ I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
+ const ObjCMethodDecl *MD = *I;
+ if (!InitSelSet.count(MD->getSelector())) {
+ Diag(ImplD->getLocation(),
+ diag::warn_objc_implementation_missing_designated_init_override)
+ << MD->getSelector();
+ Diag(MD->getLocation(), diag::note_objc_designated_init_marked_here);
+ }
+ }
+}
+
/// AddPropertyAttrs - Propagates attributes from a property to the
/// implicitly-declared getter or setter for that property.
static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod,
__attribute__((objc_root_class))
@interface B1
--(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
+-(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
-(id)initB2;
--(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
+-(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 3 {{method marked as designated initializer of the class here}}
@end
@implementation B1
-(id)initSS1 NS_DESIGNATED_INITIALIZER;
@end
-@implementation SS2
+@implementation SS2 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \
+ // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
-(id)initSS1 {
return [super initB1];
}
@end
@interface S3 : B1
--(id)initS1 NS_DESIGNATED_INITIALIZER;
+-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
@end
@interface SS3 : S3
-(id)initSS1 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
@end
-@implementation SS3
+@implementation SS3 // expected-warning {{method override for the designated initializer of the superclass '-initS1' not found}}
-(id)initSS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
return [super initB1]; // expected-warning {{designated initializer invoked a non-designated initializer}}
}
-(id)initS4;
@end
-@implementation S6
+@implementation S6 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \
+ // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
-(id)initS1 {
return [super initB1];
}