@@ -398,6 +398,54 @@ class NestedNameSpecifierValidatorCCC final
398398
399399}
400400
401+ [[nodiscard]] static bool ExtendNestedNameSpecifier (Sema &S, CXXScopeSpec &SS,
402+ const NamedDecl *ND,
403+ SourceLocation NameLoc,
404+ SourceLocation CCLoc) {
405+ TypeLocBuilder TLB;
406+ QualType T;
407+ if (const auto *USD = dyn_cast<UsingShadowDecl>(ND)) {
408+ T = S.Context .getUsingType (ElaboratedTypeKeyword::None, SS.getScopeRep (),
409+ USD);
410+ TLB.push <UsingTypeLoc>(T).set (/* ElaboratedKeywordLoc=*/ SourceLocation (),
411+ SS.getWithLocInContext (S.Context ), NameLoc);
412+ } else if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
413+ T = S.Context .getTypeDeclType (ElaboratedTypeKeyword::None, SS.getScopeRep (),
414+ TD);
415+ switch (T->getTypeClass ()) {
416+ case Type::Record:
417+ case Type::InjectedClassName:
418+ case Type::Enum: {
419+ auto TTL = TLB.push <TagTypeLoc>(T);
420+ TTL.setElaboratedKeywordLoc (SourceLocation ());
421+ TTL.setQualifierLoc (SS.getWithLocInContext (S.Context ));
422+ TTL.setNameLoc (NameLoc);
423+ break ;
424+ }
425+ case Type::Typedef:
426+ TLB.push <TypedefTypeLoc>(T).set (/* ElaboratedKeywordLoc=*/ SourceLocation (),
427+ SS.getWithLocInContext (S.Context ),
428+ NameLoc);
429+ break ;
430+ case Type::UnresolvedUsing:
431+ TLB.push <UnresolvedUsingTypeLoc>(T).set (
432+ /* ElaboratedKeywordLoc=*/ SourceLocation (),
433+ SS.getWithLocInContext (S.Context ), NameLoc);
434+ break ;
435+ default :
436+ assert (SS.isEmpty ());
437+ T = S.Context .getTypeDeclType (TD);
438+ TLB.pushTypeSpec (T).setNameLoc (NameLoc);
439+ break ;
440+ }
441+ } else {
442+ return false ;
443+ }
444+ SS.clear ();
445+ SS.Make (S.Context , TLB.getTypeLocInContext (S.Context , T), CCLoc);
446+ return true ;
447+ }
448+
401449bool Sema::BuildCXXNestedNameSpecifier (Scope *S, NestedNameSpecInfo &IdInfo,
402450 bool EnteringContext, CXXScopeSpec &SS,
403451 NamedDecl *ScopeLookupResult,
@@ -653,40 +701,9 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
653701 if (isa<EnumDecl>(TD))
654702 Diag (IdInfo.IdentifierLoc , diag::warn_cxx98_compat_enum_nested_name_spec);
655703
656- QualType T;
657- TypeLocBuilder TLB;
658- if (const auto *USD = dyn_cast<UsingShadowDecl>(SD)) {
659- T = Context.getUsingType (ElaboratedTypeKeyword::None, SS.getScopeRep (),
660- USD);
661- TLB.push <UsingTypeLoc>(T).set (/* ElaboratedKeywordLoc=*/ SourceLocation (),
662- SS.getWithLocInContext (Context),
663- IdInfo.IdentifierLoc );
664- } else if (const auto *Tag = dyn_cast<TagDecl>(TD)) {
665- T = Context.getTagType (ElaboratedTypeKeyword::None, SS.getScopeRep (), Tag,
666- /* OwnsTag=*/ false );
667- auto TTL = TLB.push <TagTypeLoc>(T);
668- TTL.setElaboratedKeywordLoc (SourceLocation ());
669- TTL.setQualifierLoc (SS.getWithLocInContext (SemaRef.Context ));
670- TTL.setNameLoc (IdInfo.IdentifierLoc );
671- } else if (auto *TN = dyn_cast<TypedefNameDecl>(TD)) {
672- T = Context.getTypedefType (ElaboratedTypeKeyword::None, SS.getScopeRep (),
673- TN);
674- TLB.push <TypedefTypeLoc>(T).set (/* ElaboratedKeywordLoc=*/ SourceLocation (),
675- SS.getWithLocInContext (SemaRef.Context ),
676- IdInfo.IdentifierLoc );
677- } else if (auto *UD = dyn_cast<UnresolvedUsingTypenameDecl>(TD)) {
678- T = Context.getUnresolvedUsingType (ElaboratedTypeKeyword::None,
679- SS.getScopeRep (), UD);
680- TLB.push <UnresolvedUsingTypeLoc>(T).set (
681- /* ElaboratedKeywordLoc=*/ SourceLocation (),
682- SS.getWithLocInContext (SemaRef.Context ), IdInfo.IdentifierLoc );
683- } else {
684- assert (SS.isEmpty ());
685- T = Context.getTypeDeclType (TD);
686- TLB.pushTypeSpec (T).setNameLoc (IdInfo.IdentifierLoc );
687- }
688- SS.clear ();
689- SS.Make (Context, TLB.getTypeLocInContext (Context, T), IdInfo.CCLoc );
704+ [[maybe_unused]] bool IsType = ::ExtendNestedNameSpecifier (
705+ *this , SS, SD, IdInfo.IdentifierLoc , IdInfo.CCLoc );
706+ assert (IsType && " unhandled declaration kind" );
690707 return false ;
691708 }
692709
@@ -762,21 +779,16 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
762779 }
763780
764781 if (!Found.empty ()) {
765- if (TypeDecl *TD = Found.getAsSingle <TypeDecl>()) {
766- QualType T;
767- if (auto *TN = dyn_cast<TypedefNameDecl>(TD)) {
768- T = Context.getTypedefType (ElaboratedTypeKeyword::None,
769- SS.getScopeRep (), TN);
770- } else {
771- // FIXME: Enumerate the possibilities here.
772- assert (!isa<TagDecl>(TD));
773- assert (SS.isEmpty ());
774- T = Context.getTypeDeclType (TD);
775- }
776-
782+ const auto *ND = Found.getAsSingle <NamedDecl>();
783+ if (::ExtendNestedNameSpecifier (*this , SS, ND, IdInfo.IdentifierLoc ,
784+ IdInfo.CCLoc )) {
785+ const Type *T = SS.getScopeRep ().getAsType ();
777786 Diag (IdInfo.IdentifierLoc , diag::err_expected_class_or_namespace)
778- << T << getLangOpts ().CPlusPlus ;
779- } else if (Found.getAsSingle <TemplateDecl>()) {
787+ << QualType (T, 0 ) << getLangOpts ().CPlusPlus ;
788+ // Recover with this type if it would be a valid nested name specifier.
789+ return !T->getAsCanonical <TagType>();
790+ }
791+ if (isa<TemplateDecl>(ND)) {
780792 ParsedType SuggestedType;
781793 DiagnoseUnknownTypeName (IdInfo.Identifier , IdInfo.IdentifierLoc , S, &SS,
782794 SuggestedType);
0 commit comments