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'
};

llvm-svn: 115347
This commit is contained in:
Francois Pichet 2010-10-01 21:19:28 +00:00
parent e6712983d2
commit 6d76e6cd92
5 changed files with 63 additions and 42 deletions

View File

@ -2140,6 +2140,8 @@ def err_qualified_param_declarator : Error<
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">;

View File

@ -3687,6 +3687,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
}
if (D.getCXXScopeSpec().isSet() && !NewFD->isInvalidDecl()) {
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);
@ -3733,6 +3734,15 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
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 X::f();
// };
Diag(NewFD->getLocation(), diag::warn_member_extra_qualification)
<< Name << FixItHint::CreateRemoval(D.getCXXScopeSpec().getRange());
}
}
// Handle attributes. We need to have merged decls when handling attributes

View File

@ -66,3 +66,8 @@ CT<1> main(void); // expected-error{{'main' must return 'int'}}
// typedef CT<1> mainT(void);
// mainT main; // TODO
// extra qualification on member
class C {
int C::foo();
};

View File

@ -117,7 +117,7 @@ struct C4 {
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}}
};

View File

@ -244,3 +244,7 @@ namespace PR7133 {
return false;
}
}
class CLASS {
void CLASS::foo2(); // expected-warning {{extra qualification on member 'foo2'}}
};