"selector element type %0 is not a valid object">;
def err_collection_expr_type : Error<
"collection expression type %0 is not a valid object">;
+def warn_collection_expr_type : Warning<
+ "collection expression type %0 may not respond to %1">;
def err_invalid_conversion_between_ext_vectors : Error<
"invalid conversion between ext-vector type %0 and %1">;
if (!SecondType->isObjCObjectPointerType())
Diag(ForLoc, diag::err_collection_expr_type)
<< SecondType << Second->getSourceRange();
+ else if (const ObjCObjectPointerType *OPT =
+ SecondType->getAsObjCInterfacePointerType()) {
+ llvm::SmallVector<IdentifierInfo *, 4> KeyIdents;
+ IdentifierInfo* selIdent =
+ &Context.Idents.get("countByEnumeratingWithState");
+ KeyIdents.push_back(selIdent);
+ selIdent = &Context.Idents.get("objects");
+ KeyIdents.push_back(selIdent);
+ selIdent = &Context.Idents.get("count");
+ KeyIdents.push_back(selIdent);
+ Selector CSelector = Context.Selectors.getSelector(3, &KeyIdents[0]);
+ if (ObjCInterfaceDecl *IDecl = OPT->getInterfaceDecl()) {
+ if (!IDecl->isForwardDecl() &&
+ !IDecl->lookupInstanceMethod(CSelector)) {
+ // Must further look into privaye implementation methods.
+ if (!LookupPrivateInstanceMethod(CSelector, IDecl))
+ Diag(ForLoc, diag::warn_collection_expr_type)
+ << SecondType << CSelector << Second->getSourceRange();
+ }
+ }
+ }
}
first.release();
second.release();
p("array.length: %d\n", [array count]);
unsigned index = 0;
- for (NSString *i in array) {
+ for (NSString *i in array) { // expected-warning {{collection expression type 'NSArray *' may not respond}}
p("element %d: %s\n", index++, [i cString]);
}
}
p("array.length: %d\n", [array count]);
unsigned index = 0;
- for (NSString *i in array) {
+ for (NSString *i in array) { // expected-warning {{collection expression type 'NSArray *' may not respond}}
index++;
if (index == 10)
continue;