This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C Parser Cleanup [Take 2]
Richard Henderson wrote:-
> This is a feature fix that apparently failed to propagate to
> the c++ front end, not the other way around.
For the record, here's the patch I'm about to commit. It has an
explanatory comment in place of DECL_UNINLINABLE, and moves the
prototype for lookup_label to c-common.h (though the C and C++ front
ends have separate implementations, the prototype is identical and
needed for finish_label_address_expr).
Neil.
* 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.
cp:
* cp-tree.h (finish_label_expr, lookup_label): Delete.
* parse.y: Update for '&&'; don't issue warning here.
* semantics.c (finish_label_expr): Delete.
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.233
diff -u -p -r1.233 c-common.c
--- c-common.c 2001/05/10 17:39:19 1.233
+++ c-common.c 2001/05/10 23:25:18
@@ -4193,6 +4193,39 @@ c_add_case_label (cases, cond, low_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: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.68
diff -u -p -r1.68 c-common.h
--- c-common.h 2001/04/30 23:58:59 1.68
+++ c-common.h 2001/05/10 23:25:27
@@ -783,6 +783,12 @@ extern tree c_add_case_label
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: c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.86
diff -u -p -r1.86 c-parse.in
--- c-parse.in 2001/05/10 16:17:06 1.86
+++ c-parse.in 2001/05/10 23:25:29
@@ -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: c-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-tree.h,v
retrieving revision 1.56
diff -u -p -r1.56 c-tree.h
--- c-tree.h 2001/04/12 18:23:09 1.56
+++ c-tree.h 2001/05/10 23:25:30
@@ -187,7 +187,6 @@ extern void implicit_decl_warning
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
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 ((cons
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: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.119
diff -u -p -r1.119 c-typeck.c
--- c-typeck.c 2001/05/06 16:38:56 1.119
+++ c-typeck.c 2001/05/10 23:25:45
@@ -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);
+}
+
/* 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;
}
+/* 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. */
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.608
diff -u -p -r1.608 cp-tree.h
--- cp-tree.h 2001/05/04 06:28:52 1.608
+++ cp-tree.h 2001/05/10 23:26:03
@@ -3791,7 +3791,6 @@ extern tree push_using_decl
extern tree push_using_directive PARAMS ((tree));
extern void push_class_level_binding PARAMS ((tree, tree));
extern tree implicitly_declare PARAMS ((tree));
-extern tree lookup_label PARAMS ((tree));
extern tree declare_local_label PARAMS ((tree));
extern tree define_label PARAMS ((const char *, int, tree));
extern void check_goto PARAMS ((tree));
@@ -4269,7 +4268,6 @@ extern tree finish_object_call_expr
extern tree finish_qualified_object_call_expr PARAMS ((tree, tree, tree));
extern tree finish_pseudo_destructor_call_expr PARAMS ((tree, tree, tree));
extern tree finish_qualified_call_expr PARAMS ((tree, tree));
-extern tree finish_label_address_expr PARAMS ((tree));
extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree));
extern tree finish_id_expr PARAMS ((tree));
extern void save_type_access_control PARAMS ((tree));
Index: cp/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parse.y,v
retrieving revision 1.218
diff -u -p -r1.218 parse.y
--- parse.y 2001/04/24 08:22:06 1.218
+++ parse.y 2001/05/10 23:26:11
@@ -1224,9 +1224,7 @@ unary_expr:
{ $$ = finish_unary_op_expr ($1, $2); }
/* Refer to the address of a label as a pointer. */
| ANDAND identifier
- { if (pedantic)
- pedwarn ("ISO C++ forbids `&&'");
- $$ = finish_label_address_expr ($2); }
+ { $$ = finish_label_address_expr ($2); }
| SIZEOF unary_expr %prec UNARY
{ $$ = expr_sizeof ($2); }
| SIZEOF '(' type_id ')' %prec HYPERUNARY
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.207
diff -u -p -r1.207 semantics.c
--- semantics.c 2001/05/01 12:56:11 1.207
+++ semantics.c 2001/05/10 23:26:17
@@ -1491,31 +1491,6 @@ finish_qualified_call_expr (fn, args)
args);
}
-/* Finish an expression taking the address of LABEL. Returns an
- expression for the address. */
-
-tree
-finish_label_address_expr (label)
- tree label;
-{
- tree result;
-
- 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;
- /* This function cannot be inlined. All jumps to the addressed
- label should wind up at the same point. */
- DECL_UNINLINABLE (current_function_decl) = 1;
- }
-
- return result;
-}
-
/* Finish an expression of the form CODE EXPR. */
tree