summaryrefslogtreecommitdiffstats
path: root/gcc/c-typeck.c
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-09-17 07:38:23 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-09-17 07:38:23 +0000
commite41f0d80e9a4aba0523a95d39a11ac03480a3be2 (patch)
tree45edb9dcda813de0e477165a8b093d17332bda80 /gcc/c-typeck.c
parent1fa8fd5c156a1b0313a58c0f0bd2f35e3c47e767 (diff)
downloadppe42-gcc-e41f0d80e9a4aba0523a95d39a11ac03480a3be2.tar.gz
ppe42-gcc-e41f0d80e9a4aba0523a95d39a11ac03480a3be2.zip
* splay-tree.c (splay_tree_predecessor): Fix typo in comment.
Convert the C front-end to use function-at-a-time mode. * c-common.h: Include splay-tree.h. (C_DECLARED_LABEL_FLAG): New macro. (struct language_function): Add x_scope_stmt_stack and x_function_name_declared_p. (RECHAIN_STMTS): Move definition. (lang_statment_code_p): Likewise. (lang_expand_stmt): Likewise. (lang_expand_decl_stmt): New variable. (lang_expand_function_end): Likewise. (current_scope_stmt_stack): New function. (add_decl_stmt): Likewise. (add_scope_stmt): Likewise. (mark_stmt_tree): Likewise. (struct c_lang_decl): New structure. (DECL_SAVED_TREE): Define. (c_mark_lang_decl): New function. (c_expand_start_cond): Change prototype. (c_finish_then): New function. (c_finish_else): Likewise. (current_function_name_declared): Remove. (set_current_function_name_declared): Likewise. (mark_c_language_function): Declare. (case_compare): Likewise. (c_add_case_label): Likewise. (c_expand_expr): Likewise. (c_safe_from_p): Likewise. * c-common.c (lang_expand_function_end): New variable. (struct if_elt): Add if_stmt. (c_expand_start_cond): Add the if-statement to the statement-tree, rather than generating RTL. (c_finish_then): New function. (c_expand_start_else): Don't generate RTL. (c_finish_else): New function. (c_expand_expr_stmt): Don't generate RTL. (statement_code_p): Add SCOPE_STMT. (case_compare): New function. (c_add_case_label): Likewise. (mark_stmt_tree): Likewise. (c_mark_lang_decl): Likewise. (mark_c_language_function): Likewise. (c_expand_expr): Likewise. (c_safe_from_p): Likewise. * c-decl.c (c_stmt_tree): New variable (c_scope_stmt_stack): Likewise. (c_function_name_declared_p): Likewise. (lang_expand_expr_stmt): Remove. (poplevel): Don't call output_inline_function for nested functions. (pushdecl): Don't set DECL_CONTEXT for a local declaration of an `extern' function. (redeclaration_error_message): Change means of computing whether or not a function is nested. (lookup_label): Don't call label_rtx. (init_decl_processing): Add more GC roots. (start_decl): Add DECL_STMTs to the statement-tree, rather than calling rest_of_decl_compilation. (finish_decl): Don't call expand_decl. (store_parm_decls): Begin the statement-tree, but don't generate RTL. (finish_function): Tie off the statement-tree. Call c_expand_body if appropriate. (c_expand_body): New function. (push_c_function_context): Save more information. (pop_c_function_contxt): Likewise. (copy_lang_decl): Now that we use DECL_LANG_SPECIFIC, copy it. (lang_mark_tree): Mark it. (current_stmt_tree): Adjust. (current_scope_stmt_stack): New function. (do_case): Remove. (set_current_name_declared): Likewise. (c_begin_compound_stmt): Define. (c_expand_decl_stmt): Likewise. * c-lang.c: Include rtl.h and expr.h. (lang_init): Set more language-specific hooks. * c-lex.c: Include expr.h. * c-parse.in: Changes throughout to add statements to the statement-tree, rather than generating RTL after every statement. * c-semantics.c (lang_expand_decl_stmt): Define. (add_decl_stmt): New function. (add_scope_stmt): Likewise. (finish_stmt_tree): Tweak. (genrtl_expr_stmt): Likewise. (genrtl_decl_stmt): Handle local labels, and call lang_expand_decl_stmt if required. (genrtl_for_stmt): Fix line-number handling. (genrtl_case_label): Handle cleanups. (genrtl_asm_stmt): Don't call combine_strings. (genrtl_compound_stmt): Simplify. (expand_stmt): Handle SCOPE_STMTs. * c-tree.h (struct lang_decl): New structure. (C_DECLARED_LABEL_FLAG): Remove. (c_begin_compound_stmt): Declare. (c_expand_decl_stmt): Likewise. (c_expand_start_case): Rename to c_start_case. (c_finish_case): New function. * c-typeck.c (start_init): Tweak setting of constructor_incremental. (c_expand_asm_operands): Tweak error-handling. Add to the statement-tree. (c_expand_return): Add to the statement-tree. (c_expand_start_case): Rename to ... (c_start_case): ... this. (struct c_switch): New type. (switch_stack): New variable. (do_case): Simplify. (c_finish_case): New function. * dependence.c: Include expr.h. (enum dependence_type): Change spelling of enumerals. (check_node_dependence): Adjust. * expr.h (lang_safe_from_p): Declare. (safe_from_p): Likewise. * expr.c (lang_safe_from_p): New variable. (safe_from_p): Give it external linkage. Use lang_safe_from_p. * stmt.c (expand_expr_stmt): Avoid clobberring of last_expr_type. * toplev.c (rest_of_decl_compilation): Robustify. * tree.c (contains_placeholder_p): Likewise. * Makefile.in: Update dependencies. * objc/objc-act.h: Adjust calculation of value for dummy_tree_code. * objc/objc-act.c: Include rtl.h, expr.h, and c-common.h. (objc_expand_function_end): New function. (finish_method_def): Use it. (init_objc): Initialize more language-specific hooks. * objc/Make-lang.in: Update dependencies. * cp-tree.h (struct cp_language_function): Remove x_scope_stmt_stack and name_declared. (current_scope_stmt_stack): Remove. (function_name_declared_p): New macro. (struct lang_decl_flags): Use c_lang_decl as a base class. (context): Remove. (struct lang_decl): Replace saved_tree with context. (DECL_FRIEND_CONTEXT): Adjust accordingly. (SET_DECL_FRIEND_CONTEXT): Likewise. (DECL_VIRTUAL_CONTEXT): Likewise. (DECL_SAVED_TREE): Remove. (C_DECLARED_LABEL_FLAG): Likewise. (cplus_expand_expr_stmt): Don't declare. (add_decl_stmt): Likewise. (add_scope_stmt): Likewise. * decl.c (mark_stmt_tree): Remove. (case_compare): Likewise. (finish_case_label): Use c_add_case_label. (init_decl_processing): Set more language-specific hooks. (build_enumerator): Fix typo in comment. (cplus_expand_expr_stmt): Remove. (mark_lang_function): Use mark_c_language_function. (lang_mark_tree): Use c_mark_lang_decl. * decl2.c: Change order of inclusion. * except.c: Likewise. * expr.c (cplus_expand_expr): Remove handling of STMT_EXPR. Fall back on c_expand_expr. * friend.c: Include expr.h. * init.c: Change order of inclusion. * Makefile.in: Update dependencies. * lex.h (free_lang_decl_chain): Remove. * optimize.c (maybe_clone_body): Use function_name_declared_p. * pt.c (build_template_decl): Don't copy DECL_VIRTUAL_CONTEXT if it doesn't exist. (instantiate_decl): Use function_name_declared_p. * semantics.c (lang_expand_expr_stmt): Remove. (set_current_function_name_declared): Likewise. (current_function_name_declared): Likewise. (begin_compound_stmt): Use function_name_declared_p. (add_decl_stmt): Remove. (setup_vtbl_ptr): Use function_name_declared_p. (add_scope_stmt): Remove. (current_scope_stmt_stack): New function. (cp_expand_stmt): Don't handle SCOPE_STMTs. (expand_body): Use function_name_declared_p. * tree.c (cp_statement_code_p): Don't include SCOPE_STMT. * typeck.c: Change order of includes. (convert_sequence): Remove. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36464 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-typeck.c')
-rw-r--r--gcc/c-typeck.c142
1 files changed, 107 insertions, 35 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 002d4e704fe..f4b42b991a5 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -4999,7 +4999,8 @@ start_init (decl, asmspec_tree, top_level)
|| TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE
|| TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE));
locus = IDENTIFIER_POINTER (DECL_NAME (decl));
- constructor_incremental |= TREE_STATIC (decl);
+ constructor_incremental
+ |= (TREE_STATIC (decl) && !DECL_CONTEXT (decl));
}
else
{
@@ -6541,7 +6542,7 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
if (TREE_CODE (string) == ADDR_EXPR)
string = TREE_OPERAND (string, 0);
- if (TREE_CODE (string) != STRING_CST)
+ if (last_tree && TREE_CODE (string) != STRING_CST)
{
error ("asm template is not a string constant");
return;
@@ -6567,7 +6568,8 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|| TREE_CODE (output) == FIX_CEIL_EXPR)
output = TREE_OPERAND (output, 0);
- lvalue_or_else (o[i], "invalid lvalue in asm statement");
+ if (last_tree)
+ lvalue_or_else (o[i], "invalid lvalue in asm statement");
}
/* Perform default conversions on array and function inputs. */
@@ -6578,6 +6580,14 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|| TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == FUNCTION_TYPE)
TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail));
+ if (last_tree)
+ {
+ add_stmt (build_stmt (ASM_STMT,
+ vol ? ridpointers[(int) RID_VOLATILE] : NULL_TREE,
+ string, outputs, inputs, clobbers));
+ return;
+ }
+
/* Generate the ASM_OPERANDS insn;
store into the TREE_VALUEs of OUTPUTS some trees for
where the values were actually stored. */
@@ -6703,53 +6713,115 @@ c_expand_return (retval)
current_function_returns_value = 1;
}
- genrtl_return_stmt (build_return_stmt (retval));
+ add_stmt (build_return_stmt (retval));
}
-/* Start a C switch statement, testing expression EXP.
- Return EXP if it is valid, an error node otherwise. */
+struct c_switch {
+ /* The SWITCH_STMT being built. */
+ tree switch_stmt;
+ /* A splay-tree mapping the low element of a case range to the high
+ element, or NULL_TREE if there is no high element. Used to
+ determine whether or not a new case label duplicates an old case
+ label. We need a tree, rather than simply a hash table, because
+ of the GNU case range extension. */
+ splay_tree cases;
+ /* The next node on the stack. */
+ struct c_switch *next;
+};
+
+/* A stack of the currently active switch statements. The innermost
+ switch statement is on the top of the stack. There is no need to
+ mark the stack for garbage collection because it is only active
+ during the processing of the body of a function, and we never
+ collect at that point. */
+
+static struct c_switch *switch_stack;
+
+/* Start a C switch statement, testing expression EXP. Return the new
+ SWITCH_STMT. */
tree
-c_expand_start_case (exp)
+c_start_case (exp)
tree exp;
{
register enum tree_code code;
tree type;
+ struct c_switch *cs;
- if (TREE_CODE (exp) == ERROR_MARK)
- return exp;
+ if (exp != error_mark_node)
+ {
+ code = TREE_CODE (TREE_TYPE (exp));
+ type = TREE_TYPE (exp);
- code = TREE_CODE (TREE_TYPE (exp));
- type = TREE_TYPE (exp);
+ if (code != INTEGER_TYPE
+ && code != ENUMERAL_TYPE
+ && code != ERROR_MARK)
+ {
+ error ("switch quantity not an integer");
+ exp = integer_zero_node;
+ }
+ else
+ {
+ tree index;
+ type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
- if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK)
- {
- error ("switch quantity not an integer");
- exp = error_mark_node;
+ if (warn_traditional && !in_system_header
+ && (type == long_integer_type_node
+ || type == long_unsigned_type_node))
+ warning ("`long' switch expression not converted to `int' in ISO C");
+
+ exp = default_conversion (exp);
+ type = TREE_TYPE (exp);
+ index = get_unwidened (exp, NULL_TREE);
+ /* We can't strip a conversion from a signed type to an
+ unsigned, because if we did, int_fits_type_p would do the
+ wrong thing when checking case values for being in range,
+ and it's too hard to do the right thing. */
+ if (TREE_UNSIGNED (TREE_TYPE (exp))
+ == TREE_UNSIGNED (TREE_TYPE (index)))
+ exp = index;
+ }
}
+
+ /* Add this new SWITCH_STMT to the stack. */
+ cs = (struct c_switch *) xmalloc (sizeof (cs));
+ cs->switch_stmt = build_stmt (SWITCH_STMT, exp, NULL_TREE, NULL_TREE);
+ cs->cases = splay_tree_new (case_compare, NULL, NULL);
+ cs->next = switch_stack;
+ switch_stack = cs;
+
+ return add_stmt (switch_stack->switch_stmt);
+}
+
+/* Process a case label. */
+
+void
+do_case (low_value, high_value)
+ tree low_value;
+ tree high_value;
+{
+ if (switch_stack)
+ c_add_case_label (switch_stack->cases,
+ SWITCH_COND (switch_stack->switch_stmt),
+ low_value,
+ high_value);
+ else if (low_value)
+ error ("case label not within a switch statement");
else
- {
- tree index;
- type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
+ error ("`default' label not within a switch statement");
+}
- if (warn_traditional && !in_system_header
- && (type == long_integer_type_node
- || type == long_unsigned_type_node))
- warning ("`long' switch expression not converted to `int' in ISO C");
+/* Finish the switch statement. */
- exp = default_conversion (exp);
- type = TREE_TYPE (exp);
- index = get_unwidened (exp, NULL_TREE);
- /* We can't strip a conversion from a signed type to an unsigned,
- because if we did, int_fits_type_p would do the wrong thing
- when checking case values for being in range,
- and it's too hard to do the right thing. */
- if (TREE_UNSIGNED (TREE_TYPE (exp))
- == TREE_UNSIGNED (TREE_TYPE (index)))
- exp = index;
- }
+void
+c_finish_case ()
+{
+ struct c_switch *cs = switch_stack;
- expand_start_case (1, exp, type, "switch statement");
+ RECHAIN_STMTS (cs->switch_stmt, SWITCH_BODY (cs->switch_stmt));
- return exp;
+ /* Pop the stack. */
+ switch_stack = switch_stack->next;
+ splay_tree_delete (cs->cases);
+ free (cs);
}
OpenPOWER on IntegriCloud