c-decl.c (gettags, [...]): Delete.

* c-decl.c (gettags, pushdecl_function_level): Delete.
	(last_function_parm_vars): Rename last_function_parm_others.
	(current_function_parm_vars): Rename current_function_parm_others.
	(struct c_scope): Rewrite comment explaining this data structure.
	Add names_last, blocks_last, parms_last fields.  Rename
	incomplete_list to incomplete.
	(SCOPE_LIST_APPEND, SCOPE_LIST_CONCAT): New macros.
	(poplevel): Ignore second argument.  No need to nreverse
	anything.  Restructure such that each list is processed
	exactly once.  Use 'const location_t *locus' syntactic sugar
	variable where useful.  Issue unused variable warnings
	ourselves, do not rely on function.c.
	(insert_block, pushdecl, bind_label): Use SCOPE_LIST_APPEND.
	(pushdecl_top_level): Likewise.  Don't call duplicate_decls.
	(implicitly_declare): decl cannot be error_mark_node.
	(undeclared_variable): Manipulate scope structure directly.
	(c_make_fname_decl): Likewise.
	(getdecls, c_init_decl_processing): Fix comment.
	(mark_forward_parm_decls): Use SCOPE_LIST_CONCAT.  No need
	for 'last' variable.
	(grokparms): No need to nreverse parms list.
	(store_parm_decls_newstyle): Set up the parms_last and
	names_last fields of the new scope too.
	(store_parm_decls_oldstyle): Can assume DECL_WEAK is not set
	on parms to begin with; check this under ENABLE_CHECKING.  Set
	up parms_last.
	(check_for_loop_decls): Refer directly to current_scope->tags.
	Use consistent quote style in diagnostics.
	(c_write_global_declarations): The names list is not backward.

	* c-common.h: Don't prototype gettags.
	* c-parse.in: Call poplevel with second argument 0 always.

From-SVN: r70061
This commit is contained in:
Zack Weinberg 2003-08-01 18:41:40 +00:00
parent a8eb1db550
commit f91f41b294
4 changed files with 294 additions and 296 deletions

View File

@ -1,3 +1,38 @@
2003-08-01 Zack Weinberg <zack@codesourcery.com>
* c-decl.c (gettags, pushdecl_function_level): Delete.
(last_function_parm_vars): Rename last_function_parm_others.
(current_function_parm_vars): Rename current_function_parm_others.
(struct c_scope): Rewrite comment explaining this data structure.
Add names_last, blocks_last, parms_last fields. Rename
incomplete_list to incomplete.
(SCOPE_LIST_APPEND, SCOPE_LIST_CONCAT): New macros.
(poplevel): Ignore second argument. No need to nreverse
anything. Restructure such that each list is processed
exactly once. Use 'const location_t *locus' syntactic sugar
variable where useful. Issue unused variable warnings
ourselves, do not rely on function.c.
(insert_block, pushdecl, bind_label): Use SCOPE_LIST_APPEND.
(pushdecl_top_level): Likewise. Don't call duplicate_decls.
(implicitly_declare): decl cannot be error_mark_node.
(undeclared_variable): Manipulate scope structure directly.
(c_make_fname_decl): Likewise.
(getdecls, c_init_decl_processing): Fix comment.
(mark_forward_parm_decls): Use SCOPE_LIST_CONCAT. No need
for 'last' variable.
(grokparms): No need to nreverse parms list.
(store_parm_decls_newstyle): Set up the parms_last and
names_last fields of the new scope too.
(store_parm_decls_oldstyle): Can assume DECL_WEAK is not set
on parms to begin with; check this under ENABLE_CHECKING. Set
up parms_last.
(check_for_loop_decls): Refer directly to current_scope->tags.
Use consistent quote style in diagnostics.
(c_write_global_declarations): The names list is not backward.
* c-common.h: Don't prototype gettags.
* c-parse.in: Call poplevel with second argument 0 always.
2003-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtins.def: Resort builtins.
@ -194,8 +229,8 @@ Thu Jul 31 19:49:53 CEST 2003 Jan Hubicka <jh@suse.cz>
2003-07-31 Vladimir Makarov <vmakarov@redhat.com>
* sched-deps.c (sched_analyze_2): Prevent interblock move of CC0
setter.
* sched-deps.c (sched_analyze_2): Prevent interblock move of CC0
setter.
2003-07-30 Roger Sayle <roger@eyesopen.com>
@ -223,7 +258,7 @@ Thu Jul 31 19:49:53 CEST 2003 Jan Hubicka <jh@suse.cz>
2003-07-31 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390.md (UNSPEC_ROUND, UNSPEC_SETHIGH,
* config/s390/s390.md (UNSPEC_ROUND, UNSPEC_SETHIGH,
UNSPECV_BLOCKAGE): New constants.
("*sethighqisi", "*sethighhisi", "*sethiqidi_64", "*sethiqidi_31",
"*extractqi", "*extracthi", "*extendqidi2" splitter, "*extendqisi2"

View File

@ -318,7 +318,6 @@ struct c_language_function GTY(()) {
extern void (*lang_expand_stmt) (tree);
extern void (*lang_expand_decl_stmt) (tree);
extern void (*lang_expand_function_end) (void);
extern tree gettags (void);
/* Callback that determines if it's ok for a function to have no
noreturn attribute. */

View File

@ -97,7 +97,7 @@ static tree last_function_parm_tags;
/* ... and a chain of all non-parameter declarations (such as
CONST_DECLs from enumerations) here. */
static tree last_function_parm_vars;
static tree last_function_parm_others;
/* After parsing the declarator that starts a function definition,
`start_function' puts the list of parameter names or chain of decls here
@ -109,9 +109,9 @@ static tree current_function_parms;
static tree current_function_parm_tags;
/* And for last_function_parm_vars. */
/* And for last_function_parm_others. */
static tree current_function_parm_vars;
static tree current_function_parm_others;
/* Similar, for the file and line that the prototype came from if this is
an old-style definition. */
@ -162,18 +162,30 @@ static int warn_about_return_type;
static int current_extern_inline;
/* For each binding contour we allocate a c_scope structure
* which records the names defined in that contour.
* Contours include:
* 0) the global one
* 1) one for each function definition,
* where internal declarations of the parameters appear.
* 2) one for each compound statement,
* to record its declarations.
*
* The current meaning of a name can be found by searching the nested
* scopes from the current one out to the global one.
*/
/* Each c_scope structure describes the complete contents of one scope.
Three scopes are distinguished specially: the innermost or current
scope, the innermost function scope, and the outermost or file scope.
Most declarations are recorded in the current scope.
All normal label declarations are recorded in the innermost
function scope, as are bindings of undeclared identifiers to
error_mark_node. (GCC permits nested functions as an extension,
hence the 'innermost' qualifier.) Explicitly declared labels
(using the __label__ extension) appear in the current scope.
Being in the global scope (current_scope == global_scope) causes
special behavior in several places below. Also, under some
conditions the Objective-C front end records declarations in the
global scope even though that isn't the current scope.
The order of the names, parms, and blocks lists matters, and they
are frequently appended to. To avoid having to walk all the way to
the end of the list on each insertion, or reverse the lists later,
we maintain a pointer to the last list entry for each of the lists.
The order of the tags, shadowed, shadowed_tags, and incomplete
lists does not matter, so we just prepend to these lists. */
struct c_scope GTY(())
{
@ -183,13 +195,14 @@ struct c_scope GTY(())
/* The next outermost function scope. */
struct c_scope *outer_function;
/* All variables, constants, functions, labels, and typedef names.
They are in the reverse of the order supplied. */
/* All variables, constants, functions, labels, and typedef names. */
tree names;
tree names_last;
/* All parameter declarations. Used only in the outermost scope of
a function. Again, in the reverse of the order supplied. */
a function. */
tree parms;
tree parms_last;
/* All structure, union, and enum type tags. */
tree tags;
@ -209,9 +222,10 @@ struct c_scope GTY(())
/* For each scope (except the global one), a chain of BLOCK nodes
for all the scopes that were entered and exited one level down. */
tree blocks;
tree blocks_last;
/* Variable declarations with incomplete type in this scope. */
tree incomplete_list;
tree incomplete;
/* True if we are currently filling this scope with parameter
declarations. */
@ -251,6 +265,28 @@ static GTY(()) struct c_scope *current_function_scope;
static GTY(()) struct c_scope *global_scope;
/* Append VAR to LIST in scope SCOPE. */ \
#define SCOPE_LIST_APPEND(scope, list, decl) do { \
struct c_scope *s_ = (scope); \
tree d_ = (decl); \
if (s_->list##_last) \
TREE_CHAIN (s_->list##_last) = d_; \
else \
s_->list = d_; \
s_->list##_last = d_; \
} while (0)
/* Concatenate FROM in scope FSCOPE onto TO in scope TSCOPE. */
#define SCOPE_LIST_CONCAT(tscope, to, fscope, from) do { \
struct c_scope *t_ = (tscope); \
struct c_scope *f_ = (fscope); \
if (t_->to##_last) \
TREE_CHAIN (t_->to##_last) = f_->from; \
else \
t_->to = f_->from; \
t_->to##_last = f_->from##_last; \
} while (0)
/* True means unconditionally make a BLOCK for the next scope pushed. */
static bool keep_next_level_flag;
@ -288,7 +324,6 @@ static tree any_external_decl (tree);
static void record_external_decl (tree);
static void warn_if_shadowing (tree, tree);
static void clone_underlying_type (tree);
static void pushdecl_function_level (tree, tree);
static bool flexible_array_type_p (tree);
static hashval_t link_hash_hash (const void *);
static int link_hash_eq (const void *, const void *);
@ -454,8 +489,8 @@ pushlevel (int dummy ATTRIBUTE_UNUSED)
debugging output. If KEEP is KEEP_MAYBE, do so only if the names
or tags lists are nonempty.
If REVERSE is nonzero, reverse the order of decls before putting
them into the BLOCK.
The second parameter is ignored; it is present only for
signature compatibility with lang_hooks.decls.poplevel.
If FUNCTIONBODY is nonzero, this level is the body of a function,
even if current_scope->function_body is not set. This is used
@ -465,186 +500,165 @@ pushlevel (int dummy ATTRIBUTE_UNUSED)
FIXME: Eliminate the need for all arguments. */
tree
poplevel (int keep, int reverse, int functionbody)
poplevel (int keep, int dummy ATTRIBUTE_UNUSED, int functionbody)
{
tree link;
struct c_scope *scope = current_scope;
tree block;
tree decl;
tree decls = current_scope->names;
tree tags = current_scope->tags;
tree subblocks = current_scope->blocks;
tree p;
functionbody |= current_scope->function_body;
scope->function_body |= functionbody;
if (keep == KEEP_MAYBE)
keep = (current_scope->names || current_scope->tags);
keep = (scope->names || scope->tags);
keep |= current_scope->keep;
keep |= functionbody;
/* We used to warn about unused variables in expand_end_bindings,
i.e. while generating RTL. But in function-at-a-time mode we may
choose to never expand a function at all (e.g. auto inlining), so
we do this explicitly now.
No warnings when the global scope is popped because the global
scope isn't popped for the last translation unit, so the warnings
are done in c_write_global_declaration. */
if (current_scope != global_scope)
warn_about_unused_variables (decls);
/* Clear out the name-meanings declared in this scope.
Propagate TREE_ADDRESSABLE from nested functions to their
containing functions. */
for (link = decls; link; link = TREE_CHAIN (link))
{
if (TREE_CODE (link) == LABEL_DECL)
{
if (TREE_USED (link) && DECL_INITIAL (link) == 0)
{
error ("%Hlabel `%D' used but not defined",
&DECL_SOURCE_LOCATION (link), link);
/* Avoid crashing later. */
DECL_INITIAL (link) = error_mark_node;
}
else if (!TREE_USED (link) && warn_unused_label)
{
if (DECL_INITIAL (link) != 0)
warning ("%Hlabel `%D' defined but not used",
&DECL_SOURCE_LOCATION (link), link);
else
warning ("%Hlabel `%D' declared but not defined",
&DECL_SOURCE_LOCATION (link), link);
}
IDENTIFIER_LABEL_VALUE (DECL_NAME (link)) = 0;
}
else if (DECL_NAME (link) != 0)
{
if (DECL_EXTERNAL (link)
&& current_scope != global_scope)
/* External decls stay in the symbol-value slot but are
inaccessible. */
C_DECL_INVISIBLE (link) = 1;
else
IDENTIFIER_SYMBOL_VALUE (DECL_NAME (link)) = 0;
}
if (TREE_CODE (link) == FUNCTION_DECL
&& ! TREE_ASM_WRITTEN (link)
&& DECL_INITIAL (link) != 0
&& TREE_ADDRESSABLE (link)
&& DECL_ABSTRACT_ORIGIN (link) != 0
&& DECL_ABSTRACT_ORIGIN (link) != link)
TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (link)) = 1;
}
/* Clear out the parameter bindings declared in this scope.
Unused-parameter warnings are handled by function.c. */
for (link = current_scope->parms; link; link = TREE_CHAIN (link))
if (DECL_NAME (link))
IDENTIFIER_SYMBOL_VALUE (DECL_NAME (link)) = 0;
/* Clear out the tag-meanings declared in this scope. */
for (link = tags; link; link = TREE_CHAIN (link))
if (TREE_PURPOSE (link))
IDENTIFIER_TAG_VALUE (TREE_PURPOSE (link)) = 0;
/* Restore all name- and label-meanings from outer scopes that were
shadowed by this scope. */
for (link = current_scope->shadowed; link; link = TREE_CHAIN (link))
if (TREE_VALUE (link) && TREE_CODE (TREE_VALUE (link)) == LABEL_DECL)
IDENTIFIER_LABEL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
else
IDENTIFIER_SYMBOL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
/* Restore all tag-meanings from outer scopes that were shadowed by
this scope. */
for (link = current_scope->shadowed_tags; link;
link = TREE_CHAIN (link))
IDENTIFIER_TAG_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
/* If this is the outermost block of a function, remove all
PARM_DECLs from current_scope->names; they are already
stored in DECL_ARGUMENTS of cfun->decl in proper order, should
not be put in BLOCK_VARS, and furthermore reversing them will
cause trouble later. They are all together at the end of the
list. */
if (functionbody && decls)
{
if (TREE_CODE (decls) == PARM_DECL)
decls = 0;
else
{
link = decls;
while (TREE_CHAIN (link)
&& TREE_CODE (TREE_CHAIN (link)) != PARM_DECL)
link = TREE_CHAIN (link);
TREE_CHAIN (link) = 0;
}
}
/* Get the decls in the order they were written.
Usually current_scope->names is in reverse order.
But parameter decls were previously put in forward order. */
if (reverse)
decls = nreverse (decls);
keep |= scope->keep;
keep |= scope->function_body;
/* If appropriate, create a BLOCK to record the decls for the life
of this function. */
block = 0;
if (keep)
{
block = make_node (BLOCK);
BLOCK_VARS (block) = decls;
BLOCK_SUBBLOCKS (block) = subblocks;
BLOCK_VARS (block) = scope->names;
BLOCK_SUBBLOCKS (block) = scope->blocks;
TREE_USED (block) = 1;
}
/* In each subblock, record that this is its superior. */
for (p = scope->blocks; p; p = TREE_CHAIN (p))
BLOCK_SUPERCONTEXT (p) = block;
for (link = subblocks; link; link = TREE_CHAIN (link))
BLOCK_SUPERCONTEXT (link) = block;
/* Clear out the variable bindings in this scope.
/* Set the TYPE_CONTEXTs for all of the tagged types belonging to this
binding contour so that they point to the appropriate construct, i.e.
either to the current FUNCTION_DECL node, or else to the BLOCK node
we just constructed.
Propagate TREE_ADDRESSABLE from nested functions to their
containing functions.
Note that for tagged types whose scope is just the formal parameter
list for some function type specification, we can't properly set
their TYPE_CONTEXTs here, because we don't have a pointer to the
appropriate FUNCTION_TYPE node readily available to us. For those
cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set
in `grokdeclarator' as soon as we have created the FUNCTION_TYPE
node which will represent the "scope" for these "parameter list local"
tagged types. */
Issue warnings for unused variables and labels, and errors for
undefined labels, if there are any. */
decl = functionbody ? current_function_decl : block;
if (decl)
for (link = tags; link; link = TREE_CHAIN (link))
TYPE_CONTEXT (TREE_VALUE (link)) = decl;
for (p = scope->names; p; p = TREE_CHAIN (p))
{
const location_t *locus = &DECL_SOURCE_LOCATION (p);
switch (TREE_CODE (p))
{
case LABEL_DECL:
if (TREE_USED (p) && !DECL_INITIAL (p))
{
error ("%Hlabel `%D' used but not defined", locus, p);
DECL_INITIAL (p) = error_mark_node;
}
else if (!TREE_USED (p) && warn_unused_label)
{
if (DECL_INITIAL (p))
warning ("%Hlabel `%D' defined but not used", locus, p);
else
warning ("%Hlabel `%D' declared but not defined", locus, p);
}
IDENTIFIER_LABEL_VALUE (DECL_NAME (p)) = 0;
break;
case FUNCTION_DECL:
if (! TREE_ASM_WRITTEN (p)
&& DECL_INITIAL (p) != 0
&& TREE_ADDRESSABLE (p)
&& DECL_ABSTRACT_ORIGIN (p) != 0
&& DECL_ABSTRACT_ORIGIN (p) != p)
TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1;
goto normal;
case VAR_DECL:
/* keep this in sync with stmt.c:warn_about_unused_variables.
No warnings when the global scope is popped because the
global scope isn't popped for the last translation unit,
so the warnings are done in c_write_global_declaration. */
if (warn_unused_variable && scope != global_scope
&& !TREE_USED (p)
&& !DECL_IN_SYSTEM_HEADER (p)
&& DECL_NAME (p)
&& !DECL_ARTIFICIAL (p))
warning ("%Hunused variable `%D'", locus, p);
/* fall through */
default:
normal:
if (DECL_NAME (p))
{
if (DECL_EXTERNAL (p) && scope != global_scope)
/* External decls stay in the symbol-value slot but are
inaccessible. */
C_DECL_INVISIBLE (p) = 1;
else
IDENTIFIER_SYMBOL_VALUE (DECL_NAME (p)) = 0;
}
break;
}
}
/* Clear out the parameter bindings in this scope, if any.
Unused-parameter warnings are handled by function.c. */
for (p = scope->parms; p; p = TREE_CHAIN (p))
if (DECL_NAME (p))
IDENTIFIER_SYMBOL_VALUE (DECL_NAME (p)) = 0;
/* Clear out the tag-meanings declared in this scope.
Set the TYPE_CONTEXTs for all of the tagged types belonging to
this scope so that they point to the appropriate construct, i.e.
either to the current FUNCTION_DECL node, or else to the BLOCK
node we just constructed.
Note that for tagged types whose scope is just the formal
parameter list for some function type specification, we can't
properly set their TYPE_CONTEXTs here, because we don't have a
pointer to the appropriate FUNCTION_TYPE node readily available
to us. For those cases, the TYPE_CONTEXTs of the relevant tagged
type nodes get set in `grokdeclarator' as soon as we have created
the FUNCTION_TYPE node which will represent the "scope" for these
"parameter list local" tagged types. */
decl = scope->function_body ? current_function_decl : block;
for (p = scope->tags; p; p = TREE_CHAIN (p))
{
if (TREE_PURPOSE (p))
IDENTIFIER_TAG_VALUE (TREE_PURPOSE (p)) = 0;
if (decl)
TYPE_CONTEXT (TREE_VALUE (p)) = decl;
}
/* Restore all name- and label-meanings from outer scopes that were
shadowed by this scope. */
for (p = scope->shadowed; p; p = TREE_CHAIN (p))
if (TREE_VALUE (p) && TREE_CODE (TREE_VALUE (p)) == LABEL_DECL)
IDENTIFIER_LABEL_VALUE (TREE_PURPOSE (p)) = TREE_VALUE (p);
else
IDENTIFIER_SYMBOL_VALUE (TREE_PURPOSE (p)) = TREE_VALUE (p);
/* Restore all tag-meanings from outer scopes that were shadowed by
this scope. */
for (p = scope->shadowed_tags; p; p = TREE_CHAIN (p))
IDENTIFIER_TAG_VALUE (TREE_PURPOSE (p)) = TREE_VALUE (p);
/* Dispose of the block that we just made inside some higher level. */
if (scope->function_body)
DECL_INITIAL (current_function_decl) = block;
else if (scope->outer)
{
if (block)
SCOPE_LIST_APPEND (scope->outer, blocks, block);
/* If we did not make a block for the scope just exited, any
blocks made for inner scopes must be carried forward so they
will later become subblocks of something else. */
else if (scope->blocks)
SCOPE_LIST_CONCAT (scope->outer, blocks, scope, blocks);
}
/* Pop the current scope, and free the structure for reuse. */
pop_scope ();
/* Dispose of the block that we just made inside some higher level. */
if (functionbody)
DECL_INITIAL (current_function_decl) = block;
else if (block && current_scope)
current_scope->blocks
= chainon (current_scope->blocks, block);
/* If we did not make a block for the scope just exited, any blocks
made for inner scopes (since they cannot be recorded as subblocks
here) must be carried forward so they will later become subblocks
of something else. */
else if (! block && subblocks)
current_scope->blocks
= chainon (current_scope->blocks, subblocks);
return block;
}
@ -656,8 +670,7 @@ void
insert_block (tree block)
{
TREE_USED (block) = 1;
current_scope->blocks
= chainon (current_scope->blocks, block);
SCOPE_LIST_APPEND (current_scope, blocks, block);
}
/* Set the BLOCK node for the innermost scope (the one we are
@ -1687,8 +1700,8 @@ pushdecl (tree x)
if (*p == old)
{
*p = TREE_CHAIN (old);
TREE_CHAIN (old) = scope->parms;
scope->parms = old;
SCOPE_LIST_APPEND (scope, parms, old);
break;
}
}
return old;
@ -1748,89 +1761,42 @@ pushdecl (tree x)
element = TREE_TYPE (element);
if (TREE_CODE (element) == RECORD_TYPE
|| TREE_CODE (element) == UNION_TYPE)
scope->incomplete_list = tree_cons (NULL_TREE, x,
scope->incomplete_list);
scope->incomplete = tree_cons (NULL_TREE, x, scope->incomplete);
}
}
/* Put decls on list in reverse order.
We will reverse them later if necessary. */
if (TREE_CODE (x) == PARM_DECL)
{
TREE_CHAIN (x) = scope->parms;
scope->parms = x;
}
SCOPE_LIST_APPEND (scope, parms, x);
else
{
TREE_CHAIN (x) = scope->names;
scope->names = x;
}
SCOPE_LIST_APPEND (scope, names, x);
return x;
}
/* Record X as belonging to the global scope (C99 "file scope").
This is used only internally by the Objective-C front end,
and is limited to its needs. It will hork if there is _any_
visible binding for X (not just a global one). */
and is limited to its needs. duplicate_decls is not called;
if there is any preexisting decl for this identifier, it is an ICE. */
tree
pushdecl_top_level (tree x)
{
tree name, old;
tree name;
if (TREE_CODE (x) != VAR_DECL)
abort ();
name = DECL_NAME (x);
old = IDENTIFIER_SYMBOL_VALUE (name);
if (old)
{
if (DECL_CONTEXT (old))
abort ();
if (!duplicate_decls (x, old, 0, false))
abort ();
return old;
}
if (IDENTIFIER_SYMBOL_VALUE (name))
abort ();
DECL_CONTEXT (x) = current_file_decl;
IDENTIFIER_SYMBOL_VALUE (name) = x;
TREE_CHAIN (x) = global_scope->names;
global_scope->names = x;
SCOPE_LIST_APPEND (global_scope, names, x);
return x;
}
/* Record X as belonging to the outermost scope of the current
function. This is used only internally, by c_make_fname_decl and
undeclared_variable, and is limited to their needs. The NAME is
provided as a separate argument because undeclared_variable wants to
use error_mark_node for X. For VAR_DECLs, duplicate_decls is not
called; if there is any preexisting decl for this identifier, it is
an ICE. */
static void
pushdecl_function_level (tree x, tree name)
{
struct c_scope *scope = current_function_scope;
if (x == error_mark_node)
scope->shadowed = tree_cons (name, IDENTIFIER_SYMBOL_VALUE (name),
scope->shadowed);
else if (TREE_CODE (x) == VAR_DECL)
{
if (name != DECL_NAME (x))
abort ();
if (IDENTIFIER_SYMBOL_VALUE (name))
abort ();
DECL_CONTEXT (x) = current_function_decl;
TREE_CHAIN (x) = scope->names;
scope->names = x;
}
IDENTIFIER_SYMBOL_VALUE (name) = x;
}
/* Generate an implicit declaration for identifier FUNCTIONID as a
function of type int (). */
@ -1840,7 +1806,7 @@ implicitly_declare (tree functionid)
{
tree decl = any_external_decl (functionid);
if (decl && decl != error_mark_node)
if (decl)
{
/* Implicit declaration of a function already declared
(somehow) in a different scope, or as a built-in.
@ -1969,12 +1935,13 @@ void
undeclared_variable (tree id)
{
static bool already = false;
struct c_scope *scope;
if (current_function_decl == 0)
{
error ("`%s' undeclared here (not in a function)",
IDENTIFIER_POINTER (id));
IDENTIFIER_SYMBOL_VALUE (id) = error_mark_node;
scope = current_scope;
}
else
{
@ -1988,8 +1955,12 @@ undeclared_variable (tree id)
already = true;
}
pushdecl_function_level (error_mark_node, id);
scope = current_function_scope;
}
scope->shadowed = tree_cons (id, IDENTIFIER_SYMBOL_VALUE (id),
scope->shadowed);
IDENTIFIER_SYMBOL_VALUE (id) = error_mark_node;
}
/* Subroutine of lookup_label, declare_label, define_label: construct a
@ -2018,8 +1989,7 @@ bind_label (tree name, tree label, struct c_scope *scope)
scope->shadowed);
IDENTIFIER_LABEL_VALUE (name) = label;
TREE_CHAIN (label) = scope->names;
scope->names = label;
SCOPE_LIST_APPEND (scope, names, label);
}
/* Get the LABEL_DECL corresponding to identifier NAME as a label.
@ -2152,8 +2122,7 @@ define_label (location_t location, tree name)
return label;
}
/* Return the list of declarations of the current scope.
Note that this list is in reverse order. */
/* Return the list of declarations of the current scope. */
tree
getdecls (void)
@ -2161,13 +2130,6 @@ getdecls (void)
return current_scope->names;
}
/* Return the list of type-tags (for structs, etc) of the current scope. */
tree
gettags (void)
{
return current_scope->tags;
}
/* Given NAME, an IDENTIFIER_NODE,
return the structure (or union or enum) definition for that name.
@ -2334,8 +2296,7 @@ c_init_decl_processing (void)
NAME depended on the type of the function. As we don't yet implement
delayed emission of static data, we mark the decl as emitted
so it is not placed in the output. Anything using it must therefore pull
out the STRING_CST initializer directly. This does mean that these names
are string merging candidates, which is wrong for C99's __func__. FIXME. */
out the STRING_CST initializer directly. FIXME. */
static tree
c_make_fname_decl (tree id, int type_dep)
@ -2361,7 +2322,11 @@ c_make_fname_decl (tree id, int type_dep)
TREE_USED (decl) = 1;
if (current_function_decl)
pushdecl_function_level (decl, DECL_NAME (decl));
{
DECL_CONTEXT (decl) = current_function_decl;
IDENTIFIER_SYMBOL_VALUE (id) = decl;
SCOPE_LIST_APPEND (current_function_scope, names, decl);
}
finish_decl (decl, init, NULL_TREE);
@ -3041,14 +3006,14 @@ push_parm_decl (tree parm)
immediate_size_expand = save_immediate_size_expand;
}
/* Shift all the existing parameter decls to the variables list,
and reset the parameters list. Used when a ; terminating
forward parameter decls is encountered. */
/* Mark all the parameter declarations to date as forward decls,
shift them to the variables list, and reset the parameters list.
Also diagnose use of this extension. */
void
mark_forward_parm_decls (void)
{
tree parm, last;
tree parm;
if (pedantic && !current_scope->warned_forward_parm_decls)
{
@ -3056,14 +3021,12 @@ mark_forward_parm_decls (void)
current_scope->warned_forward_parm_decls = true;
}
for (last = 0, parm = current_scope->parms;
parm;
last = parm, parm = TREE_CHAIN (parm))
for (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
TREE_ASM_WRITTEN (parm) = 1;
TREE_CHAIN (last) = current_scope->names;
current_scope->names = current_scope->parms;
SCOPE_LIST_CONCAT (current_scope, names, current_scope, parms);
current_scope->parms = 0;
current_scope->parms_last = 0;
}
static GTY(()) int compound_literal_number;
@ -4516,7 +4479,7 @@ grokparms (tree parms_info, int funcdef_flag)
last_function_parms = TREE_PURPOSE (parms_info);
last_function_parm_tags = TREE_VALUE (parms_info);
last_function_parm_vars = TREE_TYPE (parms_info);
last_function_parm_others = TREE_TYPE (parms_info);
if (warn_strict_prototypes && first_parm == 0 && !funcdef_flag
&& !in_system_header)
@ -4611,9 +4574,6 @@ get_parm_info (int void_at_end)
return tree_cons (0, 0, tree_cons (0, void_type_node, 0));
}
if (parms)
current_scope->parms = parms = nreverse (parms);
/* Sanity check all of the parameter declarations. */
for (decl = parms; decl; decl = TREE_CHAIN (decl))
{
@ -5196,11 +5156,11 @@ finish_struct (tree t, tree fieldlist, tree attributes)
/* If this structure or union completes the type of any previous
variable declaration, lay it out and output its rtl. */
if (current_scope->incomplete_list != NULL_TREE)
if (current_scope->incomplete != NULL_TREE)
{
tree prev = NULL_TREE;
for (x = current_scope->incomplete_list; x; x = TREE_CHAIN (x))
for (x = current_scope->incomplete; x; x = TREE_CHAIN (x))
{
tree decl = TREE_VALUE (x);
@ -5218,7 +5178,7 @@ finish_struct (tree t, tree fieldlist, tree attributes)
if (prev)
TREE_CHAIN (prev) = TREE_CHAIN (x);
else
current_scope->incomplete_list = TREE_CHAIN (x);
current_scope->incomplete = TREE_CHAIN (x);
}
else if (!COMPLETE_TYPE_P (TREE_TYPE (decl))
&& TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
@ -5242,7 +5202,7 @@ finish_struct (tree t, tree fieldlist, tree attributes)
if (prev)
TREE_CHAIN (prev) = TREE_CHAIN (x);
else
current_scope->incomplete_list = TREE_CHAIN (x);
current_scope->incomplete = TREE_CHAIN (x);
}
}
}
@ -5567,7 +5527,7 @@ start_function (tree declspecs, tree declarator, tree attributes)
where store_parm_decls will find them. */
current_function_parms = last_function_parms;
current_function_parm_tags = last_function_parm_tags;
current_function_parm_vars = last_function_parm_vars;
current_function_parm_others = last_function_parm_others;
/* Make the init_value nonzero so pushdecl knows this is not tentative.
error_mark_node is replaced below (in poplevel) with the BLOCK. */
@ -5749,11 +5709,11 @@ start_function (tree declspecs, tree declarator, tree attributes)
static void
store_parm_decls_newstyle (void)
{
tree decl;
tree decl, last;
tree fndecl = current_function_decl;
tree parms = current_function_parms;
tree tags = current_function_parm_tags;
tree vars = current_function_parm_vars;
tree others = current_function_parm_others;
if (current_scope->parms || current_scope->names || current_scope->tags)
{
@ -5767,10 +5727,9 @@ store_parm_decls_newstyle (void)
/* Now make all the parameter declarations visible in the function body.
We can bypass most of the grunt work of pushdecl. */
for (decl = parms; decl; decl = TREE_CHAIN (decl))
for (last = 0, decl = parms; decl; last = decl, decl = TREE_CHAIN (decl))
{
DECL_CONTEXT (decl) = current_function_decl;
if (DECL_NAME (decl) == 0)
error ("%Hparameter name omitted", &DECL_SOURCE_LOCATION (decl));
else
@ -5784,12 +5743,13 @@ store_parm_decls_newstyle (void)
}
}
current_scope->parms = parms;
current_scope->parms_last = last;
/* Record the parameter list in the function declaration. */
DECL_ARGUMENTS (fndecl) = parms;
/* Now make all the ancillary declarations visible, likewise. */
for (decl = vars; decl; decl = TREE_CHAIN (decl))
for (last = 0, decl = others; decl; last = decl, decl = TREE_CHAIN (decl))
{
DECL_CONTEXT (decl) = current_function_decl;
if (DECL_NAME (decl)
@ -5803,7 +5763,8 @@ store_parm_decls_newstyle (void)
IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)) = decl;
}
}
current_scope->names = vars;
current_scope->names = others;
current_scope->names_last = last;
/* And all the tag declarations. */
for (decl = tags; decl; decl = TREE_CHAIN (decl))
@ -5832,9 +5793,12 @@ store_parm_decls_oldstyle (void)
tree parmids = current_function_parms;
/* We use DECL_WEAK as a flag to show which parameters have been
seen already, since it is not used on PARM_DECL or CONST_DECL. */
seen already, since it is not used on PARM_DECL. */
#ifdef ENABLE_CHECKING
for (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
DECL_WEAK (parm) = 0;
if (DECL_WEAK (parm))
abort ();
#endif
/* Match each formal parameter name with its declaration. Save each
decl in the appropriate TREE_PURPOSE slot of the parmids chain. */
@ -5939,6 +5903,7 @@ store_parm_decls_oldstyle (void)
last = TREE_PURPOSE (parm);
DECL_WEAK (last) = 0;
}
current_scope->parms_last = last;
TREE_CHAIN (last) = 0;
}
@ -6472,7 +6437,7 @@ check_for_loop_decls (void)
/* 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");
error ("'for' loop initial declaration used outside C99 mode");
return;
}
/* C99 subclause 6.8.5 paragraph 3:
@ -6489,20 +6454,20 @@ check_for_loop_decls (void)
interpretation, to avoid creating an extension which later causes
problems. */
for (t = gettags (); t; t = TREE_CHAIN (t))
for (t = current_scope->tags; t; t = TREE_CHAIN (t))
{
if (TREE_PURPOSE (t) != 0)
{
enum tree_code code = TREE_CODE (TREE_VALUE (t));
if (code == RECORD_TYPE)
error ("`struct %s' declared in `for' loop initial declaration",
error ("'struct %s' declared in 'for' loop initial declaration",
IDENTIFIER_POINTER (TREE_PURPOSE (t)));
else if (code == UNION_TYPE)
error ("`union %s' declared in `for' loop initial declaration",
error ("'union %s' declared in 'for' loop initial declaration",
IDENTIFIER_POINTER (TREE_PURPOSE (t)));
else
error ("`enum %s' declared in `for' loop initial declaration",
error ("'enum %s' declared in 'for' loop initial declaration",
IDENTIFIER_POINTER (TREE_PURPOSE (t)));
}
}
@ -6515,7 +6480,7 @@ check_for_loop_decls (void)
"initial declaration", locus, t);
else if (TREE_STATIC (t))
error ("%Hdeclaration of static variable '%D' in 'for' loop "
"initial declaration", locus, t);
"initial declaration", locus, t);
else if (DECL_EXTERNAL (t))
error ("%Hdeclaration of 'extern' variable '%D' in 'for' loop "
"initial declaration", locus, t);
@ -6885,11 +6850,10 @@ c_write_global_declarations(void)
int i;
tree decl;
/* Process the decls in reverse order--earliest first.
Put them into VEC from back to front, then take out from front. */
/* Process the decls in the order they were written. */
for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
vec[len - i - 1] = decl;
vec[i] = decl;
wrapup_global_declarations (vec, len);

View File

@ -2135,7 +2135,7 @@ compstmt_start: '{' { compstmt_count++;
compstmt_nostart: '}'
{ $$ = convert (void_type_node, integer_zero_node); }
| pushlevel maybe_label_decls compstmt_contents_nonempty '}' poplevel
{ $$ = poplevel (KEEP_MAYBE, 1, 0);
{ $$ = poplevel (KEEP_MAYBE, 0, 0);
SCOPE_STMT_BLOCK (TREE_PURPOSE ($5))
= SCOPE_STMT_BLOCK (TREE_VALUE ($5))
= $$; }