summaryrefslogtreecommitdiffstats
path: root/gcc/c-typeck.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2000-12-20 18:18:24 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2000-12-20 18:18:24 +0000
commit7cad36f4567c5ff6571d2eafa3508938ae35aaa6 (patch)
treec348f2bb0cb4cb71bb3b6a678fa12eeac3682584 /gcc/c-typeck.c
parent4aa0811f0a5c4054e1eb9a9649e781cde6b9018c (diff)
downloadppe42-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.c130
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. */
OpenPOWER on IntegriCloud