https://github.com/zwuis created 
https://github.com/llvm/llvm-project/pull/208010

Split off from #190495.

Co-authored-by: Matheus Izvekov <[email protected]>

>From ca21bf15a609ac7d76c08ccdcf39e8b64ea04882 Mon Sep 17 00:00:00 2001
From: Yanzuo Liu <[email protected]>
Date: Tue, 7 Jul 2026 13:02:26 +0800
Subject: [PATCH 1/3] Move `return nullptr;` for null NNS to `switch` body

---
 clang/lib/Sema/SemaCXXScopeSpec.cpp | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index 255c22d9c2a31..9f8530a8a861f 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -48,9 +48,6 @@ DeclContext *Sema::computeDeclContext(QualType T) {
 
 DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
                                       bool EnteringContext) {
-  if (!SS.isSet() || SS.isInvalid())
-    return nullptr;
-
   NestedNameSpecifier NNS = SS.getScopeRep();
   if (NNS.isDependent()) {
     // If this nested-name-specifier refers to the current
@@ -143,7 +140,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec 
&SS,
     return NNS.getAsMicrosoftSuper();
 
   case NestedNameSpecifier::Kind::Null:
-    llvm_unreachable("unexpected null nested name specifier");
+    return nullptr;
   }
 
   llvm_unreachable("Invalid NestedNameSpecifier::Kind!");

>From 1997bc5ae73ac88b6e8fd1e10ded95379ce08e9b Mon Sep 17 00:00:00 2001
From: Yanzuo Liu <[email protected]>
Date: Tue, 7 Jul 2026 13:14:22 +0800
Subject: [PATCH 2/3] Decrease indent by swapping the order of branches and
 merging conditions

---
 clang/lib/Sema/SemaCXXScopeSpec.cpp | 56 ++++++++++++++---------------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index 9f8530a8a861f..d83bd29bdd60f 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -49,14 +49,34 @@ DeclContext *Sema::computeDeclContext(QualType T) {
 DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
                                       bool EnteringContext) {
   NestedNameSpecifier NNS = SS.getScopeRep();
-  if (NNS.isDependent()) {
+  if (!NNS.isDependent()) {
+  switch (NNS.getKind()) {
+  case NestedNameSpecifier::Kind::Namespace:
+    return const_cast<NamespaceDecl *>(
+        NNS.getAsNamespaceAndPrefix().Namespace->getNamespace());
+
+  case NestedNameSpecifier::Kind::Type:
+    return NNS.getAsType()->castAsTagDecl();
+
+  case NestedNameSpecifier::Kind::Global:
+    return Context.getTranslationUnitDecl();
+
+  case NestedNameSpecifier::Kind::MicrosoftSuper:
+    return NNS.getAsMicrosoftSuper();
+
+  case NestedNameSpecifier::Kind::Null:
+    return nullptr;
+  }
+
+  llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
+  }
+
     // If this nested-name-specifier refers to the current
     // instantiation, return its DeclContext.
     if (CXXRecordDecl *Record = getCurrentInstantiationOf(NNS))
       return Record;
 
-    if (EnteringContext) {
-      if (NNS.getKind() != NestedNameSpecifier::Kind::Type)
+      if (!EnteringContext || NNS.getKind() != NestedNameSpecifier::Kind::Type)
         return nullptr;
       const Type *NNSType = NNS.getAsType();
 
@@ -67,14 +87,16 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec 
&SS,
         // We are entering the context of the nested name specifier, so try to
         // match the nested name specifier to either a primary class template
         // or a class template partial specialization.
-        if (ClassTemplateDecl *ClassTemplate =
+          ClassTemplateDecl *ClassTemplate =
                 dyn_cast_or_null<ClassTemplateDecl>(
-                    SpecType->getTemplateName().getAsTemplateDecl())) {
+                    SpecType->getTemplateName().getAsTemplateDecl())
           // FIXME: The fallback on the search of partial
           // specialization using ContextType should be eventually removed 
since
           // it doesn't handle the case of constrained template parameters
           // correctly. Currently removing this fallback would change the
           // diagnostic output for invalid code in a number of tests.
+          if (!ClassTemplate)
+            return nullptr;
           ClassTemplatePartialSpecializationDecl *PartialSpec = nullptr;
           ArrayRef<TemplateParameterList *> TemplateParamLists =
               SS.getTemplateParamLists();
@@ -115,35 +137,13 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec 
&SS,
               ClassTemplate->getCanonicalInjectedSpecializationType(Context);
           if (Context.hasSameType(Injected, QualType(SpecType, 0)))
             return ClassTemplate->getTemplatedDecl();
-        }
+          return nullptr;
       } else if (const auto *RecordT = dyn_cast<RecordType>(NNSType)) {
         // The nested name specifier refers to a member of a class template.
         return RecordT->getDecl()->getDefinitionOrSelf();
       }
-    }
 
     return nullptr;
-  }
-
-  switch (NNS.getKind()) {
-  case NestedNameSpecifier::Kind::Namespace:
-    return const_cast<NamespaceDecl *>(
-        NNS.getAsNamespaceAndPrefix().Namespace->getNamespace());
-
-  case NestedNameSpecifier::Kind::Type:
-    return NNS.getAsType()->castAsTagDecl();
-
-  case NestedNameSpecifier::Kind::Global:
-    return Context.getTranslationUnitDecl();
-
-  case NestedNameSpecifier::Kind::MicrosoftSuper:
-    return NNS.getAsMicrosoftSuper();
-
-  case NestedNameSpecifier::Kind::Null:
-    return nullptr;
-  }
-
-  llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
 }
 
 bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) {

>From 83a9b4d13f28ef3904126f091af4d86997521174 Mon Sep 17 00:00:00 2001
From: Yanzuo Liu <[email protected]>
Date: Tue, 7 Jul 2026 14:51:12 +0800
Subject: [PATCH 3/3] Move comment and `git clang-format`

---
 clang/lib/Sema/SemaCXXScopeSpec.cpp | 159 ++++++++++++++--------------
 1 file changed, 78 insertions(+), 81 deletions(-)

diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index d83bd29bdd60f..00a566cfab7b0 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -50,100 +50,97 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec 
&SS,
                                       bool EnteringContext) {
   NestedNameSpecifier NNS = SS.getScopeRep();
   if (!NNS.isDependent()) {
-  switch (NNS.getKind()) {
-  case NestedNameSpecifier::Kind::Namespace:
-    return const_cast<NamespaceDecl *>(
-        NNS.getAsNamespaceAndPrefix().Namespace->getNamespace());
+    switch (NNS.getKind()) {
+    case NestedNameSpecifier::Kind::Namespace:
+      return const_cast<NamespaceDecl *>(
+          NNS.getAsNamespaceAndPrefix().Namespace->getNamespace());
 
-  case NestedNameSpecifier::Kind::Type:
-    return NNS.getAsType()->castAsTagDecl();
+    case NestedNameSpecifier::Kind::Type:
+      return NNS.getAsType()->castAsTagDecl();
 
-  case NestedNameSpecifier::Kind::Global:
-    return Context.getTranslationUnitDecl();
+    case NestedNameSpecifier::Kind::Global:
+      return Context.getTranslationUnitDecl();
 
-  case NestedNameSpecifier::Kind::MicrosoftSuper:
-    return NNS.getAsMicrosoftSuper();
+    case NestedNameSpecifier::Kind::MicrosoftSuper:
+      return NNS.getAsMicrosoftSuper();
 
-  case NestedNameSpecifier::Kind::Null:
-    return nullptr;
-  }
+    case NestedNameSpecifier::Kind::Null:
+      return nullptr;
+    }
 
-  llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
+    llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
   }
 
-    // If this nested-name-specifier refers to the current
-    // instantiation, return its DeclContext.
-    if (CXXRecordDecl *Record = getCurrentInstantiationOf(NNS))
-      return Record;
-
-      if (!EnteringContext || NNS.getKind() != NestedNameSpecifier::Kind::Type)
-        return nullptr;
-      const Type *NNSType = NNS.getAsType();
-
-      // Look through type alias templates, per C++0x [temp.dep.type]p1.
-      NNSType = Context.getCanonicalType(NNSType);
-      if (const auto *SpecType =
-              dyn_cast<TemplateSpecializationType>(NNSType)) {
-        // We are entering the context of the nested name specifier, so try to
-        // match the nested name specifier to either a primary class template
-        // or a class template partial specialization.
-          ClassTemplateDecl *ClassTemplate =
-                dyn_cast_or_null<ClassTemplateDecl>(
-                    SpecType->getTemplateName().getAsTemplateDecl())
-          // FIXME: The fallback on the search of partial
-          // specialization using ContextType should be eventually removed 
since
-          // it doesn't handle the case of constrained template parameters
-          // correctly. Currently removing this fallback would change the
-          // diagnostic output for invalid code in a number of tests.
-          if (!ClassTemplate)
-            return nullptr;
-          ClassTemplatePartialSpecializationDecl *PartialSpec = nullptr;
-          ArrayRef<TemplateParameterList *> TemplateParamLists =
-              SS.getTemplateParamLists();
-          if (!TemplateParamLists.empty()) {
-            unsigned Depth = 
ClassTemplate->getTemplateParameters()->getDepth();
-            auto L = find_if(TemplateParamLists,
+  // If this nested-name-specifier refers to the current
+  // instantiation, return its DeclContext.
+  if (CXXRecordDecl *Record = getCurrentInstantiationOf(NNS))
+    return Record;
+
+  if (!EnteringContext || NNS.getKind() != NestedNameSpecifier::Kind::Type)
+    return nullptr;
+  const Type *NNSType = NNS.getAsType();
+
+  // Look through type alias templates, per C++0x [temp.dep.type]p1.
+  NNSType = Context.getCanonicalType(NNSType);
+  if (const auto *SpecType = dyn_cast<TemplateSpecializationType>(NNSType)) {
+    // We are entering the context of the nested name specifier, so try to
+    // match the nested name specifier to either a primary class template
+    // or a class template partial specialization.
+    ClassTemplateDecl *ClassTemplate = dyn_cast_or_null<ClassTemplateDecl>(
+        SpecType->getTemplateName().getAsTemplateDecl());
+    if (!ClassTemplate)
+      return nullptr;
+    ClassTemplatePartialSpecializationDecl *PartialSpec = nullptr;
+    ArrayRef<TemplateParameterList *> TemplateParamLists =
+        SS.getTemplateParamLists();
+    if (!TemplateParamLists.empty()) {
+      unsigned Depth = ClassTemplate->getTemplateParameters()->getDepth();
+      auto L = llvm::find_if(TemplateParamLists,
                              [Depth](TemplateParameterList *TPL) {
                                return TPL->getDepth() == Depth;
                              });
-            if (L != TemplateParamLists.end()) {
-              void *Pos = nullptr;
-              PartialSpec = ClassTemplate->findPartialSpecialization(
-                  SpecType->template_arguments(), *L, Pos);
-            }
-          } else {
-            PartialSpec =
-                ClassTemplate->findPartialSpecialization(QualType(SpecType, 
0));
-          }
-
-          if (PartialSpec) {
-            // A declaration of the partial specialization must be visible.
-            // We can always recover here, because this only happens when we're
-            // entering the context, and that can't happen in a SFINAE context.
-            assert(!isSFINAEContext() && "partial specialization scope "
-                                         "specifier in SFINAE context?");
-            if (PartialSpec->hasDefinition() &&
-                !hasReachableDefinition(PartialSpec))
-              diagnoseMissingImport(SS.getLastQualifierNameLoc(), PartialSpec,
-                                    MissingImportKind::PartialSpecialization,
-                                    true);
-            return PartialSpec;
-          }
-
-          // If the type of the nested name specifier is the same as the
-          // injected class name of the named class template, we're entering
-          // into that class template definition.
-          CanQualType Injected =
-              ClassTemplate->getCanonicalInjectedSpecializationType(Context);
-          if (Context.hasSameType(Injected, QualType(SpecType, 0)))
-            return ClassTemplate->getTemplatedDecl();
-          return nullptr;
-      } else if (const auto *RecordT = dyn_cast<RecordType>(NNSType)) {
-        // The nested name specifier refers to a member of a class template.
-        return RecordT->getDecl()->getDefinitionOrSelf();
+      if (L != TemplateParamLists.end()) {
+        void *Pos = nullptr;
+        PartialSpec = ClassTemplate->findPartialSpecialization(
+            SpecType->template_arguments(), *L, Pos);
       }
+    } else {
+      // FIXME: The fallback on the search of partial
+      // specialization using ContextType should be eventually removed since
+      // it doesn't handle the case of constrained template parameters
+      // correctly. Currently removing this fallback would change the
+      // diagnostic output for invalid code in a number of tests.
+      PartialSpec =
+          ClassTemplate->findPartialSpecialization(QualType(SpecType, 0));
+    }
+
+    if (PartialSpec) {
+      // A declaration of the partial specialization must be visible.
+      // We can always recover here, because this only happens when we're
+      // entering the context, and that can't happen in a SFINAE context.
+      assert(!isSFINAEContext() && "partial specialization scope "
+                                   "specifier in SFINAE context?");
+      if (PartialSpec->hasDefinition() && !hasReachableDefinition(PartialSpec))
+        diagnoseMissingImport(SS.getLastQualifierNameLoc(), PartialSpec,
+                              MissingImportKind::PartialSpecialization, true);
+      return PartialSpec;
+    }
 
+    // If the type of the nested name specifier is the same as the
+    // injected class name of the named class template, we're entering
+    // into that class template definition.
+    CanQualType Injected =
+        ClassTemplate->getCanonicalInjectedSpecializationType(Context);
+    if (Context.hasSameType(Injected, QualType(SpecType, 0)))
+      return ClassTemplate->getTemplatedDecl();
     return nullptr;
+  }
+  if (const auto *RecordT = dyn_cast<RecordType>(NNSType)) {
+    // The nested name specifier refers to a member of a class template.
+    return RecordT->getDecl()->getDefinitionOrSelf();
+  }
+
+  return nullptr;
 }
 
 bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to