#include "defaults.h"
#include "ggc.h"
#include "tm_p.h"
-
-#if USE_CPPLIB
#include "cpplib.h"
-extern cpp_reader parse_in;
-#endif
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
int flag_traditional;
-/* Nonzero means enable C89 Amendment 1 features, other than digraphs. */
+/* Nonzero means enable C89 Amendment 1 features. */
int flag_isoc94 = 0;
int flag_isoc99 = 0;
-/* Nonzero means accept digraphs. */
-
-int flag_digraphs = 1;
-
/* Nonzero means that we have builtin functions, and main is an int */
int flag_hosted = 1;
char **argv;
{
int strings_processed;
+ const char *option_value = NULL;
char *p = argv[0];
-#if USE_CPPLIB
- strings_processed = cpp_handle_option (&parse_in, argc, argv);
-#else
- strings_processed = 0;
-#endif /* ! USE_CPPLIB */
- if (!strcmp (p, "-lang-objc"))
- c_language = clk_objective_c;
- else if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
+ strings_processed = cpp_handle_option (parse_in, argc, argv);
+
+ if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
{
flag_traditional = 1;
flag_writable_strings = 1;
- flag_digraphs = 0;
}
else if (!strcmp (p, "-fallow-single-precision"))
flag_allow_single_precision = 1;
{
flag_traditional = 0;
flag_writable_strings = 0;
- flag_digraphs = 1;
}
else if (!strncmp (p, "-std=", 5))
{
|| !strcmp (argstart, "c89"))
{
iso_1990:
- flag_digraphs = 0;
flag_isoc94 = 0;
- iso_1990_digraphs:
+ iso_1994:
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 1;
}
else if (!strcmp (argstart, "iso9899:199409"))
{
- flag_digraphs = 1;
flag_isoc94 = 1;
- goto iso_1990_digraphs;
+ goto iso_1994;
}
else if (!strcmp (argstart, "iso9899:199x")
|| !strcmp (argstart, "iso9899:1999")
flag_no_nonansi_builtin = 1;
flag_noniso_default_format_attributes = 0;
flag_isoc99 = 1;
- flag_digraphs = 1;
flag_isoc94 = 1;
}
else if (!strcmp (argstart, "gnu89"))
flag_no_nonansi_builtin = 0;
flag_noniso_default_format_attributes = 1;
flag_isoc99 = 0;
- flag_digraphs = 1;
flag_isoc94 = 0;
}
else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
flag_no_nonansi_builtin = 0;
flag_noniso_default_format_attributes = 1;
flag_isoc99 = 1;
- flag_digraphs = 1;
flag_isoc94 = 1;
}
else
flag_no_builtin = 0;
else if (!strcmp (p, "-fno-builtin"))
flag_no_builtin = 1;
+ else if ((option_value
+ = skip_leading_substring (p, "-fdump-translation-unit-")))
+ {
+ if (p[22] == '\0')
+ error ("no file specified with -fdump-translation-unit");
+ else
+ flag_dump_translation_unit = option_value;
+ }
else if (!strcmp (p, "-ansi"))
goto iso_1990;
else if (!strcmp (p, "-Werror-implicit-function-declaration"))
boolean_true_node = integer_one_node;
boolean_false_node = integer_zero_node;
+ /* With GCC, C99's _Bool is always of size 1. */
+ c_bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
+ TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
+ TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
+ TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
+ TYPE_PRECISION (c_bool_type_node) = 1;
+ pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
+ c_bool_type_node));
+ c_bool_false_node = build_int_2 (0, 0);
+ TREE_TYPE (c_bool_false_node) = c_bool_type_node;
+ c_bool_true_node = build_int_2 (1, 0);
+ TREE_TYPE (c_bool_true_node) = c_bool_type_node;
+
string_type_node = build_pointer_type (char_type_node);
const_string_type_node
= build_pointer_type (build_type_variant (char_type_node, 1, 0));
{
register tree type = TREE_TYPE (decl);
int was_incomplete = (DECL_SIZE (decl) == 0);
- char *asmspec = 0;
+ const char *asmspec = 0;
/* If a name was specified, get the string. */
if (asmspec_tree)
else
{
if (asmspec)
- DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
+ {
+ DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
+ DECL_C_HARD_REGISTER (decl) = 1;
+ }
add_decl_stmt (decl);
}
}
}
- /* Convert size to index_type, so that if it is a variable
- the computations will be done in the proper mode. */
- itype = fold (build (MINUS_EXPR, index_type,
- convert (index_type, size),
- convert (index_type, size_one_node)));
-
- /* If that overflowed, the array is too big.
- ??? While a size of INT_MAX+1 technically shouldn't cause
- an overflow (because we subtract 1), the overflow is recorded
- during the conversion to index_type, before the subtraction.
- Handling this case seems like an unnecessary complication. */
- if (TREE_OVERFLOW (itype))
+ if (integer_zerop (size))
{
- error ("size of array `%s' is too large", name);
- type = error_mark_node;
- continue;
+ /* A zero-length array cannot be represented with an
+ unsigned index type, which is what we'll get with
+ build_index_type. Create an open-ended range instead. */
+ itype = build_range_type (sizetype, size, NULL_TREE);
}
+ else
+ {
+ /* Compute the maximum valid index, that is, size - 1.
+ Do the calculation in index_type, so that if it is
+ a variable the computations will be done in the
+ proper mode. */
+ itype = fold (build (MINUS_EXPR, index_type,
+ convert (index_type, size),
+ convert (index_type, size_one_node)));
+
+ /* If that overflowed, the array is too big.
+ ??? While a size of INT_MAX+1 technically shouldn't
+ cause an overflow (because we subtract 1), the overflow
+ is recorded during the conversion to index_type, before
+ the subtraction. Handling this case seems like an
+ unnecessary complication. */
+ if (TREE_OVERFLOW (itype))
+ {
+ error ("size of array `%s' is too large", name);
+ type = error_mark_node;
+ continue;
+ }
+
+ if (size_varies)
+ itype = variable_size (itype);
+ itype = build_index_type (itype);
+ }
+ }
+ else if (decl_context == FIELD)
+ {
+ /* ??? Need to check somewhere that this is a structure
+ and not a union, that this field is last, and that
+ this structure has at least one other named member. */
+
+ if (pedantic && !flag_isoc99 && !in_system_header)
+ pedwarn ("ISO C89 does not support flexible array members");
- if (size_varies)
- itype = variable_size (itype);
- itype = build_index_type (itype);
+ /* ISO C99 Flexible array members are effectively identical
+ to GCC's zero-length array extension. */
+ itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
}
#if 0
/* Detect invalid bit-field type. */
if (DECL_INITIAL (x)
&& TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
&& TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
{
error_with_decl (x, "bit-field `%s' has invalid type");
if (DECL_INITIAL (x) && pedantic
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
+ && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
/* Accept an enum that's equivalent to int or unsigned int. */
&& !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
&& (TYPE_PRECISION (TREE_TYPE (x))
field widths. */
if (DECL_INITIAL (x))
{
+ int max_width;
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node)
+ max_width = CHAR_TYPE_SIZE;
+ else
+ max_width = TYPE_PRECISION (TREE_TYPE (x));
if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
error_with_decl (x, "negative width in bit-field `%s'");
- else if (0 < compare_tree_int (DECL_INITIAL (x),
- TYPE_PRECISION (TREE_TYPE (x))))
+ else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
pedwarn_with_decl (x, "width of `%s' exceeds its type");
else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
error_with_decl (x, "zero width for bit-field `%s'");
"`%s' is narrower than values of its type");
DECL_SIZE (x) = bitsize_int (width);
- DECL_BIT_FIELD (x) = DECL_C_BIT_FIELD (x) = 1;
+ DECL_BIT_FIELD (x) = 1;
+ SET_DECL_C_BIT_FIELD (x);
if (width == 0)
{
/* Initialize the RTL code for the function. */
current_function_decl = fndecl;
- init_function_start (fndecl, input_filename, lineno);
+ init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl));
/* This function is being processed in whole-function mode. */
cfun->x_whole_function_mode_p = 1;
}
\f
+/* Check the declarations given in a for-loop for satisfying the C99
+ constraints. */
+void
+check_for_loop_decls ()
+{
+ tree t;
+
+ if (!flag_isoc99)
+ {
+ /* If we get here, declarations have been used in a for loop without
+ the C99 for loop scope. This doesn't make much sense, so don't
+ allow it. */
+ error ("`for' loop initial declaration used outside C99 mode");
+ return;
+ }
+ /* C99 subclause 6.8.5 paragraph 3:
+
+ [#3] The declaration part of a for statement shall only
+ declare identifiers for objects having storage class auto or
+ register.
+
+ It isn't clear whether, in this sentence, "identifiers" binds to
+ "shall only declare" or to "objects" - that is, whether all identifiers
+ declared must be identifiers for objects, or whether the restriction
+ only applies to those that are. (A question on this in comp.std.c
+ in November 2000 received no answer.) We implement the strictest
+ interpretation, to avoid creating an extension which later causes
+ problems. */
+
+ for (t = gettags (); t; t = TREE_CHAIN (t))
+ {
+ if (TREE_PURPOSE (t) != 0)
+ error ("`%s %s' declared in `for' loop initial declaration",
+ (TREE_CODE (TREE_VALUE (t)) == RECORD_TYPE ? "struct"
+ : TREE_CODE (TREE_VALUE (t)) == UNION_TYPE ? "union"
+ : "enum"),
+ IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+ }
+ for (t = getdecls (); t; t = TREE_CHAIN (t))
+ {
+ if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t))
+ error_with_decl (t, "declaration of non-variable `%s' in `for' loop initial declaration");
+ else if (TREE_STATIC (t))
+ error_with_decl (t, "declaration of static variable `%s' in `for' loop initial declaration");
+ else if (DECL_EXTERNAL (t))
+ error_with_decl (t, "declaration of `extern' variable `%s' in `for' loop initial declaration");
+ }
+}
+\f
/* Save and restore the variables in this file and elsewhere
that keep track of the progress of compilation of the current function.
Used for nested functions. */