@@ -13462,13 +13462,114 @@ static ElaboratedTypeKeyword getCommonTypeKeyword(const T *X, const T *Y) {
13462
13462
: ElaboratedTypeKeyword::None;
13463
13463
}
13464
13464
13465
+ static NestedNameSpecifier *getCommonNNS(ASTContext &Ctx,
13466
+ NestedNameSpecifier *X,
13467
+ NestedNameSpecifier *Y, bool IsSame) {
13468
+ if (X == Y)
13469
+ return X;
13470
+
13471
+ NestedNameSpecifier *Canon = Ctx.getCanonicalNestedNameSpecifier(X);
13472
+ if (Canon != Ctx.getCanonicalNestedNameSpecifier(Y)) {
13473
+ assert(!IsSame && "Should be the same NestedNameSpecifier");
13474
+ return nullptr;
13475
+ }
13476
+
13477
+ NestedNameSpecifier *R = nullptr;
13478
+ switch (auto KX = X->getKind(), KY = Y->getKind(); KX) {
13479
+ case NestedNameSpecifier::SpecifierKind::Identifier: {
13480
+ assert(KY == NestedNameSpecifier::SpecifierKind::Identifier);
13481
+ IdentifierInfo *II = X->getAsIdentifier();
13482
+ assert(II == Y->getAsIdentifier());
13483
+ NestedNameSpecifier *P =
13484
+ ::getCommonNNS(Ctx, X->getPrefix(), Y->getPrefix(), /*IsSame=*/true);
13485
+ R = NestedNameSpecifier::Create(Ctx, P, II);
13486
+ break;
13487
+ }
13488
+ case NestedNameSpecifier::SpecifierKind::Namespace:
13489
+ case NestedNameSpecifier::SpecifierKind::NamespaceAlias: {
13490
+ assert(KY == NestedNameSpecifier::SpecifierKind::Namespace ||
13491
+ KY == NestedNameSpecifier::SpecifierKind::NamespaceAlias);
13492
+ NestedNameSpecifier *P = ::getCommonNNS(Ctx, X->getPrefix(), Y->getPrefix(),
13493
+ /*IsSame=*/false);
13494
+ NamespaceAliasDecl *AX = X->getAsNamespaceAlias(),
13495
+ *AY = Y->getAsNamespaceAlias();
13496
+ if (declaresSameEntity(AX, AY)) {
13497
+ R = NestedNameSpecifier::Create(Ctx, P, ::getCommonDeclChecked(AX, AY));
13498
+ break;
13499
+ }
13500
+ NamespaceDecl *NX = AX ? AX->getNamespace() : X->getAsNamespace(),
13501
+ *NY = AY ? AY->getNamespace() : Y->getAsNamespace();
13502
+ R = NestedNameSpecifier::Create(Ctx, P, ::getCommonDeclChecked(NX, NY));
13503
+ break;
13504
+ }
13505
+ case NestedNameSpecifier::SpecifierKind::TypeSpec:
13506
+ case NestedNameSpecifier::SpecifierKind::TypeSpecWithTemplate: {
13507
+ assert(KY == NestedNameSpecifier::SpecifierKind::TypeSpec ||
13508
+ KY == NestedNameSpecifier::SpecifierKind::TypeSpecWithTemplate);
13509
+ bool Template =
13510
+ KX == NestedNameSpecifier::SpecifierKind::TypeSpecWithTemplate &&
13511
+ KY == NestedNameSpecifier::SpecifierKind::TypeSpecWithTemplate;
13512
+
13513
+ const Type *TX = X->getAsType(), *TY = Y->getAsType();
13514
+ if (TX == TY) {
13515
+ NestedNameSpecifier *P =
13516
+ ::getCommonNNS(Ctx, X->getPrefix(), Y->getPrefix(),
13517
+ /*IsSame=*/false);
13518
+ R = NestedNameSpecifier::Create(Ctx, P, Template, TX);
13519
+ break;
13520
+ }
13521
+ // TODO: Try to salvage the original prefix.
13522
+ // If getCommonSugaredType removed any top level sugar, the original prefix
13523
+ // is not applicable anymore.
13524
+ NestedNameSpecifier *P = nullptr;
13525
+ const Type *T = Ctx.getCommonSugaredType(QualType(X->getAsType(), 0),
13526
+ QualType(Y->getAsType(), 0),
13527
+ /*Unqualified=*/true)
13528
+ .getTypePtr();
13529
+ switch (T->getTypeClass()) {
13530
+ case Type::Elaborated: {
13531
+ auto *ET = cast<ElaboratedType>(T);
13532
+ R = NestedNameSpecifier::Create(Ctx, ET->getQualifier(), Template,
13533
+ ET->getNamedType().getTypePtr());
13534
+ break;
13535
+ }
13536
+ case Type::DependentName: {
13537
+ auto *DN = cast<DependentNameType>(T);
13538
+ R = NestedNameSpecifier::Create(Ctx, DN->getQualifier(),
13539
+ DN->getIdentifier());
13540
+ break;
13541
+ }
13542
+ case Type::DependentTemplateSpecialization: {
13543
+ auto *DTST = cast<DependentTemplateSpecializationType>(T);
13544
+ T = Ctx.getDependentTemplateSpecializationType(
13545
+ DTST->getKeyword(), /*NNS=*/nullptr, DTST->getIdentifier(),
13546
+ DTST->template_arguments())
13547
+ .getTypePtr();
13548
+ P = DTST->getQualifier();
13549
+ R = NestedNameSpecifier::Create(Ctx, DTST->getQualifier(), Template, T);
13550
+ break;
13551
+ }
13552
+ default:
13553
+ R = NestedNameSpecifier::Create(Ctx, P, Template, T);
13554
+ break;
13555
+ }
13556
+ break;
13557
+ }
13558
+ case NestedNameSpecifier::SpecifierKind::Global:
13559
+ assert(KY == NestedNameSpecifier::SpecifierKind::Global);
13560
+ return X;
13561
+ case NestedNameSpecifier::SpecifierKind::Super:
13562
+ assert(KY == NestedNameSpecifier::SpecifierKind::Super);
13563
+ return X;
13564
+ }
13565
+ assert(Ctx.getCanonicalNestedNameSpecifier(R) == Canon);
13566
+ return R;
13567
+ }
13568
+
13465
13569
template <class T>
13466
- static NestedNameSpecifier *getCommonNNS(ASTContext &Ctx, const T *X,
13467
- const T *Y) {
13468
- // FIXME: Try to keep the common NNS sugar.
13469
- return X->getQualifier() == Y->getQualifier()
13470
- ? X->getQualifier()
13471
- : Ctx.getCanonicalNestedNameSpecifier(X->getQualifier());
13570
+ static NestedNameSpecifier *getCommonQualifier(ASTContext &Ctx, const T *X,
13571
+ const T *Y, bool IsSame) {
13572
+ return ::getCommonNNS(Ctx, X->getQualifier(), Y->getQualifier(), IsSame);
13472
13573
}
13473
13574
13474
13575
template <class T>
@@ -13879,8 +13980,9 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
13879
13980
*NY = cast<DependentNameType>(Y);
13880
13981
assert(NX->getIdentifier() == NY->getIdentifier());
13881
13982
return Ctx.getDependentNameType(
13882
- getCommonTypeKeyword(NX, NY), getCommonNNS(Ctx, NX, NY),
13883
- NX->getIdentifier(), NX->getCanonicalTypeInternal());
13983
+ getCommonTypeKeyword(NX, NY),
13984
+ getCommonQualifier(Ctx, NX, NY, /*IsSame=*/true), NX->getIdentifier(),
13985
+ NX->getCanonicalTypeInternal());
13884
13986
}
13885
13987
case Type::DependentTemplateSpecialization: {
13886
13988
const auto *TX = cast<DependentTemplateSpecializationType>(X),
@@ -13889,8 +13991,9 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
13889
13991
auto As = getCommonTemplateArguments(Ctx, TX->template_arguments(),
13890
13992
TY->template_arguments());
13891
13993
return Ctx.getDependentTemplateSpecializationType(
13892
- getCommonTypeKeyword(TX, TY), getCommonNNS(Ctx, TX, TY),
13893
- TX->getIdentifier(), As);
13994
+ getCommonTypeKeyword(TX, TY),
13995
+ getCommonQualifier(Ctx, TX, TY, /*IsSame=*/true), TX->getIdentifier(),
13996
+ As);
13894
13997
}
13895
13998
case Type::UnaryTransform: {
13896
13999
const auto *TX = cast<UnaryTransformType>(X),
@@ -14047,7 +14150,8 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
14047
14150
case Type::Elaborated: {
14048
14151
const auto *EX = cast<ElaboratedType>(X), *EY = cast<ElaboratedType>(Y);
14049
14152
return Ctx.getElaboratedType(
14050
- ::getCommonTypeKeyword(EX, EY), ::getCommonNNS(Ctx, EX, EY),
14153
+ ::getCommonTypeKeyword(EX, EY),
14154
+ ::getCommonQualifier(Ctx, EX, EY, /*IsSame=*/false),
14051
14155
Ctx.getQualifiedType(Underlying),
14052
14156
::getCommonDecl(EX->getOwnedTagDecl(), EY->getOwnedTagDecl()));
14053
14157
}
0 commit comments