void add_partial_entities (vec<tree, va_gc> *);
void add_class_entities (vec<tree, va_gc> *);
+ private:
+ void add_deduction_guides (tree decl);
+
public:
void find_dependencies (module_state *);
bool finalize_dependencies ();
/* Ignore NTTP objects. */
return false;
+ if (deduction_guide_p (decl))
+ {
+ /* Ignore deduction guides, bindings for them will be created within
+ find_dependencies for their class template. But still build a dep
+ for them so that we don't discard them. */
+ data->hash->make_dependency (decl, EK_FOR_BINDING);
+ return false;
+ }
+
if (!(flags & WMB_Using) && CP_DECL_CONTEXT (decl) != data->ns)
{
/* An unscoped enum constant implicitly brought into the containing
return ns;
}
+/* Creates bindings and dependencies for all deduction guides of
+ the given class template DECL as needed. */
+
+void
+depset::hash::add_deduction_guides (tree decl)
+{
+ /* Alias templates never have deduction guides. */
+ if (DECL_ALIAS_TEMPLATE_P (decl))
+ return;
+
+ /* We don't need to do anything for class-scope deduction guides,
+ as they will be added as members anyway. */
+ if (!DECL_NAMESPACE_SCOPE_P (decl))
+ return;
+
+ tree ns = CP_DECL_CONTEXT (decl);
+ tree name = dguide_name (decl);
+
+ /* We always add all deduction guides with a given name at once,
+ so if there's already a binding there's nothing to do. */
+ if (find_binding (ns, name))
+ return;
+
+ tree guides = lookup_qualified_name (ns, name, LOOK_want::NORMAL,
+ /*complain=*/false);
+ if (guides == error_mark_node)
+ return;
+
+ /* We have bindings to add. */
+ depset *binding = make_binding (ns, name);
+ add_namespace_context (binding, ns);
+
+ depset **slot = binding_slot (ns, name, /*insert=*/true);
+ *slot = binding;
+
+ for (lkp_iterator it (guides); it; ++it)
+ {
+ gcc_checking_assert (!TREE_VISITED (*it));
+ depset *dep = make_dependency (*it, EK_FOR_BINDING);
+ binding->deps.safe_push (dep);
+ dep->deps.safe_push (binding);
+ }
+}
+
/* Iteratively find dependencies. During the walk we may find more
entries on the same binding that need walking. */
}
walker.end ();
+ if (!walker.is_key_order ()
+ && DECL_CLASS_TEMPLATE_P (decl))
+ add_deduction_guides (decl);
+
if (!walker.is_key_order ()
&& TREE_CODE (decl) == TEMPLATE_DECL
&& !DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl))
flags |= cbf_hidden;
else if (DECL_MODULE_EXPORT_P (STRIP_TEMPLATE (bound)))
flags |= cbf_export;
+ else if (deduction_guide_p (bound))
+ /* Deduction guides are always exported so that they are
+ visible to name lookup whenever their class template
+ is reachable. */
+ flags |= cbf_export;
}
gcc_checking_assert (DECL_P (bound));
--- /dev/null
+// PR c++/115231
+// { dg-additional-options "-fmodules-ts -Wno-global-module" }
+// { dg-module-cmi M }
+
+module;
+
+template <typename T>
+struct A {
+ template <typename U> A(U);
+};
+
+template <typename T> A(T) -> A<T>;
+
+export module M;
+
+// Exporting a GMF entity should make the deduction guides reachable.
+export using ::A;
+
+
+export template <typename T>
+struct B {
+ template <typename U> B(U);
+};
+
+// Not exported, but should still be reachable by [temp.deduct.guide] p1.
+B(int) -> B<double>;
+
+
+// Class-scope deduction guides should be reachable as well, even if
+// the class body was not exported.
+export template <typename T> struct C;
+
+template <typename T>
+struct C {
+ template <typename U>
+ struct I {
+ template <typename V> I(V);
+ };
+
+ I(int) -> I<int>;
+
+ template <typename P>
+ I(const P*) -> I<P>;
+};