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 <nathanielosh...@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); -- 2.43.2