@@ -5774,44 +5774,53 @@ QualType ASTContext::getDependentTemplateSpecializationType(
57745774
57755775QualType ASTContext::getDependentTemplateSpecializationType(
57765776 ElaboratedTypeKeyword Keyword, const DependentTemplateStorage &Name,
5777- ArrayRef<TemplateArgument> Args) const {
5777+ ArrayRef<TemplateArgument> Args, bool IsCanonical ) const {
57785778 llvm::FoldingSetNodeID ID;
57795779 DependentTemplateSpecializationType::Profile(ID, *this, Keyword, Name, Args);
57805780
57815781 void *InsertPos = nullptr;
5782- DependentTemplateSpecializationType *T
5783- = DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
5784- if (T)
5782+ if (auto *T = DependentTemplateSpecializationTypes.FindNodeOrInsertPos(
5783+ ID, InsertPos))
57855784 return QualType(T, 0);
57865785
5787- NestedNameSpecifier *NNS = Name.getQualifier(),
5788- *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
5789-
5790- ElaboratedTypeKeyword CanonKeyword = Keyword;
5791- if (Keyword == ElaboratedTypeKeyword::None)
5792- CanonKeyword = ElaboratedTypeKeyword::Typename;
5793-
5794- bool AnyNonCanonArgs = false;
5795- auto CanonArgs =
5796- ::getCanonicalTemplateArguments(*this, Args, AnyNonCanonArgs);
5786+ NestedNameSpecifier *NNS = Name.getQualifier();
57975787
57985788 QualType Canon;
5799- if (AnyNonCanonArgs || CanonNNS != NNS || !Name.hasTemplateKeyword() ||
5800- CanonKeyword != Keyword) {
5801- Canon = getDependentTemplateSpecializationType(
5802- CanonKeyword, {CanonNNS, Name.getName(), /*HasTemplateKeyword=*/true},
5803- CanonArgs);
5804-
5805- // Find the insert position again.
5806- [[maybe_unused]] auto *Nothing =
5807- DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
5808- assert(!Nothing && "canonical type broken");
5789+ if (!IsCanonical) {
5790+ ElaboratedTypeKeyword CanonKeyword = Keyword != ElaboratedTypeKeyword::None
5791+ ? Keyword
5792+ : ElaboratedTypeKeyword::Typename;
5793+ NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
5794+ bool AnyNonCanonArgs = false;
5795+ auto CanonArgs =
5796+ ::getCanonicalTemplateArguments(*this, Args, AnyNonCanonArgs);
5797+
5798+ if (AnyNonCanonArgs || CanonNNS != NNS || !Name.hasTemplateKeyword() ||
5799+ CanonKeyword != Keyword) {
5800+ Canon = getDependentTemplateSpecializationType(
5801+ CanonKeyword, {CanonNNS, Name.getName(), /*HasTemplateKeyword=*/true},
5802+ CanonArgs, /*IsCanonical=*/true);
5803+ // Find the insert position again.
5804+ [[maybe_unused]] auto *Nothing =
5805+ DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID,
5806+ InsertPos);
5807+ assert(!Nothing && "canonical type broken");
5808+ }
5809+ } else {
5810+ assert(Keyword != ElaboratedTypeKeyword::None);
5811+ assert(Name.hasTemplateKeyword());
5812+ assert(NNS == getCanonicalNestedNameSpecifier(NNS));
5813+ #ifndef NDEBUG
5814+ bool AnyNonCanonArgs = false;
5815+ ::getCanonicalTemplateArguments(*this, Args, AnyNonCanonArgs);
5816+ assert(!AnyNonCanonArgs);
5817+ #endif
58095818 }
5810-
58115819 void *Mem = Allocate((sizeof(DependentTemplateSpecializationType) +
58125820 sizeof(TemplateArgument) * Args.size()),
58135821 alignof(DependentTemplateSpecializationType));
5814- T = new (Mem) DependentTemplateSpecializationType(Keyword, Name, Args, Canon);
5822+ auto *T =
5823+ new (Mem) DependentTemplateSpecializationType(Keyword, Name, Args, Canon);
58155824 Types.push_back(T);
58165825 DependentTemplateSpecializationTypes.InsertNode(T, InsertPos);
58175826 return QualType(T, 0);
@@ -7625,7 +7634,7 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
76257634 QualType NewT = getDependentTemplateSpecializationType(
76267635 ElaboratedTypeKeyword::Typename,
76277636 {/*NNS=*/nullptr, DTN.getName(), /*HasTemplateKeyword=*/true},
7628- DTST->template_arguments());
7637+ DTST->template_arguments(), /*IsCanonical=*/true );
76297638 assert(NewT.isCanonical());
76307639 NestedNameSpecifier *Prefix = DTN.getQualifier();
76317640 if (!Prefix)
0 commit comments