diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-03-27 19:02:17 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-03-27 19:02:17 +0000 |
commit | 8822f7cda557ffa755c16b5c978dada23c37d6be (patch) | |
tree | 5a38c2d0f3f437108863265133b76303785c072e | |
parent | 9a4d77f56313cae5693c8cbd64fb13086a1b43d8 (diff) |
Improve diagnostics on incomplete implementation
of objc classes; including which methods
need be implemented and where they come from.
WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99724 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 13 | ||||
-rw-r--r-- | test/Analysis/PR3991.m | 20 | ||||
-rw-r--r-- | test/Analysis/pr4209.m | 8 | ||||
-rw-r--r-- | test/SemaObjC/category-1.m | 6 | ||||
-rw-r--r-- | test/SemaObjC/compare-qualified-id.m | 7 | ||||
-rw-r--r-- | test/SemaObjC/conditional-expr.m | 4 | ||||
-rw-r--r-- | test/SemaObjC/gcc-cast-ext.m | 6 | ||||
-rw-r--r-- | test/SemaObjC/method-arg-decay.m | 10 | ||||
-rw-r--r-- | test/SemaObjC/method-undef-category-warn-1.m | 18 | ||||
-rw-r--r-- | test/SemaObjC/method-undef-extension-warn-1.m | 10 | ||||
-rw-r--r-- | test/SemaObjC/method-undefined-warn-1.m | 16 | ||||
-rw-r--r-- | test/SemaObjC/undef-protocol-methods-1.m | 34 |
13 files changed, 71 insertions, 85 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index c6f20247fa..a8bca592df 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -275,7 +275,9 @@ def err_conflicting_ivar_name : Error< def err_inconsistant_ivar_count : Error< "inconsistent number of instance variables specified">; def warn_incomplete_impl : Warning<"incomplete implementation">; -def warn_undef_method_impl : Warning<"method definition for %0 not found">; +def note_undef_method_impl : Note<"method definition for %0 not found">; +def note_required_for_protocol_at : + Note<"required for direct or indirect protocol %0">; def warn_conflicting_ret_types : Warning< "conflicting return type in implementation of %0: %1 vs %2">; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 1feeffdfe5..79a664f2e1 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -724,7 +724,8 @@ void Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method, Diag(ImpLoc, diag::warn_incomplete_impl); IncompleteImpl = true; } - Diag(ImpLoc, diag::warn_undef_method_impl) << method->getDeclName(); + Diag(method->getLocation(), diag::note_undef_method_impl) + << method->getDeclName(); } void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, @@ -806,8 +807,11 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, // uses the protocol. ObjCMethodDecl *MethodInClass = IDecl->lookupInstanceMethod(method->getSelector()); - if (!MethodInClass || !MethodInClass->isSynthesized()) + if (!MethodInClass || !MethodInClass->isSynthesized()) { WarnUndefinedMethod(ImpLoc, method, IncompleteImpl); + Diag(IDecl->getLocation(), diag::note_required_for_protocol_at) << + PDecl->getDeclName(); + } } } // check unimplemented class methods @@ -817,8 +821,11 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, ObjCMethodDecl *method = *I; if (method->getImplementationControl() != ObjCMethodDecl::Optional && !ClsMap.count(method->getSelector()) && - (!Super || !Super->lookupClassMethod(method->getSelector()))) + (!Super || !Super->lookupClassMethod(method->getSelector()))) { WarnUndefinedMethod(ImpLoc, method, IncompleteImpl); + Diag(IDecl->getLocation(), diag::note_required_for_protocol_at) << + PDecl->getDeclName(); + } } // Check on this protocols's referenced protocols, recursively. for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), diff --git a/test/Analysis/PR3991.m b/test/Analysis/PR3991.m index 3fed57e112..c1f238c77c 100644 --- a/test/Analysis/PR3991.m +++ b/test/Analysis/PR3991.m @@ -35,22 +35,16 @@ typedef struct _NSZone NSZone; @protocol IHGoogleDocsAdapterDelegate - (void)googleDocsAdapter:(IHGoogleDocsAdapter*)inGoogleDocsAdapter accountVerifyIsValid:(BOOL)inIsValid error:(NSError *)inError; @end @interface IHGoogleDocsAdapter : NSObject { } -- (NSArray *)entries; +- (NSArray *)entries; // expected-note {{method definition for 'entries' not found}} @end extern Class const kGDataUseRegisteredClass ; -@interface IHGoogleDocsAdapter () - (GDataFeedDocList *)feedDocList; -- (NSArray *)directoryPathComponents; -- (unsigned int)currentPathComponentIndex; -- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex; -- (NSURL *)folderFeedURL; +@interface IHGoogleDocsAdapter () - (GDataFeedDocList *)feedDocList; // expected-note {{method definition for 'feedDocList' not found}} +- (NSArray *)directoryPathComponents; // expected-note {{method definition for 'directoryPathComponents' not found}} +- (unsigned int)currentPathComponentIndex; // expected-note {{method definition for 'currentPathComponentIndex' not found}} +- (void)setCurrentPathComponentIndex:(unsigned int)aCurrentPathComponentIndex; // expected-note {{method definition for 'setCurrentPathComponentIndex:' not found}} +- (NSURL *)folderFeedURL; // expected-note {{method definition for 'folderFeedURL' not found}} @end -@implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject <IHGoogleDocsAdapterDelegate> *)owner { // expected-warning {{incomplete implementation}} \ -// expected-warning {{method definition for 'entries' not found}} \ -// expected-warning {{method definition for 'feedDocList' not found}} \ -// expected-warning {{method definition for 'directoryPathComponents' not found}} \ -// expected-warning {{method definition for 'currentPathComponentIndex' not found}} \ -// expected-warning {{method definition for 'setCurrentPathComponentIndex:' not found}} \ -// expected-warning {{method definition for 'folderFeedURL' not found}} +@implementation IHGoogleDocsAdapter - (id)initWithUsername:(NSString *)inUsername password:(NSString *)inPassword owner:(NSObject <IHGoogleDocsAdapterDelegate> *)owner { // expected-warning {{incomplete implementation}} return 0; } diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m index eb010157d6..dc1ef7b999 100644 --- a/test/Analysis/pr4209.m +++ b/test/Analysis/pr4209.m @@ -48,16 +48,14 @@ CMProfileLocation; @interface GBCategoryChooserPanelController : NSWindowController { GSEbayCategory *rootCategory; } -- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories; --(NSString*) categoryID; +- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories; // expected-note {{method definition for 'categoryDictionaryForCategoryID:inRootTreeCategories:' not found}} +-(NSString*) categoryID; // expected-note {{method definition for 'categoryID' not found}} @end @interface GSEbayCategory : NSObject <NSCoding> { } - (int) categoryID; - (GSEbayCategory *) parent; - (GSEbayCategory*) subcategoryWithID:(int) inID; -@end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent { // expected-warning {{incomplete implementation}} \ -// expected-warning {{method definition for 'categoryDictionaryForCategoryID:inRootTreeCategories:' not found}} \ -// expected-warning {{method definition for 'categoryID' not found}} +@end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent { // expected-warning {{incomplete implementation}} return 0; } - (void) addCategory:(EBayCategoryType*)inCategory toRootTreeCategory:(NSMutableArray*)inRootTreeCategories { diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m index 24324f8500..bf2aa53e8f 100644 --- a/test/SemaObjC/category-1.m +++ b/test/SemaObjC/category-1.m @@ -62,16 +62,16 @@ // <rdar://problem/7249233> @protocol MultipleCat_P --(void) im0; +-(void) im0; // expected-note {{method definition for 'im0' not found}} @end -@interface MultipleCat_I @end +@interface MultipleCat_I @end // expected-note {{required for direct or indirect protocol 'MultipleCat_P'}} @interface MultipleCat_I() @end @interface MultipleCat_I() <MultipleCat_P> @end -@implementation MultipleCat_I // expected-warning {{incomplete implementation}}, expected-warning {{method definition for 'im0' not found}} +@implementation MultipleCat_I // expected-warning {{incomplete implementation}} @end // <rdar://problem/7680391> - Handle nameless categories with no name that refer diff --git a/test/SemaObjC/compare-qualified-id.m b/test/SemaObjC/compare-qualified-id.m index 497a1b6afd..f4ec254028 100644 --- a/test/SemaObjC/compare-qualified-id.m +++ b/test/SemaObjC/compare-qualified-id.m @@ -5,7 +5,7 @@ typedef unsigned int NSUInteger; typedef struct _NSZone NSZone; @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; @protocol NSObject - (BOOL)isEqual:(id)object; @end -@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end +@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end // expected-note {{method definition for 'copyWithZone:' not found}} @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end @interface NSObject <NSObject> {} @end @@ -15,7 +15,7 @@ typedef struct {} NSFastEnumerationState; @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; @end extern NSString * const NSTaskDidTerminateNotification; -@interface XCPropertyExpansionContext : NSObject <NSCopying> { +@interface XCPropertyExpansionContext : NSObject <NSCopying> { // expected-note {{required for direct or indirect protocol 'NSCopying'}} NSMutableDictionary * _propNamesToPropValuesCache; } @end @@ -23,8 +23,7 @@ extern NSString * const NSTaskDidTerminateNotification; - (NSString *)evaluateAsStringInContext:(XCPropertyExpansionContext *)context withNestingState:(const void *)state; @end -@implementation XCPropertyExpansionContext // expected-warning {{method definition for 'copyWithZone:' not found}} \ - // expected-warning {{incomplete implementation}} +@implementation XCPropertyExpansionContext // expected-warning {{incomplete implementation}} - (NSString *)expandedValueForProperty:(NSString *)property { id <XCPropertyValues> cachedValueNode = [_propNamesToPropValuesCache objectForKey:property]; // expected-warning {{method '-objectForKey:' not found (return type defaults to 'id')}} if (cachedValueNode == ((void *)0)) { } diff --git a/test/SemaObjC/conditional-expr.m b/test/SemaObjC/conditional-expr.m index 914e3cabbf..1436f7ee0e 100644 --- a/test/SemaObjC/conditional-expr.m +++ b/test/SemaObjC/conditional-expr.m @@ -21,10 +21,10 @@ @end @interface DTFilterOutputStream2 -- nextOutputStream; +- nextOutputStream; // expected-note {{{{method definition for 'nextOutputStream' not found}} @end -@implementation DTFilterOutputStream2 // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'nextOutputStream' not found}} +@implementation DTFilterOutputStream2 // expected-warning {{incomplete implementation}} - (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; self = nextOutputStream; // expected-warning {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream2 *'}} diff --git a/test/SemaObjC/gcc-cast-ext.m b/test/SemaObjC/gcc-cast-ext.m index 28abfbc8b2..599e37d778 100644 --- a/test/SemaObjC/gcc-cast-ext.m +++ b/test/SemaObjC/gcc-cast-ext.m @@ -5,8 +5,8 @@ typedef struct _NSRange { } NSRange; @class PBXFileReference; @interface PBXDocBookmark -+ alloc; -- autorelease; ++ alloc; // expected-note {{{{method definition for 'alloc' not found}} +- autorelease; // expected-note {{{{method definition for 'autorelease' not found}} @end // GCC allows pointer expressions in integer constant expressions. @@ -14,7 +14,7 @@ struct { char control[((int)(char *)2)]; } xx; -@implementation PBXDocBookmark // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'autorelease' not found}} expected-warning {{method definition for 'alloc' not found}} +@implementation PBXDocBookmark // expected-warning {{incomplete implementation}} + (id)bookmarkWithFileReference:(PBXFileReference *)fileRef gylphRange:(NSRange)range anchor:(NSString *)htmlAnchor { diff --git a/test/SemaObjC/method-arg-decay.m b/test/SemaObjC/method-arg-decay.m index f600029fda..e62e7f3d18 100644 --- a/test/SemaObjC/method-arg-decay.m +++ b/test/SemaObjC/method-arg-decay.m @@ -56,7 +56,7 @@ PBXFindMatchContains, PBXFindMatchStartsWith, PBXFindMatchWholeWords, @interface PBXProjectModule : PBXModule <PBXFindableText> { } @end @class PBXBookmark; -@protocol PBXSelectionTarget - (NSObject <PBXSelectionTarget> *) performAction:(id)action withSelection:(NSArray *)selection; +@protocol PBXSelectionTarget - (NSObject <PBXSelectionTarget> *) performAction:(id)action withSelection:(NSArray *)selection; // expected-note {{method definition for 'performAction:withSelection:' not found}} @end @class XCPropertyDictionary, XCPropertyCondition, XCPropertyConditionSet, XCMutablePropertyConditionSet; extern NSMutableArray *XCFindPossibleKeyModules(PBXModule *module, BOOL useExposedModulesOnly); @interface NSString (StringUtilities) - (NSString *) trimToLength:(NSInteger)length preserveRange:(NSRange)range; @@ -67,14 +67,12 @@ extern NSMutableArray *XCFindPossibleKeyModules(PBXModule *module, BOOL useExpos @interface XCExtendedTabView : NSTabView <XCDockViewHeader> { } @end @class PBXProjectDocument, PBXFileReference, PBXModule, XCWindowTool; -@interface XCPerspectiveModule : PBXProjectModule <PBXSelectionTarget> { +@interface XCPerspectiveModule : PBXProjectModule <PBXSelectionTarget> { // expected-note {{required for direct or indirect protocol 'PBXSelectionTarget'}} XCExtendedTabView *_perspectivesTabView; } -- (PBXModule *) moduleForTab:(NSTabViewItem *)item; +- (PBXModule *) moduleForTab:(NSTabViewItem *)item; // expected-note {{method definition for 'moduleForTab:' not found}} @end -@implementation XCPerspectiveModule // expected-warning {{method definition for 'moduleForTab:' not found}} \ - // expected-warning {{method definition for 'performAction:withSelection:' not found}} \ - // expected-warning {{incomplete implementation}} +@implementation XCPerspectiveModule // expected-warning {{incomplete implementation}} + (void) openForProjectDocument:(PBXProjectDocument *)projectDocument { } - (PBXModule *) type:(Class)type inPerspective:(id)perspectiveIdentifer matchingFunction:(BOOL (void *, void *))comparator usingData:(void *)data { diff --git a/test/SemaObjC/method-undef-category-warn-1.m b/test/SemaObjC/method-undef-category-warn-1.m index 75ca5b5ff9..dace8ab294 100644 --- a/test/SemaObjC/method-undef-category-warn-1.m +++ b/test/SemaObjC/method-undef-category-warn-1.m @@ -1,30 +1,26 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -@interface MyClass1 +@interface MyClass1 // expected-note 2 {{required for direct or indirect protocol 'P'}} @end @protocol P -- (void) Pmeth; -- (void) Pmeth1; +- (void) Pmeth; // expected-note {{method definition for 'Pmeth' not found}} +- (void) Pmeth1; // expected-note {{method definition for 'Pmeth1' not found}} @end @interface MyClass1(CAT) <P> -- (void) meth2; +- (void) meth2; // expected-note {{method definition for 'meth2' not found}} @end -@implementation MyClass1(CAT) // expected-warning {{incomplete implementation}} \ - expected-warning {{method definition for 'meth2' not found}} \ - expected-warning {{method definition for 'Pmeth' not found}} +@implementation MyClass1(CAT) // expected-warning {{incomplete implementation}} - (void) Pmeth1{} @end @interface MyClass1(DOG) <P> -- (void)ppp; +- (void)ppp; // expected-note {{method definition for 'ppp' not found}} @end -@implementation MyClass1(DOG) // expected-warning {{incomplete implementation}} \ - expected-warning {{method definition for 'ppp' not found}} \ - expected-warning {{method definition for 'Pmeth1' not found}} +@implementation MyClass1(DOG) // expected-warning {{incomplete implementation}} - (void) Pmeth {} @end diff --git a/test/SemaObjC/method-undef-extension-warn-1.m b/test/SemaObjC/method-undef-extension-warn-1.m index fc27870f42..cd31754037 100644 --- a/test/SemaObjC/method-undef-extension-warn-1.m +++ b/test/SemaObjC/method-undef-extension-warn-1.m @@ -1,16 +1,16 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -@interface MyClass +@interface MyClass // expected-note {{required for direct or indirect protocol 'P'}} @end @protocol P - (void)Pmeth; -- (void)Pmeth1; +- (void)Pmeth1; // expected-note {{method definition for 'Pmeth1' not found}} @end // Class extension @interface MyClass () <P> -- (void)meth2; +- (void)meth2; // expected-note {{method definition for 'meth2' not found}} @end // Add a category to test that clang does not emit warning for this method. @@ -18,8 +18,6 @@ - (void)categoryMethod; @end -@implementation MyClass // expected-warning {{incomplete implementation}} \ - expected-warning {{method definition for 'meth2' not found}} \ - expected-warning {{method definition for 'Pmeth1' not found}} +@implementation MyClass // expected-warning {{incomplete implementation}} - (void)Pmeth {} @end diff --git a/test/SemaObjC/method-undefined-warn-1.m b/test/SemaObjC/method-undefined-warn-1.m index cfe1d56ee5..1ebc59e96b 100644 --- a/test/SemaObjC/method-undefined-warn-1.m +++ b/test/SemaObjC/method-undefined-warn-1.m @@ -3,12 +3,12 @@ @interface INTF - (void) meth; - (void) meth : (int) arg1; -- (int) int_meth; -+ (int) cls_meth; -+ (void) cls_meth1 : (int) arg1; +- (int) int_meth; // expected-note {{method definition for 'int_meth' not found}} ++ (int) cls_meth; // expected-note {{method definition for 'cls_meth' not found}} ++ (void) cls_meth1 : (int) arg1; // expected-note {{method definition for 'cls_meth1:' not found}} @end -@implementation INTF // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'int_meth' not found}} expected-warning {{method definition for 'cls_meth' not found}} expected-warning {{method definition for 'cls_meth1:' not found}} +@implementation INTF // expected-warning {{incomplete implementation}} - (void) meth {} - (void) meth : (int) arg2{} - (void) cls_meth1 : (int) arg2{} @@ -17,12 +17,12 @@ @interface INTF1 - (void) meth; - (void) meth : (int) arg1; -- (int) int_meth; -+ (int) cls_meth; -+ (void) cls_meth1 : (int) arg1; +- (int) int_meth; // expected-note {{method definition for 'int_meth' not found}} ++ (int) cls_meth; // expected-note {{method definition for 'cls_meth' not found}} ++ (void) cls_meth1 : (int) arg1; // expected-note {{method definition for 'cls_meth1:' not found}} @end -@implementation INTF1 // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'int_meth' not found}} expected-warning {{method definition for 'cls_meth' not found}} expected-warning {{method definition for 'cls_meth1:' not found}} +@implementation INTF1 // expected-warning {{incomplete implementation}} - (void) meth {} - (void) meth : (int) arg2{} - (void) cls_meth1 : (int) arg2{} diff --git a/test/SemaObjC/undef-protocol-methods-1.m b/test/SemaObjC/undef-protocol-methods-1.m index 9a35ef7ba8..6871ff06fc 100644 --- a/test/SemaObjC/undef-protocol-methods-1.m +++ b/test/SemaObjC/undef-protocol-methods-1.m @@ -1,40 +1,34 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s @protocol P1 -- (void) P1proto; -+ (void) ClsP1Proto; +- (void) P1proto; // expected-note {{method definition for 'P1proto' not found}} ++ (void) ClsP1Proto; // expected-note {{method definition for 'ClsP1Proto' not found}} - (void) DefP1proto; @end @protocol P2 -- (void) P2proto; -+ (void) ClsP2Proto; +- (void) P2proto; // expected-note {{method definition for 'P2proto' not found}} ++ (void) ClsP2Proto; // expected-note {{method definition for 'ClsP2Proto' not found}} @end @protocol P3<P2> -- (void) P3proto; -+ (void) ClsP3Proto; +- (void) P3proto; // expected-note {{method definition for 'P3proto' not found}} ++ (void) ClsP3Proto; // expected-note {{method definition for 'ClsP3Proto' not found}} + (void) DefClsP3Proto; @end @protocol PROTO<P1, P3> -- (void) meth; -- (void) meth : (int) arg1; -+ (void) cls_meth : (int) arg1; +- (void) meth; // expected-note {{method definition for 'meth' not found}} +- (void) meth : (int) arg1; // expected-note {{method definition for 'meth:' not found}} ++ (void) cls_meth : (int) arg1; // expected-note {{method definition for 'cls_meth:' not found}} @end -@interface INTF <PROTO> +@interface INTF <PROTO> // expected-note 3 {{required for direct or indirect protocol 'PROTO'}} \ + // expected-note 2 {{required for direct or indirect protocol 'P1'}} \ + // expected-note 2 {{required for direct or indirect protocol 'P3'}} \ + // expected-note 2 {{required for direct or indirect protocol 'P2'}} @end -@implementation INTF // expected-warning {{incomplete implementation}} \ - expected-warning {{method definition for 'meth' not found}} \ - expected-warning {{method definition for 'meth:' not found}} \ - expected-warning {{method definition for 'cls_meth:' not found}} \ - expected-warning {{method definition for 'P3proto' not found}} \ - expected-warning {{method definition for 'ClsP3Proto' not found}} \ - expected-warning {{method definition for 'P2proto' not found}} \ - expected-warning {{method definition for 'ClsP2Proto' not found}} \ - expected-warning {{method definition for 'ClsP1Proto' not found}} \ - expected-warning {{method definition for 'P1proto' not found}} +@implementation INTF // expected-warning {{incomplete implementation}} - (void) DefP1proto{} + (void) DefClsP3Proto{} |