[clang] [clang-tools-extra] [clang] [Sema] Preserve nested name specifier prefix in MemberPointerType (PR #118236)

Nathan Ridge via cfe-commits cfe-commits at lists.llvm.org
Sun Dec 1 16:59:17 PST 2024


https://github.com/HighCommander4 created https://github.com/llvm/llvm-project/pull/118236

Fixes https://github.com/llvm/llvm-project/issues/118198

>From 675aec86732ff4c46250fa0b17cd571387ca4ade Mon Sep 17 00:00:00 2001
From: Nathan Ridge <zeratul976 at hotmail.com>
Date: Sun, 1 Dec 2024 19:58:03 -0500
Subject: [PATCH] [clang] [Sema] Preserve nested name specifier prefix in
 MemberPointerType

---
 .../unittests/SemanticHighlightingTests.cpp     |  7 +++++++
 clang/lib/Sema/SemaType.cpp                     | 17 ++++++++++-------
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
index 30b9b1902aa9c7..1ec51d862d0a6f 100644
--- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
@@ -1092,6 +1092,13 @@ sizeof...($TemplateParameter[[Elements]]);
             $Field_dependentName[[waldo]];
           }
         };
+    )cpp",
+      // Pointer-to-member with nested-name-specifiers
+      R"cpp(
+      struct $Class_def[[Outer]] {
+        struct $Class_def[[Inner]] {};
+      };
+      using $Typedef_decl[[Alias]] = void ($Class[[Outer]]::$Class[[Inner]]:: *)();
     )cpp"};
   for (const auto &TestCase : TestCases)
     // Mask off scope modifiers to keep the tests manageable.
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index f32edc5ac06440..73c9362208b14b 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5347,15 +5347,18 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
 
         case NestedNameSpecifier::TypeSpec:
         case NestedNameSpecifier::TypeSpecWithTemplate:
-          ClsType = QualType(NNS->getAsType(), 0);
-          // Note: if the NNS has a prefix and ClsType is a nondependent
-          // TemplateSpecializationType, then the NNS prefix is NOT included
-          // in ClsType; hence we wrap ClsType into an ElaboratedType.
-          // NOTE: in particular, no wrap occurs if ClsType already is an
-          // Elaborated, DependentName, or DependentTemplateSpecialization.
-          if (isa<TemplateSpecializationType>(NNS->getAsType()))
+          const Type *NNSType = NNS->getAsType();
+          ClsType = QualType(NNSType, 0);
+          // If ClsType is an Elaborated, DependentName, or
+          // DependentTemplateSpecialization, it already stores the NNS prefix.
+          // Otherwise, wrap it in an Elaborated type to have a place to store
+          // the NNS prefix.
+          if (!(isa<ElaboratedType>(NNSType) ||
+                isa<DependentNameType>(NNSType) ||
+                isa<DependentTemplateSpecializationType>(NNSType))) {
             ClsType = Context.getElaboratedType(ElaboratedTypeKeyword::None,
                                                 NNSPrefix, ClsType);
+          }
           break;
         }
       } else {



More information about the cfe-commits mailing list