diff options
author | Serge Pavlov <sepavloff@gmail.com> | 2015-01-18 20:04:35 +0000 |
---|---|---|
committer | Serge Pavlov <sepavloff@gmail.com> | 2015-01-18 20:04:35 +0000 |
commit | 25a8afa9579e79eedac113e15e1afaa6acc1e2a0 (patch) | |
tree | 4d904b9badc9fedb05bd65a0e3b902c530e9d60c /clang/lib | |
parent | 4843f193ade5020d8722ce85826e183b0a676203 (diff) | |
download | bcm5719-llvm-25a8afa9579e79eedac113e15e1afaa6acc1e2a0.tar.gz bcm5719-llvm-25a8afa9579e79eedac113e15e1afaa6acc1e2a0.zip |
Handle unscoped enumeration in nested name specifier.
If an unscoped enum is used as a nested name specifier and the language dialect
is not C++ 11, issue an extension warning.
This fixes PR16951.
Differential Revision: http://reviews.llvm.org/D6389
llvm-svn: 226413
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaCXXScopeSpec.cpp | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index 3e56e676a15..438ad61ee9b 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -282,7 +282,11 @@ bool Sema::ActOnSuperScopeSpecifier(SourceLocation SuperLoc, /// \brief Determines whether the given declaration is an valid acceptable /// result for name lookup of a nested-name-specifier. -bool Sema::isAcceptableNestedNameSpecifier(const NamedDecl *SD) { +/// \param SD Declaration checked for nested-name-specifier. +/// \param IsExtension If not null and the declaration is accepted as an +/// extension, the pointed variable is assigned true. +bool Sema::isAcceptableNestedNameSpecifier(const NamedDecl *SD, + bool *IsExtension) { if (!SD) return false; @@ -298,14 +302,23 @@ bool Sema::isAcceptableNestedNameSpecifier(const NamedDecl *SD) { QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD)); if (T->isDependentType()) return true; - else if (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) { - if (TD->getUnderlyingType()->isRecordType() || - (Context.getLangOpts().CPlusPlus11 && - TD->getUnderlyingType()->isEnumeralType())) + if (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) { + if (TD->getUnderlyingType()->isRecordType()) return true; - } else if (isa<RecordDecl>(SD) || - (Context.getLangOpts().CPlusPlus11 && isa<EnumDecl>(SD))) + if (TD->getUnderlyingType()->isEnumeralType()) { + if (Context.getLangOpts().CPlusPlus11) + return true; + if (IsExtension) + *IsExtension = true; + } + } else if (isa<RecordDecl>(SD)) { return true; + } else if (isa<EnumDecl>(SD)) { + if (Context.getLangOpts().CPlusPlus11) + return true; + if (IsExtension) + *IsExtension = true; + } return false; } @@ -599,7 +612,13 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, } NamedDecl *SD = Found.getAsSingle<NamedDecl>(); - if (isAcceptableNestedNameSpecifier(SD)) { + bool IsExtension = false; + bool AcceptSpec = isAcceptableNestedNameSpecifier(SD, &IsExtension); + if (!AcceptSpec && IsExtension) { + AcceptSpec = true; + Diag(IdentifierLoc, diag::ext_nested_name_spec_is_enum); + } + if (AcceptSpec) { if (!ObjectType.isNull() && !ObjectTypeSearchedInScope && !getLangOpts().CPlusPlus11) { // C++03 [basic.lookup.classref]p4: |