diff options
Diffstat (limited to 'clang/lib/Sema/SemaCXXScopeSpec.cpp')
-rw-r--r-- | clang/lib/Sema/SemaCXXScopeSpec.cpp | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index a4421d2b68af..1c8f6329bd67 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -227,12 +227,19 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS, 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<EnumDecl>(tag); - if (!EnumD) - return false; + if (auto *EnumD = dyn_cast<EnumDecl>(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) { if (EnumD->isCompleteDefinition()) { // If we know about the definition but it is not visible, complain. NamedDecl *SuggestedDef = nullptr; @@ -241,8 +248,8 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS, // 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 +260,26 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS, 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()); + if (SS) + SS->SetInvalid(SS->getRange()); return true; } return false; } } - Diag(loc, diag::err_incomplete_nested_name_spec) - << type << SS.getRange(); - SS.SetInvalid(SS.getRange()); + if (SS) { + Diag(L, diag::err_incomplete_nested_name_spec) + << QualType(EnumD->getTypeForDecl(), 0) << SS->getRange(); + SS->SetInvalid(SS->getRange()); + } else { + Diag(L, diag::err_incomplete_enum) << QualType(EnumD->getTypeForDecl(), 0); + Diag(EnumD->getLocation(), diag::note_declared_at); + } + return true; } |