From 90ba78c64d0c24cfbc1bf88728db9775d44d7f9f Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 12 Mar 2011 18:54:30 +0000 Subject: [PATCH] Place duplicate argument declaration in in 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 | 2 ++ include/clang/Basic/DiagnosticGroups.td | 1 + include/clang/Parse/Parser.h | 6 ++++-- include/clang/Sema/Sema.h | 2 +- lib/Parse/ParseObjc.cpp | 18 +++++++++++------- lib/Sema/SemaDeclObjC.cpp | 7 ++++--- test/SemaObjC/method-prototype-scope.m | 4 ++-- 7 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 85c64c5cef..0b0bca0395 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -45,6 +45,8 @@ def ext_no_declarators : ExtWarn<"declaration does not declare anything">, InGroup; 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, 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">; diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 33d5016ffb..e5cd51c96c 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -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. diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 1afc3c94df..d39fa47cf0 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -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(); diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 0ba1f2e278..51cff56960 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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. diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index b6b1551907..4b702e0761 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -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(); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index d34b00031d..8717385b51 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -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); diff --git a/test/SemaObjC/method-prototype-scope.m b/test/SemaObjC/method-prototype-scope.m index 2184172f35..b08faa65b2 100644 --- a/test/SemaObjC/method-prototype-scope.m +++ b/test/SemaObjC/method-prototype-scope.m @@ -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 -- 2.40.0