/* YACC parser for C syntax and for Objective C. -*-c-*-
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
/* To whomever it may concern: I have heard that such a thing was once
written by AT&T, but I have never seen it. */
-ifobjc
-%expect 32 /* shift/reduce conflicts, and 1 reduce/reduce conflict. */
-end ifobjc
ifc
%expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
end ifc
%{
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "input.h"
#include "cpplib.h"
#include "c-pragma.h" /* For YYDEBUG definition, and parse_in. */
#include "c-tree.h"
#include "flags.h"
+#include "varray.h"
#include "output.h"
#include "toplev.h"
#include "ggc.h"
/* String constants in raw form.
yylval is a STRING_CST node. */
+
%token STRING
/* "...", used for functions with variable arglists. */
static int stmt_count;
static int compstmt_count;
-/* Input file and line number of the end of the body of last simple_if;
+/* Input location of the end of the body of last simple_if;
used by the stmt-rule immediately after simple_if returns. */
-static const char *if_stmt_file;
-static int if_stmt_line;
+static location_t if_stmt_locus;
+
/* List of types and structure classes of the current declaration. */
static GTY(()) tree current_declspecs;
extdef:
extdef_1
{ parsing_iso_function_signature = false; } /* Reset after any external definition. */
+ ;
extdef_1:
fndef
/* Refer to the address of a label as a pointer. */
| ANDAND identifier
{ $$ = 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
- { tree types = TYPE_ARG_TYPES (TREE_TYPE (current_function_decl));
- $$ = error_mark_node;
- if (TREE_VALUE (tree_last (types)) == void_type_node)
- error ("`&...' used in function with fixed number of arguments");
- else
- {
- if (pedantic)
- pedwarn ("ISO C forbids `&...'");
- $$ = tree_last (DECL_ARGUMENTS (current_function_decl));
- $$ = build_unary_op (ADDR_EXPR, $$, 0);
- } }
-*/
| sizeof unary_expr %prec UNARY
{ skip_evaluation--;
if (TREE_CODE ($2) == COMPONENT_REF
ALIGNOF { skip_evaluation++; }
;
+typeof:
+ TYPEOF { skip_evaluation++; }
+ ;
+
cast_expr:
unary_expr
| '(' typename ')' cast_expr %prec UNARY
{
parsing_iso_function_signature = false; /* Reset after decls. */
}
+ ;
old_style_parm_decls_1:
/* empty */
parsing_iso_function_signature = false; /* Reset after warning. */
}
| datadecls
- | datadecls ELLIPSIS
- /* ... is used here to indicate a varargs function. */
- { c_mark_varargs ();
- if (pedantic)
- pedwarn ("ISO C does not permit use of `varargs.h'"); }
;
/* The following are analogous to lineno_decl, decls and decl
| non_empty_protocolrefs
{ $$ = get_object_reference ($1); }
end ifobjc
- | TYPEOF '(' expr ')'
- { $$ = TREE_TYPE ($3); }
- | TYPEOF '(' typename ')'
- { $$ = groktypename ($3); }
+ | typeof '(' expr ')'
+ { skip_evaluation--; $$ = TREE_TYPE ($3); }
+ | typeof '(' typename ')'
+ { skip_evaluation--; $$ = groktypename ($3); }
;
/* typespec_nonreserved_attr does not exist. */
so that the header files compile. */
maybe_attribute:
/* empty */
- { $$ = NULL_TREE; }
+ { $$ = NULL_TREE; }
| attributes
{ $$ = $1; }
;
/* Start scope of tag before parsing components. */
}
component_decl_list '}' maybe_attribute
- { $$ = finish_struct ($<ttype>4, $5, chainon ($1, $7)); }
+ { $$ = finish_struct ($<ttype>4, nreverse ($5),
+ chainon ($1, $7)); }
| struct_head '{' component_decl_list '}' maybe_attribute
{ $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
- $3, chainon ($1, $5));
+ nreverse ($3), chainon ($1, $5));
}
| union_head identifier '{'
{ $$ = start_struct (UNION_TYPE, $2); }
component_decl_list '}' maybe_attribute
- { $$ = finish_struct ($<ttype>4, $5, chainon ($1, $7)); }
+ { $$ = finish_struct ($<ttype>4, nreverse ($5),
+ chainon ($1, $7)); }
| union_head '{' component_decl_list '}' maybe_attribute
{ $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
- $3, chainon ($1, $5));
+ nreverse ($3), chainon ($1, $5));
}
| enum_head identifier '{'
{ $$ = start_enum ($2); }
pedwarn ("comma at end of enumerator list"); }
;
+/* We chain the components in reverse order. They are put in forward
+ order in structsp_attr.
+
+ Note that component_declarator returns single decls, so components
+ and components_notype can use TREE_CHAIN directly, wheras components
+ and components_notype return lists (of comma separated decls), so
+ component_decl_list and component_decl_list2 must use chainon.
+
+ The theory behind all this is that there will be more semicolon
+ separated fields than comma separated fields, and so we'll be
+ minimizing the number of node traversals required by chainon. */
+
component_decl_list:
component_decl_list2
{ $$ = $1; }
| component_decl_list2 component_decl
- { $$ = chainon ($1, $2);
+ { $$ = chainon ($2, $1);
pedwarn ("no semicolon at end of struct or union"); }
;
component_decl_list2: /* empty */
{ $$ = NULL_TREE; }
| component_decl_list2 component_decl ';'
- { $$ = chainon ($1, $2); }
+ { $$ = chainon ($2, $1); }
| component_decl_list2 ';'
{ if (pedantic)
pedwarn ("extra semicolon in struct or union specified"); }
tree interface = lookup_interface ($3);
if (interface)
- $$ = get_class_ivars (interface);
+ $$ = nreverse (get_class_ivars (interface));
else
{
error ("cannot find interface declaration for `%s'",
components:
component_declarator
| components ',' maybe_resetattrs component_declarator
- { $$ = chainon ($1, $4); }
+ { TREE_CHAIN ($4) = $1; $$ = $4; }
;
components_notype:
component_notype_declarator
| components_notype ',' maybe_resetattrs component_notype_declarator
- { $$ = chainon ($1, $4); }
+ { TREE_CHAIN ($4) = $1; $$ = $4; }
;
component_declarator:
;
/* We chain the enumerators in reverse order.
- They are put in forward order where enumlist is used.
- (The order used to be significant, but no longer is so.
- However, we still maintain the order, just to be clean.) */
+ They are put in forward order in structsp_attr. */
enumlist:
enumerator
{ if ($1 == error_mark_node)
$$ = $1;
else
- $$ = chainon ($3, $1); }
+ TREE_CHAIN ($3) = $1, $$ = $3; }
| error
{ $$ = error_mark_node; }
;
{ c_expand_start_cond (c_common_truthvalue_conversion ($4),
compstmt_count,$<ttype>2);
$<itype>$ = stmt_count;
- if_stmt_file = $<filename>-2;
- if_stmt_line = $<lineno>-1; }
+ if_stmt_locus.file = $<filename>-2;
+ if_stmt_locus.line = $<lineno>-1; }
;
/* This is a subroutine of stmt.
save_lineno:
{ if (yychar == YYEMPTY)
yychar = YYLEX;
- $$ = lineno; }
+ $$ = input_line; }
;
lineno_labeled_stmt:
else statement. Increment stmt_count so we don't
give a second error if this is a nested `if'. */
if (extra_warnings && stmt_count++ == $<itype>1)
- warning_with_file_and_line (if_stmt_file, if_stmt_line,
- "empty body in an if-statement"); }
+ warning ("%Hempty body in an if-statement",
+ &if_stmt_locus); }
/* Make sure c_expand_end_cond is run once
for each call to c_expand_start_cond.
Otherwise a crash is likely. */
'(' expr ')' ';'
{ DO_COND ($1) = c_common_truthvalue_conversion ($3); }
| do_stmt_start error
- { }
+ { }
| FOR
{ $<ttype>$ = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE,
NULL_TREE, NULL_TREE);
$$ = 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 ')' ';'
+ asm_operands ':' asm_clobbers ')' ';'
{ stmt_count++;
$$ = build_asm_stmt ($2, $4, $6, $8, $10); }
| GOTO identifier ';'
maybe_type_qual:
/* empty */
- { emit_line_note (input_filename, lineno);
+ { emit_line_note (input_filename, input_line);
$$ = NULL_TREE; }
| TYPE_QUAL
- { emit_line_note (input_filename, lineno); }
+ { emit_line_note (input_filename, input_line); }
;
xexpr:
optparmlist:
/* empty */
{
- $$ = NULL_TREE;
+ $$ = NULL_TREE;
}
| ',' ELLIPSIS
{
}
parmlist_2
{
- /* returns a tree list node generated by get_parm_info */
+ /* returns a tree list node generated by get_parm_info */
$$ = $3;
poplevel (0, 0, 0);
}
/* RID_REINTCAST */ 0,
/* RID_STATCAST */ 0,
- /* alternate spellings */
- /* RID_AND */ 0,
- /* RID_AND_EQ */ 0,
- /* RID_NOT */ 0,
- /* RID_NOT_EQ */ 0,
- /* RID_OR */ 0,
- /* RID_OR_EQ */ 0,
- /* RID_XOR */ 0,
- /* RID_XOR_EQ */ 0,
- /* RID_BITAND */ 0,
- /* RID_BITOR */ 0,
- /* RID_COMPL */ 0,
-
/* Objective C */
/* RID_ID */ OBJECTNAME,
/* RID_AT_ENCODE */ ENCODE,
int mask = (flag_isoc99 ? 0 : D_C89)
| (flag_no_asm ? (flag_isoc99 ? D_EXT : D_EXT|D_EXT89) : 0);
- if (c_language != clk_objective_c)
+ if (!flag_objc)
mask |= D_OBJC;
- /* It is not necessary to register ridpointers as a GC root, because
- all the trees it points to are permanently interned in the
- get_identifier hash anyway. */
- ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree));
+ ridpointers = (tree *) ggc_calloc ((int) RID_MAX, sizeof (tree));
for (i = 0; i < N_reswords; i++)
{
/* If a keyword is disabled, do not enter it into the table
static int last_lineno = 0;
static const char *last_input_filename = 0;
if (warn_traditional && !in_system_header
- && (lineno != last_lineno || !last_input_filename ||
+ && (input_line != last_lineno || !last_input_filename ||
strcmp (last_input_filename, input_filename)))
{
warning ("traditional C rejects string concatenation");
- last_lineno = lineno;
+ last_lineno = input_line;
last_input_filename = input_filename;
}
end ifc
case CONSTANT:
fprintf (file, " %s", GET_MODE_NAME (TYPE_MODE (TREE_TYPE (t))));
if (TREE_CODE (t) == INTEGER_CST)
- fprintf (file,
-#if HOST_BITS_PER_WIDE_INT == 64
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
- " 0x%x%016x",
-#else
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- " 0x%lx%016lx",
-#else
- " 0x%llx%016llx",
-#endif
-#endif
-#else
-#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
- " 0x%lx%08lx",
-#else
- " 0x%x%08x",
-#endif
-#endif
- TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t));
+ {
+ fputs (" ", file);
+ fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+ TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t));
+ }
break;
}
}