This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
peeling more bits off the onion
- From: "Zack Weinberg" <zack at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 17 Jul 2003 20:37:52 -0700
- Subject: peeling more bits off the onion
Two more pieces tangentially related to the patch I'm working on.
Moving undeclared_variable into c-decl.c allows me to make
pushdecl_top_level static, and will allow further interface cleanups
(internal to c-decl.c) later. kept_level_p is used only to provide
the value of the first argument to poplevel; making that first
argument a tristate instead of a boolean lets me fold kept_level_p
into poplevel, at which point it becomes clear that there's a bunch of
redundant work going on.
bootstrapped i686-linux.
zw
* c-decl.c (pushdecl_function_level): Make static, return nothing.
(kept_level_p): Fold into poplevel.
(undeclared_variable): Moved here from c-typeck.c. Export.
* c-tree.h (KEEP_YES, KEEP_NO, KEEP_MAYBE): New #defines.
(undeclared_variable): Prototype here. Don't prototype
kept_level_p nor pushdecl_function_level.
* c-parse.in: Change first argument to poplevel from
"kept_level_p()" to "KEEP_MAYBE".
* c-typeck.c (undeclared_variable): Moved to c-decl.c.
===================================================================
Index: c-decl.c
--- c-decl.c 17 Jul 2003 20:12:13 -0000 1.407
+++ c-decl.c 18 Jul 2003 03:33:04 -0000
@@ -291,6 +291,7 @@ 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 *);
@@ -391,18 +392,6 @@ keep_next_level (void)
keep_next_level_flag = 1;
}
-/* Nonzero if the current level needs to have a BLOCK made. */
-
-int
-kept_level_p (void)
-{
- return ((current_binding_level->keep_if_subblocks
- && current_binding_level->blocks != 0)
- || current_binding_level->keep
- || current_binding_level->names != 0
- || current_binding_level->tags != 0);
-}
-
/* Identify this binding level as a level of parameters. */
void
@@ -485,8 +474,12 @@ poplevel (int keep, int reverse, int fun
tree subblocks = current_binding_level->blocks;
functionbody |= current_binding_level->function_body;
+
+ if (keep == KEEP_MAYBE)
+ keep = (current_binding_level->names || current_binding_level->tags);
+
keep |= (current_binding_level->keep || functionbody
- || (current_binding_level->keep_if_subblocks && subblocks != 0));
+ || (subblocks && current_binding_level->keep_if_subblocks));
/* 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
@@ -1830,12 +1823,12 @@ pushdecl_top_level (tree x)
/* Record X as belonging to the outermost scope of the current
function. This is used only internally, by c_make_fname_decl and
- build_external_ref, and is limited to their needs. The NAME is
- provided as a separate argument because build_external_ref wants to
+ 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. */
-tree
+static void
pushdecl_function_level (tree x, tree name)
{
struct binding_level *scope;
@@ -1862,7 +1855,6 @@ pushdecl_function_level (tree x, tree na
}
IDENTIFIER_SYMBOL_VALUE (name) = x;
- return x;
}
/* Generate an implicit declaration for identifier FUNCTIONID as a
@@ -1990,6 +1982,38 @@ redeclaration_error_message (tree newdec
&& DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl))
return 2;
return 0;
+ }
+}
+
+/* Issue an error message for a reference to an undeclared variable
+ ID, including a reference to a builtin outside of function-call
+ context. Establish a binding of the identifier to error_mark_node
+ in an appropriate scope, which will suppress further errors for the
+ same identifier. */
+void
+undeclared_variable (tree id)
+{
+ static bool already = false;
+
+ if (current_function_decl == 0)
+ {
+ error ("`%s' undeclared here (not in a function)",
+ IDENTIFIER_POINTER (id));
+ IDENTIFIER_SYMBOL_VALUE (id) = error_mark_node;
+ }
+ else
+ {
+ error ("`%s' undeclared (first use in this function)",
+ IDENTIFIER_POINTER (id));
+
+ if (! already)
+ {
+ error ("(Each undeclared identifier is reported only once");
+ error ("for each function it appears in.)");
+ already = true;
+ }
+
+ pushdecl_function_level (error_mark_node, id);
}
}
===================================================================
Index: c-parse.in
--- c-parse.in 17 Jul 2003 20:12:14 -0000 1.172
+++ c-parse.in 18 Jul 2003 03:33:04 -0000
@@ -2087,7 +2087,7 @@ c99_block_end: /* empty */
{ if (flag_isoc99)
{
tree scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
- $$ = poplevel (kept_level_p (), 0, 0);
+ $$ = poplevel (KEEP_MAYBE, 0, 0);
SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
= SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
= $$;
@@ -2137,7 +2137,7 @@ compstmt_start: '{' { compstmt_count++;
compstmt_nostart: '}'
{ $$ = convert (void_type_node, integer_zero_node); }
| pushlevel maybe_label_decls compstmt_contents_nonempty '}' poplevel
- { $$ = poplevel (kept_level_p (), 1, 0);
+ { $$ = poplevel (KEEP_MAYBE, 1, 0);
SCOPE_STMT_BLOCK (TREE_PURPOSE ($5))
= SCOPE_STMT_BLOCK (TREE_VALUE ($5))
= $$; }
===================================================================
Index: c-tree.h
--- c-tree.h 17 Jul 2003 20:12:14 -0000 1.121
+++ c-tree.h 18 Jul 2003 03:33:04 -0000
@@ -155,6 +155,11 @@ struct lang_type GTY(())
without prototypes. */
#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_BINFO (NODE)
+/* Values for the first parameter to poplevel. */
+#define KEEP_NO 0
+#define KEEP_YES 1
+#define KEEP_MAYBE 2
+
/* in c-lang.c and objc-act.c */
extern tree lookup_interface (tree);
@@ -175,7 +180,6 @@ extern void gen_aux_info_record (tree, i
/* in c-decl.c */
extern int global_bindings_p (void);
-extern int kept_level_p (void);
extern tree getdecls (void);
extern void pushlevel (int);
extern void insert_block (tree);
@@ -192,6 +196,7 @@ extern void check_for_loop_decls (void);
extern void clear_parm_order (void);
extern int complete_array_type (tree, tree, int);
extern void declare_parm_level (void);
+extern void undeclared_variable (tree);
extern tree define_label (location_t, tree);
extern void finish_decl (tree, tree, tree);
extern tree finish_enum (tree, tree, tree);
@@ -213,7 +218,6 @@ extern void pop_label_level (void);
extern void push_label_level (void);
extern void push_parm_decl (tree);
extern tree pushdecl_top_level (tree);
-extern tree pushdecl_function_level (tree, tree);
extern void pushtag (tree, tree);
extern tree set_array_declarator_type (tree, tree, int);
extern tree shadow_label (tree);
===================================================================
Index: c-typeck.c
--- c-typeck.c 17 Jul 2003 20:12:14 -0000 1.246
+++ c-typeck.c 18 Jul 2003 03:33:04 -0000
@@ -49,9 +49,6 @@ Software Foundation, 59 Temple Place - S
message within this initializer. */
static int missing_braces_mentioned;
-/* 1 if we explained undeclared var errors. */
-static int undeclared_variable_notice;
-
static tree qualify_type (tree, tree);
static int tagged_types_tu_compatible_p (tree, tree, int);
static int comp_target_types (tree, tree, int);
@@ -60,7 +57,6 @@ static int type_lists_compatible_p (tree
static tree decl_constant_value_for_broken_optimization (tree);
static tree default_function_array_conversion (tree);
static tree lookup_field (tree, tree);
-static void undeclared_variable (tree);
static tree convert_arguments (tree, tree, tree, tree);
static tree pointer_diff (tree, tree);
static tree unary_complex_lvalue (enum tree_code, tree, int);
@@ -1531,37 +1527,6 @@ build_array_ref (tree array, tree index)
}
}
-/* Issue an error message for a reference to an undeclared variable ID,
- including a reference to a builtin outside of function-call context.
- Arrange to suppress further errors for the same identifier. */
-static void
-undeclared_variable (tree id)
-{
- if (current_function_decl == 0)
- {
- error ("`%s' undeclared here (not in a function)",
- IDENTIFIER_POINTER (id));
- IDENTIFIER_SYMBOL_VALUE (id) = error_mark_node;
- }
- else
- {
- error ("`%s' undeclared (first use in this function)",
- IDENTIFIER_POINTER (id));
-
- if (! undeclared_variable_notice)
- {
- error ("(Each undeclared identifier is reported only once");
- error ("for each function it appears in.)");
- undeclared_variable_notice = 1;
- }
-
- /* Set IDENTIFIER_SYMBOL_VALUE (id) to error_mark_node
- at function scope. This suppresses further warnings
- about this undeclared identifier in this function. */
- pushdecl_function_level (error_mark_node, id);
- }
-}
-
/* Build an external reference to identifier ID. FUN indicates
whether this will be used for a function call. */
tree