diff options
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index b122f9b..ba0138d 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -776,6 +776,7 @@ static void check_function_nonnull (tree, tree); static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT); static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT); static bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *); +static int resort_field_decl_cmp (const void *, const void *); /* Table of machine-independent attributes common to all C-like languages. */ const struct attribute_spec c_common_attribute_table[] = @@ -5882,6 +5883,72 @@ check_function_arguments_recurse (void (*callback) (*callback) (ctx, param, param_num); } +/* Function to help qsort sort FIELD_DECLs by name order. */ + +int +field_decl_cmp (const void *x_p, const void *y_p) +{ + const tree *const x = x_p; + const tree *const y = y_p; + if (DECL_NAME (*x) == DECL_NAME (*y)) + /* A nontype is "greater" than a type. */ + return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL); + if (DECL_NAME (*x) == NULL_TREE) + return -1; + if (DECL_NAME (*y) == NULL_TREE) + return 1; + if (DECL_NAME (*x) < DECL_NAME (*y)) + return -1; + return 1; +} + +static struct { + gt_pointer_operator new_value; + void *cookie; +} resort_data; + +/* This routine compares two fields like field_decl_cmp but using the +pointer operator in resort_data. */ + +static int +resort_field_decl_cmp (const void *x_p, const void *y_p) +{ + const tree *const x = x_p; + const tree *const y = y_p; + + if (DECL_NAME (*x) == DECL_NAME (*y)) + /* A nontype is "greater" than a type. */ + return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL); + if (DECL_NAME (*x) == NULL_TREE) + return -1; + if (DECL_NAME (*y) == NULL_TREE) + return 1; + { + tree d1 = DECL_NAME (*x); + tree d2 = DECL_NAME (*y); + resort_data.new_value (&d1, resort_data.cookie); + resort_data.new_value (&d2, resort_data.cookie); + if (d1 < d2) + return -1; + } + return 1; +} + +/* Resort DECL_SORTED_FIELDS because pointers have been reordered. */ + +void +resort_sorted_fields (void *obj, + void *orig_obj ATTRIBUTE_UNUSED , + gt_pointer_operator new_value, + void *cookie) +{ + struct sorted_fields_type *sf = obj; + resort_data.new_value = new_value; + resort_data.cookie = cookie; + qsort (&sf->elts[0], sf->len, sizeof (tree), + resort_field_decl_cmp); +} + /* Used by estimate_num_insns. Estimate number of instructions seen by given statement. */ static tree |