llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: ykiko (16bit-ykiko)

<details>
<summary>Changes</summary>

`ExplicitInstantiationDecl::getTypeAsWritten()` incorrectly returned `nullptr` 
when a variable template's declared type was a `TagType` (struct/enum/union) or 
`TemplateSpecializationType`, because it confused the variable's declared type 
with the type encoding used for nested class instantiations.

The fix restricts the `TagTypeLoc`/`TemplateSpecializationTypeLoc` filter to 
only apply when the specialization is a `RecordDecl`, since that is the only 
case where the `TypeSourceInfo` encodes the class itself rather than a declared 
type.

Fixes #<!-- -->197797

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


2 Files Affected:

- (modified) clang/lib/AST/DeclTemplate.cpp (+11-5) 
- (modified) clang/test/AST/ast-print-explicit-instantiation.cpp (+15) 


``````````diff
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 08e6512a1c74d..3e3d21396cac0 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -1864,11 +1864,17 @@ TypeSourceInfo 
*ExplicitInstantiationDecl::getTypeAsWritten() const {
   auto *TSI = getRawTypeSourceInfo();
   if (!TSI)
     return nullptr;
-  TypeLoc TL = TSI->getTypeLoc();
-  // For class templates and nested classes, the "type" is fully described by
-  // the unified accessors (getQualifierLoc, getTemplateArg, getTagKWLoc).
-  if (TL.getAs<TemplateSpecializationTypeLoc>() || TL.getAs<TagTypeLoc>())
-    return nullptr;
+  // For class templates and nested classes, the TypeSourceInfo encodes the
+  // instantiated class itself (via TemplateSpecializationTypeLoc or
+  // TagTypeLoc), not a declared type.  Only filter those out when the
+  // specialization is a RecordDecl.  For function/variable templates the
+  // TypeSourceInfo is the declared type, which may happen to be a tag type
+  // (e.g. a variable template of struct type) and must not be filtered.
+  if (isa<RecordDecl>(getSpecialization())) {
+    TypeLoc TL = TSI->getTypeLoc();
+    if (TL.getAs<TemplateSpecializationTypeLoc>() || TL.getAs<TagTypeLoc>())
+      return nullptr;
+  }
   return TSI;
 }
 
diff --git a/clang/test/AST/ast-print-explicit-instantiation.cpp 
b/clang/test/AST/ast-print-explicit-instantiation.cpp
index 6c794e9575039..dc2b0e870652c 100644
--- a/clang/test/AST/ast-print-explicit-instantiation.cpp
+++ b/clang/test/AST/ast-print-explicit-instantiation.cpp
@@ -25,6 +25,7 @@ template int ns::var<int>;
 // CHECK: extern template float ns::var<float>;
 extern template float ns::var<float>;
 
+
 template <typename T> struct X { struct Inner {}; };
 // CHECK: template struct X<int>::Inner;
 template struct X<int>::Inner;
@@ -58,3 +59,17 @@ void A<T>::B<U>::g(V) {}
 
 // CHECK: template void A<int>::B<double>::g<float>(float);
 template void A<int>::B<double>::g<float>(float);
+
+namespace GH197797 {
+struct S {};
+enum E { X };
+template <typename T> struct Wrap {};
+
+template <typename T> T var = T{};
+// CHECK: extern template S var<S>;
+extern template S var<S>;
+// CHECK: extern template E var<E>;
+extern template E var<E>;
+// CHECK: extern template Wrap<int> var<Wrap<int>>;
+extern template Wrap<int> var<Wrap<int>>;
+} // namespace GH197797

``````````

</details>


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

Reply via email to