aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/module.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/module.cc')
-rw-r--r--gcc/cp/module.cc52
1 files changed, 33 insertions, 19 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 0f3e1d9..58ad8cb 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -2958,7 +2958,8 @@ private:
public:
tree decl_container ();
tree key_mergeable (int tag, merge_kind, tree decl, tree inner, tree type,
- tree container, bool is_attached);
+ tree container, bool is_attached,
+ bool is_imported_temploid_friend);
unsigned binfo_mergeable (tree *);
private:
@@ -7806,6 +7807,7 @@ trees_out::decl_value (tree decl, depset *dep)
|| !TYPE_PTRMEMFUNC_P (TREE_TYPE (decl)));
merge_kind mk = get_merge_kind (decl, dep);
+ bool is_imported_temploid_friend = imported_temploid_friends->get (decl);
if (CHECKING_P)
{
@@ -7841,13 +7843,11 @@ trees_out::decl_value (tree decl, depset *dep)
&& DECL_MODULE_ATTACH_P (not_tmpl))
is_attached = true;
- /* But don't consider imported temploid friends as attached,
- since importers will need to merge this decl even if it was
- attached to a different module. */
- if (imported_temploid_friends->get (decl))
- is_attached = false;
-
bits.b (is_attached);
+
+ /* Also tell the importer whether this is an imported temploid
+ friend, which has implications for merging. */
+ bits.b (is_imported_temploid_friend);
}
bits.b (dep && dep->has_defn ());
}
@@ -8024,13 +8024,12 @@ trees_out::decl_value (tree decl, depset *dep)
}
}
- if (TREE_CODE (inner) == FUNCTION_DECL
- || TREE_CODE (inner) == TYPE_DECL)
+ if (is_imported_temploid_friend)
{
/* Write imported temploid friends so that importers can reconstruct
this information on stream-in. */
tree* slot = imported_temploid_friends->get (decl);
- tree_node (slot ? *slot : NULL_TREE);
+ tree_node (*slot);
}
bool is_typedef = false;
@@ -8109,6 +8108,7 @@ trees_in::decl_value ()
{
int tag = 0;
bool is_attached = false;
+ bool is_imported_temploid_friend = false;
bool has_defn = false;
unsigned mk_u = u ();
if (mk_u >= MK_hwm || !merge_kind_name[mk_u])
@@ -8129,7 +8129,10 @@ trees_in::decl_value ()
{
bits_in bits = stream_bits ();
if (!(mk & MK_template_mask) && !state->is_header ())
- is_attached = bits.b ();
+ {
+ is_attached = bits.b ();
+ is_imported_temploid_friend = bits.b ();
+ }
has_defn = bits.b ();
}
@@ -8234,7 +8237,7 @@ trees_in::decl_value ()
parm_tag = fn_parms_init (inner);
tree existing = key_mergeable (tag, mk, decl, inner, type, container,
- is_attached);
+ is_attached, is_imported_temploid_friend);
tree existing_inner = existing;
if (existing)
{
@@ -8339,8 +8342,7 @@ trees_in::decl_value ()
}
}
- if (TREE_CODE (inner) == FUNCTION_DECL
- || TREE_CODE (inner) == TYPE_DECL)
+ if (is_imported_temploid_friend)
if (tree owner = tree_node ())
if (is_new)
imported_temploid_friends->put (decl, owner);
@@ -11177,7 +11179,8 @@ check_mergeable_decl (merge_kind mk, tree decl, tree ovl, merge_key const &key)
tree
trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
- tree type, tree container, bool is_attached)
+ tree type, tree container, bool is_attached,
+ bool is_imported_temploid_friend)
{
const char *kind = "new";
tree existing = NULL_TREE;
@@ -11319,6 +11322,7 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
case NAMESPACE_DECL:
if (is_attached
+ && !is_imported_temploid_friend
&& !(state->is_module () || state->is_partition ()))
kind = "unique";
else
@@ -11350,6 +11354,7 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
break;
case TYPE_DECL:
+ gcc_checking_assert (!is_imported_temploid_friend);
if (is_attached && !(state->is_module () || state->is_partition ())
/* Implicit member functions can come from
anywhere. */
@@ -15356,6 +15361,7 @@ module_state::read_cluster (unsigned snum)
tree visible = NULL_TREE;
tree type = NULL_TREE;
bool dedup = false;
+ bool global_p = false;
/* We rely on the bindings being in the reverse order of
the resulting overload set. */
@@ -15373,6 +15379,16 @@ module_state::read_cluster (unsigned snum)
if (sec.get_overrun ())
break;
+ if (!global_p)
+ {
+ /* Check if the decl could require GM merging. */
+ tree orig = get_originating_module_decl (decl);
+ tree inner = STRIP_TEMPLATE (orig);
+ if (!DECL_LANG_SPECIFIC (inner)
+ || !DECL_MODULE_ATTACH_P (inner))
+ global_p = true;
+ }
+
if (decls && TREE_CODE (decl) == TYPE_DECL)
{
/* Stat hack. */
@@ -15459,10 +15475,8 @@ module_state::read_cluster (unsigned snum)
break; /* Bail. */
dump () && dump ("Binding of %P", ns, name);
- if (!set_module_binding (ns, name, mod,
- is_header () ? -1
- : is_module () || is_partition () ? 1
- : 0,
+ if (!set_module_binding (ns, name, mod, global_p,
+ is_module () || is_partition (),
decls, type, visible))
sec.set_overrun ();
}