From d876eb057408fa7904dfc28ae9bc199c69b10858 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 28 Aug 2017 16:25:44 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 15 ++++ gcc/cp/cp-tree.h | 15 ++-- gcc/cp/decl.c | 3 +- gcc/cp/name-lookup.c | 174 ++++++++++++------------------------------- gcc/cp/ptree.c | 3 - 5 files changed, 73 insertions(+), 137 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 16d4635305a..37ae6ea17c0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,20 @@ 2017-08-28 Nathan Sidwell + * 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): Delete. * name-lookup.h (set_class_bindings, diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8f882d6eb6c..7d601abe56b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2014,10 +2014,10 @@ struct GTY(()) lang_type { as a list of adopted protocols or a pointer to a corresponding @interface. See objc/objc-act.h for details. */ tree objc_info; - /* sorted_fields is sorted based on a pointer, so we need to be able - to resort it if pointers get rearranged. */ - struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields"))) - sorted_fields; + + /* Map from IDENTIFIER nodes to DECLS. */ + hash_map *bindings; + /* FIXME reuse another field? */ tree lambda_expr; }; @@ -3243,10 +3243,9 @@ extern void decl_shadowed_for_var_insert (tree, tree); && TREE_CODE (TYPE_NAME (NODE)) == TYPE_DECL \ && TYPE_DECL_ALIAS_P (TYPE_NAME (NODE))) -/* For a class type: if this structure has many fields, we'll sort them - and put them into a TREE_VEC. */ -#define CLASSTYPE_SORTED_FIELDS(NODE) \ - (LANG_TYPE_CLASS_CHECK (NODE)->sorted_fields) +/* The binding map for a class (not always present). */ +#define CLASSTYPE_BINDINGS(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->bindings) /* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or TEMPLATE_DECL, the entity is either a template specialization (if diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 73b61b58d99..ff3127e4a60 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -14316,7 +14316,8 @@ finish_enum_value_list (tree enumtype) && COMPLETE_TYPE_P (current_class_type) && 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); } diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 3c4781eef5d..4c8117cdcf5 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1183,58 +1183,33 @@ lookup_fnfields_slot_nolazy (tree type, tree name) tree 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)); - if (CLASSTYPE_SORTED_FIELDS (type)) + if (CLASSTYPE_BINDINGS (type)) { - tree *fields = &CLASSTYPE_SORTED_FIELDS (type)->elts[0]; - int lo = 0, hi = CLASSTYPE_SORTED_FIELDS (type)->len; - int i; + tree *slot = CLASSTYPE_BINDINGS (type)->get (name); - while (lo < hi) + if (slot) { - i = (lo + hi) / 2; + field = *slot; - if (DECL_NAME (fields[i]) > name) - hi = i; - else if (DECL_NAME (fields[i]) < name) - lo = i + 1; - else + if (STAT_HACK_P (field)) { - 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) - { - do - field = fields[i--]; - while (i >= lo && DECL_NAME (fields[i]) == name); - if (!DECL_DECLARES_TYPE_P (field)) - field = NULL_TREE; - } + field = STAT_TYPE (field); else - { - do - field = fields[i++]; - while (i < hi && DECL_NAME (fields[i]) == name); - } - - if (field) - { - field = strip_using_decl (field); - if (is_overloaded_fn (field)) - field = NULL_TREE; - } - - return field; + field = STAT_DECL (field); } + + field = strip_using_decl (field); + if (OVL_P (field)) + field = NULL_TREE; + else if (want_type && !DECL_DECLARES_TYPE_P (field)) + field = NULL_TREE; } - return NULL_TREE; + return field; } field = TYPE_FIELDS (type); @@ -1312,113 +1287,62 @@ lookup_fnfields_slot (tree type, tree name) return lookup_fnfields_slot_nolazy (type, name); } -/* Allocate and return an instance of struct sorted_fields_type with - N fields. */ +/* Add DECL into MAP under NAME. Collisions fail silently. Doesn't + do sophisticated collision checking. Deals with STAT_HACK. */ -static struct sorted_fields_type * -sorted_fields_type_new (int n) +static void +add_class_member (hash_map *map, tree name, tree decl) { - struct sorted_fields_type *sft; - sft = (sorted_fields_type *) ggc_internal_alloc (sizeof (sorted_fields_type) - + n * sizeof (tree)); - sft->len = n; + bool existed; + tree *slot = &map->get_or_insert (name, &existed); + if (!existed) + *slot = decl; + else if (TREE_CODE (*slot) == TYPE_DECL && DECL_ARTIFICIAL (*slot)) + *slot = stat_hack (decl, *slot); + else if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) + *slot = stat_hack (*slot, decl); - return sft; + /* Else ignore collision. */ } -/* Subroutine of insert_into_classtype_sorted_fields. Recursively - count the number of fields in TYPE, including anonymous union - members. */ +/* Insert the chain FIELDS into MAP. */ -static int -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 - all the fields in the TREE_LIST FIELDS to the SORTED_FIELDS_TYPE - elts, starting at offset IDX. */ - -static int -add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, - int idx) +static void +add_class_members (hash_map *map, tree fields) { - tree x; - for (x = fields; x; x = DECL_CHAIN (x)) + for (tree field = fields; field; field = DECL_CHAIN (field)) { - if (DECL_DECLARES_FUNCTION_P (x)) - /* Functions are handled separately. */; - else if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x))) - idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx); - else - field_vec->elts[idx++] = x; + if (TREE_CODE (field) == FIELD_DECL + && ANON_AGGR_TYPE_P (TREE_TYPE (field))) + add_class_members (map, TYPE_FIELDS (TREE_TYPE (field))); + else if (DECL_NAME (field)) + add_class_member (map, DECL_NAME (field), field); } - return idx; } -/* Add all of the enum values of ENUMTYPE, to the FIELD_VEC elts, - 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. */ +/* Create the binding map of KLASS and insert FIELDS. */ void set_class_bindings (tree klass, tree fields) { - int n_fields = count_fields (fields); - if (n_fields >= 8) - { - struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); - add_fields_to_record_type (fields, field_vec, 0); - qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); - CLASSTYPE_SORTED_FIELDS (klass) = field_vec; - } + gcc_assert (!CLASSTYPE_BINDINGS (klass)); + + CLASSTYPE_BINDINGS (klass) + = hash_map::create_ggc (8); + add_class_members (CLASSTYPE_BINDINGS (klass), fields); } /* Insert lately defined enum ENUMTYPE into T for the sorted case. */ 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); - 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]; + hash_map *map = CLASSTYPE_BINDINGS (klass); - add_enum_fields_to_record_type (enumtype, field_vec, - sorted_fields->len); - qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); - CLASSTYPE_SORTED_FIELDS (t) = field_vec; - } + for (tree values = TYPE_VALUES (enumtype); + values; values = TREE_CHAIN (values)) + add_class_member (map, DECL_NAME (TREE_VALUE (values)), + TREE_VALUE (values)); } /* Compute the chain index of a binding_entry given the HASH value of its diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c index d377efc8cc5..24efe27e5e2 100644 --- a/gcc/cp/ptree.c +++ b/gcc/cp/ptree.c @@ -151,9 +151,6 @@ cxx_print_type (FILE *file, tree node, int indent) fputs (" delete[]", file); if (TYPE_HAS_COPY_ASSIGN (node)) 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) { -- 2.30.2