[cfe-commits] r116445 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/nested-name-spec.cpp
Douglas Gregor
dgregor at apple.com
Wed Oct 13 15:19:53 PDT 2010
Author: dgregor
Date: Wed Oct 13 17:19:53 2010
New Revision: 116445
URL: http://llvm.org/viewvc/llvm-project?rev=116445&view=rev
Log:
Generalize the checking for qualification of (non-friend) class
members. Provide a hard error when the qualification doesn't match the
current class type, or a warning + Fix-it if it does match the current
class type. Fixes PR8159.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.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=116445&r1=116444&r2=116445&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Oct 13 17:19:53 2010
@@ -2167,6 +2167,8 @@
InGroup<OutOfLineDeclaration>, DefaultError;
def warn_member_extra_qualification : Warning<
"extra qualification on member %0">;
+def err_member_qualification : Error<
+ "non-friend class member %0 cannot have a qualified name">;
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=116445&r1=116444&r2=116445&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Oct 13 17:19:53 2010
@@ -2265,11 +2265,30 @@
RequireCompleteDeclContext(D.getCXXScopeSpec(), DC))
return 0;
- if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) {
- Diag(D.getIdentifierLoc(),
- diag::err_member_def_undefined_record)
- << Name << DC << D.getCXXScopeSpec().getRange();
- D.setInvalidType();
+ if (isa<CXXRecordDecl>(DC)) {
+ if (!cast<CXXRecordDecl>(DC)->hasDefinition()) {
+ Diag(D.getIdentifierLoc(),
+ diag::err_member_def_undefined_record)
+ << Name << DC << D.getCXXScopeSpec().getRange();
+ D.setInvalidType();
+ } else if (isa<CXXRecordDecl>(CurContext) &&
+ !D.getDeclSpec().isFriendSpecified()) {
+ // The user provided a superfluous scope specifier inside a class
+ // definition:
+ //
+ // class X {
+ // void X::f();
+ // };
+ if (CurContext->Equals(DC))
+ Diag(D.getIdentifierLoc(), diag::warn_member_extra_qualification)
+ << Name << FixItHint::CreateRemoval(D.getCXXScopeSpec().getRange());
+ else
+ Diag(D.getIdentifierLoc(), diag::err_member_qualification)
+ << Name << D.getCXXScopeSpec().getRange();
+
+ // Pretend that this qualifier was not here.
+ D.getCXXScopeSpec().clear();
+ }
}
// Check whether we need to rebuild the type of the given
@@ -3684,18 +3703,6 @@
if (NewFD->isInvalidDecl()) {
// Ignore all the rest of this.
-
- } else if (CurContext->isRecord() && D.getCXXScopeSpec().isSet() &&
- !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());
-
} else if (!Redeclaration) {
// Fake up an access specifier if it's supposed to be a class member.
if (isa<CXXRecordDecl>(NewFD->getDeclContext()))
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=116445&r1=116444&r2=116445&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Oct 13 17:19:53 2010
@@ -896,6 +896,27 @@
Decl *Member;
if (isInstField) {
+ CXXScopeSpec &SS = D.getCXXScopeSpec();
+
+
+ if (SS.isSet() && !SS.isInvalid()) {
+ // The user provided a superfluous scope specifier inside a class
+ // definition:
+ //
+ // class X {
+ // int X::member;
+ // };
+ DeclContext *DC = 0;
+ if ((DC = computeDeclContext(SS, false)) && DC->Equals(CurContext))
+ Diag(D.getIdentifierLoc(), diag::warn_member_extra_qualification)
+ << Name << FixItHint::CreateRemoval(SS.getRange());
+ else
+ Diag(D.getIdentifierLoc(), diag::err_member_qualification)
+ << Name << SS.getRange();
+
+ SS.clear();
+ }
+
// FIXME: Check for template parameters!
Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth,
AS);
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=116445&r1=116444&r2=116445&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original)
+++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Wed Oct 13 17:19:53 2010
@@ -248,3 +248,13 @@
class CLASS {
void CLASS::foo2(); // expected-warning {{extra qualification on member 'foo2'}}
};
+
+namespace PR8159 {
+ class B { };
+
+ class A {
+ int A::a; // expected-warning{{extra qualification on member 'a'}}
+ static int A::b; // expected-warning{{extra qualification on member 'b'}}
+ int ::c; // expected-error{{non-friend class member 'c' cannot have a qualified name}}
+ };
+}
More information about the cfe-commits
mailing list