@@ -6207,6 +6207,8 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
62076207 SourceLocation Loc,
62086208 TemplateIdAnnotation *TemplateId,
62096209 bool IsMemberSpecialization) {
6210+ assert(SS.isValid() && "diagnoseQualifiedDeclaration called for declaration "
6211+ "without nested-name-specifier");
62106212 DeclContext *Cur = CurContext;
62116213 while (isa<LinkageSpecDecl>(Cur) || isa<CapturedDecl>(Cur))
62126214 Cur = Cur->getParent();
@@ -6295,22 +6297,36 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
62956297 << FixItHint::CreateRemoval(TemplateId->TemplateKWLoc);
62966298
62976299 NestedNameSpecifierLoc SpecLoc(SS.getScopeRep(), SS.location_data());
6298- while (SpecLoc.getPrefix()) {
6300+ do {
62996301 if (SpecLoc.getNestedNameSpecifier()->getKind() ==
63006302 NestedNameSpecifier::TypeSpecWithTemplate)
63016303 Diag(Loc, diag::ext_template_after_declarative_nns)
63026304 << FixItHint::CreateRemoval(
63036305 SpecLoc.getTypeLoc().getTemplateKeywordLoc());
63046306
6305- SpecLoc = SpecLoc.getPrefix();
6306- }
6307- // C++11 [dcl.meaning]p1:
6308- // [...] "The nested-name-specifier of the qualified declarator-id shall
6309- // not begin with a decltype-specifer"
6310- if (isa_and_nonnull<DecltypeType>(
6311- SpecLoc.getNestedNameSpecifier()->getAsType()))
6312- Diag(Loc, diag::err_decltype_in_declarator)
6313- << SpecLoc.getTypeLoc().getSourceRange();
6307+ if (const Type *T = SpecLoc.getNestedNameSpecifier()->getAsType()) {
6308+ if (const auto *TST = T->getAsAdjusted<TemplateSpecializationType>()) {
6309+ // C++23 [expr.prim.id.qual]p3:
6310+ // [...] If a nested-name-specifier N is declarative and has a
6311+ // simple-template-id with a template argument list A that involves a
6312+ // template parameter, let T be the template nominated by N without A.
6313+ // T shall be a class template.
6314+ if (TST->isDependentType() && TST->isTypeAlias())
6315+ Diag(Loc, diag::ext_alias_template_in_declarative_nns)
6316+ << SpecLoc.getLocalSourceRange();
6317+ } else if (T->isDecltypeType()) {
6318+ // C++23 [expr.prim.id.qual]p2:
6319+ // [...] A declarative nested-name-specifier shall not have a
6320+ // decltype-specifier.
6321+ //
6322+ // FIXME: This wording appears to be defective as it does not forbid
6323+ // declarative nested-name-specifiers with pack-index-specifiers.
6324+ // See https://github.com/cplusplus/CWG/issues/499.
6325+ Diag(Loc, diag::err_decltype_in_declarator)
6326+ << SpecLoc.getTypeLoc().getSourceRange();
6327+ }
6328+ }
6329+ } while ((SpecLoc = SpecLoc.getPrefix()));
63146330
63156331 return false;
63166332}
0 commit comments