]> granicus.if.org Git - clang/commitdiff
objective-C: issue warning when there is no whitespace
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 17 Sep 2012 19:15:26 +0000 (19:15 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 17 Sep 2012 19:15:26 +0000 (19:15 +0000)
between objc method parameter name and colon.
// rdar://12263549

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164047 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseObjc.cpp
test/SemaObjC/unused.m
test/SemaObjC/warning-missing-selector-name.m [new file with mode: 0644]

index e4e339aefc467af7fd47883fa19e0afdf18e168f..218a6a31da4f7701c43ff1975fd0516b35afc0ca 100644 (file)
@@ -213,6 +213,12 @@ def err_expected_semi_after_static_assert : Error<
   "expected ';' after static_assert">;
 def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
 def err_expected_colon_after : Error<"expected ':' after %0">;
+def missing_selector_name : Warning<
+  "parameter name used as selector"
+  " may result in incomplete method selector name">,
+  InGroup<DiagGroup<"missing-argument-name-in-selector">>;
+def note_missing_argument_name : Note<
+  "did you mean to use %0 as the selector name instead of %1">;
 def err_label_end_of_compound_statement : Error<
   "label at end of compound statement: expected statement">;
 def err_address_of_label_outside_fn : Error<
index 1465a730e44d6f6bd28f2d8b403deeb7be341e0c..48c5efac6bab963a8edf1f1d9f129e00ee5292e6 100644 (file)
@@ -18,6 +18,7 @@
 #include "clang/Sema/PrettyDeclStackTrace.h"
 #include "clang/Sema/Scope.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
 using namespace clang;
 
 
@@ -1031,7 +1032,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
                             Scope::FunctionPrototypeScope|Scope::DeclScope);
 
   AttributePool allParamAttrs(AttrFactory);
-  
+  bool warnSelectorName = false;
   while (1) {
     ParsedAttributes paramAttrs(AttrFactory);
     Sema::ObjCArgInfo ArgInfo;
@@ -1102,6 +1103,13 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
     SelIdent = ParseObjCSelectorPiece(selLoc);
     if (!SelIdent && Tok.isNot(tok::colon))
       break;
+    if (MethodDefinition && !SelIdent) {
+      SourceLocation ColonLoc = Tok.getLocation();
+      if (PP.getLocForEndOfToken(ArgInfo.NameLoc) == ColonLoc) {
+        warnSelectorName = true;
+        Diag(ArgInfo.NameLoc, diag::missing_selector_name);
+      }
+    }
     // We have a selector or a colon, continue parsing.
   }
 
@@ -1142,6 +1150,22 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
   
   Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
                                                    &KeyIdents[0]);
+  if (warnSelectorName) {
+    SmallVector<IdentifierInfo *, 12> DiagKeyIdents;
+    for (unsigned i = 0, size = KeyIdents.size(); i < size; i++)
+      if (KeyIdents[i])
+        DiagKeyIdents.push_back(KeyIdents[i]);
+      else {
+        std::string name = "Name";
+        name += llvm::utostr(i+1);
+        IdentifierInfo *NamedMissingId = &PP.getIdentifierTable().get(name);
+        DiagKeyIdents.push_back(NamedMissingId);
+      }
+      Selector NewSel = 
+        PP.getSelectorTable().getSelector(DiagKeyIdents.size(), &DiagKeyIdents[0]);
+      Diag(mLoc, diag::note_missing_argument_name)
+        << NewSel.getAsString() << Sel.getAsString();
+  }
   Decl *Result
        = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
                                         mType, DSRet, ReturnType, 
index efaf9c8f3efcf7ae9e2c1d89e358e3aac87f35ae..23d7e8cbe50d24301b88d54d36792a7205ed1453 100644 (file)
@@ -29,8 +29,9 @@ void test2() {
 @end
 
 @implementation foo
-- (int) meth: (int)x: 
-(int)y: // expected-warning{{unused}} 
+- (int) meth: (int)x:  // expected-warning {{parameter name used as selector may result in incomplete method selector name}} \
+                       // expected-note {{did you mean to use meth:Name2:Name3: as the selector name instead of meth:::}}
+(int)y: // expected-warning{{unused}}  expected-warning {{parameter name used as selector may result in incomplete method selector name}}
 (int) __attribute__((unused))z { return x; }
 @end
 
diff --git a/test/SemaObjC/warning-missing-selector-name.m b/test/SemaObjC/warning-missing-selector-name.m
new file mode 100644 (file)
index 0000000..e4bde0b
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %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;
+-(void) Name1:(id)Arg1 Name2:(id)Arg2 Name3:(id)Arg3; // Name1:Name2:Name3:
+-(void) Name1:(id)Arg1 Name2:(id) Name3:(id)Arg3;
+@end
+
+@implementation INTF
+-(void) Name1:(id)Arg1 Name2:(id)Arg2{}
+-(void) Name1:(id) Name2:(id)Arg2 {} // expected-warning {{parameter name used as selector may result in incomplete method selector name}} \
+                                    // expected-note {{did you mean to use Name1:Name2: as the selector name instead of Name1::}}
+-(void) Name1:(id)Arg1 Name2:(id)Arg2 Name3:(id)Arg3 {}
+-(void) Name1:(id)Arg1 Name2:(id) Name3:(id)Arg3 {} // expected-warning {{parameter name used as selector may result in incomplete method selector name}} \
+                                                   // expected-note {{did you mean to use Name1:Name2:Name3: as the selector name instead of Name1:Name2::}}
+@end