Message ID | 6689f9e2.050a0220.e5708.3f2d@mx.google.com |
---|---|
State | New |
Headers | show |
Series | [1/3] c++: Introduce USING_DECLs for non-function usings [PR114683] | expand |
On 7/6/24 10:13 PM, Nathaniel Shead wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? > > I have also been working on a patch that uses the locations of > using-decls in 'diagnose_name_conflict' and 'duplicate_decls' calls, but > that will need a fair bit more work that I'll probaby put off for the > meantime. Otherwise, as far as I can tell there's no circumstance when > modules-imported namespace-scope USING_DECLs have their locations > printed (hence the lack of tests), so I'm happy to defer this patch > until I've made something I can actually test. > > An alternative approach here (rather than giving locations to OVERLOADs) > would be to rewrite the modules handling to not using OVERLOADs > internally for non-function usings, that way we can attach the location > to those USING_DECLs. I went this way because I felt having locations > in OVL_USING_P overloads would be useful anyway, but happy to try that > route instead if you're uncomfortable increasing the size of most > OVERLOADs for something largely unused. That sounds better to me. > -- >8 -- > > This is used by module streaming to track locations of USING_DECLs (that > are internally wrapped and unwrapped as OVERLOADs for consistency with > function usings). No testcases with this patch as there aren't any easy > ways to actually cause a diagnostic that uses this information yet; > that'll come in a later patch. > > gcc/cp/ChangeLog: > > * cp-tree.h (OVL_SOURCE_LOCATION): New. > (struct tree_overload): Add loc field. > (class ovl_iterator): New member function. > * module.cc (depset::hash::add_binding_entity): Add parameter. > Track locations of usings. > (depset::hash::find_dependencies): Note locations of usings. > (module_state::write_cluster): Write locations of usings. > (module_state::read_cluster): Read locations of usings. > * name-lookup.cc (ovl_iterator::source_location): New. > (walk_module_binding): Add parameter to callback. Provide > locations of usings. > * name-lookup.h (walk_module_binding): Add parameter to > callback. > * ptree.cc (cxx_print_xnode): Write using location. > * tree.cc (ovl_insert): Initialise source location for usings. > (lookup_maybe_add): Propagate source location for usings. > > Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> > --- > gcc/cp/cp-tree.h | 6 ++++++ > gcc/cp/module.cc | 29 +++++++++++++++++++---------- > gcc/cp/name-lookup.cc | 32 ++++++++++++++++++++++++++------ > gcc/cp/name-lookup.h | 3 ++- > gcc/cp/ptree.cc | 6 ++++++ > gcc/cp/tree.cc | 2 ++ > 6 files changed, 61 insertions(+), 17 deletions(-) > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 8732b7dc71b..cc7c1947f9e 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -824,6 +824,10 @@ typedef struct ptrmem_cst * ptrmem_cst_t; > /* The name of the overload set. */ > #define OVL_NAME(NODE) DECL_NAME (OVL_FIRST (NODE)) > > +/* The source location of this OVL_USING_P overload. */ > +#define OVL_SOURCE_LOCATION(NODE) \ > + (((struct tree_overload*)OVERLOAD_CHECK (NODE))->loc) > + > /* Whether this is a set of overloaded functions. TEMPLATE_DECLS are > always wrapped in an OVERLOAD, so we don't need to check them > here. */ > @@ -838,6 +842,7 @@ typedef struct ptrmem_cst * ptrmem_cst_t; > struct GTY(()) tree_overload { > struct tree_common common; > tree function; > + location_t loc; > }; > > /* Iterator for a 1 dimensional overload. Permits iterating over the > @@ -895,6 +900,7 @@ class ovl_iterator { > } > bool purview_p () const; > bool exporting_p () const; > + location_t source_location () const; > > public: > tree remove_node (tree head) > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > index f5966fc8c1c..5bb3e824acb 100644 > --- a/gcc/cp/module.cc > +++ b/gcc/cp/module.cc > @@ -2581,7 +2581,7 @@ public: > void add_namespace_context (depset *, tree ns); > > private: > - static bool add_binding_entity (tree, WMB_Flags, void *); > + static bool add_binding_entity (tree, WMB_Flags, void *, location_t); > > public: > bool add_namespace_entities (tree ns, bitmap partitions); > @@ -13122,7 +13122,8 @@ struct add_binding_data > /* Return true if we are, or contain something that is exported. */ > > bool > -depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) > +depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_, > + location_t loc) > { > auto data = static_cast <add_binding_data *> (data_); > decl = strip_using_decl (decl); > @@ -13185,7 +13186,6 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) > { > 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); > @@ -13229,6 +13229,7 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) > OVL_PURVIEW_P (decl) = true; > if (flags & WMB_Export) > OVL_EXPORT_P (decl) = true; > + OVL_SOURCE_LOCATION (decl) = loc; > } > > depset *dep = data->hash->make_dependency > @@ -13616,7 +13617,10 @@ depset::hash::find_dependencies (module_state *module) > dump.indent (); > walker.begin (); > if (current->get_entity_kind () == EK_USING) > - walker.tree_node (OVL_FUNCTION (decl)); > + { > + module->note_location (OVL_SOURCE_LOCATION (decl)); > + walker.tree_node (OVL_FUNCTION (decl)); > + } > else if (TREE_VISITED (decl)) > /* A global tree. */; > else if (item->get_entity_kind () == EK_NAMESPACE) > @@ -15114,6 +15118,7 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, > depset *dep = b->deps[jx]; > tree bound = dep->get_entity (); > unsigned flags = 0; > + location_t loc = UNKNOWN_LOCATION; > if (dep->get_entity_kind () == depset::EK_USING) > { > tree ovl = bound; > @@ -15126,6 +15131,7 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, > flags |= cbf_using; > if (OVL_EXPORT_P (ovl)) > flags |= cbf_export; > + loc = OVL_SOURCE_LOCATION (ovl); > } > else > { > @@ -15140,6 +15146,8 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, > gcc_checking_assert (DECL_P (bound)); > > sec.i (flags); > + if (flags & cbf_using) > + write_location (sec, loc); > sec.tree_node (bound); > } > > @@ -15281,6 +15289,10 @@ module_state::read_cluster (unsigned snum) > && (flags & (cbf_using | cbf_export))) > sec.set_overrun (); > > + location_t loc = UNKNOWN_LOCATION; > + if (flags & cbf_using) > + loc = read_location (sec); > + > tree decl = sec.tree_node (); > if (sec.get_overrun ()) > break; > @@ -15291,8 +15303,7 @@ module_state::read_cluster (unsigned snum) > if (type || !DECL_IMPLICIT_TYPEDEF_P (decl)) > sec.set_overrun (); > > - type = build_lang_decl_loc (UNKNOWN_LOCATION, > - USING_DECL, > + type = build_lang_decl_loc (loc, USING_DECL, > DECL_NAME (decl), > NULL_TREE); > USING_DECL_DECLS (type) = decl; > @@ -15313,10 +15324,7 @@ module_state::read_cluster (unsigned snum) > if (decls) > sec.set_overrun (); > > - /* FIXME: Propagate the location of the using-decl > - for use in diagnostics. */ > - decls = build_lang_decl_loc (UNKNOWN_LOCATION, > - USING_DECL, > + decls = build_lang_decl_loc (loc, USING_DECL, > DECL_NAME (decl), > NULL_TREE); > USING_DECL_DECLS (decls) = decl; > @@ -15339,6 +15347,7 @@ module_state::read_cluster (unsigned snum) > OVL_PURVIEW_P (decls) = true; > if (flags & cbf_export) > OVL_EXPORT_P (decls) = true; > + OVL_SOURCE_LOCATION (decls) = loc; > } > > if (flags & cbf_hidden) > diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc > index 96d7f938162..52c07e46d4f 100644 > --- a/gcc/cp/name-lookup.cc > +++ b/gcc/cp/name-lookup.cc > @@ -4229,6 +4229,17 @@ ovl_iterator::exporting_p () const > return OVL_EXPORT_P (ovl); > } > > +/* The declared source location of this using. */ > + > +location_t > +ovl_iterator::source_location () const > +{ > + gcc_checking_assert (using_p ()); > + if (TREE_CODE (ovl) == USING_DECL) > + return DECL_SOURCE_LOCATION (ovl); > + return OVL_SOURCE_LOCATION (ovl); > +} > + > /* Given a namespace-level binding BINDING, walk it, calling CALLBACK > for all decls of the current module. When partitions are involved, > decls might be mentioned more than once. Return the accumulation of > @@ -4236,7 +4247,8 @@ ovl_iterator::exporting_p () const > > unsigned > walk_module_binding (tree binding, bitmap partitions, > - bool (*callback) (tree decl, WMB_Flags, void *data), > + bool (*callback) (tree decl, WMB_Flags, void *data, > + location_t loc), > void *data) > { > tree current = binding; > @@ -4249,6 +4261,7 @@ walk_module_binding (tree binding, bitmap partitions, > if (tree type = MAYBE_STAT_TYPE (current)) > { > WMB_Flags flags = WMB_None; > + location_t loc = UNKNOWN_LOCATION; > if (STAT_TYPE_HIDDEN_P (current)) > flags = WMB_Flags (flags | WMB_Hidden); > if (TREE_CODE (type) == USING_DECL) > @@ -4258,8 +4271,9 @@ walk_module_binding (tree binding, bitmap partitions, > flags = WMB_Flags (flags | WMB_Purview); > if (DECL_MODULE_EXPORT_P (type)) > flags = WMB_Flags (flags | WMB_Export); > + loc = DECL_SOURCE_LOCATION (type); > } > - count += callback (type, flags, data); > + count += callback (type, flags, data, loc); > decl_hidden = STAT_DECL_HIDDEN_P (current); > } > > @@ -4270,6 +4284,7 @@ walk_module_binding (tree binding, bitmap partitions, > if (!(decl_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter))) > { > WMB_Flags flags = WMB_None; > + location_t loc = UNKNOWN_LOCATION; > if (decl_hidden) > flags = WMB_Flags (flags | WMB_Hidden); > if (iter.using_p ()) > @@ -4279,8 +4294,9 @@ walk_module_binding (tree binding, bitmap partitions, > flags = WMB_Flags (flags | WMB_Purview); > if (iter.exporting_p ()) > flags = WMB_Flags (flags | WMB_Export); > + loc = iter.source_location (); > } > - count += callback (*iter, flags, data); > + count += callback (*iter, flags, data, loc); > } > decl_hidden = false; > } > @@ -4319,13 +4335,14 @@ walk_module_binding (tree binding, bitmap partitions, > WMB_Flags flags = WMB_None; > if (maybe_dups) > flags = WMB_Flags (flags | WMB_Dups); > - count += callback (bind, flags, data); > + count += callback (bind, flags, data, UNKNOWN_LOCATION); > } > else if (STAT_HACK_P (bind) && MODULE_BINDING_PARTITION_P (bind)) > { > if (tree btype = STAT_TYPE (bind)) > { > WMB_Flags flags = WMB_None; > + location_t loc = UNKNOWN_LOCATION; > if (maybe_dups) > flags = WMB_Flags (flags | WMB_Dups); > if (STAT_TYPE_HIDDEN_P (bind)) > @@ -4337,8 +4354,9 @@ walk_module_binding (tree binding, bitmap partitions, > flags = WMB_Flags (flags | WMB_Purview); > if (DECL_MODULE_EXPORT_P (btype)) > flags = WMB_Flags (flags | WMB_Export); > + loc = DECL_SOURCE_LOCATION (btype); > } > - count += callback (btype, flags, data); > + count += callback (btype, flags, data, loc); > } > bool part_hidden = STAT_DECL_HIDDEN_P (bind); > for (ovl_iterator iter (MAYBE_STAT_DECL (STAT_DECL (bind))); > @@ -4350,6 +4368,7 @@ walk_module_binding (tree binding, bitmap partitions, > (!(part_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter))); > > WMB_Flags flags = WMB_None; > + location_t loc = UNKNOWN_LOCATION; > if (maybe_dups) > flags = WMB_Flags (flags | WMB_Dups); > if (part_hidden) > @@ -4361,8 +4380,9 @@ walk_module_binding (tree binding, bitmap partitions, > flags = WMB_Flags (flags | WMB_Purview); > if (iter.exporting_p ()) > flags = WMB_Flags (flags | WMB_Export); > + loc = iter.source_location (); > } > - count += callback (*iter, flags, data); > + count += callback (*iter, flags, data, loc); > part_hidden = false; > } > } > diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h > index 5cf6ae6374a..8183cd50159 100644 > --- a/gcc/cp/name-lookup.h > +++ b/gcc/cp/name-lookup.h > @@ -499,7 +499,8 @@ enum WMB_Flags > }; > > extern unsigned walk_module_binding (tree binding, bitmap partitions, > - bool (*)(tree decl, WMB_Flags, void *data), > + bool (*)(tree decl, WMB_Flags, void *data, > + location_t loc), > void *data); > extern tree add_imported_namespace (tree ctx, tree name, location_t, > unsigned module, > diff --git a/gcc/cp/ptree.cc b/gcc/cp/ptree.cc > index 15e46752d01..4f7fc96cc74 100644 > --- a/gcc/cp/ptree.cc > +++ b/gcc/cp/ptree.cc > @@ -299,6 +299,12 @@ cxx_print_xnode (FILE *file, tree node, int indent) > print_node (file, "optype", BASELINK_OPTYPE (node), indent + 4); > break; > case OVERLOAD: > + if (location_t loc = OVL_SOURCE_LOCATION (node)) > + { > + expanded_location xloc = expand_location (loc); > + indent_to (file, indent + 4); > + fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column); > + } > print_node (file, "function", OVL_FUNCTION (node), indent + 4); > print_node (file, "next", OVL_CHAIN (node), indent + 4); > break; > diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc > index dfd4a3a948b..21d8e0de329 100644 > --- a/gcc/cp/tree.cc > +++ b/gcc/cp/tree.cc > @@ -2387,6 +2387,7 @@ ovl_insert (tree fn, tree maybe_ovl, int using_or_hidden) > OVL_PURVIEW_P (maybe_ovl) = true; > if (using_or_hidden > 2) > OVL_EXPORT_P (maybe_ovl) = true; > + OVL_SOURCE_LOCATION (maybe_ovl) = input_location; > } > } > else > @@ -2532,6 +2533,7 @@ lookup_maybe_add (tree fns, tree lookup, bool deduping) > { > lookup = ovl_make (OVL_FUNCTION (fns), lookup); > OVL_USING_P (lookup) = true; > + OVL_SOURCE_LOCATION (lookup) = OVL_SOURCE_LOCATION (fns); > } > else > lookup = lookup_add (OVL_FUNCTION (fns), lookup);
On Mon, Jul 08, 2024 at 02:24:14PM -0400, Jason Merrill wrote: > On 7/6/24 10:13 PM, Nathaniel Shead wrote: > > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? > > > > I have also been working on a patch that uses the locations of > > using-decls in 'diagnose_name_conflict' and 'duplicate_decls' calls, but > > that will need a fair bit more work that I'll probaby put off for the > > meantime. Otherwise, as far as I can tell there's no circumstance when > > modules-imported namespace-scope USING_DECLs have their locations > > printed (hence the lack of tests), so I'm happy to defer this patch > > until I've made something I can actually test. > > > > An alternative approach here (rather than giving locations to OVERLOADs) > > would be to rewrite the modules handling to not using OVERLOADs > > internally for non-function usings, that way we can attach the location > > to those USING_DECLs. I went this way because I felt having locations > > in OVL_USING_P overloads would be useful anyway, but happy to try that > > route instead if you're uncomfortable increasing the size of most > > OVERLOADs for something largely unused. > > That sounds better to me. OK. Just for some additional context, the diagnostics I was thinking of were in regards to PR c++/106851; currently the 'conflicts with' for such declarations just point to an apparently unrelated declaration in a different namespace, and provides no indication of the using-declaration that brought it into scope. Ideally I'd like to add another "note: brought into scope here" message for all such conflicts with using-decls, but that means that we need to actually track this for function using-decls too. That said, I imagine we could do this by instead of having a flag on the OVERLOAD, instead have the OVERLOAD wrap a USING_DECL that has this location on it. Which may be slightly less confusing, and should also optimise for the (I expect?) common case of overloads not being usings. Nathaniel > > > -- >8 -- > > > > This is used by module streaming to track locations of USING_DECLs (that > > are internally wrapped and unwrapped as OVERLOADs for consistency with > > function usings). No testcases with this patch as there aren't any easy > > ways to actually cause a diagnostic that uses this information yet; > > that'll come in a later patch. > > > > gcc/cp/ChangeLog: > > > > * cp-tree.h (OVL_SOURCE_LOCATION): New. > > (struct tree_overload): Add loc field. > > (class ovl_iterator): New member function. > > * module.cc (depset::hash::add_binding_entity): Add parameter. > > Track locations of usings. > > (depset::hash::find_dependencies): Note locations of usings. > > (module_state::write_cluster): Write locations of usings. > > (module_state::read_cluster): Read locations of usings. > > * name-lookup.cc (ovl_iterator::source_location): New. > > (walk_module_binding): Add parameter to callback. Provide > > locations of usings. > > * name-lookup.h (walk_module_binding): Add parameter to > > callback. > > * ptree.cc (cxx_print_xnode): Write using location. > > * tree.cc (ovl_insert): Initialise source location for usings. > > (lookup_maybe_add): Propagate source location for usings. > > > > Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> > > --- > > gcc/cp/cp-tree.h | 6 ++++++ > > gcc/cp/module.cc | 29 +++++++++++++++++++---------- > > gcc/cp/name-lookup.cc | 32 ++++++++++++++++++++++++++------ > > gcc/cp/name-lookup.h | 3 ++- > > gcc/cp/ptree.cc | 6 ++++++ > > gcc/cp/tree.cc | 2 ++ > > 6 files changed, 61 insertions(+), 17 deletions(-) > > > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > > index 8732b7dc71b..cc7c1947f9e 100644 > > --- a/gcc/cp/cp-tree.h > > +++ b/gcc/cp/cp-tree.h > > @@ -824,6 +824,10 @@ typedef struct ptrmem_cst * ptrmem_cst_t; > > /* The name of the overload set. */ > > #define OVL_NAME(NODE) DECL_NAME (OVL_FIRST (NODE)) > > +/* The source location of this OVL_USING_P overload. */ > > +#define OVL_SOURCE_LOCATION(NODE) \ > > + (((struct tree_overload*)OVERLOAD_CHECK (NODE))->loc) > > + > > /* Whether this is a set of overloaded functions. TEMPLATE_DECLS are > > always wrapped in an OVERLOAD, so we don't need to check them > > here. */ > > @@ -838,6 +842,7 @@ typedef struct ptrmem_cst * ptrmem_cst_t; > > struct GTY(()) tree_overload { > > struct tree_common common; > > tree function; > > + location_t loc; > > }; > > /* Iterator for a 1 dimensional overload. Permits iterating over the > > @@ -895,6 +900,7 @@ class ovl_iterator { > > } > > bool purview_p () const; > > bool exporting_p () const; > > + location_t source_location () const; > > public: > > tree remove_node (tree head) > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > > index f5966fc8c1c..5bb3e824acb 100644 > > --- a/gcc/cp/module.cc > > +++ b/gcc/cp/module.cc > > @@ -2581,7 +2581,7 @@ public: > > void add_namespace_context (depset *, tree ns); > > private: > > - static bool add_binding_entity (tree, WMB_Flags, void *); > > + static bool add_binding_entity (tree, WMB_Flags, void *, location_t); > > public: > > bool add_namespace_entities (tree ns, bitmap partitions); > > @@ -13122,7 +13122,8 @@ struct add_binding_data > > /* Return true if we are, or contain something that is exported. */ > > bool > > -depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) > > +depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_, > > + location_t loc) > > { > > auto data = static_cast <add_binding_data *> (data_); > > decl = strip_using_decl (decl); > > @@ -13185,7 +13186,6 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) > > { > > 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); > > @@ -13229,6 +13229,7 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) > > OVL_PURVIEW_P (decl) = true; > > if (flags & WMB_Export) > > OVL_EXPORT_P (decl) = true; > > + OVL_SOURCE_LOCATION (decl) = loc; > > } > > depset *dep = data->hash->make_dependency > > @@ -13616,7 +13617,10 @@ depset::hash::find_dependencies (module_state *module) > > dump.indent (); > > walker.begin (); > > if (current->get_entity_kind () == EK_USING) > > - walker.tree_node (OVL_FUNCTION (decl)); > > + { > > + module->note_location (OVL_SOURCE_LOCATION (decl)); > > + walker.tree_node (OVL_FUNCTION (decl)); > > + } > > else if (TREE_VISITED (decl)) > > /* A global tree. */; > > else if (item->get_entity_kind () == EK_NAMESPACE) > > @@ -15114,6 +15118,7 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, > > depset *dep = b->deps[jx]; > > tree bound = dep->get_entity (); > > unsigned flags = 0; > > + location_t loc = UNKNOWN_LOCATION; > > if (dep->get_entity_kind () == depset::EK_USING) > > { > > tree ovl = bound; > > @@ -15126,6 +15131,7 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, > > flags |= cbf_using; > > if (OVL_EXPORT_P (ovl)) > > flags |= cbf_export; > > + loc = OVL_SOURCE_LOCATION (ovl); > > } > > else > > { > > @@ -15140,6 +15146,8 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, > > gcc_checking_assert (DECL_P (bound)); > > sec.i (flags); > > + if (flags & cbf_using) > > + write_location (sec, loc); > > sec.tree_node (bound); > > } > > @@ -15281,6 +15289,10 @@ module_state::read_cluster (unsigned snum) > > && (flags & (cbf_using | cbf_export))) > > sec.set_overrun (); > > + location_t loc = UNKNOWN_LOCATION; > > + if (flags & cbf_using) > > + loc = read_location (sec); > > + > > tree decl = sec.tree_node (); > > if (sec.get_overrun ()) > > break; > > @@ -15291,8 +15303,7 @@ module_state::read_cluster (unsigned snum) > > if (type || !DECL_IMPLICIT_TYPEDEF_P (decl)) > > sec.set_overrun (); > > - type = build_lang_decl_loc (UNKNOWN_LOCATION, > > - USING_DECL, > > + type = build_lang_decl_loc (loc, USING_DECL, > > DECL_NAME (decl), > > NULL_TREE); > > USING_DECL_DECLS (type) = decl; > > @@ -15313,10 +15324,7 @@ module_state::read_cluster (unsigned snum) > > if (decls) > > sec.set_overrun (); > > - /* FIXME: Propagate the location of the using-decl > > - for use in diagnostics. */ > > - decls = build_lang_decl_loc (UNKNOWN_LOCATION, > > - USING_DECL, > > + decls = build_lang_decl_loc (loc, USING_DECL, > > DECL_NAME (decl), > > NULL_TREE); > > USING_DECL_DECLS (decls) = decl; > > @@ -15339,6 +15347,7 @@ module_state::read_cluster (unsigned snum) > > OVL_PURVIEW_P (decls) = true; > > if (flags & cbf_export) > > OVL_EXPORT_P (decls) = true; > > + OVL_SOURCE_LOCATION (decls) = loc; > > } > > if (flags & cbf_hidden) > > diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc > > index 96d7f938162..52c07e46d4f 100644 > > --- a/gcc/cp/name-lookup.cc > > +++ b/gcc/cp/name-lookup.cc > > @@ -4229,6 +4229,17 @@ ovl_iterator::exporting_p () const > > return OVL_EXPORT_P (ovl); > > } > > +/* The declared source location of this using. */ > > + > > +location_t > > +ovl_iterator::source_location () const > > +{ > > + gcc_checking_assert (using_p ()); > > + if (TREE_CODE (ovl) == USING_DECL) > > + return DECL_SOURCE_LOCATION (ovl); > > + return OVL_SOURCE_LOCATION (ovl); > > +} > > + > > /* Given a namespace-level binding BINDING, walk it, calling CALLBACK > > for all decls of the current module. When partitions are involved, > > decls might be mentioned more than once. Return the accumulation of > > @@ -4236,7 +4247,8 @@ ovl_iterator::exporting_p () const > > unsigned > > walk_module_binding (tree binding, bitmap partitions, > > - bool (*callback) (tree decl, WMB_Flags, void *data), > > + bool (*callback) (tree decl, WMB_Flags, void *data, > > + location_t loc), > > void *data) > > { > > tree current = binding; > > @@ -4249,6 +4261,7 @@ walk_module_binding (tree binding, bitmap partitions, > > if (tree type = MAYBE_STAT_TYPE (current)) > > { > > WMB_Flags flags = WMB_None; > > + location_t loc = UNKNOWN_LOCATION; > > if (STAT_TYPE_HIDDEN_P (current)) > > flags = WMB_Flags (flags | WMB_Hidden); > > if (TREE_CODE (type) == USING_DECL) > > @@ -4258,8 +4271,9 @@ walk_module_binding (tree binding, bitmap partitions, > > flags = WMB_Flags (flags | WMB_Purview); > > if (DECL_MODULE_EXPORT_P (type)) > > flags = WMB_Flags (flags | WMB_Export); > > + loc = DECL_SOURCE_LOCATION (type); > > } > > - count += callback (type, flags, data); > > + count += callback (type, flags, data, loc); > > decl_hidden = STAT_DECL_HIDDEN_P (current); > > } > > @@ -4270,6 +4284,7 @@ walk_module_binding (tree binding, bitmap partitions, > > if (!(decl_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter))) > > { > > WMB_Flags flags = WMB_None; > > + location_t loc = UNKNOWN_LOCATION; > > if (decl_hidden) > > flags = WMB_Flags (flags | WMB_Hidden); > > if (iter.using_p ()) > > @@ -4279,8 +4294,9 @@ walk_module_binding (tree binding, bitmap partitions, > > flags = WMB_Flags (flags | WMB_Purview); > > if (iter.exporting_p ()) > > flags = WMB_Flags (flags | WMB_Export); > > + loc = iter.source_location (); > > } > > - count += callback (*iter, flags, data); > > + count += callback (*iter, flags, data, loc); > > } > > decl_hidden = false; > > } > > @@ -4319,13 +4335,14 @@ walk_module_binding (tree binding, bitmap partitions, > > WMB_Flags flags = WMB_None; > > if (maybe_dups) > > flags = WMB_Flags (flags | WMB_Dups); > > - count += callback (bind, flags, data); > > + count += callback (bind, flags, data, UNKNOWN_LOCATION); > > } > > else if (STAT_HACK_P (bind) && MODULE_BINDING_PARTITION_P (bind)) > > { > > if (tree btype = STAT_TYPE (bind)) > > { > > WMB_Flags flags = WMB_None; > > + location_t loc = UNKNOWN_LOCATION; > > if (maybe_dups) > > flags = WMB_Flags (flags | WMB_Dups); > > if (STAT_TYPE_HIDDEN_P (bind)) > > @@ -4337,8 +4354,9 @@ walk_module_binding (tree binding, bitmap partitions, > > flags = WMB_Flags (flags | WMB_Purview); > > if (DECL_MODULE_EXPORT_P (btype)) > > flags = WMB_Flags (flags | WMB_Export); > > + loc = DECL_SOURCE_LOCATION (btype); > > } > > - count += callback (btype, flags, data); > > + count += callback (btype, flags, data, loc); > > } > > bool part_hidden = STAT_DECL_HIDDEN_P (bind); > > for (ovl_iterator iter (MAYBE_STAT_DECL (STAT_DECL (bind))); > > @@ -4350,6 +4368,7 @@ walk_module_binding (tree binding, bitmap partitions, > > (!(part_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter))); > > WMB_Flags flags = WMB_None; > > + location_t loc = UNKNOWN_LOCATION; > > if (maybe_dups) > > flags = WMB_Flags (flags | WMB_Dups); > > if (part_hidden) > > @@ -4361,8 +4380,9 @@ walk_module_binding (tree binding, bitmap partitions, > > flags = WMB_Flags (flags | WMB_Purview); > > if (iter.exporting_p ()) > > flags = WMB_Flags (flags | WMB_Export); > > + loc = iter.source_location (); > > } > > - count += callback (*iter, flags, data); > > + count += callback (*iter, flags, data, loc); > > part_hidden = false; > > } > > } > > diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h > > index 5cf6ae6374a..8183cd50159 100644 > > --- a/gcc/cp/name-lookup.h > > +++ b/gcc/cp/name-lookup.h > > @@ -499,7 +499,8 @@ enum WMB_Flags > > }; > > extern unsigned walk_module_binding (tree binding, bitmap partitions, > > - bool (*)(tree decl, WMB_Flags, void *data), > > + bool (*)(tree decl, WMB_Flags, void *data, > > + location_t loc), > > void *data); > > extern tree add_imported_namespace (tree ctx, tree name, location_t, > > unsigned module, > > diff --git a/gcc/cp/ptree.cc b/gcc/cp/ptree.cc > > index 15e46752d01..4f7fc96cc74 100644 > > --- a/gcc/cp/ptree.cc > > +++ b/gcc/cp/ptree.cc > > @@ -299,6 +299,12 @@ cxx_print_xnode (FILE *file, tree node, int indent) > > print_node (file, "optype", BASELINK_OPTYPE (node), indent + 4); > > break; > > case OVERLOAD: > > + if (location_t loc = OVL_SOURCE_LOCATION (node)) > > + { > > + expanded_location xloc = expand_location (loc); > > + indent_to (file, indent + 4); > > + fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column); > > + } > > print_node (file, "function", OVL_FUNCTION (node), indent + 4); > > print_node (file, "next", OVL_CHAIN (node), indent + 4); > > break; > > diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc > > index dfd4a3a948b..21d8e0de329 100644 > > --- a/gcc/cp/tree.cc > > +++ b/gcc/cp/tree.cc > > @@ -2387,6 +2387,7 @@ ovl_insert (tree fn, tree maybe_ovl, int using_or_hidden) > > OVL_PURVIEW_P (maybe_ovl) = true; > > if (using_or_hidden > 2) > > OVL_EXPORT_P (maybe_ovl) = true; > > + OVL_SOURCE_LOCATION (maybe_ovl) = input_location; > > } > > } > > else > > @@ -2532,6 +2533,7 @@ lookup_maybe_add (tree fns, tree lookup, bool deduping) > > { > > lookup = ovl_make (OVL_FUNCTION (fns), lookup); > > OVL_USING_P (lookup) = true; > > + OVL_SOURCE_LOCATION (lookup) = OVL_SOURCE_LOCATION (fns); > > } > > else > > lookup = lookup_add (OVL_FUNCTION (fns), lookup); >
On 7/9/24 9:55 AM, Nathaniel Shead wrote: > On Mon, Jul 08, 2024 at 02:24:14PM -0400, Jason Merrill wrote: >> On 7/6/24 10:13 PM, Nathaniel Shead wrote: >>> Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? >>> >>> I have also been working on a patch that uses the locations of >>> using-decls in 'diagnose_name_conflict' and 'duplicate_decls' calls, but >>> that will need a fair bit more work that I'll probaby put off for the >>> meantime. Otherwise, as far as I can tell there's no circumstance when >>> modules-imported namespace-scope USING_DECLs have their locations >>> printed (hence the lack of tests), so I'm happy to defer this patch >>> until I've made something I can actually test. >>> >>> An alternative approach here (rather than giving locations to OVERLOADs) >>> would be to rewrite the modules handling to not using OVERLOADs >>> internally for non-function usings, that way we can attach the location >>> to those USING_DECLs. I went this way because I felt having locations >>> in OVL_USING_P overloads would be useful anyway, but happy to try that >>> route instead if you're uncomfortable increasing the size of most >>> OVERLOADs for something largely unused. >> >> That sounds better to me. > > OK. Just for some additional context, the diagnostics I was thinking of > were in regards to PR c++/106851; currently the 'conflicts with' for > such declarations just point to an apparently unrelated declaration in a > different namespace, and provides no indication of the using-declaration > that brought it into scope. Ideally I'd like to add another "note: brought > into scope here" message for all such conflicts with using-decls, but > that means that we need to actually track this for function using-decls > too. > > That said, I imagine we could do this by instead of having a flag on the > OVERLOAD, instead have the OVERLOAD wrap a USING_DECL that has this > location on it. Which may be slightly less confusing, and should also > optimise for the (I expect?) common case of overloads not being usings. Sure, perhaps instead of individually adding the used decls to the list in the current scope, add a USING_DECL that refers to all of them, and extend ovl_iterator to handle that case. Jason
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8732b7dc71b..cc7c1947f9e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -824,6 +824,10 @@ typedef struct ptrmem_cst * ptrmem_cst_t; /* The name of the overload set. */ #define OVL_NAME(NODE) DECL_NAME (OVL_FIRST (NODE)) +/* The source location of this OVL_USING_P overload. */ +#define OVL_SOURCE_LOCATION(NODE) \ + (((struct tree_overload*)OVERLOAD_CHECK (NODE))->loc) + /* Whether this is a set of overloaded functions. TEMPLATE_DECLS are always wrapped in an OVERLOAD, so we don't need to check them here. */ @@ -838,6 +842,7 @@ typedef struct ptrmem_cst * ptrmem_cst_t; struct GTY(()) tree_overload { struct tree_common common; tree function; + location_t loc; }; /* Iterator for a 1 dimensional overload. Permits iterating over the @@ -895,6 +900,7 @@ class ovl_iterator { } bool purview_p () const; bool exporting_p () const; + location_t source_location () const; public: tree remove_node (tree head) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index f5966fc8c1c..5bb3e824acb 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -2581,7 +2581,7 @@ public: void add_namespace_context (depset *, tree ns); private: - static bool add_binding_entity (tree, WMB_Flags, void *); + static bool add_binding_entity (tree, WMB_Flags, void *, location_t); public: bool add_namespace_entities (tree ns, bitmap partitions); @@ -13122,7 +13122,8 @@ struct add_binding_data /* Return true if we are, or contain something that is exported. */ bool -depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) +depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_, + location_t loc) { auto data = static_cast <add_binding_data *> (data_); decl = strip_using_decl (decl); @@ -13185,7 +13186,6 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) { 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); @@ -13229,6 +13229,7 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) OVL_PURVIEW_P (decl) = true; if (flags & WMB_Export) OVL_EXPORT_P (decl) = true; + OVL_SOURCE_LOCATION (decl) = loc; } depset *dep = data->hash->make_dependency @@ -13616,7 +13617,10 @@ depset::hash::find_dependencies (module_state *module) dump.indent (); walker.begin (); if (current->get_entity_kind () == EK_USING) - walker.tree_node (OVL_FUNCTION (decl)); + { + module->note_location (OVL_SOURCE_LOCATION (decl)); + walker.tree_node (OVL_FUNCTION (decl)); + } else if (TREE_VISITED (decl)) /* A global tree. */; else if (item->get_entity_kind () == EK_NAMESPACE) @@ -15114,6 +15118,7 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, depset *dep = b->deps[jx]; tree bound = dep->get_entity (); unsigned flags = 0; + location_t loc = UNKNOWN_LOCATION; if (dep->get_entity_kind () == depset::EK_USING) { tree ovl = bound; @@ -15126,6 +15131,7 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, flags |= cbf_using; if (OVL_EXPORT_P (ovl)) flags |= cbf_export; + loc = OVL_SOURCE_LOCATION (ovl); } else { @@ -15140,6 +15146,8 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, gcc_checking_assert (DECL_P (bound)); sec.i (flags); + if (flags & cbf_using) + write_location (sec, loc); sec.tree_node (bound); } @@ -15281,6 +15289,10 @@ module_state::read_cluster (unsigned snum) && (flags & (cbf_using | cbf_export))) sec.set_overrun (); + location_t loc = UNKNOWN_LOCATION; + if (flags & cbf_using) + loc = read_location (sec); + tree decl = sec.tree_node (); if (sec.get_overrun ()) break; @@ -15291,8 +15303,7 @@ module_state::read_cluster (unsigned snum) if (type || !DECL_IMPLICIT_TYPEDEF_P (decl)) sec.set_overrun (); - type = build_lang_decl_loc (UNKNOWN_LOCATION, - USING_DECL, + type = build_lang_decl_loc (loc, USING_DECL, DECL_NAME (decl), NULL_TREE); USING_DECL_DECLS (type) = decl; @@ -15313,10 +15324,7 @@ module_state::read_cluster (unsigned snum) if (decls) sec.set_overrun (); - /* FIXME: Propagate the location of the using-decl - for use in diagnostics. */ - decls = build_lang_decl_loc (UNKNOWN_LOCATION, - USING_DECL, + decls = build_lang_decl_loc (loc, USING_DECL, DECL_NAME (decl), NULL_TREE); USING_DECL_DECLS (decls) = decl; @@ -15339,6 +15347,7 @@ module_state::read_cluster (unsigned snum) OVL_PURVIEW_P (decls) = true; if (flags & cbf_export) OVL_EXPORT_P (decls) = true; + OVL_SOURCE_LOCATION (decls) = loc; } if (flags & cbf_hidden) diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 96d7f938162..52c07e46d4f 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -4229,6 +4229,17 @@ ovl_iterator::exporting_p () const return OVL_EXPORT_P (ovl); } +/* The declared source location of this using. */ + +location_t +ovl_iterator::source_location () const +{ + gcc_checking_assert (using_p ()); + if (TREE_CODE (ovl) == USING_DECL) + return DECL_SOURCE_LOCATION (ovl); + return OVL_SOURCE_LOCATION (ovl); +} + /* Given a namespace-level binding BINDING, walk it, calling CALLBACK for all decls of the current module. When partitions are involved, decls might be mentioned more than once. Return the accumulation of @@ -4236,7 +4247,8 @@ ovl_iterator::exporting_p () const unsigned walk_module_binding (tree binding, bitmap partitions, - bool (*callback) (tree decl, WMB_Flags, void *data), + bool (*callback) (tree decl, WMB_Flags, void *data, + location_t loc), void *data) { tree current = binding; @@ -4249,6 +4261,7 @@ walk_module_binding (tree binding, bitmap partitions, if (tree type = MAYBE_STAT_TYPE (current)) { WMB_Flags flags = WMB_None; + location_t loc = UNKNOWN_LOCATION; if (STAT_TYPE_HIDDEN_P (current)) flags = WMB_Flags (flags | WMB_Hidden); if (TREE_CODE (type) == USING_DECL) @@ -4258,8 +4271,9 @@ walk_module_binding (tree binding, bitmap partitions, flags = WMB_Flags (flags | WMB_Purview); if (DECL_MODULE_EXPORT_P (type)) flags = WMB_Flags (flags | WMB_Export); + loc = DECL_SOURCE_LOCATION (type); } - count += callback (type, flags, data); + count += callback (type, flags, data, loc); decl_hidden = STAT_DECL_HIDDEN_P (current); } @@ -4270,6 +4284,7 @@ walk_module_binding (tree binding, bitmap partitions, if (!(decl_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter))) { WMB_Flags flags = WMB_None; + location_t loc = UNKNOWN_LOCATION; if (decl_hidden) flags = WMB_Flags (flags | WMB_Hidden); if (iter.using_p ()) @@ -4279,8 +4294,9 @@ walk_module_binding (tree binding, bitmap partitions, flags = WMB_Flags (flags | WMB_Purview); if (iter.exporting_p ()) flags = WMB_Flags (flags | WMB_Export); + loc = iter.source_location (); } - count += callback (*iter, flags, data); + count += callback (*iter, flags, data, loc); } decl_hidden = false; } @@ -4319,13 +4335,14 @@ walk_module_binding (tree binding, bitmap partitions, WMB_Flags flags = WMB_None; if (maybe_dups) flags = WMB_Flags (flags | WMB_Dups); - count += callback (bind, flags, data); + count += callback (bind, flags, data, UNKNOWN_LOCATION); } else if (STAT_HACK_P (bind) && MODULE_BINDING_PARTITION_P (bind)) { if (tree btype = STAT_TYPE (bind)) { WMB_Flags flags = WMB_None; + location_t loc = UNKNOWN_LOCATION; if (maybe_dups) flags = WMB_Flags (flags | WMB_Dups); if (STAT_TYPE_HIDDEN_P (bind)) @@ -4337,8 +4354,9 @@ walk_module_binding (tree binding, bitmap partitions, flags = WMB_Flags (flags | WMB_Purview); if (DECL_MODULE_EXPORT_P (btype)) flags = WMB_Flags (flags | WMB_Export); + loc = DECL_SOURCE_LOCATION (btype); } - count += callback (btype, flags, data); + count += callback (btype, flags, data, loc); } bool part_hidden = STAT_DECL_HIDDEN_P (bind); for (ovl_iterator iter (MAYBE_STAT_DECL (STAT_DECL (bind))); @@ -4350,6 +4368,7 @@ walk_module_binding (tree binding, bitmap partitions, (!(part_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter))); WMB_Flags flags = WMB_None; + location_t loc = UNKNOWN_LOCATION; if (maybe_dups) flags = WMB_Flags (flags | WMB_Dups); if (part_hidden) @@ -4361,8 +4380,9 @@ walk_module_binding (tree binding, bitmap partitions, flags = WMB_Flags (flags | WMB_Purview); if (iter.exporting_p ()) flags = WMB_Flags (flags | WMB_Export); + loc = iter.source_location (); } - count += callback (*iter, flags, data); + count += callback (*iter, flags, data, loc); part_hidden = false; } } diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 5cf6ae6374a..8183cd50159 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -499,7 +499,8 @@ enum WMB_Flags }; extern unsigned walk_module_binding (tree binding, bitmap partitions, - bool (*)(tree decl, WMB_Flags, void *data), + bool (*)(tree decl, WMB_Flags, void *data, + location_t loc), void *data); extern tree add_imported_namespace (tree ctx, tree name, location_t, unsigned module, diff --git a/gcc/cp/ptree.cc b/gcc/cp/ptree.cc index 15e46752d01..4f7fc96cc74 100644 --- a/gcc/cp/ptree.cc +++ b/gcc/cp/ptree.cc @@ -299,6 +299,12 @@ cxx_print_xnode (FILE *file, tree node, int indent) print_node (file, "optype", BASELINK_OPTYPE (node), indent + 4); break; case OVERLOAD: + if (location_t loc = OVL_SOURCE_LOCATION (node)) + { + expanded_location xloc = expand_location (loc); + indent_to (file, indent + 4); + fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column); + } print_node (file, "function", OVL_FUNCTION (node), indent + 4); print_node (file, "next", OVL_CHAIN (node), indent + 4); break; diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index dfd4a3a948b..21d8e0de329 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -2387,6 +2387,7 @@ ovl_insert (tree fn, tree maybe_ovl, int using_or_hidden) OVL_PURVIEW_P (maybe_ovl) = true; if (using_or_hidden > 2) OVL_EXPORT_P (maybe_ovl) = true; + OVL_SOURCE_LOCATION (maybe_ovl) = input_location; } } else @@ -2532,6 +2533,7 @@ lookup_maybe_add (tree fns, tree lookup, bool deduping) { lookup = ovl_make (OVL_FUNCTION (fns), lookup); OVL_USING_P (lookup) = true; + OVL_SOURCE_LOCATION (lookup) = OVL_SOURCE_LOCATION (fns); } else lookup = lookup_add (OVL_FUNCTION (fns), lookup);
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? I have also been working on a patch that uses the locations of using-decls in 'diagnose_name_conflict' and 'duplicate_decls' calls, but that will need a fair bit more work that I'll probaby put off for the meantime. Otherwise, as far as I can tell there's no circumstance when modules-imported namespace-scope USING_DECLs have their locations printed (hence the lack of tests), so I'm happy to defer this patch until I've made something I can actually test. An alternative approach here (rather than giving locations to OVERLOADs) would be to rewrite the modules handling to not using OVERLOADs internally for non-function usings, that way we can attach the location to those USING_DECLs. I went this way because I felt having locations in OVL_USING_P overloads would be useful anyway, but happy to try that route instead if you're uncomfortable increasing the size of most OVERLOADs for something largely unused. -- >8 -- This is used by module streaming to track locations of USING_DECLs (that are internally wrapped and unwrapped as OVERLOADs for consistency with function usings). No testcases with this patch as there aren't any easy ways to actually cause a diagnostic that uses this information yet; that'll come in a later patch. gcc/cp/ChangeLog: * cp-tree.h (OVL_SOURCE_LOCATION): New. (struct tree_overload): Add loc field. (class ovl_iterator): New member function. * module.cc (depset::hash::add_binding_entity): Add parameter. Track locations of usings. (depset::hash::find_dependencies): Note locations of usings. (module_state::write_cluster): Write locations of usings. (module_state::read_cluster): Read locations of usings. * name-lookup.cc (ovl_iterator::source_location): New. (walk_module_binding): Add parameter to callback. Provide locations of usings. * name-lookup.h (walk_module_binding): Add parameter to callback. * ptree.cc (cxx_print_xnode): Write using location. * tree.cc (ovl_insert): Initialise source location for usings. (lookup_maybe_add): Propagate source location for usings. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> --- gcc/cp/cp-tree.h | 6 ++++++ gcc/cp/module.cc | 29 +++++++++++++++++++---------- gcc/cp/name-lookup.cc | 32 ++++++++++++++++++++++++++------ gcc/cp/name-lookup.h | 3 ++- gcc/cp/ptree.cc | 6 ++++++ gcc/cp/tree.cc | 2 ++ 6 files changed, 61 insertions(+), 17 deletions(-)