diff options
Diffstat (limited to 'lib/Sema/SemaCXXScopeSpec.cpp')
| -rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 36 | 
1 files changed, 28 insertions, 8 deletions
| diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 3e56e676a15c..9e146ed3a642 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -218,6 +218,7 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,    // Fixed enum types are complete, but they aren't valid as scopes    // until we see a definition, so awkwardly pull out this special    // case. +  // FIXME: The definition might not be visible; complain if it is not.    const EnumType *enumType = dyn_cast_or_null<EnumType>(tagType);    if (!enumType || enumType->getDecl()->isCompleteDefinition())      return false; @@ -282,7 +283,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 +303,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 +613,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: | 
