]> granicus.if.org Git - clang/commitdiff
Place duplicate argument declaration in in
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 12 Mar 2011 18:54:30 +0000 (18:54 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 12 Mar 2011 18:54:30 +0000 (18:54 +0000)
method prototypes under the -Wduplicate-method-arg and
turn it off by default.

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

include/clang/Basic/DiagnosticCommonKinds.td
include/clang/Basic/DiagnosticGroups.td
include/clang/Parse/Parser.h
include/clang/Sema/Sema.h
lib/Parse/ParseObjc.cpp
lib/Sema/SemaDeclObjC.cpp
test/SemaObjC/method-prototype-scope.m

index 85c64c5cef6593284d1045bf409df1ccf8cf7400..0b0bca0395cb685fd8710cdb691605686fb953d8 100644 (file)
@@ -45,6 +45,8 @@ def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
   InGroup<MissingDeclarations>;
 def err_param_redefinition : Error<"redefinition of parameter %0">;
 def warn_method_param_redefinition : Warning<"redefinition of method parameter %0">;
+def warn_method_param_declaration : Warning<"redeclaration of method parameter %0">,
+  InGroup<DuplicateArgDecl>, DefaultIgnore;
 def err_invalid_storage_class_in_func_decl : Error<
   "invalid storage class specifier in function declarator">;
 def err_expected_namespace_name : Error<"expected namespace name">;
index 33d5016ffb6cdd13e5d295743ad4d863be7f5ec3..e5cd51c96cf8032509938108c38fc965eeba003a 100644 (file)
@@ -168,6 +168,7 @@ def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
 def : DiagGroup<"write-strings">;
 def CharSubscript : DiagGroup<"char-subscripts">;
 def LargeByValueCopy : DiagGroup<"large-by-value-copy">;
+def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
 
 // Aggregation warning settings.
 
index 1afc3c94df897c8dc551d94c49b06218350113ee..d39fa47cf03f71f2c32a7cbb20a80b3e9f34fe30 100644 (file)
@@ -1001,10 +1001,12 @@ private:
   ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, ObjCTypeNameContext Context);
   void ParseObjCMethodRequirement();
   Decl *ParseObjCMethodPrototype(Decl *classOrCat,
-            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
+            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
+            bool MethodDefinition = true);
   Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
                                 Decl *classDecl,
-            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
+            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
+            bool MethodDefinition=true);
   void ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl);
 
   Decl *ParseObjCMethodDefinition();
index 0ba1f2e27819a8e8afdaf069ca7d6a9399feeb54..51cff569605dcdb81828c6af39a452691a7fb479 100644 (file)
@@ -4559,7 +4559,7 @@ public:
     ObjCArgInfo *ArgInfo,
     DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
     AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
-    bool isVariadic = false);
+    bool isVariadic, bool MethodDefinition);
 
   // Helper method for ActOnClassMethod/ActOnInstanceMethod.
   // Will search "local" class/category implementations for a method decl.
index b6b1551907f5cb82e081eacca64b45905cd7626f..4b702e07618e00dbfeded2d576dd80af58502ec1 100644 (file)
@@ -327,7 +327,7 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl,
     // If this is a method prototype, parse it.
     if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
       Decl *methodPrototype =
-        ParseObjCMethodPrototype(interfaceDecl, MethodImplKind);
+        ParseObjCMethodPrototype(interfaceDecl, MethodImplKind, false);
       allMethods.push_back(methodPrototype);
       // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
       // method definitions.
@@ -340,7 +340,7 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl,
       ParseObjCMethodDecl(Tok.getLocation(), 
                           tok::minus, 
                           interfaceDecl,
-                          MethodImplKind);
+                          MethodImplKind, false);
       continue;
     }
     // Ignore excess semicolons.
@@ -582,12 +582,14 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl) {
 ///     __attribute__((deprecated))
 ///
 Decl *Parser::ParseObjCMethodPrototype(Decl *IDecl,
-                                       tok::ObjCKeywordKind MethodImplKind) {
+                                       tok::ObjCKeywordKind MethodImplKind,
+                                       bool MethodDefinition) {
   assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
 
   tok::TokenKind methodType = Tok.getKind();
   SourceLocation mLoc = ConsumeToken();
-  Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind);
+  Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind,
+                                    MethodDefinition);
   // Since this rule is used for both method declarations and definitions,
   // the caller is (optionally) responsible for consuming the ';'.
   return MDecl;
@@ -824,7 +826,8 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
 Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
                                   tok::TokenKind mType,
                                   Decl *IDecl,
-                                  tok::ObjCKeywordKind MethodImplKind) {
+                                  tok::ObjCKeywordKind MethodImplKind,
+                                  bool MethodDefinition) {
   ParsingDeclRAIIObject PD(*this);
 
   if (Tok.is(tok::code_completion)) {
@@ -875,7 +878,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
                                           mType, IDecl, DSRet, ReturnType, Sel,
                                           0, 
                                           CParamInfo.data(), CParamInfo.size(),
-                                          attrs.getList(), MethodImplKind);
+                                          attrs.getList(), MethodImplKind, false, 
+                                          MethodDefinition);
     PD.complete(Result);
     return Result;
   }
@@ -996,7 +1000,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
                                         &ArgInfos[0], 
                                         CParamInfo.data(), CParamInfo.size(),
                                         attrs.getList(),
-                                        MethodImplKind, isVariadic);
+                                        MethodImplKind, isVariadic, MethodDefinition);
   // Leave prototype scope.
   PrototypeScope.Exit();
   
index d34b00031df5db195332f51cf056f5c4ddef8277..8717385b51658a95f373381122e98d07aa0db519 100644 (file)
@@ -1736,7 +1736,7 @@ Decl *Sema::ActOnMethodDeclaration(
     ObjCArgInfo *ArgInfo,
     DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
     AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
-    bool isVariadic) {
+    bool isVariadic, bool MethodDefinition) {
   // Make sure we can establish a context for the method.
   if (!ClassDecl) {
     Diag(MethodLoc, diag::error_missing_method_context);
@@ -1789,8 +1789,9 @@ Decl *Sema::ActOnMethodDeclaration(
     if (R.isSingleResult()) {
       NamedDecl *PrevDecl = R.getFoundDecl();
       if (S->isDeclScope(PrevDecl)) {
-        // FIXME. This should be an error; but will break projects.
-        Diag(ArgInfo[i].NameLoc, diag::warn_method_param_redefinition) 
+        Diag(ArgInfo[i].NameLoc, 
+             (MethodDefinition ? diag::warn_method_param_redefinition 
+                               : diag::warn_method_param_declaration)) 
           << ArgInfo[i].Name;
         Diag(PrevDecl->getLocation(), 
              diag::note_previous_declaration);
index 2184172f35c90e5008d0db84d010fba8fa6014f2..b08faa65b22a39016f74f475200c4eedf482d37f 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -fsyntax-only -verify %s
+// RUN: %clang_cc1  -fsyntax-only -Wduplicate-method-arg -verify %s
 
 // rdar://8877730
 
@@ -11,7 +11,7 @@ int object;
 
 - doSomethingElseWith:(id)object;
 
-- (NSString *)doSomethingWith:(NSString *)object and:(NSArray *)object; // expected-warning {{redefinition of method parameter 'object'}} \
+- (NSString *)doSomethingWith:(NSString *)object and:(NSArray *)object; // expected-warning {{redeclaration of method parameter 'object'}} \
                                          // expected-note {{previous declaration is here}}
 @end