diff options
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 148 |
1 files changed, 54 insertions, 94 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 23c37ef8d93..2c8857fc496 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "debug.h" #include "timevar.h" #include "c-common.h" +#include "c-pragma.h" /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context @@ -1954,7 +1955,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level) } /* Merge the storage class information. */ - DECL_WEAK (newdecl) |= DECL_WEAK (olddecl); + merge_weak (newdecl, olddecl); + /* For functions, static overrides non-static. */ if (TREE_CODE (newdecl) == FUNCTION_DECL) { @@ -1995,9 +1997,10 @@ duplicate_decls (newdecl, olddecl, different_binding_level) inline, make sure we emit debug info for the inline before we throw it away, in case it was inlined into a function that hasn't been written out yet. */ - if (new_is_definition && DECL_INITIAL (olddecl) && TREE_USED (olddecl)) + if (new_is_definition && DECL_INITIAL (olddecl)) { - (*debug_hooks->outlining_inline_function) (olddecl); + if (TREE_USED (olddecl)) + (*debug_hooks->outlining_inline_function) (olddecl); /* The new defn must not be inline. */ DECL_INLINE (newdecl) = 0; @@ -3077,8 +3080,7 @@ c_init_decl_processing () 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); + c_bool_type_node = make_unsigned_type (BOOL_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; @@ -3096,55 +3098,6 @@ c_init_decl_processing () = build_function_type (ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, endlink)); - /* Types which are common to the fortran compiler and libf2c. When - changing these, you also need to be concerned with f/com.h. */ - - if (TYPE_PRECISION (float_type_node) - == TYPE_PRECISION (long_integer_type_node)) - { - g77_integer_type_node = long_integer_type_node; - g77_uinteger_type_node = long_unsigned_type_node; - } - else if (TYPE_PRECISION (float_type_node) - == TYPE_PRECISION (integer_type_node)) - { - g77_integer_type_node = integer_type_node; - g77_uinteger_type_node = unsigned_type_node; - } - else - g77_integer_type_node = g77_uinteger_type_node = NULL_TREE; - - if (g77_integer_type_node != NULL_TREE) - { - pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_integer"), - g77_integer_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_uinteger"), - g77_uinteger_type_node)); - } - - if (TYPE_PRECISION (float_type_node) * 2 - == TYPE_PRECISION (long_integer_type_node)) - { - g77_longint_type_node = long_integer_type_node; - g77_ulongint_type_node = long_unsigned_type_node; - } - else if (TYPE_PRECISION (float_type_node) * 2 - == TYPE_PRECISION (long_long_integer_type_node)) - { - g77_longint_type_node = long_long_integer_type_node; - g77_ulongint_type_node = long_long_unsigned_type_node; - } - else - g77_longint_type_node = g77_ulongint_type_node = NULL_TREE; - - if (g77_longint_type_node != NULL_TREE) - { - pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_longint"), - g77_longint_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_ulongint"), - g77_ulongint_type_node)); - } - pedantic_lvalues = pedantic; make_fname_decl = c_make_fname_decl; @@ -3484,15 +3437,9 @@ start_decl (declarator, declspecs, initialized, attributes) switch (TREE_CODE (decl)) { case TYPE_DECL: - /* typedef foo = bar means give foo the same type as bar. - We haven't parsed bar yet, so `finish_decl' will fix that up. - Any other case of an initialization in a TYPE_DECL is an error. */ - if (pedantic || list_length (declspecs) > 1) - { - error ("typedef `%s' is initialized", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - } + error ("typedef `%s' is initialized (use __typeof__ instead)", + IDENTIFIER_POINTER (DECL_NAME (decl))); + initialized = 0; break; case FUNCTION_DECL: @@ -3578,6 +3525,10 @@ start_decl (declarator, declspecs, initialized, attributes) /* Set attributes here so if duplicate decl, will have proper attributes. */ decl_attributes (&decl, attributes, 0); + /* If #pragma weak was used, mark the decl weak now. */ + if (current_binding_level == global_binding_level) + maybe_apply_pragma_weak (decl); + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) && DECL_UNINLINABLE (decl) @@ -3623,6 +3574,8 @@ finish_decl (decl, init, asmspec_tree) const char *asmspec = 0; /* If a name was specified, get the string. */ + if (current_binding_level == global_binding_level) + asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree); if (asmspec_tree) asmspec = TREE_STRING_POINTER (asmspec_tree); @@ -3635,16 +3588,7 @@ finish_decl (decl, init, asmspec_tree) init = 0; if (init) - { - if (TREE_CODE (decl) != TYPE_DECL) - store_init_value (decl, init); - else - { - /* typedef foo = bar; store the type of bar as the type of foo. */ - TREE_TYPE (decl) = TREE_TYPE (init); - DECL_INITIAL (decl) = init = 0; - } - } + store_init_value (decl, init); /* Deduce size of array from initialization, if not already known */ if (TREE_CODE (type) == ARRAY_TYPE @@ -3904,6 +3848,7 @@ build_compound_literal (type, init) DECL_CONTEXT (decl) = current_function_decl; TREE_USED (decl) = 1; TREE_TYPE (decl) = type; + TREE_READONLY (decl) = TREE_READONLY (type); store_init_value (decl, init); if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type)) @@ -3926,12 +3871,18 @@ build_compound_literal (type, init) if (TREE_STATIC (decl)) { /* This decl needs a name for the assembler output. We also need - a unique suffix to be added to the name, for which DECL_CONTEXT - must be set. */ - DECL_NAME (decl) = get_identifier ("__compound_literal"); - DECL_CONTEXT (decl) = complit; + a unique suffix to be added to the name. */ + char *name; + extern int var_labelno; + + ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal", var_labelno); + var_labelno++; + DECL_NAME (decl) = get_identifier (name); + DECL_DEFER_OUTPUT (decl) = 1; + DECL_COMDAT (decl) = 1; + DECL_ARTIFICIAL (decl) = 1; + pushdecl (decl); rest_of_decl_compilation (decl, NULL, 1, 0); - DECL_CONTEXT (decl) = NULL_TREE; } return complit; @@ -4610,7 +4561,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) even if it is (eg) a const variable with known value. */ size_varies = 1; - if (pedantic) + if (!flag_isoc99 && pedantic) { if (TREE_CONSTANT (size)) pedwarn ("ISO C89 forbids array `%s' whose size can't be evaluated", @@ -4658,10 +4609,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) } 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"); @@ -5588,8 +5535,11 @@ grokfield (filename, line, declarator, declspecs, width) { /* This is an unnamed decl. We only support unnamed structs/unions, so check for other things and refuse them. */ - if (TREE_CODE (TREE_VALUE (declspecs)) != RECORD_TYPE - && TREE_CODE (TREE_VALUE (declspecs)) != UNION_TYPE) + tree type = TREE_VALUE (declspecs); + + if (TREE_CODE (type) == TYPE_DECL) + type = TREE_TYPE (type); + if (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE) { error ("unnamed fields of type other than struct or union are not allowed"); return NULL_TREE; @@ -6228,6 +6178,10 @@ start_function (declspecs, declarator, attributes) decl_attributes (&decl1, attributes, 0); + /* If #pragma weak was used, mark the decl weak now. */ + if (current_binding_level == global_binding_level) + maybe_apply_pragma_weak (decl1); + if (DECL_DECLARED_INLINE_P (decl1) && DECL_UNINLINABLE (decl1) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1))) @@ -6884,17 +6838,21 @@ store_parm_decls () This is called after parsing the body of the function definition. - NESTED is nonzero if the function being finished is nested in another. */ + NESTED is nonzero if the function being finished is nested in another. + CAN_DEFER_P is nonzero if the function may be deferred. */ void -finish_function (nested) +finish_function (nested, can_defer_p) int nested; + int can_defer_p; { tree fndecl = current_function_decl; -/* TREE_READONLY (fndecl) = 1; - This caused &foo to be of type ptr-to-const-function - which then got a warning when stored in a ptr-to-function variable. */ +#if 0 + /* This caused &foo to be of type ptr-to-const-function which then + got a warning when stored in a ptr-to-function variable. */ + TREE_READONLY (fndecl) = 1; +#endif poplevel (1, 0, 1); BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; @@ -6938,7 +6896,8 @@ finish_function (nested) finish_stmt_tree (&DECL_SAVED_TREE (fndecl)); /* Complain if there's just no return statement. */ - if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE + if (warn_return_type + && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE && !current_function_returns_value && !current_function_returns_null /* Don't complain if we abort. */ && !current_function_returns_abnormally @@ -6946,9 +6905,9 @@ finish_function (nested) && !MAIN_NAME_P (DECL_NAME (fndecl)) /* Or if they didn't actually specify a return type. */ && !C_FUNCTION_IMPLICIT_INT (fndecl) - /* If we have -Wreturn-type, let flow complain. Unless we're an + /* Normally, with -Wreturn-type, flow will complain. Unless we're an inline function, as we might never be compiled separately. */ - && (!warn_return_type || DECL_INLINE (fndecl))) + && DECL_INLINE (fndecl)) warning ("no return statement in function returning non-void"); /* Clear out memory we no longer need. */ @@ -6961,7 +6920,8 @@ finish_function (nested) if (! nested) { /* Generate RTL for the body of this function. */ - c_expand_body (fndecl, nested, 1); + c_expand_body (fndecl, nested, can_defer_p); + /* Let the error reporting routines know that we're outside a function. For a nested function, this value is used in pop_c_function_context and then reset via pop_function_context. */ |