c-common.c (finish_label_expr): New function, lifted from from cp/semantics.c.
authorNeil Booth <neil@daikokuya.demon.co.uk>
Fri, 11 May 2001 06:38:48 +0000 (06:38 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Fri, 11 May 2001 06:38:48 +0000 (06:38 +0000)
* c-common.c (finish_label_expr): New function, lifted from
from cp/semantics.c.
* c-common.h (finish_label_expr, lookup_label): New prototypes.
* c-parse.in: Move 3 blocks of parser code into new functions.
* c-typeck.c (simple_asm_stmt, c_cast_expr): New functions.
* c-tree.h (simple_asm_stmt, c_cast_expr): New prototypes.
(lookup_label): Remove.

From-SVN: r41959

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

index b4a3b80aebf3a2278bf11a80d024ef355117c1d0..2053f37be473850eb39040597a6363a85059f224 100644 (file)
@@ -1,3 +1,13 @@
+2001-05-11  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * c-common.c (finish_label_expr): New function, lifted from
+       from cp/semantics.c.
+       * c-common.h (finish_label_expr, lookup_label): New prototypes.
+       * c-parse.in: Move 3 blocks of parser code into new functions.
+       * c-typeck.c (simple_asm_stmt, c_cast_expr): New functions.
+       * c-tree.h (simple_asm_stmt, c_cast_expr): New prototypes.
+       (lookup_label): Remove.
+
 2001-05-11  Alexandre Oliva  <aoliva@redhat.com>
 
        * config/mn10300/t-mn10300 (dp-bit.c, fp-bit.c): Don't define
index a1dc31c3160e31d367bc5df502101132dc914011..f037ecc9ae32d17d4e8e2fd8c370d3ad16368875 100644 (file)
@@ -4193,6 +4193,39 @@ c_add_case_label (cases, cond, low_value, high_value)
   return case_label;
 }
 
+/* Finish an expression taking the address of LABEL.  Returns an
+   expression for the address.  */
+
+tree 
+finish_label_address_expr (label)
+     tree label;
+{
+  tree result;
+
+  if (pedantic)
+    {
+      if (c_language == clk_cplusplus)
+       pedwarn ("ISO C++ forbids taking the address of a label");
+      else
+       pedwarn ("ISO C forbids taking the address of a label");
+    }
+
+  label = lookup_label (label);
+  if (label == NULL_TREE)
+    result = null_pointer_node;
+  else
+    {
+      TREE_USED (label) = 1;
+      result = build1 (ADDR_EXPR, ptr_type_node, label);
+      TREE_CONSTANT (result) = 1;
+      /* The current function in not necessarily uninlinable.
+        Computed gotos are incompatible with inlining, but the value
+        here could be used only in a diagnostic, for example.  */
+    }
+
+  return result;
+}
+
 /* Mark P (a stmt_tree) for GC.  The use of a `void *' for the
    parameter allows this function to be used as a GC-marking
    function.  */
index 32d7ec990034093c3576b6127be95b1c574161a5..0c2f23a8c238a7f018fa4223bedb92baa35a73ac 100644 (file)
@@ -783,6 +783,12 @@ extern tree c_add_case_label                    PARAMS ((splay_tree,
 
 extern tree build_function_call                        PARAMS ((tree, tree));
 
+extern tree finish_label_address_expr          PARAMS ((tree));
+
+/* Same function prototype, but the C and C++ front ends have
+   different implementations.  Used in c-common.c.  */
+extern tree lookup_label                       PARAMS ((tree));
+
 /* If this variable is defined to a non-NULL value, it will be called
    after the file has been completely parsed.  The argument will be
    the GLOBAL_NAMESPACE in C++, or the list of top-level declarations
index e91f9ebdf9fc7e50388d2ce5195620482f2f93f7..253cb292b66d82279e78807990e8adf46c80f46b 100644 (file)
@@ -493,18 +493,7 @@ unary_expr:
                  overflow_warning ($$); }
        /* Refer to the address of a label as a pointer.  */
        | ANDAND identifier
-               { tree label = lookup_label ($2);
-                 if (pedantic)
-                   pedwarn ("ISO C forbids `&&'");
-                 if (label == 0)
-                   $$ = null_pointer_node;
-                 else
-                   {
-                     TREE_USED (label) = 1;
-                     $$ = build1 (ADDR_EXPR, ptr_type_node, label);
-                     TREE_CONSTANT ($$) = 1;
-                   }
-               }
+               { $$ = finish_label_address_expr ($2); }
 /* This seems to be impossible on some machines, so let's turn it off.
    You can use __builtin_next_arg to find the anonymous stack args.
        | '&' ELLIPSIS
@@ -552,15 +541,7 @@ alignof:
 cast_expr:
        unary_expr
        | '(' typename ')' cast_expr  %prec UNARY
-               { tree type;
-                 int SAVED_warn_strict_prototypes = warn_strict_prototypes;
-                 /* This avoids warnings about unprototyped casts on
-                     integers.  E.g. "#define SIG_DFL (void(*)())0".  */
-                 if (TREE_CODE ($4) == INTEGER_CST)
-                   warn_strict_prototypes = 0;
-                 type = groktypename ($2);
-                 warn_strict_prototypes = SAVED_warn_strict_prototypes;
-                 $$ = build_c_cast (type, $4); }
+               { $$ = c_cast_expr ($2, $4); }
        ;
 
 expr_no_commas:
@@ -2401,26 +2382,7 @@ stmt:
                  $$ = c_expand_return ($2); }
        | ASM_KEYWORD maybe_type_qual '(' expr ')' ';'
                { stmt_count++;
-                 STRIP_NOPS ($4);
-                 if ((TREE_CODE ($4) == ADDR_EXPR
-                      && TREE_CODE (TREE_OPERAND ($4, 0)) == STRING_CST)
-                     || TREE_CODE ($4) == STRING_CST)
-                   {
-                     if (TREE_CODE ($4) == ADDR_EXPR)
-                       $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));
-                     ASM_INPUT_P ($$) = 1;
-                   }
-                 else
-                   {
-                     error ("argument of `asm' is not a constant string");
-                     $$ = NULL_TREE;
-                   }
-               }
+                 $$ = simple_asm_stmt ($4); }
        /* This is the case with just output operands.  */
        | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';'
                { stmt_count++;
index 16ab7adafce34670b11ae6f9727bf6fd85ee5fe3..543a310280f27a596640ae182963c0d1b4aca8e5 100644 (file)
@@ -187,7 +187,6 @@ extern void implicit_decl_warning               PARAMS ((tree));
 extern int  in_parm_level_p                     PARAMS ((void));
 extern void keep_next_level                     PARAMS ((void));
 extern int  kept_level_p                        PARAMS ((void));
-extern tree lookup_label                        PARAMS ((tree));
 extern tree lookup_name                         PARAMS ((tree));
 extern tree lookup_name_current_level          PARAMS ((tree));
 extern tree lookup_name_current_level_global   PARAMS ((tree));
@@ -233,7 +232,8 @@ extern tree parser_build_binary_op              PARAMS ((enum tree_code,
 extern void readonly_warning                   PARAMS ((tree, const char *));
 extern tree build_conditional_expr              PARAMS ((tree, tree, tree));
 extern tree build_compound_expr                 PARAMS ((tree));
-extern tree build_c_cast                        PARAMS ((tree, tree));
+extern tree c_cast_expr                                PARAMS ((tree, tree));
+extern tree build_c_cast                       PARAMS ((tree, tree));
 extern tree build_modify_expr                   PARAMS ((tree, enum tree_code,
                                                         tree));
 extern void store_init_value                    PARAMS ((tree, tree));
@@ -251,6 +251,7 @@ 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 simple_asm_stmt                    PARAMS ((tree));
 extern tree build_asm_stmt                     PARAMS ((tree, tree, tree,
                                                         tree, tree));
 
index 33ac1169a82956f87bf0c40231c051b38fc7da57..3cbf6c6f3efdbef9910d9cd3fde9fbcd77c86a75 100644 (file)
@@ -3867,6 +3867,24 @@ build_c_cast (type, expr)
 
   return value;
 }
+
+/* Interpret a cast of expression EXPR to type TYPE.  */
+tree
+c_cast_expr (type, expr)
+     tree type, expr;
+{
+  int saved_wsp = warn_strict_prototypes;
+
+  /* This avoids warnings about unprototyped casts on
+     integers.  E.g. "#define SIG_DFL (void(*)())0".  */
+  if (TREE_CODE (expr) == INTEGER_CST)
+    warn_strict_prototypes = 0;
+  type = groktypename (type);
+  warn_strict_prototypes = saved_wsp;
+
+  return build_c_cast (type, expr);
+}
+
 \f
 /* Build an assignment expression of lvalue LHS from value RHS.
    MODIFYCODE is the code for a binary operator that we use
@@ -6763,6 +6781,33 @@ process_init_element (value)
   constructor_range_stack = 0;
 }
 \f
+/* Build a simple asm-statement, from one string literal.  */
+tree
+simple_asm_stmt (expr)
+     tree expr;
+{
+  STRIP_NOPS (expr);
+
+  if (TREE_CODE (expr) == ADDR_EXPR)
+    expr = TREE_OPERAND (expr, 0);
+
+  if (TREE_CODE (expr) == STRING_CST)
+    {
+      tree stmt;
+
+      if (TREE_CHAIN (expr))
+       expr = combine_strings (expr);
+      stmt = add_stmt (build_stmt (ASM_STMT, NULL_TREE, expr,
+                                  NULL_TREE, NULL_TREE,
+                                  NULL_TREE));
+      ASM_INPUT_P (stmt) = 1;
+      return stmt;
+    }
+
+  error ("argument of `asm' is not a constant string");
+  return NULL_TREE;
+}
+
 /* Build an asm-statement, whose components are a CV_QUALIFIER, a
    STRING, some OUTPUTS, some INPUTS, and some CLOBBERS.  */