aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c148
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. */