aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-03-12 18:54:30 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-03-12 18:54:30 +0000
commit90ba78c64d0c24cfbc1bf88728db9775d44d7f9f (patch)
tree412a422295ab8937ff2245cabb8ed6c7e277ca6b
parentf9c32eb0f80f991cbb3fc3e403759f39929f7994 (diff)
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
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticGroups.td1
-rw-r--r--include/clang/Parse/Parser.h6
-rw-r--r--include/clang/Sema/Sema.h2
-rw-r--r--lib/Parse/ParseObjc.cpp18
-rw-r--r--lib/Sema/SemaDeclObjC.cpp7
-rw-r--r--test/SemaObjC/method-prototype-scope.m4
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<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">;
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