@@ -13462,13 +13462,155 @@ static ElaboratedTypeKeyword getCommonTypeKeyword(const T *X, const T *Y) {
13462
13462
: ElaboratedTypeKeyword::None;
13463
13463
}
13464
13464
13465
+ /// Returns a NestedNameSpecifier which has only the common sugar
13466
+ /// present in both NNS1 and NNS2.
13467
+ static NestedNameSpecifier *getCommonNNS(ASTContext &Ctx,
13468
+ NestedNameSpecifier *NNS1,
13469
+ NestedNameSpecifier *NNS2,
13470
+ bool IsSame) {
13471
+ // If they are identical, all sugar is common.
13472
+ if (NNS1 == NNS2)
13473
+ return NNS1;
13474
+
13475
+ // IsSame implies both NNSes are equivalent.
13476
+ NestedNameSpecifier *Canon = Ctx.getCanonicalNestedNameSpecifier(NNS1);
13477
+ if (Canon != Ctx.getCanonicalNestedNameSpecifier(NNS2)) {
13478
+ assert(!IsSame && "Should be the same NestedNameSpecifier");
13479
+ // If they are not the same, there is nothing to unify.
13480
+ // FIXME: It would be useful here if we could represent a canonically
13481
+ // empty NNS, which is not identical to an empty-as-written NNS.
13482
+ return nullptr;
13483
+ }
13484
+
13485
+ NestedNameSpecifier *R = nullptr;
13486
+ NestedNameSpecifier::SpecifierKind K1 = NNS1->getKind(), K2 = NNS2->getKind();
13487
+ switch (K1) {
13488
+ case NestedNameSpecifier::SpecifierKind::Identifier: {
13489
+ assert(K2 == NestedNameSpecifier::SpecifierKind::Identifier);
13490
+ IdentifierInfo *II = NNS1->getAsIdentifier();
13491
+ assert(II == NNS2->getAsIdentifier());
13492
+ // For an identifier, the prefixes are significant, so they must be the
13493
+ // same.
13494
+ NestedNameSpecifier *P = ::getCommonNNS(Ctx, NNS1->getPrefix(),
13495
+ NNS2->getPrefix(), /*IsSame=*/true);
13496
+ R = NestedNameSpecifier::Create(Ctx, P, II);
13497
+ break;
13498
+ }
13499
+ case NestedNameSpecifier::SpecifierKind::Namespace:
13500
+ case NestedNameSpecifier::SpecifierKind::NamespaceAlias: {
13501
+ assert(K2 == NestedNameSpecifier::SpecifierKind::Namespace ||
13502
+ K2 == NestedNameSpecifier::SpecifierKind::NamespaceAlias);
13503
+ // The prefixes for namespaces are not significant, its declaration
13504
+ // identifies it uniquely.
13505
+ NestedNameSpecifier *P =
13506
+ ::getCommonNNS(Ctx, NNS1->getPrefix(), NNS2->getPrefix(),
13507
+ /*IsSame=*/false);
13508
+ NamespaceAliasDecl *A1 = NNS1->getAsNamespaceAlias(),
13509
+ *A2 = NNS2->getAsNamespaceAlias();
13510
+ // Are they the same namespace alias?
13511
+ if (declaresSameEntity(A1, A2)) {
13512
+ R = NestedNameSpecifier::Create(Ctx, P, ::getCommonDeclChecked(A1, A2));
13513
+ break;
13514
+ }
13515
+ // Otherwise, look at the namespaces only.
13516
+ NamespaceDecl *N1 = A1 ? A1->getNamespace() : NNS1->getAsNamespace(),
13517
+ *N2 = A2 ? A2->getNamespace() : NNS2->getAsNamespace();
13518
+ R = NestedNameSpecifier::Create(Ctx, P, ::getCommonDeclChecked(N1, N2));
13519
+ break;
13520
+ }
13521
+ case NestedNameSpecifier::SpecifierKind::TypeSpec:
13522
+ case NestedNameSpecifier::SpecifierKind::TypeSpecWithTemplate: {
13523
+ // FIXME: See comment below, on Super case.
13524
+ if (K2 == NestedNameSpecifier::SpecifierKind::Super)
13525
+ return Ctx.getCanonicalNestedNameSpecifier(NNS1);
13526
+
13527
+ assert(K2 == NestedNameSpecifier::SpecifierKind::TypeSpec ||
13528
+ K2 == NestedNameSpecifier::SpecifierKind::TypeSpecWithTemplate);
13529
+
13530
+ // Only keep the template keyword if both sides have it.
13531
+ bool Template =
13532
+ K1 == NestedNameSpecifier::SpecifierKind::TypeSpecWithTemplate &&
13533
+ K2 == NestedNameSpecifier::SpecifierKind::TypeSpecWithTemplate;
13534
+
13535
+ const Type *T1 = NNS1->getAsType(), *T2 = NNS2->getAsType();
13536
+ if (T1 == T2) {
13537
+ // If the types are indentical, then only the prefixes differ.
13538
+ // A well-formed NNS never has these types, as they have
13539
+ // special normalized forms.
13540
+ assert((!isa<DependentNameType, ElaboratedType>(T1)));
13541
+ // Only for a DependentTemplateSpecializationType the prefix
13542
+ // is actually significant. A DependentName, which would be another
13543
+ // plausible case, cannot occur here, as explained above.
13544
+ bool IsSame = isa<DependentTemplateSpecializationType>(T1);
13545
+ NestedNameSpecifier *P =
13546
+ ::getCommonNNS(Ctx, NNS1->getPrefix(), NNS2->getPrefix(), IsSame);
13547
+ R = NestedNameSpecifier::Create(Ctx, P, Template, T1);
13548
+ break;
13549
+ }
13550
+ // TODO: Try to salvage the original prefix.
13551
+ // If getCommonSugaredType removed any top level sugar, the original prefix
13552
+ // is not applicable anymore.
13553
+ NestedNameSpecifier *P = nullptr;
13554
+ const Type *T = Ctx.getCommonSugaredType(QualType(T1, 0), QualType(T2, 0),
13555
+ /*Unqualified=*/true)
13556
+ .getTypePtr();
13557
+
13558
+ // A NestedNameSpecifier has special normalization rules for certain types.
13559
+ switch (T->getTypeClass()) {
13560
+ case Type::Elaborated: {
13561
+ // An ElaboratedType is stripped off, it's Qualifier becomes the prefix.
13562
+ auto *ET = cast<ElaboratedType>(T);
13563
+ R = NestedNameSpecifier::Create(Ctx, ET->getQualifier(), Template,
13564
+ ET->getNamedType().getTypePtr());
13565
+ break;
13566
+ }
13567
+ case Type::DependentName: {
13568
+ // A DependentName is turned into an Identifier NNS.
13569
+ auto *DN = cast<DependentNameType>(T);
13570
+ R = NestedNameSpecifier::Create(Ctx, DN->getQualifier(),
13571
+ DN->getIdentifier());
13572
+ break;
13573
+ }
13574
+ case Type::DependentTemplateSpecialization: {
13575
+ // A DependentTemplateSpecializationType loses it's Qualifier, which
13576
+ // is turned into the prefix.
13577
+ auto *DTST = cast<DependentTemplateSpecializationType>(T);
13578
+ T = Ctx.getDependentTemplateSpecializationType(
13579
+ DTST->getKeyword(), /*NNS=*/nullptr, DTST->getIdentifier(),
13580
+ DTST->template_arguments())
13581
+ .getTypePtr();
13582
+ P = DTST->getQualifier();
13583
+ R = NestedNameSpecifier::Create(Ctx, DTST->getQualifier(), Template, T);
13584
+ break;
13585
+ }
13586
+ default:
13587
+ R = NestedNameSpecifier::Create(Ctx, P, Template, T);
13588
+ break;
13589
+ }
13590
+ break;
13591
+ }
13592
+ case NestedNameSpecifier::SpecifierKind::Super:
13593
+ // FIXME: Can __super even be used with data members?
13594
+ // If it's only usable in functions, we will never see it here,
13595
+ // unless we save the qualifiers used in function types.
13596
+ // In that case, it might be possible NNS2 is a type,
13597
+ // in which case we should degrade the result to
13598
+ // a CXXRecordType.
13599
+ return Ctx.getCanonicalNestedNameSpecifier(NNS1);
13600
+ case NestedNameSpecifier::SpecifierKind::Global:
13601
+ // The global NNS is a singleton.
13602
+ assert(K2 == NestedNameSpecifier::SpecifierKind::Global &&
13603
+ "Global NNS cannot be equivalent to any other kind");
13604
+ llvm_unreachable("Global NestedNameSpecifiers did not compare equal");
13605
+ }
13606
+ assert(Ctx.getCanonicalNestedNameSpecifier(R) == Canon);
13607
+ return R;
13608
+ }
13609
+
13465
13610
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());
13611
+ static NestedNameSpecifier *getCommonQualifier(ASTContext &Ctx, const T *X,
13612
+ const T *Y, bool IsSame) {
13613
+ return ::getCommonNNS(Ctx, X->getQualifier(), Y->getQualifier(), IsSame);
13472
13614
}
13473
13615
13474
13616
template <class T>
@@ -13879,8 +14021,9 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
13879
14021
*NY = cast<DependentNameType>(Y);
13880
14022
assert(NX->getIdentifier() == NY->getIdentifier());
13881
14023
return Ctx.getDependentNameType(
13882
- getCommonTypeKeyword(NX, NY), getCommonNNS(Ctx, NX, NY),
13883
- NX->getIdentifier(), NX->getCanonicalTypeInternal());
14024
+ getCommonTypeKeyword(NX, NY),
14025
+ getCommonQualifier(Ctx, NX, NY, /*IsSame=*/true), NX->getIdentifier(),
14026
+ NX->getCanonicalTypeInternal());
13884
14027
}
13885
14028
case Type::DependentTemplateSpecialization: {
13886
14029
const auto *TX = cast<DependentTemplateSpecializationType>(X),
@@ -13889,8 +14032,9 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
13889
14032
auto As = getCommonTemplateArguments(Ctx, TX->template_arguments(),
13890
14033
TY->template_arguments());
13891
14034
return Ctx.getDependentTemplateSpecializationType(
13892
- getCommonTypeKeyword(TX, TY), getCommonNNS(Ctx, TX, TY),
13893
- TX->getIdentifier(), As);
14035
+ getCommonTypeKeyword(TX, TY),
14036
+ getCommonQualifier(Ctx, TX, TY, /*IsSame=*/true), TX->getIdentifier(),
14037
+ As);
13894
14038
}
13895
14039
case Type::UnaryTransform: {
13896
14040
const auto *TX = cast<UnaryTransformType>(X),
@@ -14047,7 +14191,8 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
14047
14191
case Type::Elaborated: {
14048
14192
const auto *EX = cast<ElaboratedType>(X), *EY = cast<ElaboratedType>(Y);
14049
14193
return Ctx.getElaboratedType(
14050
- ::getCommonTypeKeyword(EX, EY), ::getCommonNNS(Ctx, EX, EY),
14194
+ ::getCommonTypeKeyword(EX, EY),
14195
+ ::getCommonQualifier(Ctx, EX, EY, /*IsSame=*/false),
14051
14196
Ctx.getQualifiedType(Underlying),
14052
14197
::getCommonDecl(EX->getOwnedTagDecl(), EY->getOwnedTagDecl()));
14053
14198
}
0 commit comments