diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-12-05 07:51:02 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-12-05 07:51:02 +0000 |
| commit | a230224be49263d36b3aa50c2088115a6a365542 (patch) | |
| tree | 5b9d6ac95be70182c92fd4c4af77d9e2d02e2a6b /clang/lib/Sema | |
| parent | 14e92c2c62878b574e694bb0f495ec5e3fcb7b8a (diff) | |
| download | bcm5719-llvm-a230224be49263d36b3aa50c2088115a6a365542.tar.gz bcm5719-llvm-a230224be49263d36b3aa50c2088115a6a365542.zip | |
Implement DR482: namespace members can be redeclared with a qualified name
within their namespace, and such a redeclaration isn't required to be a
definition any more.
Update DR status page to say Clang 3.4 instead of SVN and add new Clang 3.5
category (but keep Clang 3.4 yellow for now).
llvm-svn: 196481
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 39 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 18 |
2 files changed, 29 insertions, 28 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 17f19dc2065..451ebd254f3 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4115,33 +4115,31 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC, /// \returns true if we cannot safely recover from this error, false otherwise. bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, DeclarationName Name, - SourceLocation Loc) { + SourceLocation Loc) { DeclContext *Cur = CurContext; while (isa<LinkageSpecDecl>(Cur) || isa<CapturedDecl>(Cur)) Cur = Cur->getParent(); - - // C++ [dcl.meaning]p1: - // A declarator-id shall not be qualified except for the definition - // of a member function (9.3) or static data member (9.4) outside of - // its class, the definition or explicit instantiation of a function - // or variable member of a namespace outside of its namespace, or the - // definition of an explicit specialization outside of its namespace, - // or the declaration of a friend function that is a member of - // another class or namespace (11.3). [...] - - // The user provided a superfluous scope specifier that refers back to the - // class or namespaces in which the entity is already declared. + + // If the user provided a superfluous scope specifier that refers back to the + // class in which the entity is already declared, diagnose and ignore it. // // class X { // void X::f(); // }; + // + // Note, it was once ill-formed to give redundant qualification in all + // contexts, but that rule was removed by DR482. if (Cur->Equals(DC)) { - Diag(Loc, LangOpts.MicrosoftExt? diag::warn_member_extra_qualification - : diag::err_member_extra_qualification) - << Name << FixItHint::CreateRemoval(SS.getRange()); - SS.clear(); + if (Cur->isRecord()) { + Diag(Loc, LangOpts.MicrosoftExt ? diag::warn_member_extra_qualification + : diag::err_member_extra_qualification) + << Name << FixItHint::CreateRemoval(SS.getRange()); + SS.clear(); + } else { + Diag(Loc, diag::warn_namespace_member_extra_qualification) << Name; + } return false; - } + } // Check whether the qualifying scope encloses the scope of the original // declaration. @@ -7248,11 +7246,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - } else if (!D.isFunctionDefinition() && D.getCXXScopeSpec().isSet() && + } else if (!D.isFunctionDefinition() && + isa<CXXMethodDecl>(NewFD) && NewFD->isOutOfLine() && !isFriend && !isFunctionTemplateSpecialization && !isExplicitSpecialization) { // An out-of-line member function declaration must also be a - // definition (C++ [dcl.meaning]p1). + // definition (C++ [class.mfct]p2). // 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 diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 04912676140..162e46ecab1 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -12133,11 +12133,13 @@ void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) { // If there is no declaration, there was an error parsing it. if (D == 0 || D->isInvalidDecl()) return; - // We should only get called for declarations with scope specifiers, like: - // int foo::bar; - assert(D->isOutOfLine()); - EnterDeclaratorContext(S, D->getDeclContext()); - + // We will always have a nested name specifier here, but this declaration + // might not be out of line if the specifier names the current namespace: + // extern int n; + // int ::n = 0; + if (D->isOutOfLine()) + EnterDeclaratorContext(S, D->getDeclContext()); + // If we are parsing the initializer for a static data member, push a // new expression evaluation context that is associated with this static // data member. @@ -12152,10 +12154,10 @@ void Sema::ActOnCXXExitDeclInitializer(Scope *S, Decl *D) { if (D == 0 || D->isInvalidDecl()) return; if (isStaticDataMember(D)) - PopExpressionEvaluationContext(); + PopExpressionEvaluationContext(); - assert(D->isOutOfLine()); - ExitDeclaratorContext(S); + if (D->isOutOfLine()) + ExitDeclaratorContext(S); } /// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a |

