Skip to content

Conversation

ilya-biryukov
Copy link
Contributor

This popped up during our internal integrates of upstream changes. It started happening after ba9d1c4, which started using TemplateSpecializationType in this place and the code was not prepared to handle it.

This popped up during our internal intergrates of upstream changes.
It started happening after ba9d1c4,
which started using `TemplateSpecializationType` in this place and
the code was not prepared to handle it.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Sep 17, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 17, 2025

@llvm/pr-subscribers-clang

Author: Ilya Biryukov (ilya-biryukov)

Changes

This popped up during our internal integrates of upstream changes. It started happening after ba9d1c4, which started using TemplateSpecializationType in this place and the code was not prepared to handle it.


Full diff: https://github.com/llvm/llvm-project/pull/159312.diff

3 Files Affected:

  • (modified) clang/lib/AST/QualTypeNames.cpp (+6-3)
  • (modified) clang/unittests/AST/CMakeLists.txt (+1)
  • (added) clang/unittests/AST/QualTypeNamesTest.cpp (+55)
diff --git a/clang/lib/AST/QualTypeNames.cpp b/clang/lib/AST/QualTypeNames.cpp
index ee7fec3372fcf..b0e9a600f41a3 100644
--- a/clang/lib/AST/QualTypeNames.cpp
+++ b/clang/lib/AST/QualTypeNames.cpp
@@ -58,9 +58,9 @@ static bool getFullyQualifiedTemplateName(const ASTContext &Ctx,
   NestedNameSpecifier NNS = std::nullopt;
 
   TemplateDecl *ArgTDecl = TName.getAsTemplateDecl();
-  // ArgTDecl won't be NULL because we asserted that this isn't a
-  // dependent context very early in the call chain.
-  assert(ArgTDecl != nullptr);
+  if (!ArgTDecl)  // ArgTDecl can be null in dependent contexts.
+    return false;
+
   QualifiedTemplateName *QTName = TName.getAsQualifiedTemplateName();
 
   if (QTName &&
@@ -252,6 +252,9 @@ createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Decl *Decl,
                                     bool WithGlobalNsPrefix) {
   assert(Decl);
 
+  // Some declaration cannot be qualified.
+  if (Decl->isTemplateParameter())
+    return std::nullopt;
   const DeclContext *DC = Decl->getDeclContext()->getRedeclContext();
   const auto *Outer = dyn_cast<NamedDecl>(DC);
   const auto *OuterNS = dyn_cast<NamespaceDecl>(DC);
diff --git a/clang/unittests/AST/CMakeLists.txt b/clang/unittests/AST/CMakeLists.txt
index f27d34e8a0719..3a12a4a06a33a 100644
--- a/clang/unittests/AST/CMakeLists.txt
+++ b/clang/unittests/AST/CMakeLists.txt
@@ -26,6 +26,7 @@ add_clang_unittest(ASTTests
   ExternalASTSourceTest.cpp
   NamedDeclPrinterTest.cpp
   ProfilingTest.cpp
+  QualTypeNamesTest.cpp
   RandstructTest.cpp
   RawCommentForDeclTest.cpp
   RecursiveASTVisitorTest.cpp
diff --git a/clang/unittests/AST/QualTypeNamesTest.cpp b/clang/unittests/AST/QualTypeNamesTest.cpp
new file mode 100644
index 0000000000000..71e4c87cedc72
--- /dev/null
+++ b/clang/unittests/AST/QualTypeNamesTest.cpp
@@ -0,0 +1,55 @@
+//===- unittests/AST/QualTypeNamesTest.cpp --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains tests for helpers from QualTypeNames.h.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/QualTypeNames.h"
+#include "ASTPrint.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/TypeBase.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace {
+
+TEST(QualTypeNamesTest, TemplateParameters) {
+  constexpr llvm::StringLiteral Code = R"cpp(
+    template <template<class> class T> struct Foo {
+      using type_of_interest = T<int>;
+    };
+  )cpp";
+  auto AST = tooling::buildASTFromCode(Code);
+  ASSERT_NE(AST, nullptr);
+
+  auto &Ctx = AST->getASTContext();
+  auto FooLR = Ctx.getTranslationUnitDecl()->lookup(
+      DeclarationName(AST->getPreprocessor().getIdentifierInfo("Foo")));
+  ASSERT_TRUE(FooLR.isSingleResult());
+
+  auto TypeLR =
+      llvm::cast<ClassTemplateDecl>(FooLR.front())
+          ->getTemplatedDecl()
+          ->lookup(DeclarationName(
+              AST->getPreprocessor().getIdentifierInfo("type_of_interest")));
+  ASSERT_TRUE(TypeLR.isSingleResult());
+
+  auto Type = cast<TypeAliasDecl>(TypeLR.front())->getUnderlyingType();
+  ASSERT_TRUE(isa<TemplateSpecializationType>(Type));
+
+  EXPECT_EQ(TypeName::getFullyQualifiedName(Type, Ctx, Ctx.getPrintingPolicy()), "T<int>");
+}
+
+} // namespace
+} // namespace clang

Copy link

github-actions bot commented Sep 17, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@ilya-biryukov ilya-biryukov force-pushed the users/ibiryukov/qualnames branch from bea01fb to f62d7ec Compare September 17, 2025 11:54
Copy link
Collaborator

@rnk rnk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Ilya!

@ilya-biryukov ilya-biryukov merged commit 2caf4c1 into main Sep 17, 2025
9 checks passed
@ilya-biryukov ilya-biryukov deleted the users/ibiryukov/qualnames branch September 17, 2025 17:28
bool WithGlobalNsPrefix) {
assert(Decl);

// Some declaration cannot be qualified.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks clearer to me:

Suggested change
// Some declaration cannot be qualified.
// Template parameters can't be qualified.

@mizvekov
Copy link
Contributor

Oh I was just about to review, but this looks fine, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants