Commit 7a142539 authored by Jeff Chapman II's avatar Jeff Chapman II

update to current devel/c++-modules

cb365f78e0c37904b90c9c529f789b0f60652f13
parent 658efded
2020-05-01 Nathan Sidwell <[email protected]>
Fix macro expansion of header-unit names
libcpp/
* macro.c (cpp_get_token_1): Pay attention to arg parsing mode,
and the existence of padding/comment tokens.
gcc/testsuite/
* g++.dg/modules/cpp-6_[abc].[CH]: New.
2020-04-30 Nathan Sidwell <[email protected]>
Set TREE_USED on stream in.
gcc/cp/
* module.cc (trees_in::unused): New field.
(trees_in::tree_node): Add defaulted off is_use arg, set TREE_USED
on streamed in obect. Adjust callers to set it.
(trees_{in,out}::core_bools): Do not stream base.used_flag.
(trees_{in,out}::core_vals): Reorder BINFO fields. Increment
unused around vtbl pieces.
(trees_in::decl_value): Save and reset unused field.
(trees_in::read_var_def): Increment unsused for vtbl initializers.
gcc/testsuite/
* g++.dg/modules/used-1_[abc].C: New.
Tweak builtin fn hack
gcc/cp/
* name-lookup.c (get_namespace_binding): Strip singleton
overloads.
gcc/testsuite/
* g++.dg/modules/libfn-1_[ab].C: New.
2020-04-28 Nathan Sidwell <[email protected]>
Partition pending indirection fixes
gcc/cp/
* module.cc (trees_in::install_entity): Treat pending flags
independently, adjust indirection installation.
(pendset_lazy_load): Add specialization_p arg. Use for
indirection adjustment.
(get_primary_module): Look at implementation unit's parent.
(lazy_load_{specializations,members}): Adjust.
gcc/testsuite/
* g++.dg/modules/part-6_[abcde].C: New.
2020-04-23 Nathan Sidwell <[email protected]>
Stream definitions after decls.
......
......@@ -2920,6 +2920,8 @@ private:
vec<tree> back_refs; /* Back references. */
duplicate_hash_map *duplicates; /* Map from existings to duplicate. */
vec<tree> post_decls; /* Decls to post process. */
unsigned unused; /* Inhibit any interior TREE_USED
marking. */
public:
trees_in (module_state *);
......@@ -2959,7 +2961,7 @@ private:
public:
/* Read a tree node. */
tree tree_node ();
tree tree_node (bool is_use = false);
private:
bool install_entity (tree decl);
......@@ -3024,7 +3026,7 @@ private:
};
trees_in::trees_in (module_state *state)
:parent (), state (state)
:parent (), state (state), unused (0)
{
duplicates = NULL;
back_refs.create (500);
......@@ -5127,15 +5129,8 @@ trees_out::core_bools (tree t)
WB (t->base.nowarning_flag);
/* base.visited read as zero (it's set for writer, because that's
how we mark nodes). */
// FIXME: We should not be writing out used flag. There are 2
// issues
// a) the importer may do more work than necessary, feeding things
// that are used only in the importee and not in the importer (this
// is harmless, but time consuming)
// b) we may be the only use of something from one of our own imports, and
// that won't be propagated into our importer. This will lead to
// unresolved symbols I think.
WB (t->base.used_flag);
/* base.used_flag is not streamed. Readers may set TREE_USED of
decls they use. */
WB (t->base.nothrow_flag);
WB (t->base.static_flag);
if (TREE_CODE_CLASS (code) != tcc_type)
......@@ -5294,7 +5289,7 @@ trees_in::core_bools (tree t)
/* base.asm_written_flag is not streamed. */
RB (t->base.nowarning_flag);
/* base.visited is not streamed. */
RB (t->base.used_flag);
/* base.used_flag is not streamed. */
RB (t->base.nothrow_flag);
RB (t->base.static_flag);
if (TREE_CODE_CLASS (code) != tcc_type)
......@@ -6011,9 +6006,10 @@ trees_out::core_vals (tree t)
WT (t->binfo.common.chain);
WT (t->binfo.offset);
WT (t->binfo.inheritance);
WT (t->binfo.vptr_field);
WT (t->binfo.vtable);
WT (t->binfo.virtuals);
WT (t->binfo.vptr_field);
WT (t->binfo.vtt_subvtt);
WT (t->binfo.vtt_vptr);
......@@ -6202,12 +6198,15 @@ trees_out::core_vals (tree t)
#undef WU
}
// FIXME: Not 100% sure I'm marking all the TREE_USED's that need to
// be marked
bool
trees_in::core_vals (tree t)
{
#define RU(X) ((X) = u ())
#define RUC(T,X) ((X) = T (u ()))
#define RT(X) ((X) = tree_node ())
#define RTU(X) ((X) = tree_node (true))
tree_code code = TREE_CODE (t);
/* First by tree shape. */
......@@ -6295,7 +6294,7 @@ trees_in::core_vals (tree t)
for (unsigned limit = (vl ? VL_EXP_OPERAND_LENGTH (t)
: TREE_OPERAND_LENGTH (t)),
ix = unsigned (vl); ix != limit; ix++)
RT (TREE_OPERAND (t, ix));
RTU (TREE_OPERAND (t, ix));
}
/* Then by CODE. Special cases and/or 1:1 tree shape
......@@ -6439,7 +6438,7 @@ trees_in::core_vals (tree t)
constructor_elt elt;
RT (elt.index);
RT (elt.value);
RTU (elt.value);
t->constructor.elts->quick_push (elt);
}
}
......@@ -6476,11 +6475,16 @@ trees_in::core_vals (tree t)
RT (t->binfo.common.chain);
RT (t->binfo.offset);
RT (t->binfo.inheritance);
RT (t->binfo.vptr_field);
/* Do not mark the vtables as USED in the address expressions
here. */
unused++;
RT (t->binfo.vtable);
RT (t->binfo.virtuals);
RT (t->binfo.vptr_field);
RT (t->binfo.vtt_subvtt);
RT (t->binfo.vtt_vptr);
unused--;
BINFO_BASE_ACCESSES (t) = tree_vec ();
if (!get_overrun ())
......@@ -6506,7 +6510,7 @@ trees_in::core_vals (tree t)
/* C++-specific nodes ... */
case BASELINK:
RT (((lang_tree_node *)t)->baselink.binfo);
RT (((lang_tree_node *)t)->baselink.functions);
RTU (((lang_tree_node *)t)->baselink.functions);
RT (((lang_tree_node *)t)->baselink.access_binfo);
break;
......@@ -7308,8 +7312,7 @@ trees_in::install_entity (tree decl)
unsigned ident = state->entity_lwm + entity_index - 1;
mc_slot &elt = (*entity_ary)[ident];
/* See module_state::read_pendings for how this got set, at most
one bit will be set. */
/* See module_state::read_pendings for how this got set. */
int pending = elt.get_lazy () & 3;
elt = decl;
......@@ -7323,21 +7326,26 @@ trees_in::install_entity (tree decl)
/* Insert into the entity hash (it cannot already be there). */
bool existed;
unsigned &slot
= entity_map->get_or_insert (DECL_UID (decl), &existed);
unsigned &slot = entity_map->get_or_insert (DECL_UID (decl), &existed);
gcc_checking_assert (!existed);
slot = ident;
}
else if (pending != 0)
{
unsigned key_ident = import_entity_index (decl);
if (!pending_table->add (pending & 1 ? key_ident : ~key_ident, ~ident))
pending = 0;
if (pending & 1)
if (!pending_table->add (key_ident, ~ident))
pending &= ~1;
if (pending & 2)
if (!pending_table->add (~key_ident, ~ident))
pending &= ~2;
}
if (pending & 1)
DECL_MODULE_PENDING_SPECIALIZATIONS_P (decl) = true;
else if (pending & 2)
if (pending & 2)
{
DECL_MODULE_PENDING_MEMBERS_P (decl) = true;
if (TREE_CODE (decl) == TEMPLATE_DECL)
......@@ -7614,6 +7622,10 @@ trees_in::decl_value ()
set_overrun ();
return NULL_TREE;
}
unsigned saved_unused = unused;
unused = 0;
merge_kind mk = merge_kind (mk_u);
tree decl = start ();
......@@ -7718,6 +7730,7 @@ trees_in::decl_value ()
back_refs[~tag] = NULL_TREE;
set_overrun ();
/* Bail. */
unused = saved_unused;
return NULL_TREE;
}
......@@ -7955,6 +7968,7 @@ trees_in::decl_value ()
}
}
unused = saved_unused;
return decl;
}
......@@ -8810,7 +8824,7 @@ trees_out::tree_node (tree t)
/* Stream in a tree node. */
tree
trees_in::tree_node ()
trees_in::tree_node (bool is_use)
{
if (get_overrun ())
return NULL_TREE;
......@@ -9292,9 +9306,7 @@ trees_in::tree_node ()
for (res = CLASSTYPE_VTABLES (ctx); res; res = DECL_CHAIN (res))
if (!ix--)
break;
if (res)
mark_used (res, tf_none);
else
if (!res)
set_overrun ();
}
break;
......@@ -9398,6 +9410,23 @@ trees_in::tree_node ()
break;
}
if (is_use && !unused && res && DECL_P (res) && !TREE_USED (res))
{
/* Mark decl used as mark_used does -- we cannot call
mark_used in the middle of streaming, we only need a subset
of its functionality. */
TREE_USED (res) = true;
/* And for structured bindings also the underlying decl. */
if (DECL_DECOMPOSITION_P (res) && DECL_DECOMP_BASE (res))
TREE_USED (DECL_DECOMP_BASE (res)) = true;
if (DECL_CLONED_FUNCTION_P (res))
TREE_USED (DECL_CLONED_FUNCTION (res)) = true;
// FIXME: What about the enum const debug thingy?
}
dump.outdent ();
return res;
}
......@@ -11000,6 +11029,8 @@ trees_in::read_function_def (tree decl, tree maybe_template)
return true;
}
// Also for CONCEPT_DECLs
void
trees_out::write_var_def (tree decl)
{
......@@ -11014,7 +11045,11 @@ trees_out::mark_var_def (tree)
bool
trees_in::read_var_def (tree decl, tree maybe_template)
{
/* Do not mark the virtual table entries as used. */
bool vtable = TREE_CODE (decl) == VAR_DECL && DECL_VTABLE_OR_VTT_P (decl);
unused += vtable;
tree init = tree_node ();
unused -= vtable;
if (get_overrun ())
return false;
......@@ -12943,7 +12978,7 @@ depset::hash::connect ()
/* Load the entities referred to by this pendset. */
static bool
pendset_lazy_load (pendset *pendings)
pendset_lazy_load (pendset *pendings, bool specializations_p)
{
bool ok = true;
......@@ -12953,8 +12988,10 @@ pendset_lazy_load (pendset *pendings)
if (index & ~(~0u >> 1))
{
/* An indirection. */
pendset *other = pending_table->get (~index, true);
if (!pendset_lazy_load (other))
if (specializations_p)
index = ~index;
pendset *other = pending_table->get (index, true);
if (!pendset_lazy_load (other, specializations_p))
ok = false;
}
else
......@@ -13142,6 +13179,11 @@ get_primary (module_state *parent)
{
while (parent->is_partition ())
parent = parent->parent;
if (!parent->name)
// Implementation unit has null name
parent = parent->parent;
return parent;
}
......@@ -14572,7 +14614,7 @@ void
module_state::write_entities (elf_out *to, vec<depset *> depsets,
unsigned count, unsigned *crc_p)
{
dump () && dump ("Writing entites");
dump () && dump ("Writing entities");
dump.indent ();
bytes_out sec (to);
......@@ -17976,7 +18018,7 @@ lazy_load_specializations (tree tmpl)
&& dump ("Reading %u pending specializations keyed to %M[%u] %N",
set->num, import_entity_module (ident),
ident - import_entity_module (ident)->entity_lwm, tmpl);
if (!pendset_lazy_load (set))
if (!pendset_lazy_load (set, true))
ok = false;
dump.pop (n);
......@@ -18023,7 +18065,7 @@ lazy_load_members (tree decl)
dump () && dump ("Reading %u pending members keyed to %M[%u] %N",
set->num, import_entity_module (ident),
ident - import_entity_module (ident)->entity_lwm, decl);
pendset_lazy_load (set);
pendset_lazy_load (set, false);
dump.pop (n);
function_depth--;
......
......@@ -5840,9 +5840,23 @@ get_namespace_binding (tree ns, tree name)
if (ret && TREE_CODE (ret) == MODULE_VECTOR)
{
// FIXME: We should really be pulling out this TU's definition,
// and then dealing with duplicate discovery in push_decl. But
// the users of get_namespace_binding are generally unprepared
// to deal with that happening. So fake things by looking in
// the global slot.
unsigned ix = MODULE_SLOT_GLOBAL / MODULE_VECTOR_SLOTS_PER_CLUSTER;
unsigned off = MODULE_SLOT_GLOBAL % MODULE_VECTOR_SLOTS_PER_CLUSTER;
ret = MODULE_VECTOR_CLUSTER (ret, ix).slots[off];
/* The GLOBAL slot is always OVERLOADS. For robustness the
rest of the compiler should already be coping with that.
But it rarely expects that for its library interface. */
if (ret)
{
gcc_checking_assert (TREE_CODE (ret) == OVERLOAD);
if (!OVL_CHAIN (ret))
ret = OVL_FUNCTION (ret);
}
}
timevar_cond_stop (TV_NAME_LOOKUP, subtime);
......
// { dg-additional-options -fmodule-header }
// { dg-module-cmi {} }
#define bibity cpp-6_b.H
// { dg-additional-options -fmodule-header }
// { dg-module-cmi {} }
#define bobity cpp-6_b
// { dg-do preprocess }
// { dg-additional-options "-fmodules-ts -isystem [srcdir]" }
#define empty
#define nop(X) X
ONE bibity bobity
import <cpp-6_a.H>;
TWO bibity bobity
import empty nop(<bibity>);
THREE bibity bobity
import empty <bobity.H>;
FOUR bibity bobity
// { dg-final { scan-file cpp-6_c.i {ONE bibity bobity\n} } }
// { dg-final { scan-file cpp-6_c.i {TWO cpp-6_b.H bobity\n} } }
// { dg-final { scan-file cpp-6_c.i {THREE cpp-6_b.H cpp-6_b\n} } }
// { dg-final { scan-file cpp-6_c.i {FOUR cpp-6_b.H cpp-6_b\n} } }
......@@ -2,10 +2,6 @@
import "iostream-1_a.H";
// This hack is needed for the moment. iostream contains a static var
// definition by which it invokes its global ctors.
// static std::ios_base::Init __ioinit;
int main ()
{
std::cout << "hello world!\n";
......
// { dg-additional-options -fmodules-ts }
// Make sure we're not confused by an imported declaration of a
// library fn
export module foo;
// { dg-module-cmi foo }
export inline void thrower ()
{
try
{
throw 1;
}
catch (...)
{
}
}
// { dg-additional-options -fmodules-ts }
import foo;
void bar ()
{
thrower ();
}
void baz ()
{
try
{
throw 1;
}
catch (...)
{
}
}
// { dg-module-do link }
// { dg-additional-options -fmodules-ts }
export module foo:exp;
// { dg-module-cmi foo:exp }
export class Foo
{
Foo ();
public:
void Func ();
static Foo *Factory ();
};
// { dg-additional-options -fmodules-ts }
export module foo;
// { dg-module-cmi foo }
export import :exp;
// { dg-additional-options -fmodules-ts }
module foo:bits;
import :exp;
void Foo::Func ()
{
}
inline Foo::Foo ()
{
}
// { dg-additional-options -fmodules-ts }
module foo;
import :bits;
Foo *Foo::Factory ()
{
return new Foo ();
}
// { dg-additional-options -fmodules-ts }
import foo;
int main ()
{
Foo::Factory ()->Func ();
}
// { dg-additional-options -fmodule-header }
// { dg-module-cmi {} }
inline int frob (int x)
{
return x;
}
// { dg-additional-options -fmodule-header }
// { dg-module-cmi {} }
import "used-1_a.H";
inline int wrapper (int x)
{
return frob (x);
}
// { dg-additional-options -fmodules-ts }
import "used-1_b.H";
int main ()
{
return wrapper (0);
}
// { dg-final { scan-assembler {_Z4frobi:} } }
......@@ -2936,6 +2936,8 @@ cpp_get_token_1 (cpp_reader *pfile, location_t *location)
pfile->about_to_expand_macro_p = saved_about_to_expand_macro;
if (pfile->state.directive_file_token
&& !pfile->state.parsing_args
&& !(result->type == CPP_PADDING || result->type == CPP_COMMENT)
&& !(15 & --pfile->state.directive_file_token))
{
/* Do header-name frobbery. Concatenate < ... > as approprate.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment