aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/arith.c
diff options
context:
space:
mode:
authorTobias Schlüter <tobi@gcc.gnu.org>2005-10-30 19:09:55 +0100
committerTobias Schlüter <tobi@gcc.gnu.org>2005-10-30 19:09:55 +0100
commit25d8f0a2839a99417ab79879fb55f2ead76fcf2a (patch)
tree3920d0fc1db1a9d875d55587afd2ffefff790a10 /gcc/fortran/arith.c
parente8299ec258037fb73ee906633760ff1191bf05e1 (diff)
downloadgcc-25d8f0a2839a99417ab79879fb55f2ead76fcf2a.zip
gcc-25d8f0a2839a99417ab79879fb55f2ead76fcf2a.tar.gz
gcc-25d8f0a2839a99417ab79879fb55f2ead76fcf2a.tar.bz2
arith.c (gfc_enum_initializer): New function.
fortran/ 2005-10-30 Gaurav Gautam <gauravga@noida.hcltech.com> Tobias Schl"uter <tobias.schlueter@physik.uni-muenchen.de> * arith.c (gfc_enum_initializer): New function. (gfc_check_integer_range): Made extern. * decl.c (enumerator_history): New typedef. (last_initializer, enum_history, max_enum): New variables. (create_enum_history, gfc_free_enum_history): New functions. (add_init_expr_to_sym): Call create_enum_history if parsing ENUM. (variable_decl): Modified to parse enumerator definition. (match_attr_spec): Add PARAMETER attribute to ENUMERATORs. (gfc_match_data_decl): Issues error, if match_type_spec do not return desired return values. (set_enum_kind, gfc_match_enum, gfc_match_enumerator_def): New functions. (gfc_match_end): Deal with END ENUM. * gfortran.h (gfc_statement): ST_ENUM, ST_ENUMERATOR, ST_END_ENUM added. (symbol_attribute): Bit field for enumerator added. (gfc_options): Add fshort_enums. (gfc_enum_initializer, gfc_check_integer_range): Add prototypes. * options.c: Include target.h (gfc_init_options): Initialize fshort_enums. (gfc_handle_option): Deal with fshort_enums. * parse.c (decode_statement): Match ENUM and ENUMERATOR statement. (gfc_ascii_statement): Deal with the enumerator statements. (parse_enum): New function to parse enum construct. (parse_spec): Added case ST_ENUM. * parse.h (gfc_compile_state): COMP_ENUM added. (gfc_match_enum, gfc_match_enumerator_def, gfc_free_enum_history): Prototype added. * symbol.c (gfc_copy_attr): Copy enumeration attribute. * lang.opt (fshort-enums): Option added. testsuite/ 2005-10-30 Tobias Schl"uter <tobias.schlueter@physik.uni-muenchen.de> * gfortran.dg/enum_10.f90, gfortran.dg/enum_10.c: New test. 2005-10-30 Gaurav Gautam <gauravga@noida.hcltech.com> * gfortran.dg/enum_1.f90, gfortran.dg/enum_2.f90, gfortran.dg/enum_3.f90, gfortran.dg/enum_4.f90, gfortran.dg/enum_5.f90, gfortran.dg/enum_6.f90, gfortran.dg/enum_7.f90, gfortran.dg/enum_8.f90, gfortran.dg/enum_9.f90, gfortran.fortran-torture/compile/enum_1.f90, gfortran.fortran-torture/execute/enum_1.f90, gfortran.fortran-torture/execute/enum_2.f90, gfortran.fortran-torture/execute/enum_3.f90, gfortran.fortran-torture/execute/enum_4.f90: New tests. From-SVN: r106246
Diffstat (limited to 'gcc/fortran/arith.c')
-rw-r--r--gcc/fortran/arith.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
index e0c1f4b..aac3cb4 100644
--- a/gcc/fortran/arith.c
+++ b/gcc/fortran/arith.c
@@ -339,7 +339,7 @@ gfc_arith_done_1 (void)
the range of the kind. Returns ARITH_OK, ARITH_ASYMMETRIC or
ARITH_OVERFLOW. */
-static arith
+arith
gfc_check_integer_range (mpz_t p, int kind)
{
arith result;
@@ -2405,3 +2405,47 @@ gfc_hollerith2logical (gfc_expr * src, int kind)
return result;
}
+
+/* Returns an initializer whose value is one higher than the value of the
+ LAST_INITIALIZER argument. If that is argument is NULL, the
+ initializers value will be set to zero. The initializer's kind
+ will be set to gfc_c_int_kind.
+
+ If -fshort-enums is given, the appropriate kind will be selected
+ later after all enumerators have been parsed. A warning is issued
+ here if an initializer exceeds gfc_c_int_kind. */
+
+gfc_expr *
+gfc_enum_initializer (gfc_expr *last_initializer, locus where)
+{
+ gfc_expr *result;
+
+ result = gfc_get_expr ();
+ result->expr_type = EXPR_CONSTANT;
+ result->ts.type = BT_INTEGER;
+ result->ts.kind = gfc_c_int_kind;
+ result->where = where;
+
+ mpz_init (result->value.integer);
+
+ if (last_initializer != NULL)
+ {
+ mpz_add_ui (result->value.integer, last_initializer->value.integer, 1);
+ result->where = last_initializer->where;
+
+ if (gfc_check_integer_range (result->value.integer,
+ gfc_c_int_kind) != ARITH_OK)
+ {
+ gfc_error ("Enumerator exceeds the C integer type at %C");
+ return NULL;
+ }
+ }
+ else
+ {
+ /* Control comes here, if it's the very first enumerator and no
+ initializer has been given. It will be initialized to ZERO (0). */
+ mpz_set_si (result->value.integer, 0);
+ }
+
+ return result;
+}