inner = DECL_TEMPLATE_RESULT (inner);
if ((!DECL_LANG_SPECIFIC (inner) || !DECL_MODULE_PURVIEW_P (inner))
- && !((flags & WMB_Using) && (flags & WMB_Export)))
- /* Ignore global module fragment entities unless explicitly
- exported with a using declaration. */
+ && !((flags & WMB_Using) && (flags & WMB_Purview)))
+ /* Ignore entities not within the module purview. */
return false;
if (VAR_OR_FUNCTION_DECL_P (inner)
{
if (!(flags & WMB_Hidden))
d->clear_hidden_binding ();
+ OVL_PURVIEW_P (d->get_entity ()) = true;
if (flags & WMB_Export)
OVL_EXPORT_P (d->get_entity ()) = true;
return bool (flags & WMB_Export);
decl = ovl_make (decl, NULL_TREE);
if (!unscoped_enum_const_p)
OVL_USING_P (decl) = true;
+ OVL_PURVIEW_P (decl) = true;
if (flags & WMB_Export)
OVL_EXPORT_P (decl) = true;
}
{
dedup = true;
OVL_USING_P (decls) = true;
+ OVL_PURVIEW_P (decls) = true;
if (flags & cbf_export)
OVL_EXPORT_P (decls) = true;
}
if (iter.using_p ())
{
flags = WMB_Flags (flags | WMB_Using);
+ if (iter.purview_p ())
+ flags = WMB_Flags (flags | WMB_Purview);
if (iter.exporting_p ())
flags = WMB_Flags (flags | WMB_Export);
}
if (iter.using_p ())
{
flags = WMB_Flags (flags | WMB_Using);
+ if (iter.purview_p ())
+ flags = WMB_Flags (flags | WMB_Purview);
if (iter.exporting_p ())
flags = WMB_Flags (flags | WMB_Export);
}
for (lkp_iterator usings (lookup.value); usings; ++usings)
{
tree new_fn = *usings;
- bool exporting = revealing_p && module_exporting_p ();
- if (exporting)
- exporting = check_can_export_using_decl (new_fn);
+ tree inner = STRIP_TEMPLATE (new_fn);
+ bool exporting_p = revealing_p && module_exporting_p ();
+ if (exporting_p)
+ exporting_p = check_can_export_using_decl (new_fn);
/* [namespace.udecl]
;
else if (old.using_p ())
{
- if (exporting)
- /* Update in place. 'tis ok. */
+ /* Update in place. 'tis ok. */
+ OVL_PURVIEW_P (old.get_using ()) = true;
+ if (exporting_p)
OVL_EXPORT_P (old.get_using ()) = true;
- ;
- }
- else if (DECL_MODULE_EXPORT_P (new_fn))
- ;
- else
- {
- value = old.remove_node (value);
- found = false;
}
+ else if (!DECL_LANG_SPECIFIC (inner)
+ || !DECL_MODULE_PURVIEW_P (inner))
+ /* We need to re-insert this function as a revealed
+ (possibly exported) declaration. We can't remove
+ the existing decl because that will change any
+ overloads cached in template functions. */
+ found = false;
break;
}
else if (old.using_p ())
continue; /* Parameters do not match. */
else if (decls_match (new_fn, old_fn))
{
- /* Extern "C" in different namespaces. */
+ /* Extern "C" in different namespaces. But similarly
+ to above, if revealing a not-revealed thing we may
+ need to reinsert. */
found = true;
+ if (revealing_p
+ && (!DECL_LANG_SPECIFIC (inner)
+ || !DECL_MODULE_PURVIEW_P (inner)))
+ found = false;
break;
}
else
/* Unlike the decl-pushing case we don't drop anticipated
builtins here. They don't cause a problem, and we'd
like to match them with a future declaration. */
- value = ovl_insert (new_fn, value, 1 + exporting);
+ value = ovl_insert (new_fn, value, 1 + revealing_p + exporting_p);
}
}
else if (value
}
else if (insert_p)
{
- if (revealing_p
- && module_exporting_p ()
- && check_can_export_using_decl (lookup.value)
- && lookup.value == value
- && !DECL_MODULE_EXPORT_P (value))
+ /* FIXME: Handle exporting declarations from a different scope
+ without also marking those declarations as exported.
+ This will require not just binding directly to the underlying
+ value; see c++/114863 and c++/114865. We allow this for purview
+ declarations for now as this doesn't (currently) cause ICEs
+ later down the line, but this should be revisited. */
+ if (revealing_p)
{
- /* We're redeclaring the same value, but this time as
- newly exported: make sure to mark it as such. */
- if (TREE_CODE (value) == TEMPLATE_DECL)
- {
- DECL_MODULE_EXPORT_P (value) = true;
-
- tree result = DECL_TEMPLATE_RESULT (value);
- retrofit_lang_decl (result);
- DECL_MODULE_PURVIEW_P (result) = true;
- DECL_MODULE_EXPORT_P (result) = true;
- }
- else
+ if (module_exporting_p ()
+ && check_can_export_using_decl (lookup.value)
+ && lookup.value == value
+ && !DECL_MODULE_EXPORT_P (lookup.value))
{
- retrofit_lang_decl (value);
- DECL_MODULE_PURVIEW_P (value) = true;
- DECL_MODULE_EXPORT_P (value) = true;
+ /* We're redeclaring the same value, but this time as
+ newly exported: make sure to mark it as such. */
+ if (TREE_CODE (lookup.value) == TEMPLATE_DECL)
+ DECL_MODULE_EXPORT_P (DECL_TEMPLATE_RESULT (lookup.value)) = true;
+ DECL_MODULE_EXPORT_P (lookup.value) = true;
}
+ /* We're also revealing this declaration with a using-decl,
+ so mark it as purview to ensure it's emitted. */
+ tree inner = STRIP_TEMPLATE (lookup.value);
+ retrofit_lang_decl (inner);
+ DECL_MODULE_PURVIEW_P (inner) = true;
}
- else
- value = lookup.value;
+ value = lookup.value;
}
/* Now the type binding. */
}
else if (insert_p)
{
- if (revealing_p
- && module_exporting_p ()
- && check_can_export_using_decl (lookup.type)
- && lookup.type == type
- && !DECL_MODULE_EXPORT_P (type))
+ if (revealing_p)
{
- /* We're redeclaring the same type, but this time as
- newly exported: make sure to mark it as such. */
- retrofit_lang_decl (type);
- DECL_MODULE_PURVIEW_P (type) = true;
- DECL_MODULE_EXPORT_P (type) = true;
+ /* As with revealing value bindings. */
+ if (module_exporting_p ()
+ && check_can_export_using_decl (lookup.type)
+ && lookup.type == type)
+ DECL_MODULE_EXPORT_P (lookup.type) = true;
+ retrofit_lang_decl (lookup.type);
+ DECL_MODULE_PURVIEW_P (lookup.type) = true;
}
- else
- type = lookup.type;
+ type = lookup.type;
}
}
return result;
}
-/* Add FN to the (potentially NULL) overload set OVL. USING_OR_HIDDEN is >
- zero if this is a using-decl. It is > 1 if we're exporting the
- using decl. USING_OR_HIDDEN is < 0, if FN is hidden. (A decl
- cannot be both using and hidden.) We keep the hidden decls first,
- but remaining ones are unordered. */
+/* Add FN to the (potentially NULL) overload set OVL. USING_OR_HIDDEN is > 0
+ if this is a using-decl. It is > 1 if we're revealing the using decl.
+ It is > 2 if we're also exporting it. USING_OR_HIDDEN is < 0, if FN is
+ hidden. (A decl cannot be both using and hidden.) We keep the hidden
+ decls first, but remaining ones are unordered. */
tree
ovl_insert (tree fn, tree maybe_ovl, int using_or_hidden)
{
OVL_DEDUP_P (maybe_ovl) = OVL_USING_P (maybe_ovl) = true;
if (using_or_hidden > 1)
+ OVL_PURVIEW_P (maybe_ovl) = true;
+ if (using_or_hidden > 2)
OVL_EXPORT_P (maybe_ovl) = true;
}
}