-- >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);