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
