summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/c-parse.in112
-rw-r--r--gcc/c-tree.h4
-rw-r--r--gcc/c-typeck.c65
4 files changed, 110 insertions, 90 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3c3b8605748..346d86f1d86 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2004-02-12 Zack Weinberg <zack@codesourcery.com>
+
+ * c-parse.in (maybe_type_qual): Delete.
+ (maybe_volatile, simple_asm_expr, asmdef, asm_stmt)
+ (asm_argument): New grammar rules.
+ (extdef_1): Use asmdef.
+ (maybeasm): Move down with other asm rules; use simple_asm_expr.
+ (xexpr): Move up with other expression rules.
+ (stmt): Use asm_stmt.
+
+ * c-typeck.c (build_asm_expr): New function - body mostly
+ pulled from build_asm_stmt.
+ (build_asm_stmt): Just handle tacking on the volatile qualifier.
+ * c-tree.h (build_asm_expr, build_asm_stmt): Update prototypes.
+
2004-02-12 Richard Sandiford <rsandifo@redhat.com>
PR bootstrap/13617
@@ -197,7 +212,7 @@
2004-02-10 Matt Kraai <kraai@alumni.cmu.edu>
- * doc/install.texi: Remove extra cd.
+ * doc/install.texi: Remove extra cd.
2004-02-10 Ziemowit Laski <zlaski@apple.com>
@@ -383,7 +398,7 @@
* config/m68k/linux.h, config/m68k/m68k.c: Remove traling whitespace.
2004-02-08 Andreas Schwab <schwab@suse.de>
- Bernardo Innocenti <bernie@develer.com>
+ Bernardo Innocenti <bernie@develer.com>
* config/m68k/m68k.h (REGISTER_NAMES): Prefix each name with
REGISTER_PREFIX.
diff --git a/gcc/c-parse.in b/gcc/c-parse.in
index 6645dea896d..7a68dbf077f 100644
--- a/gcc/c-parse.in
+++ b/gcc/c-parse.in
@@ -200,9 +200,9 @@ do { \
%type <ttype> typespec_reserved_nonattr typespec_reserved_attr
%type <ttype> typespec_nonreserved_nonattr
-%type <ttype> scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_type_qual
-%type <ttype> initdecls notype_initdecls initdcl notype_initdcl
-%type <ttype> init maybeasm
+%type <ttype> scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_volatile
+%type <ttype> initdecls notype_initdecls initdcl notype_initdcl init
+%type <ttype> simple_asm_expr maybeasm asmdef asm_stmt asm_argument
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
%type <ttype> maybe_attribute attributes attribute attribute_list attrib
%type <ttype> any_word
@@ -375,19 +375,12 @@ extdef:
extdef_1:
fndef
| datadef
+ | asmdef
+ | extension extdef
+ { RESTORE_EXT_FLAGS ($1); }
@@ifobjc
| objcdef
@@end_ifobjc
- | ASM_KEYWORD '(' expr ')' ';'
- { STRIP_NOPS ($3);
- if ((TREE_CODE ($3) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND ($3, 0)) == STRING_CST)
- || TREE_CODE ($3) == STRING_CST)
- assemble_asm ($3);
- else
- error ("argument of `asm' is not a constant string"); }
- | extension extdef
- { RESTORE_EXT_FLAGS ($1); }
;
datadef:
@@ -1392,13 +1385,6 @@ notype_initdecls:
| notype_initdecls ',' maybe_resetattrs notype_initdcl
;
-maybeasm:
- /* empty */
- { $$ = NULL_TREE; }
- | ASM_KEYWORD '(' STRING ')'
- { $$ = $3; }
- ;
-
initdcl:
declarator maybeasm maybe_attribute '='
{ $<ttype>$ = start_decl ($1, current_declspecs, 1,
@@ -2346,6 +2332,12 @@ for_init_stmt:
{ check_for_loop_decls (); }
;
+xexpr:
+ /* empty */
+ { $$ = NULL_TREE; }
+ | expr
+ ;
+
/* Parse a single real statement, not including any labels. */
stmt:
compstmt
@@ -2381,23 +2373,7 @@ stmt:
| RETURN expr ';'
{ stmt_count++;
$$ = c_expand_return ($2); }
- | ASM_KEYWORD maybe_type_qual '(' expr ')' ';'
- { stmt_count++;
- $$ = simple_asm_stmt ($4); }
- /* This is the case with just output operands. */
- | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';'
- { stmt_count++;
- $$ = 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 ')' ';'
- { stmt_count++;
- $$ = 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++;
- $$ = build_asm_stmt ($2, $4, $6, $8, $10); }
+ | asm_stmt
| GOTO identifier ';'
{ tree decl;
stmt_count++;
@@ -2499,19 +2475,65 @@ label: CASE expr_no_commas ':'
}
;
-/* Either a type-qualifier or nothing. First thing in an `asm' statement. */
+/* Asm expressions and statements */
-maybe_type_qual:
- /* empty */
+/* simple_asm_expr is used in restricted contexts, where a full
+ expression with inputs and outputs does not make sense. */
+simple_asm_expr:
+ ASM_KEYWORD '(' STRING ')'
+ { $$ = $3; }
+ ;
+
+/* maybeasm: used for assembly names for declarations */
+maybeasm:
+ /* empty */
{ $$ = NULL_TREE; }
- | TYPE_QUAL
- { }
+ | simple_asm_expr
;
-xexpr:
+/* asmdef: asm() outside a function body. */
+asmdef:
+ simple_asm_expr ';'
+ { assemble_asm ($1); }
+ ;
+
+/* Full-blown asm statement with inputs, outputs, clobbers, and
+ volatile tag allowed. */
+asm_stmt:
+ ASM_KEYWORD maybe_volatile '(' asm_argument ')' ';'
+ { stmt_count++;
+ $$ = build_asm_stmt ($2, $4); }
+ ;
+
+asm_argument:
+ /* no operands */
+ STRING
+ { $$ = build_asm_expr ($1, 0, 0, 0, true); }
+ /* output operands */
+ | STRING ':' asm_operands
+ { $$ = build_asm_expr ($1, $3, 0, 0, false); }
+ /* output and input operands */
+ | STRING ':' asm_operands ':' asm_operands
+ { $$ = build_asm_expr ($1, $3, $5, 0, false); }
+ /* output and input operands and clobbers */
+ | STRING ':' asm_operands ':' asm_operands ':' asm_clobbers
+ { $$ = build_asm_expr ($1, $3, $5, $7, false); }
+ ;
+
+/* Either 'volatile' or nothing. First thing in an `asm' statement. */
+
+maybe_volatile:
/* empty */
- { $$ = NULL_TREE; }
- | expr
+ { $$ = 0; }
+ | TYPE_QUAL
+ { if ($1 != ridpointers[RID_VOLATILE])
+ {
+ warning ("%E qualifier ignored on asm", $1);
+ $$ = 0;
+ }
+ else
+ $$ = $1;
+ }
;
/* These are the operands other than the first string and colon
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index e6c7b27857b..1de2e25eab7 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -291,8 +291,8 @@ extern void pedwarn_c90 (const char *, ...) ATTRIBUTE_PRINTF_1;
extern void pedwarn_c99 (const char *, ...) ATTRIBUTE_PRINTF_1;
extern tree c_start_case (tree);
extern void c_finish_case (void);
-extern tree simple_asm_stmt (tree);
-extern tree build_asm_stmt (tree, tree, tree, tree, tree);
+extern tree build_asm_expr (tree, tree, tree, tree, bool);
+extern tree build_asm_stmt (tree, tree);
extern tree c_convert_parm_for_inlining (tree, tree, tree, int);
/* Set to 0 at beginning of a function definition, set to 1 if
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 95a2c3495cd..ff37fea9216 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -6002,52 +6002,28 @@ process_init_element (tree value)
constructor_range_stack = 0;
}
-/* Build a simple asm-statement, from one string literal. */
+/* Build a complete asm-statement, whose components are a CV_QUALIFIER
+ (guaranteed to be 'volatile' or null) and ARGS (represented using
+ an ASM_STMT node). */
tree
-simple_asm_stmt (tree expr)
+build_asm_stmt (tree cv_qualifier, tree args)
{
- STRIP_NOPS (expr);
-
- if (TREE_CODE (expr) == ADDR_EXPR)
- expr = TREE_OPERAND (expr, 0);
-
- if (TREE_CODE (expr) == STRING_CST)
- {
- tree stmt;
-
- /* Simple asm statements are treated as volatile. */
- stmt = add_stmt (build_stmt (ASM_STMT, ridpointers[(int) RID_VOLATILE],
- 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;
+ if (!TREE_OPERAND (args, 0))
+ TREE_OPERAND (args, 0) = cv_qualifier;
+ return add_stmt (args);
}
-/* Build an asm-statement, whose components are a CV_QUALIFIER, a
- STRING, some OUTPUTS, some INPUTS, and some CLOBBERS. */
-
+/* Build an asm-expr, whose components are a STRING, some OUTPUTS,
+ some INPUTS, and some CLOBBERS. The latter three may be NULL.
+ SIMPLE indicates whether there was anything at all after the
+ string in the asm expression -- asm("blah") and asm("blah" : )
+ are subtly different. We use a ASM_STMT node to represent this. */
tree
-build_asm_stmt (tree cv_qualifier, tree string, tree outputs, tree inputs,
- tree clobbers)
+build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
+ bool simple)
{
tree tail;
-
- if (TREE_CODE (string) != STRING_CST)
- {
- error ("asm template is not a string constant");
- return NULL_TREE;
- }
-
- 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;
- }
+ tree args;
/* We can remove output conversions that change the type,
but not the mode. */
@@ -6086,8 +6062,15 @@ build_asm_stmt (tree cv_qualifier, tree string, tree outputs, tree inputs,
for (tail = inputs; tail; tail = TREE_CHAIN (tail))
TREE_VALUE (tail) = default_function_array_conversion (TREE_VALUE (tail));
- return add_stmt (build_stmt (ASM_STMT, cv_qualifier, string,
- outputs, inputs, clobbers));
+ args = build_stmt (ASM_STMT, 0, string, outputs, inputs, clobbers);
+
+ /* Simple asm statements are treated as volatile. */
+ if (simple)
+ {
+ TREE_OPERAND (args, 0) = ridpointers[RID_VOLATILE];
+ ASM_INPUT_P (args) = 1;
+ }
+ return args;
}
/* Expand an ASM statement with operands, handling output operands