Commit d876eb05 by Nathan Sidwell Committed by Nathan Sidwell

cp-tree.h (lang_type): Replace sorted_fields vector with bindings map.

	* cp-tree.h (lang_type): Replace sorted_fields vector with
	bindings map.
	(CLASSTYPE_SORTED_FIELDS): Delete.
	(CLASSTYPE_BINDINGS): New.
	* decl.c (finish_enum_value_list): Swap args of
	insert_late_enum_def_bindings.
	* name-lookup.c (lookup_field_1): Replace binary search of sorted
	fields with map->get.
	(sorted_fields_type_new, count_fields,
	add_fields_to_record_type, add_enum_fields_to_record_type): Delete.
	(add_class_member, add_class_members): New.
	(set_class_bindings): Create map and insert.
	(insert_late_enum_def_binding): Swap parms.  Use add_clasS_member.
	* ptree.c (cxx_print_type): Delete sorted fields printing.

From-SVN: r251388
parent 41970ff1
2017-08-28 Nathan Sidwell <nathan@acm.org> 2017-08-28 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (lang_type): Replace sorted_fields vector with
bindings map.
(CLASSTYPE_SORTED_FIELDS): Delete.
(CLASSTYPE_BINDINGS): New.
* decl.c (finish_enum_value_list): Swap args of
insert_late_enum_def_bindings.
* name-lookup.c (lookup_field_1): Replace binary search of sorted
fields with map->get.
(sorted_fields_type_new, count_fields,
add_fields_to_record_type, add_enum_fields_to_record_type): Delete.
(add_class_member, add_class_members): New.
(set_class_bindings): Create map and insert.
(insert_late_enum_def_binding): Swap parms. Use add_clasS_member.
* ptree.c (cxx_print_type): Delete sorted fields printing.
* cp-tree.h (insert_late_enum_def_into_classtype_sorted_fields): * cp-tree.h (insert_late_enum_def_into_classtype_sorted_fields):
Delete. Delete.
* name-lookup.h (set_class_bindings, * name-lookup.h (set_class_bindings,
......
...@@ -2014,10 +2014,10 @@ struct GTY(()) lang_type { ...@@ -2014,10 +2014,10 @@ struct GTY(()) lang_type {
as a list of adopted protocols or a pointer to a corresponding as a list of adopted protocols or a pointer to a corresponding
@interface. See objc/objc-act.h for details. */ @interface. See objc/objc-act.h for details. */
tree objc_info; tree objc_info;
/* sorted_fields is sorted based on a pointer, so we need to be able
to resort it if pointers get rearranged. */ /* Map from IDENTIFIER nodes to DECLS. */
struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields"))) hash_map<lang_identifier *, tree> *bindings;
sorted_fields;
/* FIXME reuse another field? */ /* FIXME reuse another field? */
tree lambda_expr; tree lambda_expr;
}; };
...@@ -3243,10 +3243,9 @@ extern void decl_shadowed_for_var_insert (tree, tree); ...@@ -3243,10 +3243,9 @@ extern void decl_shadowed_for_var_insert (tree, tree);
&& TREE_CODE (TYPE_NAME (NODE)) == TYPE_DECL \ && TREE_CODE (TYPE_NAME (NODE)) == TYPE_DECL \
&& TYPE_DECL_ALIAS_P (TYPE_NAME (NODE))) && TYPE_DECL_ALIAS_P (TYPE_NAME (NODE)))
/* For a class type: if this structure has many fields, we'll sort them /* The binding map for a class (not always present). */
and put them into a TREE_VEC. */ #define CLASSTYPE_BINDINGS(NODE) \
#define CLASSTYPE_SORTED_FIELDS(NODE) \ (LANG_TYPE_CLASS_CHECK (NODE)->bindings)
(LANG_TYPE_CLASS_CHECK (NODE)->sorted_fields)
/* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or /* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or
TEMPLATE_DECL, the entity is either a template specialization (if TEMPLATE_DECL, the entity is either a template specialization (if
......
...@@ -14316,7 +14316,8 @@ finish_enum_value_list (tree enumtype) ...@@ -14316,7 +14316,8 @@ finish_enum_value_list (tree enumtype)
&& COMPLETE_TYPE_P (current_class_type) && COMPLETE_TYPE_P (current_class_type)
&& UNSCOPED_ENUM_P (enumtype)) && UNSCOPED_ENUM_P (enumtype))
{ {
insert_late_enum_def_bindings (enumtype, current_class_type); insert_late_enum_def_bindings (current_class_type, enumtype);
/* TYPE_FIELDS needs fixup. */
fixup_type_variants (current_class_type); fixup_type_variants (current_class_type);
} }
......
...@@ -1183,59 +1183,34 @@ lookup_fnfields_slot_nolazy (tree type, tree name) ...@@ -1183,59 +1183,34 @@ lookup_fnfields_slot_nolazy (tree type, tree name)
tree tree
lookup_field_1 (tree type, tree name, bool want_type) lookup_field_1 (tree type, tree name, bool want_type)
{ {
tree field; tree field = NULL_TREE;
gcc_assert (identifier_p (name) && RECORD_OR_UNION_TYPE_P (type)); gcc_assert (identifier_p (name) && RECORD_OR_UNION_TYPE_P (type));
if (CLASSTYPE_SORTED_FIELDS (type)) if (CLASSTYPE_BINDINGS (type))
{ {
tree *fields = &CLASSTYPE_SORTED_FIELDS (type)->elts[0]; tree *slot = CLASSTYPE_BINDINGS (type)->get (name);
int lo = 0, hi = CLASSTYPE_SORTED_FIELDS (type)->len;
int i;
while (lo < hi) if (slot)
{ {
i = (lo + hi) / 2; field = *slot;
if (DECL_NAME (fields[i]) > name) if (STAT_HACK_P (field))
hi = i;
else if (DECL_NAME (fields[i]) < name)
lo = i + 1;
else
{ {
field = NULL_TREE;
/* We might have a nested class and a field with the
same name; we sorted them appropriately via
field_decl_cmp, so just look for the first or last
field with this name. */
if (want_type) if (want_type)
{ field = STAT_TYPE (field);
do
field = fields[i--];
while (i >= lo && DECL_NAME (fields[i]) == name);
if (!DECL_DECLARES_TYPE_P (field))
field = NULL_TREE;
}
else else
{ field = STAT_DECL (field);
do
field = fields[i++];
while (i < hi && DECL_NAME (fields[i]) == name);
} }
if (field)
{
field = strip_using_decl (field); field = strip_using_decl (field);
if (is_overloaded_fn (field)) if (OVL_P (field))
field = NULL_TREE;
else if (want_type && !DECL_DECLARES_TYPE_P (field))
field = NULL_TREE; field = NULL_TREE;
} }
return field; return field;
} }
}
return NULL_TREE;
}
field = TYPE_FIELDS (type); field = TYPE_FIELDS (type);
...@@ -1312,113 +1287,62 @@ lookup_fnfields_slot (tree type, tree name) ...@@ -1312,113 +1287,62 @@ lookup_fnfields_slot (tree type, tree name)
return lookup_fnfields_slot_nolazy (type, name); return lookup_fnfields_slot_nolazy (type, name);
} }
/* Allocate and return an instance of struct sorted_fields_type with /* Add DECL into MAP under NAME. Collisions fail silently. Doesn't
N fields. */ do sophisticated collision checking. Deals with STAT_HACK. */
static struct sorted_fields_type * static void
sorted_fields_type_new (int n) add_class_member (hash_map<lang_identifier *, tree> *map, tree name, tree decl)
{ {
struct sorted_fields_type *sft; bool existed;
sft = (sorted_fields_type *) ggc_internal_alloc (sizeof (sorted_fields_type) tree *slot = &map->get_or_insert (name, &existed);
+ n * sizeof (tree)); if (!existed)
sft->len = n; *slot = decl;
else if (TREE_CODE (*slot) == TYPE_DECL && DECL_ARTIFICIAL (*slot))
return sft; *slot = stat_hack (decl, *slot);
} else if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
*slot = stat_hack (*slot, decl);
/* Subroutine of insert_into_classtype_sorted_fields. Recursively
count the number of fields in TYPE, including anonymous union
members. */
static int /* Else ignore collision. */
count_fields (tree fields)
{
tree x;
int n_fields = 0;
for (x = fields; x; x = DECL_CHAIN (x))
{
if (DECL_DECLARES_FUNCTION_P (x))
/* Functions are dealt with separately. */;
else if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x)));
else
n_fields += 1;
}
return n_fields;
} }
/* Subroutine of insert_into_classtype_sorted_fields. Recursively add /* Insert the chain FIELDS into MAP. */
all the fields in the TREE_LIST FIELDS to the SORTED_FIELDS_TYPE
elts, starting at offset IDX. */
static int static void
add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, add_class_members (hash_map<lang_identifier *, tree> *map, tree fields)
int idx)
{ {
tree x; for (tree field = fields; field; field = DECL_CHAIN (field))
for (x = fields; x; x = DECL_CHAIN (x))
{ {
if (DECL_DECLARES_FUNCTION_P (x)) if (TREE_CODE (field) == FIELD_DECL
/* Functions are handled separately. */; && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
else if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x))) add_class_members (map, TYPE_FIELDS (TREE_TYPE (field)));
idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx); else if (DECL_NAME (field))
else add_class_member (map, DECL_NAME (field), field);
field_vec->elts[idx++] = x;
} }
return idx;
} }
/* Add all of the enum values of ENUMTYPE, to the FIELD_VEC elts, /* Create the binding map of KLASS and insert FIELDS. */
starting at offset IDX. */
static int
add_enum_fields_to_record_type (tree enumtype,
struct sorted_fields_type *field_vec,
int idx)
{
tree values;
for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
field_vec->elts[idx++] = TREE_VALUE (values);
return idx;
}
/* Insert FIELDS into T for the sorted case if the FIELDS count is
equal to THRESHOLD or greater than THRESHOLD. */
void void
set_class_bindings (tree klass, tree fields) set_class_bindings (tree klass, tree fields)
{ {
int n_fields = count_fields (fields); gcc_assert (!CLASSTYPE_BINDINGS (klass));
if (n_fields >= 8)
{ CLASSTYPE_BINDINGS (klass)
struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); = hash_map<lang_identifier *, tree>::create_ggc (8);
add_fields_to_record_type (fields, field_vec, 0); add_class_members (CLASSTYPE_BINDINGS (klass), fields);
qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp);
CLASSTYPE_SORTED_FIELDS (klass) = field_vec;
}
} }
/* Insert lately defined enum ENUMTYPE into T for the sorted case. */ /* Insert lately defined enum ENUMTYPE into T for the sorted case. */
void void
insert_late_enum_def_bindings (tree enumtype, tree t) insert_late_enum_def_bindings (tree klass, tree enumtype)
{ {
struct sorted_fields_type *sorted_fields = CLASSTYPE_SORTED_FIELDS (t); hash_map<lang_identifier *, tree> *map = CLASSTYPE_BINDINGS (klass);
if (sorted_fields)
{
int i;
int n_fields
= list_length (TYPE_VALUES (enumtype)) + sorted_fields->len;
struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields);
for (i = 0; i < sorted_fields->len; ++i)
field_vec->elts[i] = sorted_fields->elts[i];
add_enum_fields_to_record_type (enumtype, field_vec, for (tree values = TYPE_VALUES (enumtype);
sorted_fields->len); values; values = TREE_CHAIN (values))
qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); add_class_member (map, DECL_NAME (TREE_VALUE (values)),
CLASSTYPE_SORTED_FIELDS (t) = field_vec; TREE_VALUE (values));
}
} }
/* Compute the chain index of a binding_entry given the HASH value of its /* Compute the chain index of a binding_entry given the HASH value of its
......
...@@ -151,9 +151,6 @@ cxx_print_type (FILE *file, tree node, int indent) ...@@ -151,9 +151,6 @@ cxx_print_type (FILE *file, tree node, int indent)
fputs (" delete[]", file); fputs (" delete[]", file);
if (TYPE_HAS_COPY_ASSIGN (node)) if (TYPE_HAS_COPY_ASSIGN (node))
fputs (" this=(X&)", file); fputs (" this=(X&)", file);
if (CLASSTYPE_SORTED_FIELDS (node))
fprintf (file, " sorted-fields %p",
(void *) CLASSTYPE_SORTED_FIELDS (node));
if (TREE_CODE (node) == RECORD_TYPE) if (TREE_CODE (node) == RECORD_TYPE)
{ {
......
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