/* Where current instance of the decl got declared/defined/instantiated. */
extern void set_instantiating_module (tree);
extern void set_defining_module (tree);
+extern void set_defining_module_for_partial_spec (tree);
extern void maybe_key_decl (tree ctx, tree decl);
extern void propagate_defining_module (tree decl, tree orig);
extern void remove_defining_module (tree decl);
add_mergeable_specialization (!is_type, &spec, decl, spec_flags);
}
+ /* When making a CMI from a partition we're going to need to walk partial
+ specializations again, so make sure they're tracked. */
+ if (state->is_partition () && (spec_flags & 2))
+ set_defining_module_for_partial_spec (inner);
+
if (NAMESPACE_SCOPE_P (decl)
&& (mk == MK_named || mk == MK_unique
|| mk == MK_enum || mk == MK_friend_spec)
vec_safe_push (class_members, decl);
}
}
- else if (DECL_IMPLICIT_TYPEDEF_P (decl)
- && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
- /* This is a partial or explicit specialization. */
- vec_safe_push (partial_specializations, decl);
}
}
+/* Also remember DECL if it's a newly declared class template partial
+ specialization, because these are not necessarily added to the
+ instantiation tables. */
+
+void
+set_defining_module_for_partial_spec (tree decl)
+{
+ if (module_p ()
+ && DECL_IMPLICIT_TYPEDEF_P (decl)
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
+ vec_safe_push (partial_specializations, decl);
+}
+
void
set_originating_module (tree decl, bool friend_p ATTRIBUTE_UNUSED)
{
gcc_checking_assert (!TI_PARTIAL_INFO (tinfo));
TI_PARTIAL_INFO (tinfo) = build_template_info (tmpl, NULL_TREE);
+ set_defining_module_for_partial_spec (decl);
+
for (inst = DECL_TEMPLATE_INSTANTIATIONS (maintmpl); inst;
inst = TREE_CHAIN (inst))
{
--- /dev/null
+// PR c++/114947
+// { dg-additional-options "-fmodules-ts -std=c++20" }
+// { dg-module-cmi M:part }
+module M:part;
+
+template <typename> struct R {};
+template <typename T> requires false struct R<T> {};
+template <typename T> requires true struct R<T>;