diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-10-13 22:19:53 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-10-13 22:19:53 +0000 |
| commit | a007d36c1bad5941ad81dcea44a34af253bc4c65 (patch) | |
| tree | 7f5251d49fa78725877c64a249df11feb6f57fea /clang/lib | |
| parent | 16db3287c04f316510583950313aeb365592ad5a (diff) | |
| download | bcm5719-llvm-a007d36c1bad5941ad81dcea44a34af253bc4c65.tar.gz bcm5719-llvm-a007d36c1bad5941ad81dcea44a34af253bc4c65.zip | |
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.
llvm-svn: 116445
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 41 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 21 |
2 files changed, 45 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a34d7ecf63e..10785270e5b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2265,11 +2265,30 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, 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 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, 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())) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 55f668b5c51..a63f057ae0a 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -896,6 +896,27 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, 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); |

