static GTY(()) tree c_scope_stmt_stack;
+/* State saving variables. */
+int c_in_iteration_stmt;
+int c_in_case_stmt;
+
/* A list of external DECLs that appeared at block scope when there was
some other global meaning for that identifier. */
static GTY(()) tree truly_local_externals;
scope_freelist = scope;
}
+/* The Objective-C front-end often needs to determine the current scope. */
+
+void *
+get_current_scope (void)
+{
+ return current_scope;
+}
+
+/* The following function is used only by Objective-C. It needs to live here
+ because it accesses the innards of c_scope. */
+
+void
+objc_mark_locals_volatile (void *enclosing_blk)
+{
+ struct c_scope *scope;
+
+ for (scope = current_scope;
+ scope && scope != enclosing_blk;
+ scope = scope->outer)
+ {
+ tree decl;
+
+ for (decl = scope->names; decl; decl = TREE_CHAIN (decl))
+ {
+ DECL_REGISTER (decl) = 0;
+ TREE_THIS_VOLATILE (decl) = 1;
+ }
+ /* Do not climb up past the current function. */
+ if (scope->function_body)
+ break;
+ }
+}
+
/* Nonzero if we are currently in the global scope. */
int
information so that meaningful diagnostics can be given. */
if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0
&& ! different_binding_level)
- {
- DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
- DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
- }
+ DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
/* Merge the unused-warning information. */
if (DECL_IN_SYSTEM_HEADER (olddecl))
if (! DECL_EXTERNAL (newdecl))
{
DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
+ DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
/* If we have two non-EXTERNAL file-scope decls that are
the same, only one of them should be written out. */
if (different_tu)
been written out yet. */
if (new_is_definition && DECL_INITIAL (olddecl))
{
- if (TREE_USED (olddecl))
+ if (TREE_USED (olddecl)
+ /* In unit-at-a-time mode we never inline re-defined extern
+ inline functions. */
+ && !flag_unit_at_a_time)
(*debug_hooks->outlining_inline_function) (olddecl);
/* The new defn must not be inline. */
DECL_CONTEXT (x) = current_file_decl;
else
DECL_CONTEXT (x) = current_function_decl;
-
+
if (name)
{
tree old;
if (DECL_EXTERNAL (x) || scope == global_scope)
{
/* Find and check against a previous, not-in-scope, external
- decl for this identifier. (C99 s???: If two declarations
- with external linkage, referring to the same object, have
- incompatible types, the behavior is undefined). */
- tree ext = any_external_decl (name);
+ decl for this identifier. (C99 6.2.7p2: All declarations
+ that refer to the same object or function shall have
+ compatible type; otherwise, the behavior is undefined.) */
+ tree ext = any_external_decl (name);
if (ext)
{
- if (duplicate_decls (x, ext, scope != global_scope,
+ if (duplicate_decls (x, ext, scope != global_scope,
false))
x = copy_node (ext);
}
tree endlink;
tree ptr_ftype_void, ptr_ftype_ptr;
location_t save_loc = input_location;
-
+
/* Adds some ggc roots, and reserved words for c-parse.in. */
c_parse_init ();
if (init)
store_init_value (decl, init);
+ if (c_dialect_objc () && (TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == FIELD_DECL))
+ objc_check_decl (decl);
+
/* Deduce size of array from initialization, if not already known */
if (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_DOMAIN (type) == 0
#endif
}
SET_DECL_RTL (decl, NULL_RTX);
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (starred));
+ change_decl_assembler_name (decl, get_identifier (starred));
}
/* If #pragma weak was used, mark the decl weak now. */
warning ("%Jignoring asm-specifier for non-static local "
"variable '%D'", decl, decl);
else
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
+ change_decl_assembler_name (decl, get_identifier (asmspec));
}
if (TREE_CODE (decl) != FUNCTION_DECL)
mark_referenced (DECL_ASSEMBLER_NAME (decl));
if (TREE_CODE (decl) == TYPE_DECL)
- {
- /* This is a no-op in c-lang.c or something real in objc-act.c. */
- if (c_dialect_objc ())
- objc_check_decl (decl);
- rest_of_decl_compilation (decl, NULL, DECL_FILE_SCOPE_P (decl), 0);
- }
+ rest_of_decl_compilation (decl, NULL, DECL_FILE_SCOPE_P (decl), 0);
/* At the end of a declaration, throw away any variable type sizes
of types defined inside that declaration. There is no use
default: abort ();
}
- if (TREE_PURPOSE (decl))
+ if (TREE_PURPOSE (decl))
/* The first %s will be one of 'struct', 'union', or 'enum'. */
warning ("\"%s %s\" declared inside parameter list",
keyword, IDENTIFIER_POINTER (TREE_PURPOSE (decl)));
finish_decl (value, NULL_TREE, NULL_TREE);
DECL_INITIAL (value) = width;
- if (c_dialect_objc ())
- objc_check_decl (value);
return value;
}
\f
tree *field_array;
struct lang_type *space;
struct sorted_fields_type *space2;
-
+
len += list_length (x);
-
+
/* Use the same allocation policy here that make_node uses, to
ensure that this lives as long as the rest of the struct decl.
All decls in an inline function need to be saved. */
-
+
space = ggc_alloc (sizeof (struct lang_type));
space2 = ggc_alloc (sizeof (struct sorted_fields_type) + len * sizeof (tree));
-
+
len = 0;
space->s = space2;
field_array = &space2->elts[0];
for (x = fieldlist; x; x = TREE_CHAIN (x))
{
field_array[len++] = x;
-
+
/* If there is anonymous struct or union, break out of the loop. */
if (DECL_NAME (x) == NULL)
break;
}
}
}
-
+
for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
{
TYPE_FIELDS (x) = TYPE_FIELDS (t);
current_function_returns_abnormally = 0;
warn_about_return_type = 0;
current_extern_inline = 0;
+ c_in_iteration_stmt = 0;
+ c_in_case_stmt = 0;
/* Don't expand any sizes in the return type of the function. */
immediate_size_expand = 0;
This is called after parsing the body of the function definition. */
void
-finish_function ()
+finish_function (void)
{
tree fndecl = current_function_decl;
}
}
\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. */
-
-struct language_function GTY(())
-{
- struct c_language_function base;
- int returns_value;
- int returns_null;
- int returns_abnormally;
- int warn_about_return_type;
- int extern_inline;
-};
-
/* Save and reinitialize the variables
used during compilation of a C function. */
p->base.x_stmt_tree = c_stmt_tree;
p->base.x_scope_stmt_stack = c_scope_stmt_stack;
+ p->x_in_iteration_stmt = c_in_iteration_stmt;
+ p->x_in_case_stmt = c_in_case_stmt;
p->returns_value = current_function_returns_value;
p->returns_null = current_function_returns_null;
p->returns_abnormally = current_function_returns_abnormally;
c_stmt_tree = p->base.x_stmt_tree;
c_scope_stmt_stack = p->base.x_scope_stmt_stack;
+ c_in_iteration_stmt = p->x_in_iteration_stmt;
+ c_in_case_stmt = p->x_in_case_stmt;
current_function_returns_value = p->returns_value;
current_function_returns_null = p->returns_null;
current_function_returns_abnormally = p->returns_abnormally;
tree decl;
htab_t link_hash_table;
tree block;
-
+
/* Create the BLOCK that poplevel would have created, but don't
actually call poplevel since that's expensive. */
block = make_node (BLOCK);
DECL_EXTERNAL (decl) = 1;
else if (DECL_COMMON (old_decl) || DECL_ONE_ONLY (old_decl))
DECL_EXTERNAL (old_decl) = 1;
-
+
if (DECL_EXTERNAL (decl))
{
DECL_INITIAL (decl) = NULL_TREE;
{
tree global_decl;
global_decl = htab_find (link_hash_table, decl);
-
+
if (! global_decl)
continue;
-
+
/* Print any appropriate error messages, and partially merge
the decls. */
(void) duplicate_decls (decl, global_decl, true, true);
c_write_global_declarations(void)
{
tree link;
-
+
for (link = current_file_decl; link; link = TREE_CHAIN (link))
{
tree globals = BLOCK_VARS (DECL_INITIAL (link));
tree *vec = xmalloc (sizeof (tree) * len);
int i;
tree decl;
-
+
/* Process the decls in the order they were written. */
for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
vec[i] = decl;
-
+
wrapup_global_declarations (vec, len);
-
+
check_global_declarations (vec, len);
-
+
/* Clean up. */
free (vec);
}
{
tree link;
tree file_scope_decl;
-
+
/* Pop the global scope. */
if (current_scope != global_scope)
current_scope = global_scope;