]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c-typeck.c (build_asm_stmt): New, broken out from ...
authorRichard Henderson <rth@redhat.com>
Wed, 20 Dec 2000 18:18:24 +0000 (10:18 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 20 Dec 2000 18:18:24 +0000 (10:18 -0800)
        * 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.

From-SVN: r38402

gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-parse.in
gcc/c-semantics.c
gcc/c-tree.h
gcc/c-typeck.c

index 1f19a8099baabd414161d9d0ca28ae7b1de8fbc9..6eca585b1072867a39f8b6b5db6b66c690e79487 100644 (file)
@@ -1,3 +1,20 @@
+2000-12-20  Richard Henderson  <rth@redhat.com>
+
+        * 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.
+
 2000-12-20  Bernd Schmidt  <bernds@redhat.com>
 
        * Makefile.in (OBJS): Add sched-ebb.o.
index a1970e2cd0c210d0802a5ff468eeec255d9cc480..5d13345eda0257165651827a424dbf07522ba5cd 100644 (file)
@@ -3950,7 +3950,7 @@ verify_sequence_points (expr)
   obstack_free (&tlist_obstack, tlist_firstobj);
 }
 
-void
+tree
 c_expand_expr_stmt (expr)
      tree expr;
 {
@@ -3969,7 +3969,7 @@ c_expand_expr_stmt (expr)
     error ("expression statement has incomplete type");
 
   last_expr_type = TREE_TYPE (expr); 
-  add_stmt (build_stmt (EXPR_STMT, expr));
+  return add_stmt (build_stmt (EXPR_STMT, expr));
 }
 \f
 /* Validate the expression after `case' and apply default promotions.  */
index b31499ff7eaae94a19fe4c8fb1121709a7ddda22..a23b8715b35171c6e8a73df414d13971f843572a 100644 (file)
@@ -467,7 +467,7 @@ extern void c_apply_type_quals_to_decl              PARAMS ((int, tree));
 /* Print an error message for invalid operands to arith operation CODE.
    NOP_EXPR is used as a special case (see truthvalue_conversion).  */
 extern void binary_op_error                    PARAMS ((enum tree_code));
-extern void c_expand_expr_stmt                 PARAMS ((tree));
+extern tree c_expand_expr_stmt                 PARAMS ((tree));
 extern void c_expand_start_cond                        PARAMS ((tree, int));
 extern void c_finish_then                       PARAMS ((void));
 extern void c_expand_start_else                        PARAMS ((void));
@@ -713,8 +713,8 @@ extern int anon_aggr_type_p                     PARAMS ((tree));
 extern void emit_local_var                      PARAMS ((tree));
 extern void make_rtl_for_local_static           PARAMS ((tree));
 extern tree expand_cond                         PARAMS ((tree));
-extern void c_expand_return                    PARAMS ((tree));
-extern void do_case                            PARAMS ((tree, tree));
+extern tree c_expand_return                    PARAMS ((tree));
+extern tree do_case                            PARAMS ((tree, tree));
 extern tree build_stmt                          PARAMS ((enum tree_code, ...));
 extern tree build_case_label                    PARAMS ((tree, tree, tree));
 extern tree build_continue_stmt                 PARAMS ((void));
index cf010e6a091a16ba83e1bbd1c95c65e6ff1c3268..8b211d1384ba5249c133cd805e5dc3b13d107230 100644 (file)
@@ -177,7 +177,7 @@ end ifc
 %type <ttype> any_word extension
 
 %type <ttype> compstmt compstmt_start compstmt_nostart compstmt_primary_start
-%type <ttype> do_stmt_start poplevel
+%type <ttype> do_stmt_start poplevel stmt label
 
 %type <ttype> c99_block_start c99_block_end
 %type <ttype> declarator
@@ -365,8 +365,10 @@ fndef:
                }
          old_style_parm_decls
                { store_parm_decls (); }
-         compstmt_or_error
-               { finish_function (0); 
+         save_filename save_lineno compstmt_or_error
+               { DECL_SOURCE_FILE (current_function_decl) = $7;
+                 DECL_SOURCE_LINE (current_function_decl) = $8;
+                 finish_function (0); 
                  current_declspecs = TREE_VALUE (declspec_stack);
                  prefix_attributes = TREE_PURPOSE (declspec_stack);
                  declspec_stack = TREE_CHAIN (declspec_stack); }
@@ -381,8 +383,10 @@ fndef:
                }
          old_style_parm_decls
                { store_parm_decls (); }
-         compstmt_or_error
-               { finish_function (0); 
+         save_filename save_lineno compstmt_or_error
+               { DECL_SOURCE_FILE (current_function_decl) = $7;
+                 DECL_SOURCE_LINE (current_function_decl) = $8;
+                 finish_function (0); 
                  current_declspecs = TREE_VALUE (declspec_stack);
                  prefix_attributes = TREE_PURPOSE (declspec_stack);
                  declspec_stack = TREE_CHAIN (declspec_stack); }
@@ -397,8 +401,10 @@ fndef:
                }
          old_style_parm_decls
                { store_parm_decls (); }
-         compstmt_or_error
-               { finish_function (0); 
+         save_filename save_lineno compstmt_or_error
+               { DECL_SOURCE_FILE (current_function_decl) = $6;
+                 DECL_SOURCE_LINE (current_function_decl) = $7;
+                 finish_function (0); 
                  current_declspecs = TREE_VALUE (declspec_stack);
                  prefix_attributes = TREE_PURPOSE (declspec_stack);
                  declspec_stack = TREE_CHAIN (declspec_stack); }
@@ -1192,8 +1198,10 @@ nested_function:
    which then was handled by compstmt_or_error.
    There followed a repeated execution of that same rule,
    which called YYERROR1 again, and so on.  */
-         compstmt
+         save_filename save_lineno compstmt
                { tree decl = current_function_decl;
+                 DECL_SOURCE_FILE (decl) = $5;
+                 DECL_SOURCE_LINE (decl) = $6;
                  finish_function (1);
                  pop_function_context (); 
                  add_decl_stmt (decl); }
@@ -1220,8 +1228,10 @@ notype_nested_function:
    which then was handled by compstmt_or_error.
    There followed a repeated execution of that same rule,
    which called YYERROR1 again, and so on.  */
-         compstmt
+         save_filename save_lineno compstmt
                { tree decl = current_function_decl;
+                 DECL_SOURCE_FILE (decl) = $5;
+                 DECL_SOURCE_LINE (decl) = $6;
                  finish_function (1);
                  pop_function_context (); 
                  add_decl_stmt (decl); }
@@ -1750,7 +1760,7 @@ compstmt_primary_start:
 
 compstmt: compstmt_start compstmt_nostart
                { RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); 
-                  $$ = $2; }
+                  $$ = $1; }
        ;
 
 /* Value is number of statements counted as of the closeparen.  */
@@ -1808,13 +1818,8 @@ save_lineno:
        ;
 
 lineno_labeled_stmt:
-         save_filename save_lineno stmt
-               { }
-/*     | save_filename save_lineno error
-               { }
-*/
-       | save_filename save_lineno label lineno_labeled_stmt
-               { }
+         lineno_stmt
+       | lineno_label lineno_labeled_stmt
        ;
 
 /* Like lineno_labeled_stmt, but a block in C99.  */
@@ -1826,12 +1831,25 @@ c99_block_lineno_labeled_stmt:
 
 lineno_stmt:
          save_filename save_lineno stmt
-               { }
+               { if ($3)
+                   {
+                     STMT_LINENO ($3) = $2;
+                     /* ??? We currently have no way of recording
+                        the filename for a statement.  This probably
+                        matters little in practice at the moment,
+                        but I suspect that problems will ocurr when
+                        doing inlining at the tree level.  */
+                   }
+               }
        ;
 
 lineno_label:
          save_filename save_lineno label
-               { }
+               { if ($3)
+                   {
+                     STMT_LINENO ($3) = $2;
+                   }
+               }
        ;
 
 select_or_iter_stmt:
@@ -1900,25 +1918,26 @@ for_init_stmt:
 /* Parse a single real statement, not including any labels.  */
 stmt:
          compstmt
-               { stmt_count++; }
+               { stmt_count++; $$ = $1; }
        | expr ';'
                { stmt_count++;
-                 c_expand_expr_stmt ($1); }
+                 $$ = c_expand_expr_stmt ($1); }
        | c99_block_start select_or_iter_stmt c99_block_end
                { if (flag_isoc99)
-                   RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); }
+                   RECHAIN_STMTS ($1, COMPOUND_BODY ($1));
+                 $$ = NULL_TREE; }
        | BREAK ';'
                { stmt_count++;
-                 add_stmt (build_break_stmt ()); }
+                 $$ = add_stmt (build_break_stmt ()); }
        | CONTINUE ';'
                 { stmt_count++;
-                 add_stmt (build_continue_stmt ()); }
+                 $$ = add_stmt (build_continue_stmt ()); }
        | RETURN ';'
                 { stmt_count++;
-                 c_expand_return (NULL_TREE); }
+                 $$ = c_expand_return (NULL_TREE); }
        | RETURN expr ';'
                 { stmt_count++;
-                 c_expand_return ($2); }
+                 $$ = c_expand_return ($2); }
        | ASM_KEYWORD maybe_type_qual '(' expr ')' ';'
                { stmt_count++;
                  STRIP_NOPS ($4);
@@ -1930,30 +1949,30 @@ stmt:
                        $4 = TREE_OPERAND ($4, 0);
                      if (TREE_CHAIN ($4))
                        $4 = combine_strings ($4);
-                     add_stmt (build_stmt (ASM_STMT, NULL_TREE, $4,
-                                           NULL_TREE, NULL_TREE, NULL_TREE));
+                     $$ = add_stmt (build_stmt (ASM_STMT, NULL_TREE, $4,
+                                                NULL_TREE, NULL_TREE,
+                                                NULL_TREE));
                    }
                  else
-                   error ("argument of `asm' is not a constant string"); }
+                   {
+                     error ("argument of `asm' is not a constant string");
+                     $$ = NULL_TREE;
+                   }
+               }
        /* This is the case with just output operands.  */
        | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';'
                { stmt_count++;
-                 c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
-                                        $2 == ridpointers[(int)RID_VOLATILE],
-                                        input_filename, lineno); }
+                 $$ = build_asm_stmt ($2, $4, $6, NULL_TREE, NULL_TREE); }
        /* This is the case with input operands as well.  */
-       | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':' asm_operands ')' ';'
+       | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':'
+         asm_operands ')' ';'
                { stmt_count++;
-                 c_expand_asm_operands ($4, $6, $8, NULL_TREE,
-                                        $2 == ridpointers[(int)RID_VOLATILE],
-                                        input_filename, lineno); }
+                 $$ = build_asm_stmt ($2, $4, $6, $8, NULL_TREE); }
        /* This is the case with clobbered registers as well.  */
        | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':'
          asm_operands ':' asm_clobbers ')' ';'
                { stmt_count++;
-                 c_expand_asm_operands ($4, $6, $8, $10,
-                                        $2 == ridpointers[(int)RID_VOLATILE],
-                                        input_filename, lineno); }
+                 $$ = build_asm_stmt ($2, $4, $6, $8, $10); }
        | GOTO identifier ';'
                { tree decl;
                  stmt_count++;
@@ -1961,16 +1980,19 @@ stmt:
                  if (decl != 0)
                    {
                      TREE_USED (decl) = 1;
-                     add_stmt (build_stmt (GOTO_STMT, decl));
+                     $$ = add_stmt (build_stmt (GOTO_STMT, decl));
                    }
+                 else
+                   $$ = NULL_TREE;
                }
        | GOTO '*' expr ';'
                { if (pedantic)
                    pedwarn ("ISO C forbids `goto *expr;'");
                  stmt_count++;
                  $3 = convert (ptr_type_node, $3);
-                 add_stmt (build_stmt (GOTO_STMT, $3)); }
+                 $$ = add_stmt (build_stmt (GOTO_STMT, $3)); }
        | ';'
+               { $$ = NULL_TREE; }
        ;
 
 /* Any kind of label, including jump labels and case labels.
@@ -1979,21 +2001,23 @@ stmt:
 
 label:   CASE expr_no_commas ':'
                 { stmt_count++;
-                 do_case ($2, NULL_TREE); }
+                 $$ = do_case ($2, NULL_TREE); }
        | CASE expr_no_commas ELLIPSIS expr_no_commas ':'
                 { stmt_count++;
-                 do_case ($2, $4); }
+                 $$ = do_case ($2, $4); }
        | DEFAULT ':'
                 { stmt_count++;
-                 do_case (NULL_TREE, NULL_TREE); }
+                 $$ = do_case (NULL_TREE, NULL_TREE); }
        | identifier save_filename save_lineno ':' maybe_attribute
                { tree label = define_label ($2, $3, $1);
                  stmt_count++;
                  if (label)
                    {
                      decl_attributes (label, $5, NULL_TREE);
-                     add_stmt (build_stmt (LABEL_STMT, label));
+                     $$ = add_stmt (build_stmt (LABEL_STMT, label));
                    }
+                 else
+                   $$ = NULL_TREE;
                }
        ;
 
index d5150ba45f4cb9ab9ff2477751bf046310224d7a..4cf457279de2c99c8f31d604473138ba328773c7 100644 (file)
@@ -220,7 +220,9 @@ finish_stmt_tree (t)
 
 /* Build a generic statement based on the given type of node and
    arguments. Similar to `build_nt', except that we set
-   TREE_COMPLEXITY to be the current line number.  */
+   STMT_LINENO to be the current line number.  */
+/* ??? This should be obsolete with the lineno_stmt productions
+   in the grammar.  */
 
 tree
 build_stmt VPARAMS ((enum tree_code code, ...))
@@ -241,7 +243,7 @@ build_stmt VPARAMS ((enum tree_code code, ...))
 
   t = make_node (code);
   length = TREE_CODE_LENGTH (code);
-  TREE_COMPLEXITY (t) = lineno;
+  STMT_LINENO (t) = lineno;
 
   for (i = 0; i < length; i++)
     TREE_OPERAND (t, i) = va_arg (p, tree);
index ee769e7a6ca64d95798fb946cdcb7ab4f2335bf6..939ca3fafed6ddc944d221fdcb2a8773b218dac2 100644 (file)
@@ -275,6 +275,8 @@ extern void pedwarn_c99                             PARAMS ((const char *, ...))
                                                        ATTRIBUTE_PRINTF_1;
 extern tree c_start_case                        PARAMS ((tree));
 extern void c_finish_case                       PARAMS ((void));
+extern tree build_asm_stmt                     PARAMS ((tree, tree, tree,
+                                                        tree, tree));
 
 /* Set to 0 at beginning of a function definition, set to 1 if
    a return statement that specifies a return value is seen.  */
index 9122a756c833086b0a774c533d7e0a8b3d04416a..d7efc2d56f7e98e5fc447b771989e99090559f10 100644 (file)
@@ -6303,41 +6303,43 @@ process_init_element (value)
     }
 }
 \f
-/* 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));
 }
 \f
 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.  */