diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-05-05 02:13:49 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-05-05 02:13:49 +0000 |
| commit | 5cbeb75a994be6fd6a73f9d48a0a95337f743096 (patch) | |
| tree | cd13a3b1ea1ac3ef5c581c7977a658c499337f4d /clang/lib | |
| parent | 5ee54086251b7380c2997ff090311cdb739c17ea (diff) | |
| download | bcm5719-llvm-5cbeb75a994be6fd6a73f9d48a0a95337f743096.tar.gz bcm5719-llvm-5cbeb75a994be6fd6a73f9d48a0a95337f743096.zip | |
Fix implementation of C++'s restrictions on using-declarations referring to enumerators:
* an unscoped enumerator whose enumeration is a class member is itself a class
member, so can only be the subject of a class-scope using-declaration.
* a scoped enumerator cannot be the subject of a class-scope using-declaration.
llvm-svn: 268594
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 21db3be3ccf..f478f0419b2 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7738,7 +7738,7 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig, // function will silently decide not to build a shadow decl, which // will pre-empt further diagnostics. // - // We don't need to do this in C++0x because we do the check once on + // We don't need to do this in C++11 because we do the check once on // the qualifier. // // FIXME: diagnose the following if we care enough: @@ -8227,7 +8227,7 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, } } - // C++0x N2914 [namespace.udecl]p6: + // C++14 [namespace.udecl]p6: // A using-declaration shall not name a namespace. if (R.getAsSingle<NamespaceDecl>()) { Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace) @@ -8235,6 +8235,16 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, return BuildInvalid(); } + // C++14 [namespace.udecl]p7: + // A using-declaration shall not name a scoped enumerator. + if (auto *ED = R.getAsSingle<EnumConstantDecl>()) { + if (cast<EnumDecl>(ED->getDeclContext())->isScoped()) { + Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_scoped_enum) + << SS.getRange(); + return BuildInvalid(); + } + } + UsingDecl *UD = BuildValid(); // The normal rules do not apply to inheriting constructor declarations. @@ -8359,8 +8369,10 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc, // If we weren't able to compute a valid scope, it must be a // dependent class scope. - if (!NamedContext || NamedContext->isRecord()) { - auto *RD = dyn_cast_or_null<CXXRecordDecl>(NamedContext); + if (!NamedContext || NamedContext->getRedeclContext()->isRecord()) { + auto *RD = NamedContext + ? cast<CXXRecordDecl>(NamedContext->getRedeclContext()) + : nullptr; if (RD && RequireCompleteDeclContext(const_cast<CXXScopeSpec&>(SS), RD)) RD = nullptr; @@ -8444,7 +8456,7 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc, return true; if (getLangOpts().CPlusPlus11) { - // C++0x [namespace.udecl]p3: + // C++11 [namespace.udecl]p3: // In a using-declaration used as a member-declaration, the // nested-name-specifier shall name a base class of the class // being defined. |

