X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-common.c;h=983cd29100ddab49c57b74ccad0145017e5b1c87;hb=c6a06e1fe0602704f8ef7f7c8597b5c3edd12b3d;hp=75c29118851daef26a52ee62d4f22d7def5f9edc;hpb=c7fbc74112d4963785e6ba0163b064ad4d774671;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-common.c b/gcc/c-common.c index 75c29118851..983cd29100d 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "tree.h" #include "real.h" #include "flags.h" @@ -29,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "c-pragma.h" #include "rtl.h" #include "ggc.h" +#include "varray.h" #include "expr.h" #include "c-common.h" #include "diagnostic.h" @@ -188,11 +191,38 @@ enum c_language_kind c_language; tree c_global_trees[CTI_MAX]; +/* Nonzero if we can read a PCH file now. */ + +int allow_pch = 1; + /* Switches common to the C front ends. */ /* Nonzero if prepreprocessing only. */ + int flag_preprocess_only; +/* Nonzero means don't output line number information. */ + +char flag_no_line_commands; + +/* Nonzero causes -E output not to be done, but directives such as + #define that have side effects are still obeyed. */ + +char flag_no_output; + +/* Nonzero means dump macros in some fashion. */ + +char flag_dump_macros; + +/* Nonzero means pass #include lines through to the output. */ + +char flag_dump_includes; + +/* The file name to which we should write a precompiled header, or + NULL if no header will be written in this compile. */ + +const char *pch_file; + /* Nonzero if an ISO standard was selected. It rejects macros in the user's namespace. */ int flag_iso; @@ -860,7 +890,7 @@ const struct attribute_spec c_common_attribute_table[] = }; /* Give the specifications for the format attributes, used by C and all - descendents. */ + descendants. */ const struct attribute_spec c_common_format_attribute_table[] = { @@ -1048,13 +1078,18 @@ finish_fname_decls () if (body) { - /* They were called into existence, so add to statement tree. */ - body = chainon (body, - TREE_CHAIN (DECL_SAVED_TREE (current_function_decl))); - body = build_stmt (COMPOUND_STMT, body); - - COMPOUND_STMT_NO_SCOPE (body) = 1; - TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)) = body; + /* They were called into existence, so add to statement tree. Add + the DECL_STMTs inside the outermost scope. */ + tree *p = &DECL_SAVED_TREE (current_function_decl); + /* Skip the dummy EXPR_STMT and any EH_SPEC_BLOCK. */ + while (TREE_CODE (*p) != COMPOUND_STMT) + p = &TREE_CHAIN (*p); + p = &COMPOUND_BODY (*p); + if (TREE_CODE (*p) == SCOPE_STMT) + p = &TREE_CHAIN (*p); + + body = chainon (body, *p); + *p = body; } for (ix = 0; fname_vars[ix].decl; ix++) @@ -1077,7 +1112,7 @@ finish_fname_decls () saved_function_name_decls = stack; } -/* Return the text name of the current function, suitable prettified +/* Return the text name of the current function, suitably prettified by PRETTY_P. */ const char * @@ -1161,7 +1196,7 @@ fname_decl (rid, id) } if (!ix && !current_function_decl) pedwarn_with_decl (decl, "`%s' is not defined outside of function scope"); - + return decl; } @@ -2800,6 +2835,7 @@ c_common_truthvalue_conversion (expr) case ABS_EXPR: case FLOAT_EXPR: case FFS_EXPR: + case POPCOUNT_EXPR: /* These don't change whether an object is nonzero or zero. */ return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)); @@ -2977,7 +3013,7 @@ c_common_get_alias_set (t) if (! TYPE_P (t)) return -1; - /* The C standard guarantess that any object may be accessed via an + /* The C standard guarantees that any object may be accessed via an lvalue that has character type. */ if (t == char_type_node || t == signed_char_type_node @@ -3090,7 +3126,7 @@ c_sizeof_or_alignof_type (type, op, complain) TYPE_IS_SIZETYPE means that certain things (like overflow) will never happen. However, this node should really have type `size_t', which is just a typedef for an ordinary integer type. */ - value = fold (build1 (NOP_EXPR, c_size_type_node, value)); + value = fold (build1 (NOP_EXPR, size_type_node, value)); my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (value)), 20001021); return value; @@ -3141,7 +3177,7 @@ c_alignof_expr (expr) else return c_alignof (TREE_TYPE (expr)); - return fold (build1 (NOP_EXPR, c_size_type_node, t)); + return fold (build1 (NOP_EXPR, size_type_node, t)); } /* Handle C and C++ default attributes. */ @@ -3185,6 +3221,7 @@ c_common_nodes_and_builtins () #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME, #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME, #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME, +#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME, #define DEF_POINTER_TYPE(NAME, TYPE) NAME, #include "builtin-types.def" #undef DEF_PRIMITIVE_TYPE @@ -3196,6 +3233,7 @@ c_common_nodes_and_builtins () #undef DEF_FUNCTION_TYPE_VAR_0 #undef DEF_FUNCTION_TYPE_VAR_1 #undef DEF_FUNCTION_TYPE_VAR_2 +#undef DEF_FUNCTION_TYPE_VAR_3 #undef DEF_POINTER_TYPE BT_LAST }; @@ -3284,10 +3322,10 @@ c_common_nodes_and_builtins () /* `unsigned long' is the standard type for sizeof. Note that stddef.h uses `unsigned long', and this must agree, even if long and int are the same size. */ - c_size_type_node = + size_type_node = TREE_TYPE (identifier_global_value (get_identifier (SIZE_TYPE))); - signed_size_type_node = c_common_signed_type (c_size_type_node); - set_sizetype (c_size_type_node); + signed_size_type_node = c_common_signed_type (size_type_node); + set_sizetype (size_type_node); build_common_tree_nodes_2 (flag_short_double); @@ -3390,8 +3428,6 @@ c_common_nodes_and_builtins () = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST)); - (*targetm.init_builtins) (); - /* This is special for C++ so functions can be overloaded. */ wchar_type_node = get_identifier (MODIFIED_WCHAR_TYPE); wchar_type_node = TREE_TYPE (identifier_global_value (wchar_type_node)); @@ -3515,6 +3551,19 @@ c_common_nodes_and_builtins () tree_cons (NULL_TREE, \ builtin_types[(int) ARG2], \ NULL_TREE))); + +#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \ + builtin_types[(int) ENUM] \ + = build_function_type \ + (builtin_types[(int) RETURN], \ + tree_cons (NULL_TREE, \ + builtin_types[(int) ARG1], \ + tree_cons (NULL_TREE, \ + builtin_types[(int) ARG2], \ + tree_cons (NULL_TREE, \ + builtin_types[(int) ARG3], \ + NULL_TREE)))); + #define DEF_POINTER_TYPE(ENUM, TYPE) \ builtin_types[(int) ENUM] \ = build_pointer_type (builtin_types[(int) TYPE]); @@ -3526,13 +3575,15 @@ c_common_nodes_and_builtins () #undef DEF_FUNCTION_TYPE_4 #undef DEF_FUNCTION_TYPE_VAR_0 #undef DEF_FUNCTION_TYPE_VAR_1 +#undef DEF_FUNCTION_TYPE_VAR_2 +#undef DEF_FUNCTION_TYPE_VAR_3 #undef DEF_POINTER_TYPE if (!c_attrs_initialized) c_init_attributes (); #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, \ - BOTH_P, FALLBACK_P, NONANSI_P, ATTRS) \ + BOTH_P, FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT) \ if (NAME) \ { \ tree decl; \ @@ -3559,10 +3610,14 @@ c_common_nodes_and_builtins () built_in_attributes[(int) ATTRS]); \ \ built_in_decls[(int) ENUM] = decl; \ + if (IMPLICIT) \ + implicit_built_in_decls[(int) ENUM] = decl; \ } #include "builtins.def" #undef DEF_BUILTIN + (*targetm.init_builtins) (); + main_identifier_node = get_identifier ("main"); } @@ -4490,9 +4545,9 @@ c_expand_builtin_printf (arglist, target, tmode, modifier, ignore, unlocked) int unlocked; { tree fn_putchar = unlocked ? - built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : built_in_decls[BUILT_IN_PUTCHAR]; + implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTCHAR]; tree fn_puts = unlocked ? - built_in_decls[BUILT_IN_PUTS_UNLOCKED] : built_in_decls[BUILT_IN_PUTS]; + implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTS]; tree fn, format_arg, stripped_string; /* If the return value is used, or the replacement _DECL isn't @@ -4594,9 +4649,9 @@ c_expand_builtin_fprintf (arglist, target, tmode, modifier, ignore, unlocked) int unlocked; { tree fn_fputc = unlocked ? - built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : built_in_decls[BUILT_IN_FPUTC]; + implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTC]; tree fn_fputs = unlocked ? - built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : built_in_decls[BUILT_IN_FPUTS]; + implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTS]; tree fn, format_arg, stripped_string; /* If the return value is used, or the replacement _DECL isn't @@ -4877,6 +4932,18 @@ builtin_define_float_constants (name_prefix, fp_suffix, type) sprintf (buf, "0.0%s", fp_suffix); builtin_define_with_value (name, buf, 0); } + + /* For C++ std::numeric_limits::has_infinity. */ + sprintf (name, "__%s_HAS_INFINITY__", name_prefix); + builtin_define_with_int_value (name, + MODE_HAS_INFINITIES (TYPE_MODE (type))); + /* For C++ std::numeric_limits::has_quiet_NaN. We do not have a + predicate to distinguish a target that has both quiet and + signalling NaNs from a target that has only quiet NaNs or only + signalling NaNs, so we assume that a target that has any kind of + NaN has quiet NaNs. */ + sprintf (name, "__%s_HAS_QUIET_NAN__", name_prefix); + builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type))); } /* Hook that registers front end and target-specific built-ins. */ @@ -5106,8 +5173,9 @@ builtin_define_with_hex_fp_value (macro, type, digits, hex_str, fp_suffix) cpp_define (parse_in, buf); } -/* Define MAX for TYPE based on the precision of the type, which is assumed - to be signed. IS_LONG is 1 for type "long" and 2 for "long long". */ +/* Define MAX for TYPE based on the precision of the type. IS_LONG is + 1 for type "long" and 2 for "long long". We have to handle + unsigned types, since wchar_t might be unsigned. */ static void builtin_define_type_max (macro, type, is_long) @@ -5115,41 +5183,37 @@ builtin_define_type_max (macro, type, is_long) tree type; int is_long; { - const char *value; + static const char *const values[] + = { "127", "255", + "32767", "65535", + "2147483647", "4294967295", + "9223372036854775807", "18446744073709551615", + "170141183460469231731687303715884105727", + "340282366920938463463374607431768211455" }; + static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" }; + + const char *value, *suffix; char *buf; - size_t mlen, vlen, extra; + size_t idx; /* Pre-rendering the values mean we don't have to futz with printing a multi-word decimal value. There are also a very limited number of precisions that we support, so it's really a waste of time. */ switch (TYPE_PRECISION (type)) { - case 8: - value = "127"; - break; - case 16: - value = "32767"; - break; - case 32: - value = "2147483647"; - break; - case 64: - value = "9223372036854775807"; - break; - case 128: - value = "170141183460469231731687303715884105727"; - break; - default: - abort (); + case 8: idx = 0; break; + case 16: idx = 2; break; + case 32: idx = 4; break; + case 64: idx = 6; break; + case 128: idx = 8; break; + default: abort (); } - mlen = strlen (macro); - vlen = strlen (value); - extra = 2 + is_long; - buf = alloca (mlen + vlen + extra); + value = values[idx + TREE_UNSIGNED (type)]; + suffix = suffixes[is_long * 2 + TREE_UNSIGNED (type)]; - sprintf (buf, "%s=%s%s", macro, value, - (is_long == 1 ? "L" : is_long == 2 ? "LL" : "")); + buf = alloca (strlen (macro) + 1 + strlen (value) + strlen (suffix) + 1); + sprintf (buf, "%s=%s%s", macro, value, suffix); cpp_define (parse_in, buf); } @@ -5386,16 +5450,19 @@ handle_always_inline_attribute (node, name, args, flags, no_add_attrs) struct attribute_spec.handler. */ static tree -handle_used_attribute (node, name, args, flags, no_add_attrs) - tree *node; +handle_used_attribute (pnode, name, args, flags, no_add_attrs) + tree *pnode; tree name; tree args ATTRIBUTE_UNUSED; int flags ATTRIBUTE_UNUSED; bool *no_add_attrs; { - if (TREE_CODE (*node) == FUNCTION_DECL) - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (*node)) - = TREE_USED (*node) = 1; + tree node = *pnode; + + if (TREE_CODE (node) == FUNCTION_DECL + || (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node))) + TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (node)) + = TREE_USED (node) = 1; else { warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); @@ -5604,6 +5671,7 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs) int len = strlen (p); enum machine_mode mode = VOIDmode; tree typefm; + tree ptr_type; if (len > 4 && p[0] == '_' && p[1] == '_' && p[len - 1] == '_' && p[len - 2] == '_') @@ -5633,6 +5701,10 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs) else if (0 == (typefm = (*lang_hooks.types.type_for_mode) (mode, TREE_UNSIGNED (type)))) error ("no data type for mode `%s'", p); + else if ((TREE_CODE (type) == POINTER_TYPE + || TREE_CODE (type) == REFERENCE_TYPE) + && !(*targetm.valid_pointer_mode) (mode)) + error ("invalid pointer mode `%s'", p); else { /* If this is a vector, make sure we either have hardware @@ -5645,6 +5717,19 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs) return NULL_TREE; } + if (TREE_CODE (type) == POINTER_TYPE) + { + ptr_type = build_pointer_type_for_mode (TREE_TYPE (type), + mode); + *node = ptr_type; + } + else if (TREE_CODE (type) == REFERENCE_TYPE) + { + ptr_type = build_reference_type_for_mode (TREE_TYPE (type), + mode); + *node = ptr_type; + } + else *node = typefm; /* No need to layout the type here. The caller should do this. */ } @@ -5891,9 +5976,10 @@ handle_visibility_attribute (node, name, args, flags, no_add_attrs) } if (strcmp (TREE_STRING_POINTER (id), "hidden") && strcmp (TREE_STRING_POINTER (id), "protected") - && strcmp (TREE_STRING_POINTER (id), "internal")) + && strcmp (TREE_STRING_POINTER (id), "internal") + && strcmp (TREE_STRING_POINTER (id), "default")) { - error ("visibility arg must be one of \"hidden\", \"protected\" or \"internal\""); + error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\""); *no_add_attrs = true; return NULL_TREE; } @@ -6123,7 +6209,7 @@ handle_deprecated_attribute (node, name, args, flags, no_add_attrs) The normal mechanism to prevent duplicates is to use type_hash_canon, but since we want to distinguish types that are essentially identical (except for their debug representation), we use a local list here. */ -static tree vector_type_node_list = 0; +static GTY(()) tree vector_type_node_list = 0; /* Handle a "vector_size" attribute; arguments as in struct attribute_spec.handler. */ @@ -6322,7 +6408,7 @@ handle_nonnull_attribute (node, name, args, flags, no_add_attrs) unsigned HOST_WIDE_INT attr_arg_num; /* If no arguments are specified, all pointer arguments should be - non-null. Veryify a full prototype is given so that the arguments + non-null. Verify a full prototype is given so that the arguments will have the correct types when we actually check them later. */ if (! args) {