@@ -13462,13 +13462,114 @@ static ElaboratedTypeKeyword getCommonTypeKeyword(const T *X, const T *Y) {
1346213462 : ElaboratedTypeKeyword::None;
1346313463}
1346413464
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+
1346513569template <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);
1347213573}
1347313574
1347413575template <class T>
@@ -13879,8 +13980,9 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
1387913980 *NY = cast<DependentNameType>(Y);
1388013981 assert(NX->getIdentifier() == NY->getIdentifier());
1388113982 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());
1388413986 }
1388513987 case Type::DependentTemplateSpecialization: {
1388613988 const auto *TX = cast<DependentTemplateSpecializationType>(X),
@@ -13889,8 +13991,9 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
1388913991 auto As = getCommonTemplateArguments(Ctx, TX->template_arguments(),
1389013992 TY->template_arguments());
1389113993 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);
1389413997 }
1389513998 case Type::UnaryTransform: {
1389613999 const auto *TX = cast<UnaryTransformType>(X),
@@ -14047,7 +14150,8 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
1404714150 case Type::Elaborated: {
1404814151 const auto *EX = cast<ElaboratedType>(X), *EY = cast<ElaboratedType>(Y);
1404914152 return Ctx.getElaboratedType(
14050- ::getCommonTypeKeyword(EX, EY), ::getCommonNNS(Ctx, EX, EY),
14153+ ::getCommonTypeKeyword(EX, EY),
14154+ ::getCommonQualifier(Ctx, EX, EY, /*IsSame=*/false),
1405114155 Ctx.getQualifiedType(Underlying),
1405214156 ::getCommonDecl(EX->getOwnedTagDecl(), EY->getOwnedTagDecl()));
1405314157 }
0 commit comments