diff options
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 111 |
1 files changed, 56 insertions, 55 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 50d20e6..b1dc379 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -6705,65 +6705,44 @@ elaborate_reference (tree ref, Entity_Id gnat_entity, bool definition, the value passed against the list of choices. */ static tree -choices_to_gnu (tree operand, Node_Id choices) +choices_to_gnu (tree gnu_operand, Node_Id gnat_choices) { - Node_Id choice; - Node_Id gnat_temp; - tree result = boolean_false_node; - tree this_test, low = 0, high = 0, single = 0; + tree gnu_result = boolean_false_node, gnu_type; + + gnu_operand = maybe_character_value (gnu_operand); + gnu_type = TREE_TYPE (gnu_operand); - for (choice = First (choices); Present (choice); choice = Next (choice)) + for (Node_Id gnat_choice = First (gnat_choices); + Present (gnat_choice); + gnat_choice = Next (gnat_choice)) { - switch (Nkind (choice)) + tree gnu_low = NULL_TREE, gnu_high = NULL_TREE; + tree gnu_test; + + switch (Nkind (gnat_choice)) { case N_Range: - low = gnat_to_gnu (Low_Bound (choice)); - high = gnat_to_gnu (High_Bound (choice)); - - this_test - = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node, - build_binary_op (GE_EXPR, boolean_type_node, - operand, low, true), - build_binary_op (LE_EXPR, boolean_type_node, - operand, high, true), - true); - + gnu_low = gnat_to_gnu (Low_Bound (gnat_choice)); + gnu_high = gnat_to_gnu (High_Bound (gnat_choice)); break; case N_Subtype_Indication: - gnat_temp = Range_Expression (Constraint (choice)); - low = gnat_to_gnu (Low_Bound (gnat_temp)); - high = gnat_to_gnu (High_Bound (gnat_temp)); - - this_test - = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node, - build_binary_op (GE_EXPR, boolean_type_node, - operand, low, true), - build_binary_op (LE_EXPR, boolean_type_node, - operand, high, true), - true); + gnu_low = gnat_to_gnu (Low_Bound (Range_Expression + (Constraint (gnat_choice)))); + gnu_high = gnat_to_gnu (High_Bound (Range_Expression + (Constraint (gnat_choice)))); break; case N_Identifier: case N_Expanded_Name: - /* This represents either a subtype range, an enumeration - literal, or a constant Ekind says which. If an enumeration - literal or constant, fall through to the next case. */ - if (Ekind (Entity (choice)) != E_Enumeration_Literal - && Ekind (Entity (choice)) != E_Constant) + /* This represents either a subtype range or a static value of + some kind; Ekind says which. */ + if (Is_Type (Entity (gnat_choice))) { - tree type = gnat_to_gnu_type (Entity (choice)); - - low = TYPE_MIN_VALUE (type); - high = TYPE_MAX_VALUE (type); - - this_test - = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node, - build_binary_op (GE_EXPR, boolean_type_node, - operand, low, true), - build_binary_op (LE_EXPR, boolean_type_node, - operand, high, true), - true); + tree gnu_type = get_unpadded_type (Entity (gnat_choice)); + + gnu_low = TYPE_MIN_VALUE (gnu_type); + gnu_high = TYPE_MAX_VALUE (gnu_type); break; } @@ -6771,27 +6750,49 @@ choices_to_gnu (tree operand, Node_Id choices) case N_Character_Literal: case N_Integer_Literal: - single = gnat_to_gnu (choice); - this_test = build_binary_op (EQ_EXPR, boolean_type_node, operand, - single, true); + gnu_low = gnat_to_gnu (gnat_choice); break; case N_Others_Choice: - this_test = boolean_true_node; break; default: gcc_unreachable (); } - if (result == boolean_false_node) - result = this_test; + /* Everything should be folded into constants at this point. */ + gcc_assert (!gnu_low || TREE_CODE (gnu_low) == INTEGER_CST); + gcc_assert (!gnu_high || TREE_CODE (gnu_high) == INTEGER_CST); + + if (gnu_low && TREE_TYPE (gnu_low) != gnu_type) + gnu_low = convert (gnu_type, gnu_low); + if (gnu_high && TREE_TYPE (gnu_high) != gnu_type) + gnu_high = convert (gnu_type, gnu_high); + + if (gnu_low && gnu_high) + gnu_test + = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node, + build_binary_op (GE_EXPR, boolean_type_node, + gnu_operand, gnu_low, true), + build_binary_op (LE_EXPR, boolean_type_node, + gnu_operand, gnu_high, true), + true); + else if (gnu_low) + gnu_test + = build_binary_op (EQ_EXPR, boolean_type_node, gnu_operand, gnu_low, + true); + else + gnu_test = boolean_true_node; + + if (gnu_result == boolean_false_node) + gnu_result = gnu_test; else - result = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, result, - this_test, true); + gnu_result + = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, gnu_result, + gnu_test, true); } - return result; + return gnu_result; } /* Adjust PACKED setting as passed to gnat_to_gnu_field for a field of |