diff options
| author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-12-20 18:18:24 +0000 |
|---|---|---|
| committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-12-20 18:18:24 +0000 |
| commit | 7cad36f4567c5ff6571d2eafa3508938ae35aaa6 (patch) | |
| tree | c348f2bb0cb4cb71bb3b6a678fa12eeac3682584 /gcc/c-typeck.c | |
| parent | 4aa0811f0a5c4054e1eb9a9649e781cde6b9018c (diff) | |
| download | ppe42-gcc-7cad36f4567c5ff6571d2eafa3508938ae35aaa6.tar.gz ppe42-gcc-7cad36f4567c5ff6571d2eafa3508938ae35aaa6.zip | |
* c-typeck.c (build_asm_stmt): New, broken out from ...
(c_expand_asm_operands): ... here. Just do rtl expansion.
(c_expand_return): Return the new stmt node.
(c_start_case, do_case): Likewise.
* c-common.c (c_expand_expr_stmt): Likewise.
* c-common.h: Update declarations.
* c-tree.h: Likewise.
* c-semantics.c (build_stmt): Use STMT_LINENO not TREE_COMPLEXITY.
* c-parse.in (fndef): Set DECL_SOURCE_LINE to the open brace.
(nested_function, notype_nested_function): Likewise.
(compstmt): Return the compound statement not the binding level.
(lineno_labeled_stmt): Simplify.
(lineno_stmt, lineno_label): Set STMT_LINENO.
(stmt, label): Return the new stmt node.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38402 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-typeck.c')
| -rw-r--r-- | gcc/c-typeck.c | 130 |
1 files changed, 82 insertions, 48 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 9122a756c83..d7efc2d56f7 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -6303,41 +6303,43 @@ process_init_element (value) } } -/* Expand an ASM statement with operands, handling output operands - that are not variables or INDIRECT_REFS by transforming such - cases into cases that expand_asm_operands can handle. - - Arguments are same as for expand_asm_operands. */ +/* Build an asm-statement, whose components are a CV_QUALIFIER, a + STRING, some OUTPUTS, some INPUTS, and some CLOBBERS. */ -void -c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) - tree string, outputs, inputs, clobbers; - int vol; - const char *filename; - int line; +tree +build_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers) + tree cv_qualifier; + tree string; + tree outputs; + tree inputs; + tree clobbers; { - int noutputs = list_length (outputs); - register int i; - /* o[I] is the place that output number I should be written. */ - register tree *o = (tree *) alloca (noutputs * sizeof (tree)); - register tree tail; + tree tail; - if (TREE_CODE (string) == ADDR_EXPR) - string = TREE_OPERAND (string, 0); - if (last_tree && TREE_CODE (string) != STRING_CST) + if (TREE_CHAIN (string)) + string = combine_strings (string); + if (TREE_CODE (string) != STRING_CST) { error ("asm template is not a string constant"); - return; + return NULL_TREE; } - /* Record the contents of OUTPUTS before it is modified. */ - for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) + if (cv_qualifier != NULL_TREE + && cv_qualifier != ridpointers[(int) RID_VOLATILE]) + { + warning ("%s qualifier ignored on asm", + IDENTIFIER_POINTER (cv_qualifier)); + cv_qualifier = NULL_TREE; + } + + /* We can remove output conversions that change the type, + but not the mode. */ + for (tail = outputs; tail; tail = TREE_CHAIN (tail)) { tree output = TREE_VALUE (tail); - /* We can remove conversions that just change the type, not the mode. */ STRIP_NOPS (output); - o[i] = output; + TREE_VALUE (tail) = output; /* Allow conversions as LHS here. build_modify_expr as called below will do the right thing with them. */ @@ -6350,29 +6352,54 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) || TREE_CODE (output) == FIX_CEIL_EXPR) output = TREE_OPERAND (output, 0); - if (last_tree) - lvalue_or_else (o[i], "invalid lvalue in asm statement"); + lvalue_or_else (TREE_VALUE (tail), "invalid lvalue in asm statement"); + } + + /* Remove output conversions that change the type but not the mode. */ + for (tail = outputs; tail; tail = TREE_CHAIN (tail)) + { + tree output = TREE_VALUE (tail); + STRIP_NOPS (output); + TREE_VALUE (tail) = output; } - /* Perform default conversions on array and function inputs. */ - /* Don't do this for other types-- - it would screw up operands expected to be in memory. */ - for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++) + /* Perform default conversions on array and function inputs. + Don't do this for other types as it would screw up operands + expected to be in memory. */ + for (tail = inputs; tail; tail = TREE_CHAIN (tail)) if (TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == ARRAY_TYPE || 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; - } + return add_stmt (build_stmt (ASM_STMT, cv_qualifier, string, + outputs, inputs, clobbers)); +} + +/* Expand an ASM statement with operands, handling output operands + that are not variables or INDIRECT_REFS by transforming such + cases into cases that expand_asm_operands can handle. + + Arguments are same as for expand_asm_operands. */ + +void +c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) + tree string, outputs, inputs, clobbers; + int vol; + const char *filename; + int line; +{ + int noutputs = list_length (outputs); + register int i; + /* o[I] is the place that output number I should be written. */ + register tree *o = (tree *) alloca (noutputs * sizeof (tree)); + register tree tail; + + /* Record the contents of OUTPUTS before it is modified. */ + for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) + o[i] = TREE_VALUE (tail); - /* Generate the ASM_OPERANDS insn; - store into the TREE_VALUEs of OUTPUTS some trees for - where the values were actually stored. */ + /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of + OUTPUTS some trees for where the values were actually stored. */ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line); /* Copy all the intermediate outputs into the specified outputs. */ @@ -6410,7 +6437,7 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) RETVAL is the expression for what to return, or a null pointer for `return;' with no value. */ -void +tree c_expand_return (retval) tree retval; { @@ -6440,7 +6467,7 @@ c_expand_return (retval) tree inner; if (t == error_mark_node) - return; + return NULL_TREE; inner = t = convert (TREE_TYPE (res), t); @@ -6499,7 +6526,7 @@ c_expand_return (retval) current_function_returns_value = 1; } - add_stmt (build_return_stmt (retval)); + return add_stmt (build_return_stmt (retval)); } struct c_switch { @@ -6581,20 +6608,27 @@ c_start_case (exp) /* Process a case label. */ -void +tree do_case (low_value, high_value) tree low_value; tree high_value; { + tree label = NULL_TREE; + if (switch_stack) - c_add_case_label (switch_stack->cases, - SWITCH_COND (switch_stack->switch_stmt), - low_value, - high_value); + { + label = c_add_case_label (switch_stack->cases, + SWITCH_COND (switch_stack->switch_stmt), + low_value, high_value); + if (label == error_mark_node) + label = NULL_TREE; + } else if (low_value) error ("case label not within a switch statement"); else error ("`default' label not within a switch statement"); + + return label; } /* Finish the switch statement. */ |

