[cfe-commits] r115347 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/FixIt/fixit.cpp test/SemaCXX/class.cpp test/SemaCXX/nested-name-spec.cpp
Francois Pichet
pichet2000 at gmail.com
Fri Oct 1 14:19:28 PDT 2010
Author: fpichet
Date: Fri Oct 1 16:19:28 2010
New Revision: 115347
URL: http://llvm.org/viewvc/llvm-project?rev=115347&view=rev
Log:
Better diagnostic for superfluous scope specifier inside a class definition for member functions. + Fixit.
Example:
class A {
void A::foo(); //warning: extra qualification on member 'foo'
};
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/FixIt/fixit.cpp
cfe/trunk/test/SemaCXX/class.cpp
cfe/trunk/test/SemaCXX/nested-name-spec.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=115347&r1=115346&r2=115347&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Oct 1 16:19:28 2010
@@ -2140,6 +2140,8 @@
def ext_out_of_line_declaration : ExtWarn<
"out-of-line declaration of a member must be a definition">,
InGroup<OutOfLineDeclaration>, DefaultError;
+def warn_member_extra_qualification : Warning<
+ "extra qualification on member %0">;
def note_member_def_close_match : Note<"member declaration nearly matches">;
def err_typecheck_ivar_variable_size : Error<
"instance variables must have a constant size">;
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=115347&r1=115346&r2=115347&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Oct 1 16:19:28 2010
@@ -3687,51 +3687,61 @@
}
if (D.getCXXScopeSpec().isSet() && !NewFD->isInvalidDecl()) {
- // Fake up an access specifier if it's supposed to be a class member.
- if (!Redeclaration && isa<CXXRecordDecl>(NewFD->getDeclContext()))
- NewFD->setAccess(AS_public);
-
- // An out-of-line member function declaration must also be a
- // definition (C++ [dcl.meaning]p1).
- // Note that this is not the case for explicit specializations of
- // function templates or member functions of class templates, per
- // C++ [temp.expl.spec]p2. We also allow these declarations as an extension
- // for compatibility with old SWIG code which likes to generate them.
- if (!IsFunctionDefinition && !isFriend &&
- !isFunctionTemplateSpecialization && !isExplicitSpecialization) {
- Diag(NewFD->getLocation(), diag::ext_out_of_line_declaration)
- << D.getCXXScopeSpec().getRange();
- }
- if (!Redeclaration && !(isFriend && CurContext->isDependentContext())) {
- // The user tried to provide an out-of-line definition for a
- // function that is a member of a class or namespace, but there
- // was no such member function declared (C++ [class.mfct]p2,
- // C++ [namespace.memdef]p2). For example:
+ if (!CurContext->isRecord()) {
+ // Fake up an access specifier if it's supposed to be a class member.
+ if (!Redeclaration && isa<CXXRecordDecl>(NewFD->getDeclContext()))
+ NewFD->setAccess(AS_public);
+
+ // An out-of-line member function declaration must also be a
+ // definition (C++ [dcl.meaning]p1).
+ // Note that this is not the case for explicit specializations of
+ // function templates or member functions of class templates, per
+ // C++ [temp.expl.spec]p2. We also allow these declarations as an extension
+ // for compatibility with old SWIG code which likes to generate them.
+ if (!IsFunctionDefinition && !isFriend &&
+ !isFunctionTemplateSpecialization && !isExplicitSpecialization) {
+ Diag(NewFD->getLocation(), diag::ext_out_of_line_declaration)
+ << D.getCXXScopeSpec().getRange();
+ }
+ if (!Redeclaration && !(isFriend && CurContext->isDependentContext())) {
+ // The user tried to provide an out-of-line definition for a
+ // function that is a member of a class or namespace, but there
+ // was no such member function declared (C++ [class.mfct]p2,
+ // C++ [namespace.memdef]p2). For example:
+ //
+ // class X {
+ // void f() const;
+ // };
+ //
+ // void X::f() { } // ill-formed
+ //
+ // Complain about this problem, and attempt to suggest close
+ // matches (e.g., those that differ only in cv-qualifiers and
+ // whether the parameter types are references).
+ Diag(D.getIdentifierLoc(), diag::err_member_def_does_not_match)
+ << Name << DC << D.getCXXScopeSpec().getRange();
+ NewFD->setInvalidDecl();
+
+ LookupResult Prev(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+ ForRedeclaration);
+ LookupQualifiedName(Prev, DC);
+ assert(!Prev.isAmbiguous() &&
+ "Cannot have an ambiguity in previous-declaration lookup");
+ for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
+ Func != FuncEnd; ++Func) {
+ if (isa<FunctionDecl>(*Func) &&
+ isNearlyMatchingFunction(Context, cast<FunctionDecl>(*Func), NewFD))
+ Diag((*Func)->getLocation(), diag::note_member_def_close_match);
+ }
+ }
+ } else if (!isFriend) {
+ // The user provided a superfluous scope specifier inside a class definition:
//
// class X {
- // void f() const;
+ // void X::f();
// };
- //
- // void X::f() { } // ill-formed
- //
- // Complain about this problem, and attempt to suggest close
- // matches (e.g., those that differ only in cv-qualifiers and
- // whether the parameter types are references).
- Diag(D.getIdentifierLoc(), diag::err_member_def_does_not_match)
- << Name << DC << D.getCXXScopeSpec().getRange();
- NewFD->setInvalidDecl();
-
- LookupResult Prev(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
- ForRedeclaration);
- LookupQualifiedName(Prev, DC);
- assert(!Prev.isAmbiguous() &&
- "Cannot have an ambiguity in previous-declaration lookup");
- for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
- Func != FuncEnd; ++Func) {
- if (isa<FunctionDecl>(*Func) &&
- isNearlyMatchingFunction(Context, cast<FunctionDecl>(*Func), NewFD))
- Diag((*Func)->getLocation(), diag::note_member_def_close_match);
- }
+ Diag(NewFD->getLocation(), diag::warn_member_extra_qualification)
+ << Name << FixItHint::CreateRemoval(D.getCXXScopeSpec().getRange());
}
}
Modified: cfe/trunk/test/FixIt/fixit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit.cpp?rev=115347&r1=115346&r2=115347&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit.cpp (original)
+++ cfe/trunk/test/FixIt/fixit.cpp Fri Oct 1 16:19:28 2010
@@ -66,3 +66,8 @@
// typedef CT<1> mainT(void);
// mainT main; // TODO
+// extra qualification on member
+class C {
+ int C::foo();
+};
+
Modified: cfe/trunk/test/SemaCXX/class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class.cpp?rev=115347&r1=115346&r2=115347&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/class.cpp (original)
+++ cfe/trunk/test/SemaCXX/class.cpp Fri Oct 1 16:19:28 2010
@@ -117,7 +117,7 @@
struct S
{
void f(); // expected-note 1 {{previous declaration}}
- void S::f() {} // expected-error {{class member cannot be redeclared}} expected-note {{previous declaration}} expected-note {{previous definition}}
+ void S::f() {} // expected-warning {{extra qualification on member}} expected-error {{class member cannot be redeclared}} expected-note {{previous declaration}} expected-note {{previous definition}}
void f() {} // expected-error {{class member cannot be redeclared}} expected-error {{redefinition}}
};
Modified: cfe/trunk/test/SemaCXX/nested-name-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nested-name-spec.cpp?rev=115347&r1=115346&r2=115347&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original)
+++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Fri Oct 1 16:19:28 2010
@@ -244,3 +244,7 @@
return false;
}
}
+
+class CLASS {
+ void CLASS::foo2(); // expected-warning {{extra qualification on member 'foo2'}}
+};
More information about the cfe-commits
mailing list