def warn_cstyle_param : Warning<
"use of C-style parameters in Objective-C method declarations"
" is deprecated">, InGroup<DeprecatedDeclarations>;
+def warn_missing_argument_name : Warning<
+ "no parameter name in the middle of a selector"
+ " may result in incomplete selector name">,
+ InGroup<DiagGroup<"missing-argument-name-in-selector">>, DefaultIgnore;
+def note_missing_argument_name : Note<
+ "did you mean %0 as the selector name">;
let CategoryName = "ARC Parse Issue" in {
def err_arc_bridge_retain : Error<
Scope::FunctionPrototypeScope|Scope::DeclScope);
AttributePool allParamAttrs(AttrFactory);
-
+ bool warnSelectorName = false;
while (1) {
ParsedAttributes paramAttrs(AttrFactory);
Sema::ObjCArgInfo ArgInfo;
// Check for another keyword selector.
SelIdent = ParseObjCSelectorPiece(selLoc);
- if (!SelIdent && Tok.isNot(tok::colon))
- break;
+ if (!SelIdent) {
+ if (Tok.isNot(tok::colon))
+ break;
+ // parameter name was not followed with selector name; as in:
+ // - (void) Meth: (id) Name:(id)Arg2; Issue a warning as user
+ // might have meant: - (void) Meth: (id)Arg1 Name:(id)Arg2;
+ Diag(Tok, diag::warn_missing_argument_name); // missing argument name.
+ warnSelectorName = true;
+ }
+
// We have a selector or a colon, continue parsing.
}
Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
&KeyIdents[0]);
+ if (warnSelectorName)
+ Diag(mLoc, diag::note_missing_argument_name) << Sel.getAsString();
+
Decl *Result
= Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
mType, DSRet, ReturnType,
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class -Wmissing-argument-name-in-selector %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class -Wmissing-argument-name-in-selector %s
+// rdar://12263549
+
+@interface Super @end
+@interface INTF : Super
+-(void) Name1:(id)Arg1 Name2:(id)Arg2; // Name1:Name2:
+-(void) Name1:(id) Name2:(id)Arg2; // expected-warning {{no parameter name in the middle of a selector may result in incomplete selector name}} \
+ // expected-note {{did you mean Name1:: as the selector name}}
+-(void) Name1:(id)Arg1 Name2:(id)Arg2 Name3:(id)Arg3; // Name1:Name2:Name3:
+-(void) Name1:(id)Arg1 Name2:(id) Name3:(id)Arg3; // expected-warning {{no parameter name in the middle of a selector may result in incomplete selector name}} \
+ // expected-note {{did you mean Name1:Name2:: as the selector name}}
+@end
+
+@implementation INTF
+-(void) Name1:(id)Arg1 Name2:(id)Arg2{}
+-(void) Name1:(id) Name2:(id)Arg2 {} // expected-warning {{no parameter name in the middle of a selector may result in incomplete selector name}} \
+ // expected-note {{did you mean Name1:: as the selector name}}
+-(void) Name1:(id)Arg1 Name2:(id)Arg2 Name3:(id)Arg3 {}
+-(void) Name1:(id)Arg1 Name2:(id) Name3:(id)Arg3 {} // expected-warning {{no parameter name in the middle of a selector may result in incomplete selector name}} \
+ // expected-note {{did you mean Name1:Name2:: as the selector name}}
+@end