Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -6375,6 +6375,9 @@ // Marks SS invalid if it represents an incomplete type. bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC); + // Complete an enum decl, maybe without a scope spec. + bool RequireCompleteEnumDecl(EnumDecl *D, SourceLocation L, + CXXScopeSpec *SS = nullptr); DeclContext *computeDeclContext(QualType T); DeclContext *computeDeclContext(const CXXScopeSpec &SS, Index: clang/lib/Sema/SemaCXXScopeSpec.cpp =================================================================== --- clang/lib/Sema/SemaCXXScopeSpec.cpp +++ clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -227,12 +227,20 @@ return true; } - // Fixed enum types are complete, but they aren't valid as scopes - // until we see a definition, so awkwardly pull out this special - // case. - auto *EnumD = dyn_cast(tag); - if (!EnumD) - return false; + if (auto *EnumD = dyn_cast(tag)) + // Fixed enum types and scoped enum instantiations are complete, but they + // aren't valid as scopes until we see or instantiate their definition. + return RequireCompleteEnumDecl(EnumD, loc, &SS); + + return false; +} + +/// Require that the EnumDecl is completed with its enumerators defined or +/// instantiated. SS, if provided, is the ScopeRef parsed. +/// +bool Sema::RequireCompleteEnumDecl(EnumDecl *EnumD, SourceLocation L, + CXXScopeSpec *SS) { + assert (SS && "missing scope"); if (EnumD->isCompleteDefinition()) { // If we know about the definition but it is not visible, complain. NamedDecl *SuggestedDef = nullptr; @@ -241,8 +249,8 @@ // If the user is going to see an error here, recover by making the // definition visible. bool TreatAsComplete = !isSFINAEContext(); - diagnoseMissingImport(loc, SuggestedDef, MissingImportKind::Definition, - /*Recover*/TreatAsComplete); + diagnoseMissingImport(L, SuggestedDef, MissingImportKind::Definition, + /*Recover*/ TreatAsComplete); return !TreatAsComplete; } return false; @@ -253,19 +261,20 @@ if (EnumDecl *Pattern = EnumD->getInstantiatedFromMemberEnum()) { MemberSpecializationInfo *MSI = EnumD->getMemberSpecializationInfo(); if (MSI->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) { - if (InstantiateEnum(loc, EnumD, Pattern, + if (InstantiateEnum(L, EnumD, Pattern, getTemplateInstantiationArgs(EnumD), TSK_ImplicitInstantiation)) { - SS.SetInvalid(SS.getRange()); + SS->SetInvalid(SS->getRange()); return true; } return false; } } - Diag(loc, diag::err_incomplete_nested_name_spec) - << type << SS.getRange(); - SS.SetInvalid(SS.getRange()); + Diag(L, diag::err_incomplete_nested_name_spec) + << QualType(EnumD->getTypeForDecl(), 0) << SS->getRange(); + SS->SetInvalid(SS->getRange()); + return true; }