summaryrefslogtreecommitdiff
path: root/gcc/cp/module.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/module.cc')
-rw-r--r--gcc/cp/module.cc117
1 files changed, 69 insertions, 48 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 27b8f64ce75..547bf360c4f 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -47,10 +47,14 @@ along with GCC; see the file COPYING3. If not see
module-local index.
Each importable DECL contains several flags. The simple set are
- DECL_EXPORT_P, DECL_MODULE_PURVIEW_P and DECL_MODULE_IMPORT_P. The
- first indicates whether it is exported, the second whether it is in
- the module purview (as opposed to the global module fragment), and
- the third indicates whether it was an import into this TU or not.
+ DECL_MODULE_EXPORT_P, DECL_MODULE_PURVIEW_P, DECL_MODULE_ATTACH_P
+ and DECL_MODULE_IMPORT_P. The first indicates whether it is
+ exported, the second whether it is in module or header-unit
+ purview. The third indicates it is attached to the named module in
+ whose purview it resides and the fourth indicates whether it was an
+ import into this TU or not. DECL_MODULE_ATTACH_P will be false for
+ all decls in a header-unit, and for those in a named module inside
+ a linkage declaration.
The more detailed flags are DECL_MODULE_PARTITION_P,
DECL_MODULE_ENTITY_P. The first is set in a primary interface unit
@@ -2927,7 +2931,7 @@ private:
public:
tree decl_container ();
tree key_mergeable (int tag, merge_kind, tree decl, tree inner, tree type,
- tree container, bool is_mod);
+ tree container, bool is_attached);
unsigned binfo_mergeable (tree *);
private:
@@ -5529,9 +5533,11 @@ trees_out::lang_decl_bools (tree t)
WB (lang->u.base.concept_p);
WB (lang->u.base.var_declared_inline_p);
WB (lang->u.base.dependent_init_p);
- /* When building a header unit, everthing is marked as purview, but
- that's the GM purview, so not what the importer will mean */
+ /* When building a header unit, everthing is marked as purview, (so
+ we know which decls to write). But when we import them we do not
+ want to mark them as in module purview. */
WB (lang->u.base.module_purview_p && !header_module_p ());
+ WB (lang->u.base.module_attach_p);
if (VAR_OR_FUNCTION_DECL_P (t))
WB (lang->u.base.module_keyed_decls_p);
switch (lang->u.base.selector)
@@ -5602,6 +5608,7 @@ trees_in::lang_decl_bools (tree t)
RB (lang->u.base.var_declared_inline_p);
RB (lang->u.base.dependent_init_p);
RB (lang->u.base.module_purview_p);
+ RB (lang->u.base.module_attach_p);
if (VAR_OR_FUNCTION_DECL_P (t))
RB (lang->u.base.module_keyed_decls_p);
switch (lang->u.base.selector)
@@ -7535,14 +7542,14 @@ trees_out::decl_value (tree decl, depset *dep)
or a module entity. This bool merges into the next block
of bools. Sneaky. */
tree o = get_originating_module_decl (decl);
- bool is_mod = false;
+ bool is_attached = false;
tree not_tmpl = STRIP_TEMPLATE (o);
if (DECL_LANG_SPECIFIC (not_tmpl)
- && DECL_MODULE_PURVIEW_P (not_tmpl))
- is_mod = true;
+ && DECL_MODULE_ATTACH_P (not_tmpl))
+ is_attached = true;
- b (is_mod);
+ b (is_attached);
}
b (dep && dep->has_defn ());
}
@@ -7791,7 +7798,7 @@ tree
trees_in::decl_value ()
{
int tag = 0;
- bool is_mod = false;
+ bool is_attached = false;
bool has_defn = false;
unsigned mk_u = u ();
if (mk_u >= MK_hwm || !merge_kind_name[mk_u])
@@ -7812,7 +7819,7 @@ trees_in::decl_value ()
{
if (!(mk & MK_template_mask) && !state->is_header ())
/* See note in trees_out about where this bool is sequenced. */
- is_mod = b ();
+ is_attached = b ();
has_defn = b ();
}
@@ -7916,7 +7923,8 @@ trees_in::decl_value ()
if (TREE_CODE (inner) == FUNCTION_DECL)
parm_tag = fn_parms_init (inner);
- tree existing = key_mergeable (tag, mk, decl, inner, type, container, is_mod);
+ tree existing = key_mergeable (tag, mk, decl, inner, type, container,
+ is_attached);
tree existing_inner = existing;
if (existing)
{
@@ -10652,7 +10660,7 @@ 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_mod)
+ tree type, tree container, bool is_attached)
{
const char *kind = "new";
tree existing = NULL_TREE;
@@ -10792,14 +10800,15 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
}
}
}
- else if (is_mod && !(state->is_module () || state->is_partition ()))
+ else if (is_attached
+ && !(state->is_module () || state->is_partition ()))
kind = "unique";
else
{
gcc_checking_assert (mk == MK_named || mk == MK_enum);
tree mvec;
tree *vslot = mergeable_namespace_slots (container, name,
- !is_mod, &mvec);
+ is_attached, &mvec);
existing = check_mergeable_decl (mk, decl, *vslot, key);
if (!existing)
add_mergeable_namespace_entity (vslot, decl);
@@ -10807,7 +10816,7 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
{
/* Note that we now have duplicates to deal with in
name lookup. */
- if (is_mod)
+ if (is_attached)
BINDING_VECTOR_PARTITION_DUPS_P (mvec) = true;
else
BINDING_VECTOR_GLOBAL_DUPS_P (mvec) = true;
@@ -10824,7 +10833,7 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
break;
case TYPE_DECL:
- if (is_mod && !(state->is_module () || state->is_partition ())
+ if (is_attached && !(state->is_module () || state->is_partition ())
/* Implicit member functions can come from
anywhere. */
&& !(DECL_ARTIFICIAL (decl)
@@ -18389,14 +18398,11 @@ get_originating_module (tree decl, bool for_mangle)
if (!DECL_LANG_SPECIFIC (not_tmpl))
return for_mangle ? -1 : 0;
- if (for_mangle && !DECL_MODULE_PURVIEW_P (not_tmpl))
+ if (for_mangle && !DECL_MODULE_ATTACH_P (not_tmpl))
return -1;
int mod = !DECL_MODULE_IMPORT_P (not_tmpl) ? 0 : get_importing_module (owner);
-
- if (for_mangle && (*modules)[mod]->is_header ())
- return -1;
-
+ gcc_checking_assert (!for_mangle || !(*modules)[mod]->is_header ());
return mod;
}
@@ -18416,9 +18422,34 @@ get_importing_module (tree decl, bool flexible)
bool
module_may_redeclare (tree decl)
{
+ for (;;)
+ {
+ tree ctx = CP_DECL_CONTEXT (decl);
+ if (TREE_CODE (ctx) == NAMESPACE_DECL)
+ // Found the namespace-scope decl.
+ break;
+ if (!CLASS_TYPE_P (ctx))
+ // We've met a non-class scope. Such a thing is not
+ // reopenable, so we must be ok.
+ return true;
+ decl = TYPE_NAME (ctx);
+ }
+
+ tree not_tmpl = STRIP_TEMPLATE (decl);
+
+ int use_tpl = 0;
+ if (node_template_info (not_tmpl, use_tpl) && use_tpl)
+ // Specializations of any kind can be redeclared anywhere.
+ // FIXME: Should we be checking this in more places on the scope chain?
+ return true;
+
+ if (!DECL_LANG_SPECIFIC (not_tmpl) || !DECL_MODULE_ATTACH_P (not_tmpl))
+ // Decl is attached to global module. Current scope needs to be too.
+ return !module_attach_p ();
+
module_state *me = (*modules)[0];
module_state *them = me;
- tree not_tmpl = STRIP_TEMPLATE (decl);
+
if (DECL_LANG_SPECIFIC (not_tmpl) && DECL_MODULE_IMPORT_P (not_tmpl))
{
/* We can be given the TEMPLATE_RESULT. We want the
@@ -18446,30 +18477,14 @@ module_may_redeclare (tree decl)
them = import_entity_module (index);
}
- if (them->is_header ())
- {
- if (!header_module_p ())
- return !module_purview_p ();
-
- if (DECL_SOURCE_LOCATION (decl) == BUILTINS_LOCATION)
- /* This is a builtin, being declared in header-unit. We
- now need to mark it as an export. */
- DECL_MODULE_EXPORT_P (decl) = true;
-
- /* If it came from a header, it's in the global module. */
- return true;
- }
+ // Decl is attached to named module. Current scope needs to be
+ // attaching to the same module.
+ if (!module_attach_p ())
+ return false;
+ // Both attached to named module.
if (me == them)
- return ((DECL_LANG_SPECIFIC (not_tmpl) && DECL_MODULE_PURVIEW_P (not_tmpl))
- == module_purview_p ());
-
- if (!me->name)
- me = me->parent;
-
- /* We can't have found a GMF entity from a named module. */
- gcc_checking_assert (DECL_LANG_SPECIFIC (not_tmpl)
- && DECL_MODULE_PURVIEW_P (not_tmpl));
+ return true;
return me && get_primary (them) == get_primary (me);
}
@@ -18554,11 +18569,17 @@ set_originating_module (tree decl, bool friend_p ATTRIBUTE_UNUSED)
{
set_instantiating_module (decl);
- if (TREE_CODE (CP_DECL_CONTEXT (decl)) != NAMESPACE_DECL)
+ if (!DECL_NAMESPACE_SCOPE_P (decl))
return;
gcc_checking_assert (friend_p || decl == get_originating_module_decl (decl));
+ if (module_attach_p ())
+ {
+ retrofit_lang_decl (decl);
+ DECL_MODULE_ATTACH_P (decl) = true;
+ }
+
if (!module_exporting_p ())
return;