| /* 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, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
| |
| This file is part of GCC. |
| |
| GCC is free software; you can redistribute it and/or modify it under |
| the terms of the GNU General Public License as published by the Free |
| Software Foundation; either version 2, or (at your option) any later |
| version. |
| |
| GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
| WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GCC; see the file COPYING. If not, write to the Free |
| Software Foundation, 59 Temple Place - Suite 330, Boston, MA |
| 02111-1307, USA. */ |
| |
| /* This file defines the grammar of C and that of Objective C. |
| @@ifobjc ... @@end_ifobjc conditionals contain code for Objective C only. |
| @@ifc ... @@end_ifc conditionals contain code for C only. |
| Sed commands in Makefile.in are used to convert this file into |
| c-parse.y and into objc-parse.y. */ |
| |
| /* To whomever it may concern: I have heard that such a thing was once |
| written by AT&T, but I have never seen it. */ |
| |
| @@ifc |
| /* APPLE LOCAL CW asm blocks */ |
| %expect 16 /* 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 "langhooks.h" |
| #include "input.h" |
| #include "cpplib.h" |
| #include "intl.h" |
| #include "timevar.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" |
| #include "c-common.h" |
| |
| #define YYERROR1 { yyerror ("syntax error"); YYERROR; } |
| |
| /* Like the default stack expander, except (1) use realloc when possible, |
| (2) impose no hard maxiumum on stack size, (3) REALLY do not use alloca. |
| |
| Irritatingly, YYSTYPE is defined after this %{ %} block, so we cannot |
| give malloced_yyvs its proper type. This is ok since all we need from |
| it is to be able to free it. */ |
| |
| static short *malloced_yyss; |
| static void *malloced_yyvs; |
| |
| #define yyoverflow(MSG, SS, SSSIZE, VS, VSSIZE, YYSSZ) \ |
| do { \ |
| size_t newsize; \ |
| short *newss; \ |
| YYSTYPE *newvs; \ |
| newsize = *(YYSSZ) *= 2; \ |
| if (malloced_yyss) \ |
| { \ |
| newss = really_call_realloc (*(SS), newsize * sizeof (short)); \ |
| newvs = really_call_realloc (*(VS), newsize * sizeof (YYSTYPE)); \ |
| } \ |
| else \ |
| { \ |
| newss = really_call_malloc (newsize * sizeof (short)); \ |
| newvs = really_call_malloc (newsize * sizeof (YYSTYPE)); \ |
| if (newss) \ |
| memcpy (newss, *(SS), (SSSIZE)); \ |
| if (newvs) \ |
| memcpy (newvs, *(VS), (VSSIZE)); \ |
| } \ |
| if (!newss || !newvs) \ |
| { \ |
| yyerror (MSG); \ |
| return 2; \ |
| } \ |
| *(SS) = newss; \ |
| *(VS) = newvs; \ |
| malloced_yyss = newss; \ |
| malloced_yyvs = (void *) newvs; \ |
| } while (0) |
| %} |
| |
| %start program |
| |
| %union {long itype; tree ttype; void *otype; struct c_expr exprtype; |
| struct c_arg_info *arginfotype; struct c_declarator *dtrtype; |
| struct c_type_name *typenametype; struct c_parm *parmtype; |
| struct c_declspecs *dsptype; struct c_typespec tstype; |
| enum tree_code code; location_t location; } |
| |
| /* All identifiers that are not reserved words |
| and are not declared typedefs in the current block */ |
| %token IDENTIFIER |
| |
| /* All identifiers that are declared typedefs in the current block. |
| In some contexts, they are treated just like IDENTIFIER, |
| but they can also serve as typespecs in declarations. */ |
| %token TYPENAME |
| |
| /* Reserved words that specify storage class. |
| yylval contains an IDENTIFIER_NODE which indicates which one. */ |
| %token SCSPEC /* Storage class other than static. */ |
| %token STATIC /* Static storage class. */ |
| |
| /* Reserved words that specify type. |
| yylval contains an IDENTIFIER_NODE which indicates which one. */ |
| %token TYPESPEC |
| |
| /* Reserved words that qualify type: "const", "volatile", or "restrict". |
| yylval contains an IDENTIFIER_NODE which indicates which one. */ |
| %token TYPE_QUAL |
| |
| /* Objective-C protocol qualifiers. These acquire their magic powers |
| only in certain contexts. */ |
| %token OBJC_TYPE_QUAL |
| |
| /* Character or numeric constants. |
| yylval is the node for the constant. */ |
| %token CONSTANT |
| |
| /* String constants in raw form. |
| yylval is a STRING_CST node. */ |
| |
| %token STRING |
| |
| /* "...", used for functions with variable arglists. */ |
| %token ELLIPSIS |
| |
| /* the reserved words */ |
| /* SCO include files test "ASM", so use something else. */ |
| %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT |
| %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF |
| %token ATTRIBUTE EXTENSION LABEL |
| %token REALPART IMAGPART VA_ARG CHOOSE_EXPR TYPES_COMPATIBLE_P |
| %token FUNC_NAME OFFSETOF |
| |
| /* APPLE LOCAL begin CW asm blocks (in 4.2 ac) */ |
| /* This token is a pseudo-storage-class. */ |
| %token IASM_ASM_KEYWORD |
| %type <ttype> IASM_ASM_KEYWORD |
| /* These tokens indicate beginning and end of each asm line. */ |
| %token IASM_BOL IASM_EOL |
| /* APPLE LOCAL end CW asm blocks (in 4.2 ac) */ |
| |
| /* Add precedence rules to solve dangling else s/r conflict */ |
| %nonassoc IF |
| %nonassoc ELSE |
| |
| /* Define the operator tokens and their precedences. |
| The value is an integer because, if used, it is the tree code |
| to use in the expression made from the operator. */ |
| |
| %right <code> ASSIGN '=' |
| %right <code> '?' ':' |
| %left <code> OROR |
| %left <code> ANDAND |
| %left <code> '|' |
| %left <code> '^' |
| %left <code> '&' |
| %left <code> EQCOMPARE |
| %left <code> ARITHCOMPARE |
| %left <code> LSHIFT RSHIFT |
| %left <code> '+' '-' |
| %left <code> '*' '/' '%' |
| %right <code> UNARY PLUSPLUS MINUSMINUS |
| %left HYPERUNARY |
| %left <code> POINTSAT '.' '(' '[' |
| |
| /* The Objective-C keywords. These are included in C and in |
| Objective C, so that the token codes are the same in both. */ |
| %token AT_INTERFACE AT_IMPLEMENTATION AT_END AT_SELECTOR AT_DEFS AT_ENCODE |
| %token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL |
| %token AT_CLASS AT_ALIAS |
| %token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED |
| %token OBJC_STRING |
| /* APPLE LOCAL begin C* language (in 4.2 not needed) */ |
| %token AT_IN AT_OPTIONAL AT_REQUIRED |
| /* APPLE LOCAL end C* language (in 4.2 not needed) */ |
| /* APPLE LOCAL begin C* property (Radar 4436866, 4591909, 4621020) (in 4.2 not needed, except for 4591909, 4621020) */ |
| %token AT_PROPERTY AT_READONLY AT_PROP_BYCOPY AT_GETTER AT_SETTER AT_IVAR |
| %token AT_PROP_BYREF AT_PROP_DYNAMIC AT_WEAK |
| /* APPLE LOCAL end C* property (Radar 4436866, 4591909, 4621020) (in 4.2 not needed, except for 4591909, 4621020) */ |
| /* APPLE LOCAL objc new property */ |
| %token AT_SYNTHESIZE AT_DYNAMIC AT_READWRITE AT_ASSIGN AT_RETAIN AT_COPY |
| /* APPLE LOCAL radar 4947014 - objc atomic property */ |
| %token AT_NONATOMIC |
| /* APPLE LOCAL radar 4564694 */ |
| %token AT_PACKAGE |
| |
| %type <code> unop |
| %type <ttype> ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT |
| %type <ttype> BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF |
| |
| %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT STRING FUNC_NAME |
| %type <ttype> nonnull_exprlist exprlist |
| %type <exprtype> expr expr_no_commas cast_expr unary_expr primary |
| %type <dsptype> declspecs_nosc_nots_nosa_noea declspecs_nosc_nots_nosa_ea |
| %type <dsptype> declspecs_nosc_nots_sa_noea declspecs_nosc_nots_sa_ea |
| %type <dsptype> declspecs_nosc_ts_nosa_noea declspecs_nosc_ts_nosa_ea |
| %type <dsptype> declspecs_nosc_ts_sa_noea declspecs_nosc_ts_sa_ea |
| %type <dsptype> declspecs_sc_nots_nosa_noea declspecs_sc_nots_nosa_ea |
| %type <dsptype> declspecs_sc_nots_sa_noea declspecs_sc_nots_sa_ea |
| %type <dsptype> declspecs_sc_ts_nosa_noea declspecs_sc_ts_nosa_ea |
| %type <dsptype> declspecs_sc_ts_sa_noea declspecs_sc_ts_sa_ea |
| %type <dsptype> declspecs_ts declspecs_nots |
| %type <dsptype> declspecs_ts_nosa declspecs_nots_nosa |
| %type <dsptype> declspecs_nosc_ts declspecs_nosc_nots declspecs_nosc declspecs |
| %type <dsptype> maybe_type_quals_attrs |
| %type <tstype> typespec_nonattr typespec_attr |
| %type <tstype> typespec_reserved_nonattr typespec_reserved_attr |
| %type <tstype> typespec_nonreserved_nonattr |
| %type <ttype> offsetof_member_designator |
| |
| %type <ttype> scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_volatile |
| %type <ttype> initdecls notype_initdecls initdcl notype_initdcl |
| %type <exprtype> init |
| %type <ttype> simple_asm_expr maybeasm asm_stmt asm_argument asm_string |
| %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers |
| %type <ttype> maybe_attribute attributes attribute attribute_list attrib |
| %type <ttype> any_word |
| |
| %type <ttype> compstmt compstmt_start compstmt_primary_start |
| %type <ttype> stmt label stmt_nocomp start_break start_continue |
| |
| %type <ttype> c99_block_start c99_block_lineno_labeled_stmt |
| %type <ttype> if_statement_1 if_statement_2 |
| %type <dtrtype> declarator |
| %type <dtrtype> notype_declarator after_type_declarator |
| %type <dtrtype> parm_declarator |
| %type <dtrtype> parm_declarator_starttypename parm_declarator_nostarttypename |
| %type <dtrtype> array_declarator |
| |
| %type <tstype> structsp_attr structsp_nonattr |
| %type <ttype> component_decl_list component_decl_list2 |
| %type <ttype> component_decl components components_notype component_declarator |
| %type <ttype> component_notype_declarator |
| %type <ttype> enumlist enumerator |
| %type <ttype> struct_head union_head enum_head |
| %type <typenametype> typename |
| %type <dtrtype> absdcl absdcl1 absdcl1_ea absdcl1_noea direct_absdcl1 |
| %type <parmtype> absdcl_maybe_attribute |
| %type <ttype> condition xexpr for_cond_expr for_incr_expr |
| %type <parmtype> parm firstparm |
| %type <ttype> identifiers |
| |
| %type <arginfotype> parms parmlist parmlist_1 parmlist_2 |
| %type <arginfotype> parmlist_or_identifiers parmlist_or_identifiers_1 |
| %type <ttype> identifiers_or_typenames |
| |
| /* APPLE LOCAL begin CW asm blocks */ |
| %type <ttype> iasm_identifier iasm_identifier1 iasm_maybe_prefix |
| %type <exprtype> iasm_expr_no_commas iasm_unary_expr |
| %type <exprtype> iasm_primary |
| %type <ttype> iasm_operands iasm_nonnull_operands |
| %type <exprtype> iasm_operand |
| %type <ttype> iasm_stmt iasm_stmt_nobol single_iasm_stmt |
| %type <ttype> iasm_compstmt iasm_compstmt_start |
| /* iasm_compstmt_nostart */ |
| /* APPLE LOCAL end CW asm blocks */ |
| |
| %type <itype> setspecs setspecs_fp extension |
| |
| %type <location> save_location |
| |
| %type <otype> save_obstack_position |
| |
| @@ifobjc |
| /* the Objective-C nonterminals */ |
| |
| %type <ttype> methoddecl unaryselector keywordselector selector |
| %type <code> methodtype |
| %type <ttype> keyworddecl receiver objcmessageexpr messageargs |
| %type <ttype> keywordexpr keywordarglist keywordarg |
| %type <ttype> optparmlist optparms reservedwords objcselectorexpr |
| %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr |
| %type <ttype> non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr |
| /* APPLE LOCAL C* language */ |
| %type <ttype> for_objc_collection |
| /* APPLE LOCAL objc new property */ |
| %type <ttype> property_synthesize_item property_synthesize_list property_implementation |
| |
| %type <ttype> CLASSNAME OBJC_STRING OBJC_TYPE_QUAL |
| |
| %type <ttype> superclass objc_quals objc_qual objc_typename |
| %type <itype> objc_try_catch_stmt optellipsis |
| /* APPLE LOCAL radar 2848255 */ |
| %type <parmtype> objc_catch_parm |
| /* APPLE LOCAL radar 4965989 */ |
| %type <ttype> optidentifier |
| @@end_ifobjc |
| |
| %{ |
| /* Declaration specifiers of the current declaration. */ |
| static struct c_declspecs *current_declspecs; |
| static GTY(()) tree prefix_attributes; |
| |
| /* List of all the attributes applying to the identifier currently being |
| declared; includes prefix_attributes and possibly some more attributes |
| just after a comma. */ |
| static GTY(()) tree all_prefix_attributes; |
| |
| /* Structure to save declaration specifiers. */ |
| struct c_declspec_stack { |
| /* Saved value of current_declspecs. */ |
| struct c_declspecs *current_declspecs; |
| /* Saved value of prefix_attributes. */ |
| tree prefix_attributes; |
| /* Saved value of all_prefix_attributes. */ |
| tree all_prefix_attributes; |
| /* Next level of stack. */ |
| struct c_declspec_stack *next; |
| }; |
| |
| /* Stack of saved values of current_declspecs, prefix_attributes and |
| all_prefix_attributes. */ |
| static struct c_declspec_stack *declspec_stack; |
| |
| /* INDIRECT_REF with a TREE_TYPE of the type being queried for offsetof. */ |
| static tree offsetof_base; |
| |
| /* PUSH_DECLSPEC_STACK is called from setspecs; POP_DECLSPEC_STACK |
| should be called from the productions making use of setspecs. */ |
| #define PUSH_DECLSPEC_STACK \ |
| do { \ |
| struct c_declspec_stack *t = XOBNEW (&parser_obstack, \ |
| struct c_declspec_stack); \ |
| t->current_declspecs = current_declspecs; \ |
| t->prefix_attributes = prefix_attributes; \ |
| t->all_prefix_attributes = all_prefix_attributes; \ |
| t->next = declspec_stack; \ |
| declspec_stack = t; \ |
| } while (0) |
| |
| #define POP_DECLSPEC_STACK \ |
| do { \ |
| current_declspecs = declspec_stack->current_declspecs; \ |
| prefix_attributes = declspec_stack->prefix_attributes; \ |
| all_prefix_attributes = declspec_stack->all_prefix_attributes; \ |
| declspec_stack = declspec_stack->next; \ |
| } while (0) |
| |
| /* For __extension__, save/restore the warning flags which are |
| controlled by __extension__. */ |
| #define SAVE_EXT_FLAGS() \ |
| (pedantic \ |
| | (warn_pointer_arith << 1) \ |
| | (warn_traditional << 2) \ |
| | (flag_iso << 3)) |
| |
| #define RESTORE_EXT_FLAGS(val) \ |
| do { \ |
| pedantic = val & 1; \ |
| warn_pointer_arith = (val >> 1) & 1; \ |
| warn_traditional = (val >> 2) & 1; \ |
| flag_iso = (val >> 3) & 1; \ |
| } while (0) |
| |
| @@ifobjc |
| /* Objective-C specific parser/lexer information */ |
| |
| static int objc_pq_context = 0; |
| |
| /* The following flag is needed to contextualize ObjC lexical analysis. |
| In some cases (e.g., 'int NSObject;'), it is undesirable to bind |
| an identifier to an ObjC class, even if a class with that name |
| exists. */ |
| static int objc_need_raw_identifier; |
| #define OBJC_NEED_RAW_IDENTIFIER(VAL) objc_need_raw_identifier = VAL |
| /* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 d) */ |
| /* For checking property attribute keywords */ |
| static int objc_property_attr_context = 0; |
| /* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 d) */ |
| /* APPLE LOCAL radar 3803157 - objc attribute (in 4.2 e) */ |
| static tree objc_method_attributes = NULL_TREE; |
| @@end_ifobjc |
| |
| @@ifc |
| #define OBJC_NEED_RAW_IDENTIFIER(VAL) /* nothing */ |
| @@end_ifc |
| |
| /* Tell yyparse how to print a token's value, if yydebug is set. */ |
| |
| #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) |
| |
| /* APPLE LOCAL begin C* language (in 4.2 f) */ |
| /* For checking for 'foreach' context. */ |
| static int objc_foreach_context = 0; |
| /* APPLE LOCAL end C* language (in 4.2 f) */ |
| static void yyprint (FILE *, int, YYSTYPE); |
| static void yyerror (const char *); |
| static int yylexname (void); |
| static inline int _yylex (void); |
| static int yylex (void); |
| static void init_reswords (void); |
| /* APPLE LOCAL begin CW asm blocks (in 4.2 g) */ |
| static int iasm_lineno = 0; |
| #ifndef IASM_SEE_OPCODE |
| #define IASM_SEE_OPCODE(YYCHAR, T) YYCHAR |
| #endif |
| |
| static tree c_parse_iasm_maybe_prefix (tree id); |
| /* APPLE LOCAL end CW asm blocks (in 4.2 g) */ |
| |
| /* Initialization routine for this file. */ |
| void |
| c_parse_init (void) |
| { |
| init_reswords (); |
| } |
| |
| %} |
| |
| %% |
| program: /* empty */ |
| { if (pedantic) |
| pedwarn ("ISO C forbids an empty source file"); |
| } |
| | extdefs |
| ; |
| |
| /* the reason for the strange actions in this rule |
| is so that notype_initdecls when reached via datadef |
| can find valid declaration specifiers in $0. */ |
| |
| extdefs: |
| save_obstack_position { $<dsptype>$ = NULL; } extdef |
| { obstack_free (&parser_obstack, $1); } |
| | extdefs save_obstack_position |
| { $<dsptype>$ = NULL; ggc_collect (); } extdef |
| { obstack_free (&parser_obstack, $2); } |
| ; |
| |
| extdef: |
| fndef |
| | datadef |
| | asmdef |
| | extension extdef |
| { RESTORE_EXT_FLAGS ($1); } |
| @@ifobjc |
| | objcdef |
| @@end_ifobjc |
| ; |
| |
| /* Record the current position of parser_obstack before a |
| declaration to restore it afterwards. */ |
| save_obstack_position: |
| { $$ = obstack_alloc (&parser_obstack, 0); } |
| ; |
| |
| datadef: |
| setspecs notype_initdecls ';' |
| { pedwarn ("data definition has no type or storage class"); |
| POP_DECLSPEC_STACK; } |
| | declspecs_nots setspecs notype_initdecls ';' |
| { POP_DECLSPEC_STACK; } |
| | declspecs_ts setspecs initdecls ';' |
| { POP_DECLSPEC_STACK; } |
| | declspecs ';' |
| { shadow_tag (finish_declspecs ($1)); } |
| | error ';' |
| | error '}' |
| | ';' |
| { if (pedantic) |
| pedwarn ("ISO C does not allow extra %<;%> outside of a function"); } |
| ; |
| |
| fndef: |
| declspecs_ts setspecs declarator |
| { if (!start_function (current_declspecs, $3, |
| all_prefix_attributes)) |
| YYERROR1; |
| } |
| old_style_parm_decls save_location |
| { DECL_SOURCE_LOCATION (current_function_decl) = $6; |
| store_parm_decls (); } |
| compstmt_or_error |
| { finish_function (); |
| POP_DECLSPEC_STACK; } |
| | declspecs_ts setspecs declarator error |
| { POP_DECLSPEC_STACK; } |
| | declspecs_nots setspecs notype_declarator |
| { if (!start_function (current_declspecs, $3, |
| all_prefix_attributes)) |
| YYERROR1; |
| } |
| old_style_parm_decls save_location |
| { DECL_SOURCE_LOCATION (current_function_decl) = $6; |
| store_parm_decls (); } |
| compstmt_or_error |
| { finish_function (); |
| POP_DECLSPEC_STACK; } |
| | declspecs_nots setspecs notype_declarator error |
| { POP_DECLSPEC_STACK; } |
| | setspecs notype_declarator |
| { if (!start_function (current_declspecs, $2, |
| all_prefix_attributes)) |
| YYERROR1; |
| } |
| old_style_parm_decls save_location |
| { DECL_SOURCE_LOCATION (current_function_decl) = $5; |
| store_parm_decls (); } |
| compstmt_or_error |
| { finish_function (); |
| POP_DECLSPEC_STACK; } |
| | setspecs notype_declarator error |
| { POP_DECLSPEC_STACK; } |
| ; |
| |
| identifier: |
| IDENTIFIER |
| | TYPENAME |
| @@ifobjc |
| | CLASSNAME |
| @@end_ifobjc |
| ; |
| |
| unop: '&' |
| { $$ = ADDR_EXPR; } |
| | '-' |
| { $$ = NEGATE_EXPR; } |
| | '+' |
| { $$ = CONVERT_EXPR; |
| @@ifc |
| if (warn_traditional && !in_system_header) |
| warning ("traditional C rejects the unary plus operator"); |
| @@end_ifc |
| } |
| | PLUSPLUS |
| { $$ = PREINCREMENT_EXPR; } |
| | MINUSMINUS |
| { $$ = PREDECREMENT_EXPR; } |
| | '~' |
| { $$ = BIT_NOT_EXPR; } |
| | '!' |
| { $$ = TRUTH_NOT_EXPR; } |
| ; |
| |
| expr: expr_no_commas |
| | expr ',' expr_no_commas |
| { $$.value = build_compound_expr ($1.value, $3.value); |
| $$.original_code = COMPOUND_EXPR; } |
| ; |
| |
| exprlist: |
| /* empty */ |
| { $$ = NULL_TREE; } |
| | nonnull_exprlist |
| ; |
| |
| nonnull_exprlist: |
| expr_no_commas |
| { $$ = build_tree_list (NULL_TREE, $1.value); } |
| | nonnull_exprlist ',' expr_no_commas |
| { chainon ($1, build_tree_list (NULL_TREE, $3.value)); } |
| ; |
| |
| unary_expr: |
| primary |
| | '*' cast_expr %prec UNARY |
| { $$.value = build_indirect_ref ($2.value, "unary *"); |
| $$.original_code = ERROR_MARK; } |
| /* __extension__ turns off -pedantic for following primary. */ |
| | extension cast_expr %prec UNARY |
| { $$ = $2; |
| RESTORE_EXT_FLAGS ($1); } |
| | unop cast_expr %prec UNARY |
| { $$.value = build_unary_op ($1, $2.value, 0); |
| overflow_warning ($$.value); |
| $$.original_code = ERROR_MARK; } |
| /* Refer to the address of a label as a pointer. */ |
| | ANDAND identifier |
| { $$.value = finish_label_address_expr ($2); |
| $$.original_code = ERROR_MARK; } |
| | sizeof unary_expr %prec UNARY |
| { skip_evaluation--; |
| in_sizeof--; |
| if (TREE_CODE ($2.value) == COMPONENT_REF |
| && DECL_C_BIT_FIELD (TREE_OPERAND ($2.value, 1))) |
| error ("%<sizeof%> applied to a bit-field"); |
| $$ = c_expr_sizeof_expr ($2); } |
| | sizeof '(' typename ')' %prec HYPERUNARY |
| { skip_evaluation--; |
| in_sizeof--; |
| /* APPLE LOCAL begin mainline 2006-05-18 4336222 */ |
| if ($3->declarator->kind == cdk_array |
| && $3->declarator->u.array.vla_unspec_p) |
| { |
| /* C99 6.7.5.2p4 */ |
| error ("%<[*]%> not allowed in other than a declaration"); |
| } |
| /* APPLE LOCAL end mainline 2006-05-18 4336222 */ |
| $$ = c_expr_sizeof_type ($3); } |
| | alignof unary_expr %prec UNARY |
| { skip_evaluation--; |
| in_alignof--; |
| $$.value = c_alignof_expr ($2.value); |
| $$.original_code = ERROR_MARK; } |
| | alignof '(' typename ')' %prec HYPERUNARY |
| { skip_evaluation--; |
| in_alignof--; |
| $$.value = c_alignof (groktypename ($3)); |
| $$.original_code = ERROR_MARK; } |
| | REALPART cast_expr %prec UNARY |
| { $$.value = build_unary_op (REALPART_EXPR, $2.value, 0); |
| $$.original_code = ERROR_MARK; } |
| | IMAGPART cast_expr %prec UNARY |
| { $$.value = build_unary_op (IMAGPART_EXPR, $2.value, 0); |
| $$.original_code = ERROR_MARK; } |
| ; |
| |
| sizeof: |
| SIZEOF { skip_evaluation++; in_sizeof++; } |
| ; |
| |
| alignof: |
| ALIGNOF { skip_evaluation++; in_alignof++; } |
| ; |
| |
| typeof: |
| TYPEOF { skip_evaluation++; in_typeof++; } |
| ; |
| |
| cast_expr: |
| unary_expr |
| | '(' typename ')' cast_expr %prec UNARY |
| { $$.value = c_cast_expr ($2, $4.value); |
| $$.original_code = ERROR_MARK; } |
| ; |
| |
| expr_no_commas: |
| /* APPLE LOCAL begin radar 4426814 */ |
| cast_expr |
| { |
| if (c_dialect_objc() && flag_objc_gc) |
| $$.value = objc_generate_weak_read ($1.value); } |
| /* APPLE LOCAL end radar 4426814 */ |
| | expr_no_commas '+' expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas '-' expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas '*' expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas '/' expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas '%' expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas LSHIFT expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas RSHIFT expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas ARITHCOMPARE expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas EQCOMPARE expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas '&' expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas '|' expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas '^' expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | expr_no_commas ANDAND |
| { $1.value = lang_hooks.truthvalue_conversion |
| (default_conversion ($1.value)); |
| skip_evaluation += $1.value == truthvalue_false_node; } |
| expr_no_commas |
| { skip_evaluation -= $1.value == truthvalue_false_node; |
| $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $4); } |
| | expr_no_commas OROR |
| { $1.value = lang_hooks.truthvalue_conversion |
| (default_conversion ($1.value)); |
| skip_evaluation += $1.value == truthvalue_true_node; } |
| expr_no_commas |
| { skip_evaluation -= $1.value == truthvalue_true_node; |
| $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $4); } |
| | expr_no_commas '?' |
| { $1.value = lang_hooks.truthvalue_conversion |
| (default_conversion ($1.value)); |
| skip_evaluation += $1.value == truthvalue_false_node; } |
| expr ':' |
| { skip_evaluation += (($1.value == truthvalue_true_node) |
| - ($1.value == truthvalue_false_node)); } |
| expr_no_commas |
| { skip_evaluation -= $1.value == truthvalue_true_node; |
| $$.value = build_conditional_expr ($1.value, $4.value, |
| $7.value); |
| $$.original_code = ERROR_MARK; } |
| | expr_no_commas '?' |
| { if (pedantic) |
| pedwarn ("ISO C forbids omitting the middle term of a ?: expression"); |
| /* Make sure first operand is calculated only once. */ |
| $<ttype>2 = save_expr (default_conversion ($1.value)); |
| $1.value = lang_hooks.truthvalue_conversion ($<ttype>2); |
| skip_evaluation += $1.value == truthvalue_true_node; } |
| ':' expr_no_commas |
| { skip_evaluation -= $1.value == truthvalue_true_node; |
| $$.value = build_conditional_expr ($1.value, $<ttype>2, |
| $5.value); |
| $$.original_code = ERROR_MARK; } |
| | expr_no_commas '=' expr_no_commas |
| { $$.value = build_modify_expr ($1.value, NOP_EXPR, $3.value); |
| $$.original_code = MODIFY_EXPR; |
| } |
| | expr_no_commas ASSIGN expr_no_commas |
| { $$.value = build_modify_expr ($1.value, $2, $3.value); |
| TREE_NO_WARNING ($$.value) = 1; |
| $$.original_code = ERROR_MARK; |
| } |
| ; |
| |
| primary: |
| IDENTIFIER |
| { |
| if (yychar == YYEMPTY) |
| yychar = YYLEX; |
| $$.value = build_external_ref ($1, yychar == '('); |
| $$.original_code = ERROR_MARK; |
| } |
| | CONSTANT |
| { $$.value = $1; $$.original_code = ERROR_MARK; } |
| | STRING |
| { $$.value = $1; $$.original_code = STRING_CST; } |
| | FUNC_NAME |
| { $$.value = fname_decl (C_RID_CODE ($1), $1); |
| $$.original_code = ERROR_MARK; } |
| | '(' typename ')' '{' |
| { start_init (NULL_TREE, NULL, 0); |
| $<ttype>$ = groktypename ($2); |
| if (C_TYPE_VARIABLE_SIZE ($<ttype>$)) |
| { |
| error ("compound literal has variable size"); |
| $<ttype>$ = error_mark_node; |
| } |
| really_start_incremental_init ($<ttype>$); } |
| initlist_maybe_comma '}' %prec UNARY |
| { struct c_expr init = pop_init_level (0); |
| tree constructor = init.value; |
| tree type = $<ttype>5; |
| finish_init (); |
| maybe_warn_string_init (type, init); |
| |
| /* APPLE LOCAL AltiVec (in 4.2 o) */ |
| if (pedantic && TREE_CODE (type) != VECTOR_TYPE && !flag_isoc99) |
| pedwarn ("ISO C90 forbids compound literals"); |
| $$.value = build_compound_literal (type, constructor); |
| $$.original_code = ERROR_MARK; |
| } |
| | '(' expr ')' |
| { $$.value = $2.value; |
| if (TREE_CODE ($$.value) == MODIFY_EXPR) |
| TREE_NO_WARNING ($$.value) = 1; |
| $$.original_code = ERROR_MARK; } |
| | '(' error ')' |
| { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } |
| | compstmt_primary_start compstmt_nostart ')' |
| { if (pedantic) |
| pedwarn ("ISO C forbids braced-groups within expressions"); |
| $$.value = c_finish_stmt_expr ($1); |
| $$.original_code = ERROR_MARK; |
| } |
| | compstmt_primary_start error ')' |
| { c_finish_stmt_expr ($1); |
| $$.value = error_mark_node; |
| $$.original_code = ERROR_MARK; |
| } |
| | primary '(' exprlist ')' %prec '.' |
| { $$.value = build_function_call ($1.value, $3); |
| $$.original_code = ERROR_MARK; } |
| | VA_ARG '(' expr_no_commas ',' typename ')' |
| { $$.value = build_va_arg ($3.value, groktypename ($5)); |
| $$.original_code = ERROR_MARK; } |
| |
| | OFFSETOF '(' typename ',' |
| { tree type = groktypename ($3); |
| if (type == error_mark_node) |
| offsetof_base = error_mark_node; |
| else |
| offsetof_base = build1 (INDIRECT_REF, type, NULL); |
| } |
| offsetof_member_designator ')' |
| { $$.value = fold_offsetof ($6); |
| $$.original_code = ERROR_MARK; } |
| | OFFSETOF '(' error ')' |
| { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } |
| | CHOOSE_EXPR '(' expr_no_commas ',' expr_no_commas ',' |
| expr_no_commas ')' |
| { |
| tree c; |
| |
| c = fold ($3.value); |
| STRIP_NOPS (c); |
| if (TREE_CODE (c) != INTEGER_CST) |
| error ("first argument to %<__builtin_choose_expr%> not" |
| " a constant"); |
| $$ = integer_zerop (c) ? $7 : $5; |
| } |
| | CHOOSE_EXPR '(' error ')' |
| { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } |
| | TYPES_COMPATIBLE_P '(' typename ',' typename ')' |
| { |
| tree e1, e2; |
| |
| e1 = TYPE_MAIN_VARIANT (groktypename ($3)); |
| e2 = TYPE_MAIN_VARIANT (groktypename ($5)); |
| |
| $$.value = comptypes (e1, e2) |
| ? build_int_cst (NULL_TREE, 1) |
| : build_int_cst (NULL_TREE, 0); |
| $$.original_code = ERROR_MARK; |
| } |
| | TYPES_COMPATIBLE_P '(' error ')' |
| { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } |
| | primary '[' expr ']' %prec '.' |
| { $$.value = build_array_ref ($1.value, $3.value); |
| $$.original_code = ERROR_MARK; } |
| | primary '.' identifier |
| { $$.value = build_component_ref ($1.value, $3); |
| $$.original_code = ERROR_MARK; } |
| | primary POINTSAT identifier |
| { |
| tree expr = build_indirect_ref ($1.value, "->"); |
| $$.value = build_component_ref (expr, $3); |
| $$.original_code = ERROR_MARK; |
| } |
| | primary PLUSPLUS |
| { $$.value = build_unary_op (POSTINCREMENT_EXPR, $1.value, 0); |
| $$.original_code = ERROR_MARK; } |
| | primary MINUSMINUS |
| { $$.value = build_unary_op (POSTDECREMENT_EXPR, $1.value, 0); |
| $$.original_code = ERROR_MARK; } |
| @@ifobjc |
| | objcmessageexpr |
| { $$.value = objc_build_message_expr ($1); |
| $$.original_code = ERROR_MARK; } |
| | objcselectorexpr |
| { $$.value = objc_build_selector_expr ($1); |
| $$.original_code = ERROR_MARK; } |
| | objcprotocolexpr |
| { $$.value = objc_build_protocol_expr ($1); |
| $$.original_code = ERROR_MARK; } |
| | objcencodeexpr |
| { $$.value = objc_build_encode_expr ($1); |
| $$.original_code = ERROR_MARK; } |
| | OBJC_STRING |
| { $$.value = objc_build_string_object ($1); |
| $$.original_code = ERROR_MARK; } |
| @@end_ifobjc |
| ; |
| |
| /* This is the second argument to __builtin_offsetof. We must have one |
| identifier, and beyond that we want to accept sub structure and sub |
| array references. */ |
| |
| offsetof_member_designator: |
| identifier |
| { $$ = build_component_ref (offsetof_base, $1); } |
| | offsetof_member_designator '.' identifier |
| { $$ = build_component_ref ($1, $3); } |
| | offsetof_member_designator '[' expr ']' |
| { $$ = build_array_ref ($1, $3.value); } |
| ; |
| |
| old_style_parm_decls: |
| /* empty */ |
| | datadecls |
| ; |
| |
| /* The following are analogous to lineno_decl, decls and decl |
| except that they do not allow nested functions. |
| They are used for old-style parm decls. */ |
| lineno_datadecl: |
| save_location datadecl |
| { } |
| ; |
| |
| datadecls: |
| lineno_datadecl |
| | errstmt |
| | datadecls lineno_datadecl |
| | lineno_datadecl errstmt |
| ; |
| |
| /* We don't allow prefix attributes here because they cause reduce/reduce |
| conflicts: we can't know whether we're parsing a function decl with |
| attribute suffix, or function defn with attribute prefix on first old |
| style parm. */ |
| datadecl: |
| declspecs_ts_nosa setspecs initdecls ';' |
| { POP_DECLSPEC_STACK; } |
| | declspecs_nots_nosa setspecs notype_initdecls ';' |
| { POP_DECLSPEC_STACK; } |
| | declspecs_ts_nosa ';' |
| { shadow_tag_warned (finish_declspecs ($1), 1); |
| pedwarn ("empty declaration"); } |
| | declspecs_nots_nosa ';' |
| { pedwarn ("empty declaration"); } |
| ; |
| |
| /* This combination which saves a lineno before a decl |
| is the normal thing to use, rather than decl itself. |
| This is to avoid shift/reduce conflicts in contexts |
| where statement labels are allowed. */ |
| lineno_decl: |
| save_location decl |
| /* APPLE LOCAL CW asm blocks (in 4.2 al) */ |
| { if (flag_iasm_blocks) iasm_in_decl = false; } |
| ; |
| |
| /* records the type and storage class specs to use for processing |
| the declarators that follow. |
| Maintains a stack of outer-level values of current_declspecs, |
| for the sake of parm declarations nested in function declarators. */ |
| setspecs: /* empty */ |
| { pending_xref_error (); |
| PUSH_DECLSPEC_STACK; |
| if ($<dsptype>0) |
| { |
| prefix_attributes = $<dsptype>0->attrs; |
| $<dsptype>0->attrs = NULL_TREE; |
| current_declspecs = $<dsptype>0; |
| } |
| else |
| { |
| prefix_attributes = NULL_TREE; |
| current_declspecs = build_null_declspecs (); |
| } |
| current_declspecs = finish_declspecs (current_declspecs); |
| all_prefix_attributes = prefix_attributes; } |
| ; |
| |
| /* Possibly attributes after a comma, which should reset all_prefix_attributes |
| to prefix_attributes with these ones chained on the front. */ |
| maybe_resetattrs: |
| maybe_attribute |
| { all_prefix_attributes = chainon ($1, prefix_attributes); } |
| ; |
| |
| decl: |
| declspecs_ts setspecs initdecls ';' |
| { POP_DECLSPEC_STACK; } |
| | declspecs_nots setspecs notype_initdecls ';' |
| { POP_DECLSPEC_STACK; } |
| | declspecs_ts setspecs nested_function |
| { POP_DECLSPEC_STACK; } |
| | declspecs_nots setspecs notype_nested_function |
| { POP_DECLSPEC_STACK; } |
| | declspecs ';' |
| { shadow_tag (finish_declspecs ($1)); } |
| | extension decl |
| { RESTORE_EXT_FLAGS ($1); } |
| ; |
| |
| /* A list of declaration specifiers. These are: |
| |
| - Storage class specifiers (scspec), which for GCC currently includes |
| function specifiers ("inline"). |
| |
| - Type specifiers (typespec_*). |
| |
| - Type qualifiers (TYPE_QUAL). |
| |
| - Attribute specifier lists (attributes). |
| |
| The various cases below are classified according to: |
| |
| (a) Whether a storage class specifier is included or not; some |
| places in the grammar disallow storage class specifiers (_sc or _nosc). |
| |
| (b) Whether a type specifier has been seen; after a type specifier, |
| a typedef name is an identifier to redeclare (_ts or _nots). |
| |
| (c) Whether the list starts with an attribute; in certain places, |
| the grammar requires specifiers that don't start with an attribute |
| (_sa or _nosa). |
| |
| (d) Whether the list ends with an attribute (or a specifier such that |
| any following attribute would have been parsed as part of that specifier); |
| this avoids shift-reduce conflicts in the parsing of attributes |
| (_ea or _noea). |
| |
| TODO: |
| |
| (i) Distinguish between function specifiers and storage class specifiers, |
| at least for the purpose of warnings about obsolescent usage. |
| |
| (ii) Halve the number of productions here by eliminating the _sc/_nosc |
| distinction and instead checking where required that storage class |
| specifiers aren't present. */ |
| |
| /* Declspecs which contain at least one type specifier or typedef name. |
| (Just `const' or `volatile' is not enough.) |
| A typedef'd name following these is taken as a name to be declared. */ |
| |
| declspecs_nosc_nots_nosa_noea: |
| TYPE_QUAL |
| { $$ = declspecs_add_qual (build_null_declspecs (), $1); } |
| | declspecs_nosc_nots_nosa_noea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_nosc_nots_nosa_ea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| ; |
| |
| declspecs_nosc_nots_nosa_ea: |
| declspecs_nosc_nots_nosa_noea attributes |
| { $$ = declspecs_add_attrs ($1, $2); } |
| ; |
| |
| declspecs_nosc_nots_sa_noea: |
| declspecs_nosc_nots_sa_noea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_nosc_nots_sa_ea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| ; |
| |
| declspecs_nosc_nots_sa_ea: |
| attributes |
| { $$ = declspecs_add_attrs (build_null_declspecs (), $1); } |
| | declspecs_nosc_nots_sa_noea attributes |
| { $$ = declspecs_add_attrs ($1, $2); } |
| ; |
| |
| declspecs_nosc_ts_nosa_noea: |
| typespec_nonattr |
| { $$ = declspecs_add_type (build_null_declspecs (), $1); } |
| | declspecs_nosc_ts_nosa_noea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_nosc_ts_nosa_ea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_nosc_ts_nosa_noea typespec_reserved_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_ts_nosa_ea typespec_reserved_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_nots_nosa_noea typespec_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_nots_nosa_ea typespec_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| ; |
| |
| declspecs_nosc_ts_nosa_ea: |
| typespec_attr |
| { $$ = declspecs_add_type (build_null_declspecs (), $1); } |
| | declspecs_nosc_ts_nosa_noea attributes |
| { $$ = declspecs_add_attrs ($1, $2); } |
| | declspecs_nosc_ts_nosa_noea typespec_reserved_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_ts_nosa_ea typespec_reserved_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_nots_nosa_noea typespec_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_nots_nosa_ea typespec_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| ; |
| |
| declspecs_nosc_ts_sa_noea: |
| declspecs_nosc_ts_sa_noea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_nosc_ts_sa_ea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_nosc_ts_sa_noea typespec_reserved_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_ts_sa_ea typespec_reserved_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_nots_sa_noea typespec_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_nots_sa_ea typespec_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| ; |
| |
| declspecs_nosc_ts_sa_ea: |
| declspecs_nosc_ts_sa_noea attributes |
| { $$ = declspecs_add_attrs ($1, $2); } |
| | declspecs_nosc_ts_sa_noea typespec_reserved_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_ts_sa_ea typespec_reserved_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_nots_sa_noea typespec_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_nots_sa_ea typespec_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| ; |
| |
| declspecs_sc_nots_nosa_noea: |
| scspec |
| { $$ = declspecs_add_scspec (build_null_declspecs (), $1); } |
| | declspecs_sc_nots_nosa_noea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_sc_nots_nosa_ea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_nosc_nots_nosa_noea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_nosc_nots_nosa_ea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_sc_nots_nosa_noea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_sc_nots_nosa_ea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| ; |
| |
| declspecs_sc_nots_nosa_ea: |
| declspecs_sc_nots_nosa_noea attributes |
| { $$ = declspecs_add_attrs ($1, $2); } |
| ; |
| |
| declspecs_sc_nots_sa_noea: |
| declspecs_sc_nots_sa_noea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_sc_nots_sa_ea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_nosc_nots_sa_noea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_nosc_nots_sa_ea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_sc_nots_sa_noea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_sc_nots_sa_ea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| ; |
| |
| declspecs_sc_nots_sa_ea: |
| declspecs_sc_nots_sa_noea attributes |
| { $$ = declspecs_add_attrs ($1, $2); } |
| ; |
| |
| declspecs_sc_ts_nosa_noea: |
| declspecs_sc_ts_nosa_noea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_sc_ts_nosa_ea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_sc_ts_nosa_noea typespec_reserved_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_ts_nosa_ea typespec_reserved_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_nots_nosa_noea typespec_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_nots_nosa_ea typespec_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_ts_nosa_noea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_nosc_ts_nosa_ea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_sc_ts_nosa_noea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_sc_ts_nosa_ea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| ; |
| |
| declspecs_sc_ts_nosa_ea: |
| declspecs_sc_ts_nosa_noea attributes |
| { $$ = declspecs_add_attrs ($1, $2); } |
| | declspecs_sc_ts_nosa_noea typespec_reserved_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_ts_nosa_ea typespec_reserved_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_nots_nosa_noea typespec_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_nots_nosa_ea typespec_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| ; |
| |
| declspecs_sc_ts_sa_noea: |
| declspecs_sc_ts_sa_noea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_sc_ts_sa_ea TYPE_QUAL |
| { $$ = declspecs_add_qual ($1, $2); } |
| | declspecs_sc_ts_sa_noea typespec_reserved_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_ts_sa_ea typespec_reserved_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_nots_sa_noea typespec_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_nots_sa_ea typespec_nonattr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_nosc_ts_sa_noea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_nosc_ts_sa_ea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_sc_ts_sa_noea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| | declspecs_sc_ts_sa_ea scspec |
| { $$ = declspecs_add_scspec ($1, $2); } |
| ; |
| |
| declspecs_sc_ts_sa_ea: |
| declspecs_sc_ts_sa_noea attributes |
| { $$ = declspecs_add_attrs ($1, $2); } |
| | declspecs_sc_ts_sa_noea typespec_reserved_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_ts_sa_ea typespec_reserved_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_nots_sa_noea typespec_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| | declspecs_sc_nots_sa_ea typespec_attr |
| { $$ = declspecs_add_type ($1, $2); } |
| ; |
| |
| /* Particular useful classes of declspecs. */ |
| declspecs_ts: |
| declspecs_nosc_ts_nosa_noea |
| | declspecs_nosc_ts_nosa_ea |
| | declspecs_nosc_ts_sa_noea |
| | declspecs_nosc_ts_sa_ea |
| | declspecs_sc_ts_nosa_noea |
| | declspecs_sc_ts_nosa_ea |
| | declspecs_sc_ts_sa_noea |
| | declspecs_sc_ts_sa_ea |
| ; |
| |
| declspecs_nots: |
| declspecs_nosc_nots_nosa_noea |
| | declspecs_nosc_nots_nosa_ea |
| | declspecs_nosc_nots_sa_noea |
| | declspecs_nosc_nots_sa_ea |
| | declspecs_sc_nots_nosa_noea |
| | declspecs_sc_nots_nosa_ea |
| | declspecs_sc_nots_sa_noea |
| | declspecs_sc_nots_sa_ea |
| ; |
| |
| declspecs_ts_nosa: |
| declspecs_nosc_ts_nosa_noea |
| | declspecs_nosc_ts_nosa_ea |
| | declspecs_sc_ts_nosa_noea |
| | declspecs_sc_ts_nosa_ea |
| ; |
| |
| declspecs_nots_nosa: |
| declspecs_nosc_nots_nosa_noea |
| | declspecs_nosc_nots_nosa_ea |
| | declspecs_sc_nots_nosa_noea |
| | declspecs_sc_nots_nosa_ea |
| ; |
| |
| declspecs_nosc_ts: |
| declspecs_nosc_ts_nosa_noea |
| | declspecs_nosc_ts_nosa_ea |
| | declspecs_nosc_ts_sa_noea |
| | declspecs_nosc_ts_sa_ea |
| ; |
| |
| declspecs_nosc_nots: |
| declspecs_nosc_nots_nosa_noea |
| | declspecs_nosc_nots_nosa_ea |
| | declspecs_nosc_nots_sa_noea |
| | declspecs_nosc_nots_sa_ea |
| ; |
| |
| declspecs_nosc: |
| declspecs_nosc_ts_nosa_noea |
| | declspecs_nosc_ts_nosa_ea |
| | declspecs_nosc_ts_sa_noea |
| | declspecs_nosc_ts_sa_ea |
| | declspecs_nosc_nots_nosa_noea |
| | declspecs_nosc_nots_nosa_ea |
| | declspecs_nosc_nots_sa_noea |
| | declspecs_nosc_nots_sa_ea |
| ; |
| |
| declspecs: |
| declspecs_nosc_nots_nosa_noea |
| | declspecs_nosc_nots_nosa_ea |
| | declspecs_nosc_nots_sa_noea |
| | declspecs_nosc_nots_sa_ea |
| | declspecs_nosc_ts_nosa_noea |
| | declspecs_nosc_ts_nosa_ea |
| | declspecs_nosc_ts_sa_noea |
| | declspecs_nosc_ts_sa_ea |
| | declspecs_sc_nots_nosa_noea |
| | declspecs_sc_nots_nosa_ea |
| | declspecs_sc_nots_sa_noea |
| | declspecs_sc_nots_sa_ea |
| | declspecs_sc_ts_nosa_noea |
| | declspecs_sc_ts_nosa_ea |
| | declspecs_sc_ts_sa_noea |
| | declspecs_sc_ts_sa_ea |
| ; |
| |
| /* A (possibly empty) sequence of type qualifiers and attributes. */ |
| maybe_type_quals_attrs: |
| /* empty */ |
| { $$ = NULL; } |
| | declspecs_nosc_nots |
| { $$ = $1; } |
| ; |
| |
| /* A type specifier (but not a type qualifier). |
| Once we have seen one of these in a declaration, |
| if a typedef name appears then it is being redeclared. |
| |
| The _reserved versions start with a reserved word and may appear anywhere |
| in the declaration specifiers; the _nonreserved versions may only |
| appear before any other type specifiers, and after that are (if names) |
| being redeclared. |
| |
| FIXME: should the _nonreserved version be restricted to names being |
| redeclared only? The other entries there relate only the GNU extensions |
| and Objective C, and are historically parsed thus, and don't make sense |
| after other type specifiers, but it might be cleaner to count them as |
| _reserved. |
| |
| _attr means: specifiers that either end with attributes, |
| or are such that any following attributes would |
| be parsed as part of the specifier. |
| |
| _nonattr: other specifiers not ending with attributes. */ |
| |
| typespec_nonattr: |
| typespec_reserved_nonattr |
| | typespec_nonreserved_nonattr |
| ; |
| |
| typespec_attr: |
| typespec_reserved_attr |
| ; |
| |
| typespec_reserved_nonattr: |
| TYPESPEC |
| { OBJC_NEED_RAW_IDENTIFIER (1); |
| $$.kind = ctsk_resword; |
| $$.spec = $1; } |
| | structsp_nonattr |
| ; |
| |
| typespec_reserved_attr: |
| structsp_attr |
| ; |
| |
| typespec_nonreserved_nonattr: |
| TYPENAME |
| { /* For a typedef name, record the meaning, not the name. |
| In case of `foo foo, bar;'. */ |
| $$.kind = ctsk_typedef; |
| $$.spec = lookup_name ($1); } |
| @@ifobjc |
| | CLASSNAME protocolrefs |
| { $$.kind = ctsk_objc; |
| $$.spec = objc_get_protocol_qualified_type ($1, $2); } |
| | TYPENAME non_empty_protocolrefs |
| { $$.kind = ctsk_objc; |
| $$.spec = objc_get_protocol_qualified_type ($1, $2); } |
| |
| /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" |
| - nisse@lysator.liu.se */ |
| | non_empty_protocolrefs |
| { $$.kind = ctsk_objc; |
| $$.spec = objc_get_protocol_qualified_type (NULL_TREE, $1); } |
| @@end_ifobjc |
| | typeof '(' expr ')' |
| /* APPLE LOCAL begin mainline 2006-05-18 4336222 */ |
| { bool was_vm; |
| skip_evaluation--; |
| in_typeof--; |
| if (TREE_CODE ($3.value) == COMPONENT_REF |
| && DECL_C_BIT_FIELD (TREE_OPERAND ($3.value, 1))) |
| error ("%<typeof%> applied to a bit-field"); |
| $$.kind = ctsk_typeof; |
| $$.spec = TREE_TYPE ($3.value); |
| /* APPLE LOCAL begin radar 4204796 (in 4.2 n) */ |
| if (c_dialect_objc() |
| && lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES ($$.spec))) |
| $$.spec = build_qualified_type |
| ($$.spec, (TYPE_QUALS ($$.spec) & ~TYPE_QUAL_VOLATILE)); |
| /* APPLE LOCAL end radar 4204796 (in 4.2 n) */ |
| was_vm = variably_modified_type_p ($$.spec, NULL_TREE); |
| /* This should be returned with the type so that when the type |
| is evaluated, this can be evaluated. For now, we avoid |
| evaluation when the context might. */ |
| if (!skip_evaluation && was_vm) |
| c_finish_expr_stmt ($3.value); |
| pop_maybe_used (was_vm); } |
| /* APPLE LOCAL end mainline 2006-05-18 4336222 */ |
| | typeof '(' typename ')' |
| { skip_evaluation--; |
| in_typeof--; |
| $$.kind = ctsk_typeof; |
| $$.spec = groktypename ($3); |
| pop_maybe_used (variably_modified_type_p ($$.spec, |
| NULL_TREE)); } |
| ; |
| |
| /* typespec_nonreserved_attr does not exist. */ |
| |
| initdecls: |
| initdcl |
| | initdecls ',' maybe_resetattrs initdcl |
| ; |
| |
| notype_initdecls: |
| notype_initdcl |
| | notype_initdecls ',' maybe_resetattrs notype_initdcl |
| ; |
| |
| initdcl: |
| declarator maybeasm maybe_attribute '=' |
| { $<ttype>$ = start_decl ($1, current_declspecs, true, |
| chainon ($3, all_prefix_attributes)); |
| if (!$<ttype>$) |
| $<ttype>$ = error_mark_node; |
| start_init ($<ttype>$, $2, global_bindings_p ()); } |
| init |
| /* Note how the declaration of the variable is in effect while its init is parsed! */ |
| { finish_init (); |
| if ($<ttype>5 != error_mark_node) |
| { |
| maybe_warn_string_init (TREE_TYPE ($<ttype>5), $6); |
| finish_decl ($<ttype>5, $6.value, $2); |
| } |
| } |
| | declarator maybeasm maybe_attribute |
| { tree d = start_decl ($1, current_declspecs, false, |
| chainon ($3, all_prefix_attributes)); |
| if (d) |
| finish_decl (d, NULL_TREE, $2); |
| } |
| ; |
| |
| notype_initdcl: |
| notype_declarator maybeasm maybe_attribute '=' |
| { $<ttype>$ = start_decl ($1, current_declspecs, true, |
| chainon ($3, all_prefix_attributes)); |
| if (!$<ttype>$) |
| $<ttype>$ = error_mark_node; |
| start_init ($<ttype>$, $2, global_bindings_p ()); } |
| init |
| /* Note how the declaration of the variable is in effect while its init is parsed! */ |
| { finish_init (); |
| if ($<ttype>5 != error_mark_node) |
| { |
| maybe_warn_string_init (TREE_TYPE ($<ttype>5), $6); |
| finish_decl ($<ttype>5, $6.value, $2); |
| } |
| } |
| | notype_declarator maybeasm maybe_attribute |
| { tree d = start_decl ($1, current_declspecs, false, |
| chainon ($3, all_prefix_attributes)); |
| if (d) |
| finish_decl (d, NULL_TREE, $2); } |
| ; |
| /* the * rules are dummies to accept the Apollo extended syntax |
| so that the header files compile. */ |
| maybe_attribute: |
| /* empty */ |
| { $$ = NULL_TREE; } |
| | attributes |
| { $$ = $1; } |
| ; |
| |
| attributes: |
| attribute |
| { $$ = $1; } |
| | attributes attribute |
| { $$ = chainon ($1, $2); } |
| ; |
| |
| attribute: |
| ATTRIBUTE stop_string_translation |
| '(' '(' attribute_list ')' ')' start_string_translation |
| { $$ = $5; } |
| | ATTRIBUTE error start_string_translation |
| { $$ = NULL_TREE; } |
| ; |
| |
| attribute_list: |
| attrib |
| { $$ = $1; } |
| | attribute_list ',' attrib |
| { $$ = chainon ($1, $3); } |
| ; |
| |
| attrib: |
| /* empty */ |
| { $$ = NULL_TREE; } |
| | any_word |
| { $$ = build_tree_list ($1, NULL_TREE); } |
| | any_word '(' IDENTIFIER ')' |
| { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); } |
| | any_word '(' IDENTIFIER ',' nonnull_exprlist ')' |
| { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); } |
| | any_word '(' exprlist ')' |
| { $$ = build_tree_list ($1, $3); } |
| ; |
| |
| /* This still leaves out most reserved keywords, |
| shouldn't we include them? */ |
| |
| any_word: |
| identifier |
| | scspec |
| | TYPESPEC |
| | TYPE_QUAL |
| ; |
| |
| scspec: |
| STATIC |
| /* APPLE LOCAL CW asm blocks (in 4.2 ac) */ |
| | IASM_ASM_KEYWORD |
| | SCSPEC |
| ; |
| |
| /* Initializers. `init' is the entry point. */ |
| |
| init: |
| expr_no_commas |
| { $$ = $1; } |
| | '{' |
| { really_start_incremental_init (NULL_TREE); } |
| initlist_maybe_comma '}' |
| { $$ = pop_init_level (0); } |
| | error |
| { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } |
| ; |
| |
| /* `initlist_maybe_comma' is the guts of an initializer in braces. */ |
| initlist_maybe_comma: |
| /* empty */ |
| { if (pedantic) |
| pedwarn ("ISO C forbids empty initializer braces"); } |
| | initlist1 maybecomma |
| ; |
| |
| initlist1: |
| initelt |
| | initlist1 ',' initelt |
| ; |
| |
| /* `initelt' is a single element of an initializer. |
| It may use braces. */ |
| initelt: |
| designator_list '=' initval |
| { if (pedantic && !flag_isoc99) |
| pedwarn ("ISO C90 forbids specifying subobject to initialize"); } |
| | array_designator initval |
| { if (pedantic) |
| pedwarn ("obsolete use of designated initializer without %<=%>"); } |
| | identifier ':' |
| { set_init_label ($1); |
| if (pedantic) |
| pedwarn ("obsolete use of designated initializer with %<:%>"); } |
| initval |
| {} |
| | initval |
| ; |
| |
| initval: |
| '{' |
| { push_init_level (0); } |
| initlist_maybe_comma '}' |
| { process_init_element (pop_init_level (0)); } |
| | expr_no_commas |
| { process_init_element ($1); } |
| | error |
| ; |
| |
| designator_list: |
| designator |
| | designator_list designator |
| ; |
| |
| designator: |
| '.' identifier |
| { set_init_label ($2); } |
| | array_designator |
| ; |
| |
| array_designator: |
| '[' expr_no_commas ELLIPSIS expr_no_commas ']' |
| { set_init_index ($2.value, $4.value); |
| if (pedantic) |
| pedwarn ("ISO C forbids specifying range of elements to initialize"); } |
| | '[' expr_no_commas ']' |
| { set_init_index ($2.value, NULL_TREE); } |
| ; |
| |
| nested_function: |
| declarator |
| { if (pedantic) |
| pedwarn ("ISO C forbids nested functions"); |
| /* APPLE LOCAL begin nested functions 4258406 4357979 (in 4.2 m) */ |
| else if (flag_nested_functions == 0) |
| error ("nested functions are disabled, use -fnested-functions to re-enable"); |
| /* APPLE LOCAL end nested functions 4258406 4357979 (in 4.2 m) */ |
| |
| push_function_context (); |
| if (!start_function (current_declspecs, $1, |
| all_prefix_attributes)) |
| { |
| pop_function_context (); |
| YYERROR1; |
| } |
| } |
| old_style_parm_decls save_location |
| { tree decl = current_function_decl; |
| DECL_SOURCE_LOCATION (decl) = $4; |
| store_parm_decls (); } |
| /* This used to use compstmt_or_error. That caused a bug with |
| input `f(g) int g {}', where the use of YYERROR1 above caused |
| an error 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 |
| { tree decl = current_function_decl; |
| add_stmt ($6); |
| finish_function (); |
| pop_function_context (); |
| add_stmt (build_stmt (DECL_EXPR, decl)); } |
| ; |
| |
| notype_nested_function: |
| notype_declarator |
| { if (pedantic) |
| pedwarn ("ISO C forbids nested functions"); |
| /* APPLE LOCAL begin nested functions 4258406 4357979 (in 4.2 m) */ |
| else if (flag_nested_functions == 0) |
| error ("nested functions are disabled, use -fnested-functions to re-enable"); |
| /* APPLE LOCAL end nested functions 4258406 4357979 (in 4.2 m) */ |
| |
| push_function_context (); |
| if (!start_function (current_declspecs, $1, |
| all_prefix_attributes)) |
| { |
| pop_function_context (); |
| YYERROR1; |
| } |
| } |
| old_style_parm_decls save_location |
| { tree decl = current_function_decl; |
| DECL_SOURCE_LOCATION (decl) = $4; |
| store_parm_decls (); } |
| /* This used to use compstmt_or_error. That caused a bug with |
| input `f(g) int g {}', where the use of YYERROR1 above caused |
| an error 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 |
| { tree decl = current_function_decl; |
| add_stmt ($6); |
| finish_function (); |
| pop_function_context (); |
| add_stmt (build_stmt (DECL_EXPR, decl)); } |
| ; |
| |
| /* Any kind of declarator (thus, all declarators allowed |
| after an explicit typespec). */ |
| |
| declarator: |
| after_type_declarator |
| | notype_declarator |
| ; |
| |
| /* A declarator that is allowed only after an explicit typespec. */ |
| |
| after_type_declarator: |
| '(' maybe_attribute after_type_declarator ')' |
| { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } |
| | after_type_declarator '(' parmlist_or_identifiers %prec '.' |
| { $$ = build_function_declarator ($3, $1); } |
| | after_type_declarator array_declarator %prec '.' |
| { $$ = set_array_declarator_inner ($2, $1, false); } |
| | '*' maybe_type_quals_attrs after_type_declarator %prec UNARY |
| { $$ = make_pointer_declarator ($2, $3); } |
| | TYPENAME |
| { $$ = build_id_declarator ($1); } |
| /* APPLE LOCAL begin radar 4281748 */ |
| @@ifobjc |
| | CLASSNAME |
| { $$ = build_id_declarator ($1); } |
| @@end_ifobjc |
| /* APPLE LOCAL end radar 4281748 */ |
| ; |
| |
| /* Kinds of declarator that can appear in a parameter list |
| in addition to notype_declarator. This is like after_type_declarator |
| but does not allow a typedef name in parentheses as an identifier |
| (because it would conflict with a function with that typedef as arg). */ |
| parm_declarator: |
| parm_declarator_starttypename |
| | parm_declarator_nostarttypename |
| ; |
| |
| parm_declarator_starttypename: |
| parm_declarator_starttypename '(' parmlist_or_identifiers %prec '.' |
| { $$ = build_function_declarator ($3, $1); } |
| | parm_declarator_starttypename array_declarator %prec '.' |
| { $$ = set_array_declarator_inner ($2, $1, false); } |
| | TYPENAME |
| { $$ = build_id_declarator ($1); } |
| ; |
| |
| parm_declarator_nostarttypename: |
| parm_declarator_nostarttypename '(' parmlist_or_identifiers %prec '.' |
| { $$ = build_function_declarator ($3, $1); } |
| | parm_declarator_nostarttypename array_declarator %prec '.' |
| { $$ = set_array_declarator_inner ($2, $1, false); } |
| | '*' maybe_type_quals_attrs parm_declarator_starttypename %prec UNARY |
| { $$ = make_pointer_declarator ($2, $3); } |
| | '*' maybe_type_quals_attrs parm_declarator_nostarttypename %prec UNARY |
| { $$ = make_pointer_declarator ($2, $3); } |
| | '(' maybe_attribute parm_declarator_nostarttypename ')' |
| { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } |
| ; |
| |
| /* A declarator allowed whether or not there has been |
| an explicit typespec. These cannot redeclare a typedef-name. */ |
| |
| notype_declarator: |
| notype_declarator '(' parmlist_or_identifiers %prec '.' |
| { $$ = build_function_declarator ($3, $1); } |
| | '(' maybe_attribute notype_declarator ')' |
| { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } |
| | '*' maybe_type_quals_attrs notype_declarator %prec UNARY |
| { $$ = make_pointer_declarator ($2, $3); } |
| | notype_declarator array_declarator %prec '.' |
| { $$ = set_array_declarator_inner ($2, $1, false); } |
| | IDENTIFIER |
| { $$ = build_id_declarator ($1); } |
| ; |
| |
| struct_head: |
| STRUCT |
| { $$ = NULL_TREE; } |
| | STRUCT attributes |
| { $$ = $2; } |
| ; |
| |
| union_head: |
| UNION |
| { $$ = NULL_TREE; } |
| | UNION attributes |
| { $$ = $2; } |
| ; |
| |
| enum_head: |
| ENUM |
| { $$ = NULL_TREE; } |
| | ENUM attributes |
| { $$ = $2; } |
| ; |
| |
| /* structsp_attr: struct/union/enum specifiers that either |
| end with attributes, or are such that any following attributes would |
| be parsed as part of the struct/union/enum specifier. |
| |
| structsp_nonattr: other struct/union/enum specifiers. */ |
| |
| structsp_attr: |
| struct_head identifier '{' |
| { $<ttype>$ = start_struct (RECORD_TYPE, $2); |
| /* Start scope of tag before parsing components. */ |
| } |
| component_decl_list '}' maybe_attribute |
| { $$.spec = finish_struct ($<ttype>4, nreverse ($5), |
| chainon ($1, $7)); |
| $$.kind = ctsk_tagdef; } |
| | struct_head '{' component_decl_list '}' maybe_attribute |
| { $$.spec = finish_struct (start_struct (RECORD_TYPE, |
| NULL_TREE), |
| nreverse ($3), chainon ($1, $5)); |
| $$.kind = ctsk_tagdef; |
| } |
| | union_head identifier '{' |
| { $<ttype>$ = start_struct (UNION_TYPE, $2); } |
| component_decl_list '}' maybe_attribute |
| { $$.spec = finish_struct ($<ttype>4, nreverse ($5), |
| chainon ($1, $7)); |
| $$.kind = ctsk_tagdef; } |
| | union_head '{' component_decl_list '}' maybe_attribute |
| { $$.spec = finish_struct (start_struct (UNION_TYPE, |
| NULL_TREE), |
| nreverse ($3), chainon ($1, $5)); |
| $$.kind = ctsk_tagdef; |
| } |
| | enum_head identifier '{' |
| { $<ttype>$ = start_enum ($2); } |
| enumlist maybecomma_warn '}' maybe_attribute |
| { $$.spec = finish_enum ($<ttype>4, nreverse ($5), |
| chainon ($1, $8)); |
| $$.kind = ctsk_tagdef; } |
| | enum_head '{' |
| { $<ttype>$ = start_enum (NULL_TREE); } |
| enumlist maybecomma_warn '}' maybe_attribute |
| { $$.spec = finish_enum ($<ttype>3, nreverse ($4), |
| chainon ($1, $7)); |
| $$.kind = ctsk_tagdef; } |
| ; |
| |
| structsp_nonattr: |
| struct_head identifier |
| { $$ = parser_xref_tag (RECORD_TYPE, $2); } |
| | union_head identifier |
| { $$ = parser_xref_tag (UNION_TYPE, $2); } |
| | enum_head identifier |
| { $$ = parser_xref_tag (ENUMERAL_TYPE, $2); |
| /* In ISO C, enumerated types can be referred to |
| only if already defined. */ |
| if (pedantic && !COMPLETE_TYPE_P ($$.spec)) |
| pedwarn ("ISO C forbids forward references to %<enum%> types"); } |
| ; |
| |
| maybecomma: |
| /* empty */ |
| | ',' |
| ; |
| |
| maybecomma_warn: |
| /* empty */ |
| | ',' |
| { if (pedantic && !flag_isoc99) |
| 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 ($2, $1); |
| pedwarn ("no semicolon at end of struct or union"); } |
| ; |
| |
| component_decl_list2: /* empty */ |
| { $$ = NULL_TREE; } |
| | component_decl_list2 component_decl ';' |
| { $$ = chainon ($2, $1); } |
| | component_decl_list2 ';' |
| { if (pedantic) |
| pedwarn ("extra semicolon in struct or union specified"); } |
| @@ifobjc |
| /* foo(sizeof(struct{ @defs(ClassName)})); */ |
| | AT_DEFS '(' CLASSNAME ')' |
| /* APPLE LOCAL begin C* warnings to easy porting to new abi */ |
| { $$ = nreverse (objc_get_class_ivars ($3)); |
| if (flag_objc2_check && flag_objc_abi == 1) |
| warning ("@defs will not be supported in future"); |
| /* APPLE LOCAL radar 4705250 */ |
| else if (flag_objc_abi == 2 && flag_objc_atdefs != 1) |
| error ("@defs is not supported in new abi"); |
| } |
| /* APPLE LOCAL end C* warnings to easy porting to new abi */ |
| @@end_ifobjc |
| ; |
| |
| component_decl: |
| declspecs_nosc_ts setspecs components |
| { $$ = $3; |
| POP_DECLSPEC_STACK; } |
| | declspecs_nosc_ts setspecs |
| { |
| /* Support for unnamed structs or unions as members of |
| structs or unions (which is [a] useful and [b] supports |
| MS P-SDK). */ |
| $$ = grokfield (build_id_declarator (NULL_TREE), |
| current_declspecs, NULL_TREE); |
| POP_DECLSPEC_STACK; } |
| | declspecs_nosc_nots setspecs components_notype |
| { $$ = $3; |
| POP_DECLSPEC_STACK; } |
| | declspecs_nosc_nots |
| { if (pedantic) |
| pedwarn ("ISO C forbids member declarations with no members"); |
| shadow_tag_warned (finish_declspecs ($1), pedantic); |
| $$ = NULL_TREE; } |
| | error |
| { $$ = NULL_TREE; } |
| | extension component_decl |
| { $$ = $2; |
| RESTORE_EXT_FLAGS ($1); } |
| ; |
| |
| components: |
| component_declarator |
| | components ',' maybe_resetattrs component_declarator |
| { TREE_CHAIN ($4) = $1; $$ = $4; } |
| ; |
| |
| components_notype: |
| component_notype_declarator |
| | components_notype ',' maybe_resetattrs component_notype_declarator |
| { TREE_CHAIN ($4) = $1; $$ = $4; } |
| ; |
| |
| component_declarator: |
| declarator maybe_attribute |
| { $$ = grokfield ($1, current_declspecs, NULL_TREE); |
| decl_attributes (&$$, |
| chainon ($2, all_prefix_attributes), 0); } |
| | declarator ':' expr_no_commas maybe_attribute |
| { $$ = grokfield ($1, current_declspecs, $3.value); |
| decl_attributes (&$$, |
| chainon ($4, all_prefix_attributes), 0); } |
| | ':' expr_no_commas maybe_attribute |
| { $$ = grokfield (build_id_declarator (NULL_TREE), |
| current_declspecs, $2.value); |
| decl_attributes (&$$, |
| chainon ($3, all_prefix_attributes), 0); } |
| ; |
| |
| component_notype_declarator: |
| notype_declarator maybe_attribute |
| { $$ = grokfield ($1, current_declspecs, NULL_TREE); |
| decl_attributes (&$$, |
| chainon ($2, all_prefix_attributes), 0); } |
| | notype_declarator ':' expr_no_commas maybe_attribute |
| { $$ = grokfield ($1, current_declspecs, $3.value); |
| decl_attributes (&$$, |
| chainon ($4, all_prefix_attributes), 0); } |
| | ':' expr_no_commas maybe_attribute |
| { $$ = grokfield (build_id_declarator (NULL_TREE), |
| current_declspecs, $2.value); |
| decl_attributes (&$$, |
| chainon ($3, all_prefix_attributes), 0); } |
| ; |
| |
| /* We chain the enumerators in reverse order. |
| They are put in forward order in structsp_attr. */ |
| |
| enumlist: |
| enumerator |
| | enumlist ',' enumerator |
| { if ($1 == error_mark_node) |
| $$ = $1; |
| else |
| TREE_CHAIN ($3) = $1, $$ = $3; } |
| | error |
| { $$ = error_mark_node; } |
| ; |
| |
| |
| enumerator: |
| identifier |
| { $$ = build_enumerator ($1, NULL_TREE); } |
| | identifier '=' expr_no_commas |
| { $$ = build_enumerator ($1, $3.value); } |
| ; |
| |
| typename: |
| declspecs_nosc |
| { pending_xref_error (); |
| $<dsptype>$ = finish_declspecs ($1); } |
| absdcl |
| { $$ = XOBNEW (&parser_obstack, struct c_type_name); |
| $$->specs = $<dsptype>2; |
| $$->declarator = $3; } |
| ; |
| |
| absdcl: /* an absolute declarator */ |
| /* empty */ |
| { $$ = build_id_declarator (NULL_TREE); } |
| | absdcl1 |
| ; |
| |
| absdcl_maybe_attribute: /* absdcl maybe_attribute, but not just attributes */ |
| /* empty */ |
| { $$ = build_c_parm (current_declspecs, all_prefix_attributes, |
| build_id_declarator (NULL_TREE)); } |
| | absdcl1 |
| { $$ = build_c_parm (current_declspecs, all_prefix_attributes, |
| $1); } |
| | absdcl1_noea attributes |
| { $$ = build_c_parm (current_declspecs, |
| chainon ($2, all_prefix_attributes), |
| $1); } |
| ; |
| |
| absdcl1: /* a nonempty absolute declarator */ |
| absdcl1_ea |
| | absdcl1_noea |
| ; |
| |
| absdcl1_noea: |
| direct_absdcl1 |
| | '*' maybe_type_quals_attrs absdcl1_noea |
| { $$ = make_pointer_declarator ($2, $3); } |
| ; |
| |
| absdcl1_ea: |
| '*' maybe_type_quals_attrs |
| { $$ = make_pointer_declarator |
| ($2, build_id_declarator (NULL_TREE)); } |
| | '*' maybe_type_quals_attrs absdcl1_ea |
| { $$ = make_pointer_declarator ($2, $3); } |
| ; |
| |
| direct_absdcl1: |
| '(' maybe_attribute absdcl1 ')' |
| { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } |
| | direct_absdcl1 '(' parmlist |
| { $$ = build_function_declarator ($3, $1); } |
| | direct_absdcl1 array_declarator |
| { $$ = set_array_declarator_inner ($2, $1, true); } |
| | '(' parmlist |
| { $$ = build_function_declarator |
| ($2, build_id_declarator (NULL_TREE)); } |
| | array_declarator |
| { $$ = set_array_declarator_inner |
| ($1, build_id_declarator (NULL_TREE), true); } |
| ; |
| |
| /* The [...] part of a declarator for an array type. */ |
| |
| array_declarator: |
| '[' maybe_type_quals_attrs expr_no_commas ']' |
| { $$ = build_array_declarator ($3.value, $2, false, false); } |
| | '[' maybe_type_quals_attrs ']' |
| { $$ = build_array_declarator (NULL_TREE, $2, false, false); } |
| | '[' maybe_type_quals_attrs '*' ']' |
| { $$ = build_array_declarator (NULL_TREE, $2, false, true); } |
| | '[' STATIC maybe_type_quals_attrs expr_no_commas ']' |
| { $$ = build_array_declarator ($4.value, $3, true, false); } |
| /* declspecs_nosc_nots is a synonym for type_quals_attrs. */ |
| | '[' declspecs_nosc_nots STATIC expr_no_commas ']' |
| { $$ = build_array_declarator ($4.value, $2, true, false); } |
| ; |
| |
| /* A nonempty series of declarations and statements (possibly followed by |
| some labels) that can form the body of a compound statement. |
| NOTE: we don't allow labels on declarations; this might seem like a |
| natural extension, but there would be a conflict between attributes |
| on the label and prefix attributes on the declaration. */ |
| |
| stmts_and_decls: |
| lineno_stmt_decl_or_labels_ending_stmt |
| | lineno_stmt_decl_or_labels_ending_decl |
| | lineno_stmt_decl_or_labels_ending_label |
| { |
| error ("label at end of compound statement"); |
| } |
| | lineno_stmt_decl_or_labels_ending_error |
| ; |
| |
| lineno_stmt_decl_or_labels_ending_stmt: |
| lineno_stmt |
| | lineno_stmt_decl_or_labels_ending_stmt lineno_stmt |
| | lineno_stmt_decl_or_labels_ending_decl lineno_stmt |
| | lineno_stmt_decl_or_labels_ending_label lineno_stmt |
| | lineno_stmt_decl_or_labels_ending_error lineno_stmt |
| ; |
| |
| lineno_stmt_decl_or_labels_ending_decl: |
| lineno_decl |
| | lineno_stmt_decl_or_labels_ending_stmt lineno_decl |
| { |
| if ((pedantic && !flag_isoc99) |
| || warn_declaration_after_statement) |
| pedwarn_c90 ("ISO C90 forbids mixed declarations and code"); |
| } |
| | lineno_stmt_decl_or_labels_ending_decl lineno_decl |
| | lineno_stmt_decl_or_labels_ending_error lineno_decl |
| ; |
| |
| lineno_stmt_decl_or_labels_ending_label: |
| lineno_label |
| | lineno_stmt_decl_or_labels_ending_stmt lineno_label |
| | lineno_stmt_decl_or_labels_ending_decl lineno_label |
| | lineno_stmt_decl_or_labels_ending_label lineno_label |
| | lineno_stmt_decl_or_labels_ending_error lineno_label |
| ; |
| |
| lineno_stmt_decl_or_labels_ending_error: |
| errstmt |
| | lineno_stmt_decl_or_labels errstmt |
| ; |
| |
| lineno_stmt_decl_or_labels: |
| lineno_stmt_decl_or_labels_ending_stmt |
| | lineno_stmt_decl_or_labels_ending_decl |
| | lineno_stmt_decl_or_labels_ending_label |
| | lineno_stmt_decl_or_labels_ending_error |
| ; |
| |
| errstmt: error ';' |
| ; |
| |
| /* Start and end blocks created for the new scopes of C99. */ |
| c99_block_start: /* empty */ |
| /* APPLE LOCAL begin radar 4472881 (in 4.2 ah) */ |
| { $$ = c_begin_compound_stmt ( |
| flag_isoc99 |
| || (c_dialect_objc() && objc_foreach_context)); } |
| /* APPLE LOCAL end radar 4472881 (in 4.2 ah) */ |
| ; |
| |
| /* Read zero or more forward-declarations for labels |
| that nested functions can jump to. */ |
| maybe_label_decls: |
| /* empty */ |
| | label_decls |
| { if (pedantic) |
| pedwarn ("ISO C forbids label declarations"); } |
| ; |
| |
| label_decls: |
| label_decl |
| | label_decls label_decl |
| ; |
| |
| label_decl: |
| LABEL identifiers_or_typenames ';' |
| { tree link; |
| for (link = $2; link; link = TREE_CHAIN (link)) |
| { |
| tree label = declare_label (TREE_VALUE (link)); |
| C_DECLARED_LABEL_FLAG (label) = 1; |
| add_stmt (build_stmt (DECL_EXPR, label)); |
| } |
| } |
| ; |
| |
| /* This is the body of a function definition. |
| It causes syntax errors to ignore to the next openbrace. */ |
| compstmt_or_error: |
| compstmt |
| { add_stmt ($1); } |
| | error compstmt |
| ; |
| |
| compstmt_start: '{' { $$ = c_begin_compound_stmt (true); } |
| ; |
| |
| compstmt_nostart: '}' |
| | maybe_label_decls compstmt_contents_nonempty '}' |
| /* APPLE LOCAL begin CW asm blocks (in 4.2 am) */ |
| { |
| if (flag_iasm_blocks) |
| iasm_end_block (); |
| } |
| /* APPLE LOCAL end CW asm blocks */ |
| ; |
| |
| compstmt_contents_nonempty: |
| stmts_and_decls |
| | error |
| ; |
| |
| compstmt_primary_start: |
| '(' '{' |
| { if (cur_stmt_list == NULL) |
| { |
| error ("braced-group within expression allowed " |
| "only inside a function"); |
| YYERROR; |
| } |
| $$ = c_begin_stmt_expr (); |
| } |
| ; |
| |
| compstmt: compstmt_start compstmt_nostart |
| { $$ = c_end_compound_stmt ($1, true); } |
| ; |
| |
| /* APPLE LOCAL begin CW asm blocks */ |
| /* (in 4.2 ax) */ |
| iasm_save_location: save_location |
| { iasm_lineno = input_line; } |
| ; |
| |
| /* (in 4.2 au) */ |
| /* A CW-style asm statement is recognized by having a BOL token preceding it. */ |
| iasm_stmt: IASM_BOL iasm_save_location iasm_stmt_list IASM_EOL |
| { $$ = NULL_TREE; } |
| ; |
| |
| /* (in 4.2 ay) */ |
| iasm_stmt_nobol: iasm_save_location iasm_stmt_list IASM_EOL |
| { |
| $$ = NULL_TREE; |
| iasm_state = iasm_none; |
| iasm_at_bol = false; |
| } |
| ; |
| |
| /* (in 4.2 ap) */ |
| /* A single line may have multiple statements separated by ';'. */ |
| iasm_stmt_list: |
| /* empty */ |
| | single_iasm_stmt |
| {} |
| | iasm_stmt_list ';' iasm_maybe_comment single_iasm_stmt |
| | iasm_stmt_list ';' iasm_maybe_comment |
| | iasm_stmt_list ASM_KEYWORD |
| | iasm_stmt_list ASM_KEYWORD single_iasm_stmt |
| ; |
| |
| /* (in 4.2 ao) */ |
| iasm_maybe_comment: |
| { |
| if (flag_ms_asms) |
| { |
| iasm_skip_to_eol (); |
| yychar = YYEMPTY; |
| } |
| } |
| ; |
| |
| /* (in 4.2 aq) */ |
| iasm_identifier: |
| iasm_identifier1 ' ' |
| { $$ = $1; } |
| | iasm_identifier1 |
| { $$ = $1; iasm_split_next = 0; } |
| ; |
| |
| /* (in 4.2 aq) */ |
| iasm_identifier1: |
| identifier |
| { |
| if (iasm_split_next && |
| (yychar == '.' |
| || yychar == '+' |
| || yychar == '-')) |
| { |
| iasm_insert_saved_token (); |
| yychar = ' '; |
| } |
| } |
| | iasm_identifier1 '.' |
| { $$ = iasm_get_identifier ($1, "."); } |
| | iasm_identifier1 '+' |
| { $$ = iasm_get_identifier ($1, "+"); } |
| | iasm_identifier1 '-' |
| { $$ = iasm_get_identifier ($1, "-"); } |
| | '.' identifier |
| { $$ = prepend_char_identifier ($2, '.'); } |
| ; |
| |
| /* (in 4.2 an) */ |
| iasm_maybe_prefix: |
| iasm_identifier |
| { $$ = c_parse_iasm_maybe_prefix ($1); } |
| ; |
| |
| /* (in 4.2 ar) */ |
| /* A single statement consists of one or more labels (identified by a |
| leading '@' and/or a trailing ':'), optionally followed by opcode |
| and operands. */ |
| single_iasm_stmt: |
| iasm_maybe_prefix |
| { iasm_in_operands = true; } |
| iasm_operands |
| { $$ = iasm_stmt ($1, $3, iasm_lineno); } |
| | identifier STATIC iasm_operand |
| { $$ = iasm_entry ($1, $2, $3.value); } |
| | identifier SCSPEC iasm_operand |
| { $$ = iasm_entry ($1, $2, $3.value); } |
| | iasm_label |
| {} |
| | iasm_label single_iasm_stmt |
| {} |
| ; |
| |
| /* (in 4.2 ar) */ |
| iasm_label: |
| identifier ':' |
| { iasm_label ($1, 0); } |
| | '@' identifier |
| { iasm_label ($2, 1); } |
| | '@' identifier ':' |
| { iasm_label ($2, 1); } |
| | '@' CONSTANT |
| { iasm_label ($2, 1); } |
| | '@' CONSTANT ':' |
| { iasm_label ($2, 1); } |
| ; |
| |
| /* (in 4.2 au) */ |
| iasm_stmts: |
| stmt |
| {} |
| | iasm_stmts stmt |
| {} |
| ; |
| |
| /* (in 4.2 as) */ |
| /* (in 4.2 at) */ |
| /* An asm block within a function is simpler than asm functions; no |
| declarations are possible, so we switch to the block interior state |
| immediately. */ |
| iasm_compstmt_start: ASM_KEYWORD '{' |
| { |
| if (flag_iasm_blocks) |
| { |
| iasm_state = iasm_asm; |
| inside_iasm_block = true; |
| iasm_at_bol = true; |
| iasm_clear_labels (); |
| } |
| else |
| /* This will probably choke badly... */ |
| error ("asm blocks not enabled, use `-fasm-blocks'"); |
| $$ = c_begin_compound_stmt (true); |
| } |
| ; |
| |
| iasm_compstmt: ASM_KEYWORD |
| { |
| if (flag_iasm_blocks) |
| { |
| iasm_state = iasm_asm; |
| inside_iasm_block = true; |
| iasm_clear_labels (); |
| if (yychar == ';' && flag_ms_asms) |
| { |
| iasm_skip_to_eol (); |
| yychar = YYEMPTY; |
| } |
| yychar = IASM_SEE_OPCODE (yychar, yylval.ttype); |
| } |
| else |
| /* This will probably choke badly... */ |
| error ("asm blocks not enabled, use `-fasm-blocks'"); |
| $<ttype>$ = c_begin_compound_stmt (true); |
| } |
| iasm_stmt_nobol |
| { |
| $$ = c_finish_expr_stmt ($3); |
| iasm_end_block (); |
| $<ttype>$ = c_end_compound_stmt ($<ttype>2, true); |
| } |
| ; |
| |
| /* (in 4.2 aw) */ |
| iasm_compstmt_nostart: |
| '}' |
| | iasm_compstmt_contents_nonempty '}' |
| { |
| iasm_end_block (); |
| } |
| ; |
| |
| /* (in 4.2 au) */ |
| iasm_compstmt_contents_nonempty: |
| iasm_stmts |
| | error |
| ; |
| |
| /* (in 4.2 av) */ |
| iasm_compstmt: iasm_compstmt_start iasm_compstmt_nostart |
| { $$ = c_end_compound_stmt ($1, true); } |
| ; |
| |
| /* (in 4.2 az) */ |
| iasm_operands: |
| /* empty */ |
| { $$ = NULL_TREE; } |
| | iasm_nonnull_operands |
| ; |
| |
| /* (in 4.2 az) */ |
| iasm_nonnull_operands: |
| iasm_operand |
| { $$ = build_tree_list (NULL_TREE, $1.value); } |
| | iasm_nonnull_operands ',' iasm_operand |
| { $$ = chainon ($1, build_tree_list (NULL_TREE, $3.value)); } |
| ; |
| |
| /* Alternatively this could go to the regular expr_no_commas, but then |
| all the semantic actions would need to be tweaked to handle the |
| possibility of CW asm coming through. For example, "offset(reg)" |
| would be handled by function call code (bleah). */ |
| iasm_operand: iasm_expr_no_commas |
| | iasm_operand '(' iasm_expr_no_commas ')' |
| { $$.value = iasm_build_register_offset ($1.value, $3.value); |
| $$.original_code = ERROR_MARK; } |
| ; |
| /* APPLE LOCAL end CW asm blocks */ |
| |
| /* The forced readahead in here is because we might be at the end of a |
| line, and the line and file won't be bumped until yylex absorbs the |
| first token on the next line. */ |
| |
| save_location: |
| { if (yychar == YYEMPTY) |
| yychar = YYLEX; |
| $$ = input_location; } |
| ; |
| |
| lineno_labels: |
| /* empty */ |
| | lineno_labels lineno_label |
| ; |
| |
| /* A labeled statement. In C99 it also generates an implicit block. */ |
| c99_block_lineno_labeled_stmt: |
| c99_block_start lineno_labels lineno_stmt |
| /* APPLE LOCAL begin radar 4502236 */ |
| { $$ = c_end_compound_stmt ($1, |
| flag_isoc99 |
| || (c_dialect_objc() && objc_foreach_context)); } |
| /* APPLE LOCAL end radar 4502236 */ |
| ; |
| |
| lineno_stmt: |
| save_location stmt |
| { |
| /* Two cases cannot and do not have line numbers associated: |
| If stmt is degenerate, such as "2;", then stmt is an |
| INTEGER_CST, which cannot hold line numbers. But that's |
| ok because the statement will either be changed to a |
| MODIFY_EXPR during gimplification of the statement expr, |
| or discarded. If stmt was compound, but without new |
| variables, we will have skipped the creation of a BIND |
| and will have a bare STATEMENT_LIST. But that's ok |
| because (recursively) all of the component statments |
| should already have line numbers assigned. */ |
| if ($2 && EXPR_P ($2)) |
| SET_EXPR_LOCATION ($2, $1); |
| } |
| ; |
| |
| lineno_label: |
| save_location label |
| { if ($2) SET_EXPR_LOCATION ($2, $1); } |
| ; |
| |
| condition: save_location expr |
| { $$ = lang_hooks.truthvalue_conversion ($2.value); |
| if (EXPR_P ($$)) |
| SET_EXPR_LOCATION ($$, $1); } |
| ; |
| |
| /* Implement -Wparenthesis by special casing IF statement directly nested |
| within IF statement. This requires some amount of duplication of the |
| productions under c99_block_lineno_labeled_stmt in order to work out. |
| But it's still likely more maintainable than lots of state outside the |
| parser... */ |
| |
| if_statement_1: |
| c99_block_start lineno_labels if_statement |
| { $$ = c_end_compound_stmt ($1, flag_isoc99); } |
| ; |
| |
| if_statement_2: |
| c99_block_start lineno_labels ';' |
| { if (extra_warnings) |
| add_stmt (build (NOP_EXPR, NULL_TREE, NULL_TREE)); |
| $$ = c_end_compound_stmt ($1, flag_isoc99); } |
| | c99_block_lineno_labeled_stmt |
| ; |
| |
| if_statement: |
| IF c99_block_start save_location '(' condition ')' |
| if_statement_1 ELSE if_statement_2 |
| { c_finish_if_stmt ($3, $5, $7, $9, true); |
| add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } |
| | IF c99_block_start save_location '(' condition ')' |
| if_statement_2 ELSE if_statement_2 |
| { c_finish_if_stmt ($3, $5, $7, $9, false); |
| add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } |
| | IF c99_block_start save_location '(' condition ')' |
| if_statement_1 %prec IF |
| { c_finish_if_stmt ($3, $5, $7, NULL, true); |
| add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } |
| | IF c99_block_start save_location '(' condition ')' |
| if_statement_2 %prec IF |
| { c_finish_if_stmt ($3, $5, $7, NULL, false); |
| add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } |
| ; |
| |
| start_break: /* empty */ |
| { $$ = c_break_label; c_break_label = NULL; } |
| ; |
| |
| start_continue: /* empty */ |
| { $$ = c_cont_label; c_cont_label = NULL; } |
| ; |
| |
| while_statement: |
| WHILE c99_block_start save_location '(' condition ')' |
| start_break start_continue c99_block_lineno_labeled_stmt |
| { c_finish_loop ($3, $5, NULL, $9, c_break_label, |
| c_cont_label, true); |
| add_stmt (c_end_compound_stmt ($2, flag_isoc99)); |
| c_break_label = $7; c_cont_label = $8; } |
| ; |
| |
| do_statement: |
| DO c99_block_start save_location start_break start_continue |
| c99_block_lineno_labeled_stmt WHILE |
| { $<ttype>$ = c_break_label; c_break_label = $4; } |
| { $<ttype>$ = c_cont_label; c_cont_label = $5; } |
| '(' condition ')' ';' |
| { c_finish_loop ($3, $11, NULL, $6, $<ttype>8, |
| $<ttype>9, false); |
| add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } |
| ; |
| |
| xexpr: |
| /* empty */ |
| { $$ = NULL_TREE; } |
| | expr |
| { $$ = $1.value; } |
| ; |
| |
| /* APPLE LOCAL begin C* language (in 4.2 aj) */ |
| for_init_stmt: |
| xexpr ';' |
| { objc_foreach_context = 0; c_finish_expr_stmt ($1); } |
| | decl |
| { objc_foreach_context = 0; check_for_loop_decls (); } |
| ; |
| /* APPLE LOCAL end C* language (in 4.2 aj) */ |
| |
| for_cond_expr: save_location xexpr |
| { if ($2) |
| { |
| $$ = lang_hooks.truthvalue_conversion ($2); |
| if (EXPR_P ($$)) |
| SET_EXPR_LOCATION ($$, $1); |
| } |
| else |
| $$ = NULL; |
| } |
| ; |
| |
| for_incr_expr: xexpr |
| { $$ = c_process_expr_stmt ($1); } |
| ; |
| |
| /* APPLE LOCAL begin C* language */ |
| @@ifobjc |
| for_objc_collection: |
| declspecs_ts setspecs declarator maybeasm maybe_attribute AT_IN |
| { objc_foreach_context = 0; |
| $<ttype>$ = start_decl ($3, current_declspecs, true, |
| chainon ($5, all_prefix_attributes)); |
| if (!$<ttype>$) |
| $<ttype>$ = error_mark_node; |
| start_init ($<ttype>$, $4, global_bindings_p ()); } |
| init |
| /* APPLE LOCAL begin radar 4472881 */ |
| { int save_flag_isoc99 = flag_isoc99; |
| finish_init (); |
| $$ = build_tree_list ($<ttype>7, $8.value); |
| POP_DECLSPEC_STACK; |
| flag_isoc99 = 1; |
| check_for_loop_decls (); |
| flag_isoc99 = save_flag_isoc99; |
| } |
| /* APPLE LOCAL end radar 4472881 */ |
| | expr AT_IN init |
| { |
| /* APPLE LOCAL radar 4550582 */ |
| objc_foreach_context = 0; |
| $$ = build_tree_list ($1.value, $3.value); |
| } |
| ; |
| @@end_ifobjc |
| |
| /* APPLE LOCAL radar 4472881 (in 4.2 u) */ |
| for_keyword: FOR |
| {objc_foreach_context = 1;} |
| ; |
| |
| for_statement: |
| for_keyword c99_block_start '(' for_init_stmt |
| /* APPLE LOCAL end C* language */ |
| save_location for_cond_expr ';' for_incr_expr ')' |
| start_break start_continue c99_block_lineno_labeled_stmt |
| { c_finish_loop ($5, $6, $8, $12, c_break_label, |
| c_cont_label, true); |
| /* APPLE LOCAL radar 4472881 (in 4.2 ai) */ |
| add_stmt (c_end_compound_stmt ($2, flag_isoc99 || c_dialect_objc ())); |
| c_break_label = $10; c_cont_label = $11; } |
| |
| /* APPLE LOCAL begin C* language */ |
| @@ifobjc |
| | for_keyword c99_block_start '(' for_objc_collection save_location ')' |
| start_break start_continue c99_block_lineno_labeled_stmt |
| { objc_finish_foreach_loop ($5, $4, $9, c_break_label, c_cont_label); |
| /* APPLE LOCAL radar 4472881 */ |
| add_stmt (c_end_compound_stmt ($2, 1)); |
| c_break_label = $7; c_cont_label = $8; |
| } |
| @@end_ifobjc |
| ; |
| /* APPLE LOCAL end C* language */ |
| |
| switch_statement: |
| SWITCH c99_block_start '(' expr ')' |
| { $<ttype>$ = c_start_case ($4.value); } |
| start_break c99_block_lineno_labeled_stmt |
| { c_finish_case ($8); |
| if (c_break_label) |
| add_stmt (build (LABEL_EXPR, void_type_node, |
| c_break_label)); |
| c_break_label = $7; |
| add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } |
| ; |
| |
| /* Parse a single real statement, not including any labels or compounds. */ |
| stmt_nocomp: |
| expr ';' |
| { $$ = c_finish_expr_stmt ($1.value); } |
| | if_statement |
| { $$ = NULL_TREE; } |
| | while_statement |
| { $$ = NULL_TREE; } |
| | do_statement |
| { $$ = NULL_TREE; } |
| | for_statement |
| { $$ = NULL_TREE; } |
| | switch_statement |
| { $$ = NULL_TREE; } |
| /* APPLE LOCAL begin CW asm blocks */ |
| /* (in 4.2 as) */ |
| | iasm_compstmt |
| { $$ = c_finish_expr_stmt ($1); } |
| | iasm_stmt |
| { $$ = c_finish_expr_stmt ($1); } |
| /* APPLE LOCAL end CW asm blocks */ |
| | BREAK ';' |
| { $$ = c_finish_bc_stmt (&c_break_label, true); } |
| | CONTINUE ';' |
| { $$ = c_finish_bc_stmt (&c_cont_label, false); } |
| | RETURN ';' |
| { $$ = c_finish_return (NULL_TREE); } |
| | RETURN expr ';' |
| { $$ = c_finish_return ($2.value); } |
| | asm_stmt |
| | GOTO identifier ';' |
| { $$ = c_finish_goto_label ($2); } |
| | GOTO '*' expr ';' |
| { $$ = c_finish_goto_ptr ($3.value); } |
| | ';' |
| { $$ = NULL_TREE; } |
| @@ifobjc |
| | AT_THROW expr ';' |
| { $$ = objc_build_throw_stmt ($2.value); } |
| | AT_THROW ';' |
| { $$ = objc_build_throw_stmt (NULL_TREE); } |
| | objc_try_catch_stmt |
| { $$ = NULL_TREE; } |
| | AT_SYNCHRONIZED save_location '(' expr ')' compstmt |
| { objc_build_synchronized ($2, $4.value, $6); $$ = NULL_TREE; } |
| ; |
| |
| /* APPLE LOCAL begin radar 2848255 */ |
| objc_catch_parm: |
| parm |
| { $$ = $1; } |
| | ELLIPSIS |
| { $$ = NULL_TREE; } |
| ; |
| |
| objc_catch_prefix: |
| AT_CATCH '(' objc_catch_parm ')' |
| { objc_begin_catch_clause ($3 == NULL_TREE |
| ? NULL_TREE |
| : grokparm ($3)); } |
| ; |
| /* APPLE LOCAL end radar 2848255 */ |
| |
| objc_catch_clause: |
| objc_catch_prefix '{' compstmt_nostart |
| { objc_finish_catch_clause (); } |
| | objc_catch_prefix '{' error '}' |
| { objc_finish_catch_clause (); } |
| ; |
| |
| objc_opt_catch_list: |
| /* empty */ |
| | objc_opt_catch_list objc_catch_clause |
| ; |
| |
| objc_try_catch_clause: |
| AT_TRY save_location compstmt |
| { objc_begin_try_stmt ($2, $3); } |
| objc_opt_catch_list |
| ; |
| |
| objc_finally_clause: |
| AT_FINALLY save_location compstmt |
| { objc_build_finally_clause ($2, $3); } |
| ; |
| |
| objc_try_catch_stmt: |
| objc_try_catch_clause |
| { objc_finish_try_stmt (); } |
| | objc_try_catch_clause objc_finally_clause |
| { objc_finish_try_stmt (); } |
| @@end_ifobjc |
| ; |
| |
| /* Parse a single or compound real statement, not including any labels. */ |
| stmt: |
| compstmt |
| { add_stmt ($1); $$ = NULL_TREE; } |
| | stmt_nocomp |
| ; |
| |
| /* Any kind of label, including jump labels and case labels. |
| ANSI C accepts labels only before statements, but we allow them |
| also at the end of a compound statement. */ |
| |
| label: CASE expr_no_commas ':' |
| { $$ = do_case ($2.value, NULL_TREE); } |
| | CASE expr_no_commas ELLIPSIS expr_no_commas ':' |
| { $$ = do_case ($2.value, $4.value); } |
| | DEFAULT ':' |
| { $$ = do_case (NULL_TREE, NULL_TREE); } |
| | identifier save_location ':' maybe_attribute |
| { tree label = define_label ($2, $1); |
| if (label) |
| { |
| decl_attributes (&label, $4, 0); |
| $$ = add_stmt (build_stmt (LABEL_EXPR, label)); |
| } |
| else |
| $$ = NULL_TREE; |
| } |
| ; |
| |
| /* Asm expressions and statements */ |
| |
| /* 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 stop_string_translation |
| '(' asm_string ')' start_string_translation |
| { $$ = $4; } |
| ; |
| |
| /* maybeasm: used for assembly names for declarations */ |
| maybeasm: |
| /* empty */ |
| { $$ = NULL_TREE; } |
| | simple_asm_expr |
| ; |
| |
| /* asmdef: asm() outside a function body. */ |
| asmdef: |
| simple_asm_expr ';' |
| { assemble_asm ($1); } |
| | ASM_KEYWORD error start_string_translation ';' |
| {} |
| ; |
| |
| /* Full-blown asm statement with inputs, outputs, clobbers, and |
| volatile tag allowed. */ |
| asm_stmt: |
| ASM_KEYWORD maybe_volatile stop_string_translation |
| '(' asm_argument ')' start_string_translation ';' |
| { $$ = build_asm_stmt ($2, $5); } |
| ; |
| |
| asm_argument: |
| /* no operands */ |
| asm_string |
| { $$ = build_asm_expr ($1, 0, 0, 0, true); } |
| /* output operands */ |
| | asm_string ':' asm_operands |
| { $$ = build_asm_expr ($1, $3, 0, 0, false); } |
| /* output and input operands */ |
| | asm_string ':' asm_operands ':' asm_operands |
| { $$ = build_asm_expr ($1, $3, $5, 0, false); } |
| /* output and input operands and clobbers */ |
| | asm_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 */ |
| { $$ = 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 |
| in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */ |
| asm_operands: /* empty */ |
| { $$ = NULL_TREE; } |
| | nonnull_asm_operands |
| ; |
| |
| nonnull_asm_operands: |
| asm_operand |
| | nonnull_asm_operands ',' asm_operand |
| { $$ = chainon ($1, $3); } |
| ; |
| |
| asm_operand: |
| asm_string start_string_translation '(' expr ')' |
| stop_string_translation |
| { $$ = build_tree_list (build_tree_list (NULL_TREE, $1), |
| $4.value); } |
| | '[' identifier ']' asm_string start_string_translation |
| '(' expr ')' stop_string_translation |
| { $2 = build_string (IDENTIFIER_LENGTH ($2), |
| IDENTIFIER_POINTER ($2)); |
| $$ = build_tree_list (build_tree_list ($2, $4), $7.value); } |
| ; |
| |
| asm_clobbers: |
| asm_string |
| { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } |
| | asm_clobbers ',' asm_string |
| { $$ = tree_cons (NULL_TREE, $3, $1); } |
| ; |
| |
| /* Strings in 'asm' must be narrow strings. */ |
| asm_string: |
| STRING |
| { if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE ($1))) |
| != char_type_node) |
| { |
| error ("wide string literal in %<asm%>"); |
| $$ = build_string (1, ""); |
| } |
| else |
| $$ = $1; } |
| ; |
| |
| stop_string_translation: |
| { c_lex_string_translate = 0; } |
| ; |
| |
| start_string_translation: |
| { c_lex_string_translate = 1; } |
| ; |
| |
| /* APPLE LOCAL begin CW asm blocks */ |
| iasm_expr_no_commas: |
| iasm_unary_expr |
| | iasm_expr_no_commas '+' iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas '-' iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas '*' iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas '/' iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas '%' iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas LSHIFT iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas RSHIFT iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas ARITHCOMPARE iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas EQCOMPARE iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas '&' iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas '|' iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas '^' iasm_expr_no_commas |
| { $$ = parser_build_binary_op ($2, $1, $3); } |
| | iasm_expr_no_commas ANDAND |
| { $1.value = c_common_truthvalue_conversion |
| (default_conversion ($1.value)); |
| skip_evaluation += $1.value == boolean_false_node; } |
| iasm_expr_no_commas |
| { skip_evaluation -= $1.value == boolean_false_node; |
| $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $4); } |
| | iasm_expr_no_commas OROR |
| { $1.value = c_common_truthvalue_conversion |
| (default_conversion ($1.value)); |
| skip_evaluation += $1.value == boolean_true_node; } |
| iasm_expr_no_commas |
| { skip_evaluation -= $1.value == boolean_true_node; |
| $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $4); } |
| ; |
| |
| iasm_unary_expr: |
| iasm_primary |
| /* (in 4.2 bb) */ |
| | iasm_primary IDENTIFIER iasm_unary_expr |
| { |
| /* Handle things like: inc dword ptr [eax] */ |
| if (strcasecmp (IDENTIFIER_POINTER ($2), "ptr") != 0) |
| error ("expected %<ptr%>"); |
| $$.value = iasm_ptr_conv ($1.value, $3.value); |
| $$.original_code = ERROR_MARK; |
| } |
| | '*' iasm_unary_expr %prec UNARY |
| { $$.value = build_indirect_ref ($2.value, "unary *"); |
| $$.original_code = ERROR_MARK; } |
| | unop iasm_unary_expr %prec UNARY |
| { |
| if (TREE_CODE ($2.value) == COMPOUND_EXPR) |
| { |
| tree neg = build_unary_op ($1, TREE_OPERAND ($2.value, 0), 0); |
| tree reg = TREE_OPERAND ($2.value, 1); |
| $$.value = iasm_build_register_offset (neg, reg); |
| } |
| else |
| { |
| /* (in 4.2 bc) */ |
| if (TREE_CODE ($2.value) == LABEL_DECL |
| && $1 == ADDR_EXPR) |
| $$.value = finish_label_address_expr (DECL_NAME ($2.value)); |
| else |
| $$.value = build_unary_op ($1, $2.value, 0); |
| overflow_warning ($$.value); |
| } |
| $$.original_code = ERROR_MARK; |
| } |
| | sizeof iasm_unary_expr %prec UNARY |
| { skip_evaluation--; |
| if (TREE_CODE ($2.value) == COMPONENT_REF |
| && DECL_C_BIT_FIELD (TREE_OPERAND ($2.value, 1))) |
| error ("`sizeof' applied to a bit-field"); |
| else if (TREE_CODE ($2.value) == IDENTIFIER_NODE) |
| { |
| undeclared_variable ($2.value); |
| $2.value = error_mark_node; |
| } |
| $$.value = c_sizeof (TREE_TYPE ($2.value)); |
| $$.original_code = ERROR_MARK; } |
| | sizeof '(' typename ')' %prec HYPERUNARY |
| { skip_evaluation--; |
| $$.value = c_sizeof (groktypename ($3)); |
| $$.original_code = ERROR_MARK; } |
| | alignof iasm_unary_expr %prec UNARY |
| { skip_evaluation--; |
| $$.value = c_alignof_expr ($2.value); |
| $$.original_code = ERROR_MARK; } |
| | alignof '(' typename ')' %prec HYPERUNARY |
| { skip_evaluation--; |
| $$.value = c_alignof (groktypename ($3)); |
| $$.original_code = ERROR_MARK; } |
| ; |
| |
| iasm_primary: |
| IDENTIFIER |
| { |
| if (yychar == YYEMPTY) |
| yychar = YYLEX; |
| $$.value = build_external_ref ($1, yychar == '('); |
| $$.original_code = ERROR_MARK; |
| } |
| | '@' IDENTIFIER |
| { |
| tree atsignid = prepend_char_identifier ($2, '@'); |
| if (yychar == YYEMPTY) |
| yychar = YYLEX; |
| $$.value = build_external_ref (atsignid, yychar == '('); |
| $$.original_code = ERROR_MARK; |
| } |
| | CONSTANT |
| { $$.value = $1; $$.original_code = ERROR_MARK; } |
| | STRING |
| { $$.value = $1; $$.original_code = STRING_CST; } |
| | '(' iasm_expr_no_commas ')' |
| { char class = TREE_CODE_CLASS (TREE_CODE ($2.value)); |
| if (IS_EXPR_CODE_CLASS (class)) |
| $2.original_code = ERROR_MARK; |
| $$ = $2; } |
| | '(' error ')' |
| { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } |
| | iasm_primary '[' iasm_expr_no_commas ']' %prec '.' |
| { $$.value = build_array_ref ($1.value, $3.value); |
| $$.original_code = ERROR_MARK; } |
| | '[' iasm_expr_no_commas ']' %prec '.' |
| { $$.value = iasm_build_bracket ($2.value, NULL_TREE); |
| $$.original_code = ERROR_MARK; } |
| | TYPENAME '.' identifier |
| { $$.value = iasm_c_build_component_ref ($1, $3); |
| $$.original_code = ERROR_MARK; } |
| | iasm_primary '.' identifier |
| { $$.value = iasm_c_build_component_ref ($1.value, $3); |
| $$.original_code = ERROR_MARK; } |
| /* (in 4.2 bc) */ |
| | iasm_primary '.' CONSTANT |
| { /* We allow [eax].16 to refer to [eax + 16]. */ |
| $$.value = iasm_c_build_component_ref ($1.value, $3); |
| $$.original_code = ERROR_MARK; } |
| | iasm_primary POINTSAT identifier |
| { |
| tree expr = build_indirect_ref ($1.value, "->"); |
| $$.value = build_component_ref (expr, $3); |
| $$.original_code = ERROR_MARK; |
| } |
| /* (in 4.2 ba) */ |
| | '.' |
| { |
| $$.value = get_identifier (".");; |
| $$.original_code = ERROR_MARK; |
| } |
| ; |
| /* APPLE LOCAL end CW asm blocks */ |
| |
| /* This is what appears inside the parens in a function declarator. |
| Its value is a list of ..._TYPE nodes. Attributes must appear here |
| to avoid a conflict with their appearance after an open parenthesis |
| in an abstract declarator, as in |
| "void bar (int (__attribute__((__mode__(SI))) int foo));". */ |
| parmlist: |
| maybe_attribute |
| { push_scope (); |
| declare_parm_level (); } |
| parmlist_1 |
| { $$ = $3; |
| pop_scope (); } |
| ; |
| |
| parmlist_1: |
| parmlist_2 ')' |
| | parms ';' |
| { mark_forward_parm_decls (); } |
| maybe_attribute |
| { /* Dummy action so attributes are in known place |
| on parser stack. */ } |
| parmlist_1 |
| { $$ = $6; } |
| | error ')' |
| { $$ = XOBNEW (&parser_obstack, struct c_arg_info); |
| $$->parms = 0; |
| $$->tags = 0; |
| $$->types = 0; |
| /* APPLE LOCAL mainline 2006-05-19 4336222 */ |
| $$->had_vla_unspec = 0; |
| $$->others = 0; } |
| ; |
| |
| /* This is what appears inside the parens in a function declarator. |
| Its value is represented in the format that grokdeclarator expects. */ |
| parmlist_2: /* empty */ |
| { $$ = XOBNEW (&parser_obstack, struct c_arg_info); |
| $$->parms = 0; |
| $$->tags = 0; |
| $$->types = 0; |
| /* APPLE LOCAL mainline 2006-05-19 4336222 */ |
| $$->had_vla_unspec = 0; |
| $$->others = 0; } |
| | ELLIPSIS |
| { $$ = XOBNEW (&parser_obstack, struct c_arg_info); |
| $$->parms = 0; |
| $$->tags = 0; |
| $$->others = 0; |
| /* APPLE LOCAL mainline 2006-05-19 4336222 */ |
| $$->had_vla_unspec = 0; |
| /* Suppress -Wold-style-definition for this case. */ |
| $$->types = error_mark_node; |
| error ("ISO C requires a named argument before %<...%>"); |
| } |
| | parms |
| { $$ = get_parm_info (/*ellipsis=*/false); } |
| | parms ',' ELLIPSIS |
| { $$ = get_parm_info (/*ellipsis=*/true); } |
| ; |
| |
| parms: |
| firstparm |
| { push_parm_decl ($1); } |
| | parms ',' parm |
| { push_parm_decl ($3); } |
| ; |
| |
| /* A single parameter declaration or parameter type name, |
| as found in a parmlist. */ |
| parm: |
| declspecs_ts setspecs parm_declarator maybe_attribute |
| { $$ = build_c_parm (current_declspecs, |
| chainon ($4, all_prefix_attributes), $3); |
| POP_DECLSPEC_STACK; } |
| | declspecs_ts setspecs notype_declarator maybe_attribute |
| { $$ = build_c_parm (current_declspecs, |
| chainon ($4, all_prefix_attributes), $3); |
| POP_DECLSPEC_STACK; } |
| | declspecs_ts setspecs absdcl_maybe_attribute |
| { $$ = $3; |
| POP_DECLSPEC_STACK; } |
| | declspecs_nots setspecs notype_declarator maybe_attribute |
| { $$ = build_c_parm (current_declspecs, |
| chainon ($4, all_prefix_attributes), $3); |
| POP_DECLSPEC_STACK; } |
| |
| | declspecs_nots setspecs absdcl_maybe_attribute |
| { $$ = $3; |
| POP_DECLSPEC_STACK; } |
| ; |
| |
| /* The first parm, which must suck attributes from off the top of the parser |
| stack. */ |
| firstparm: |
| declspecs_ts_nosa setspecs_fp parm_declarator maybe_attribute |
| { $$ = build_c_parm (current_declspecs, |
| chainon ($4, all_prefix_attributes), $3); |
| POP_DECLSPEC_STACK; } |
| | declspecs_ts_nosa setspecs_fp notype_declarator maybe_attribute |
| { $$ = build_c_parm (current_declspecs, |
| chainon ($4, all_prefix_attributes), $3); |
| POP_DECLSPEC_STACK; } |
| | declspecs_ts_nosa setspecs_fp absdcl_maybe_attribute |
| { $$ = $3; |
| POP_DECLSPEC_STACK; } |
| | declspecs_nots_nosa setspecs_fp notype_declarator maybe_attribute |
| { $$ = build_c_parm (current_declspecs, |
| chainon ($4, all_prefix_attributes), $3); |
| POP_DECLSPEC_STACK; } |
| |
| | declspecs_nots_nosa setspecs_fp absdcl_maybe_attribute |
| { $$ = $3; |
| POP_DECLSPEC_STACK; } |
| ; |
| |
| setspecs_fp: |
| setspecs |
| { prefix_attributes = chainon (prefix_attributes, $<ttype>-2); |
| all_prefix_attributes = prefix_attributes; } |
| ; |
| |
| /* This is used in a function definition |
| where either a parmlist or an identifier list is ok. |
| Its value is a list of ..._TYPE nodes or a list of identifiers. */ |
| parmlist_or_identifiers: |
| maybe_attribute |
| { push_scope (); |
| declare_parm_level (); } |
| parmlist_or_identifiers_1 |
| { $$ = $3; |
| pop_scope (); } |
| ; |
| |
| parmlist_or_identifiers_1: |
| parmlist_1 |
| | identifiers ')' |
| { $$ = XOBNEW (&parser_obstack, struct c_arg_info); |
| $$->parms = 0; |
| $$->tags = 0; |
| $$->types = $1; |
| $$->others = 0; |
| /* APPLE LOCAL mainline 2006-05-19 4336222 */ |
| $$->had_vla_unspec = 0; |
| |
| /* Make sure we have a parmlist after attributes. */ |
| if ($<ttype>-1 != 0) |
| YYERROR1; |
| } |
| ; |
| |
| /* A nonempty list of identifiers. */ |
| identifiers: |
| IDENTIFIER |
| { $$ = build_tree_list (NULL_TREE, $1); } |
| | identifiers ',' IDENTIFIER |
| { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } |
| ; |
| |
| /* A nonempty list of identifiers, including typenames. */ |
| identifiers_or_typenames: |
| identifier |
| { $$ = build_tree_list (NULL_TREE, $1); } |
| | identifiers_or_typenames ',' identifier |
| { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } |
| ; |
| |
| extension: |
| EXTENSION |
| { $$ = SAVE_EXT_FLAGS (); |
| pedantic = 0; |
| warn_pointer_arith = 0; |
| warn_traditional = 0; |
| flag_iso = 0; } |
| ; |
| |
| @@ifobjc |
| /* Objective-C productions. */ |
| |
| objcdef: |
| classdef |
| | classdecl |
| | aliasdecl |
| | protocoldef |
| | methoddef |
| /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 x) */ |
| | property_declaration |
| /* APPLE LOCAL objc new property - also radar 4923440 */ |
| | property_implementation {} |
| | AT_END |
| { |
| objc_finish_implementation (); |
| } |
| ; |
| |
| /* A nonempty list of identifiers. */ |
| identifier_list: |
| identifier |
| { $$ = build_tree_list (NULL_TREE, $1); } |
| | identifier_list ',' identifier |
| { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } |
| ; |
| |
| classdecl: |
| AT_CLASS identifier_list ';' |
| { |
| objc_declare_class ($2); |
| } |
| ; |
| |
| aliasdecl: |
| AT_ALIAS identifier identifier ';' |
| { |
| objc_declare_alias ($2, $3); |
| } |
| ; |
| |
| superclass: |
| ':' identifier { $$ = $2; } |
| | /* NULL */ %prec HYPERUNARY { $$ = NULL_TREE; } |
| ; |
| |
| class_ivars: |
| '{' ivar_decl_list '}' |
| | /* NULL */ |
| ; |
| |
| /* APPLE LOCAL begin C* property (Radar 4436866, 4591909) (in 4.2 s, except for 4591909) */ |
| property_attribute: |
| AT_READONLY |
| { |
| objc_set_property_attr (1, NULL_TREE); |
| } |
| | AT_GETTER '=' IDENTIFIER |
| { |
| objc_set_property_attr (2, $3); |
| } |
| | AT_SETTER '=' IDENTIFIER ':' |
| { |
| objc_set_property_attr (3, $3); |
| } |
| | AT_IVAR '=' IDENTIFIER |
| { |
| objc_set_property_attr (4, $3); |
| } |
| | AT_IVAR |
| { |
| objc_set_property_attr (4, NULL_TREE); |
| } |
| | AT_PROP_BYCOPY |
| { |
| objc_set_property_attr (5, NULL_TREE); |
| } |
| | AT_PROP_BYREF |
| { |
| objc_set_property_attr (6, NULL_TREE); |
| } |
| | AT_PROP_DYNAMIC |
| { |
| objc_set_property_attr (7, NULL_TREE); |
| } |
| /* APPLE LOCAL begin radar 4621020 */ |
| | AT_WEAK |
| { |
| objc_set_property_attr (8, NULL_TREE); |
| } |
| /* APPLE LOCAL end radar 4621020 */ |
| /* APPLE LOCAL begin objc new property */ |
| | AT_READWRITE |
| { |
| objc_set_property_attr (9, NULL_TREE); |
| } |
| | AT_ASSIGN |
| { |
| objc_set_property_attr (10, NULL_TREE); |
| } |
| | AT_RETAIN |
| { |
| objc_set_property_attr (11, NULL_TREE); |
| } |
| | AT_COPY |
| { |
| objc_set_property_attr (12, NULL_TREE); |
| } |
| /* APPLE LOCAL end objc new property */ |
| /* APPLE LOCAL begin radar 4947014 - objc atomic property */ |
| | AT_NONATOMIC |
| { |
| objc_set_property_attr (13, NULL_TREE); |
| } |
| /* APPLE LOCAL end radar 4947014 - objc atomic property */ |
| ; |
| |
| property_attrlist: |
| property_attribute |
| | property_attrlist ',' property_attribute |
| ; |
| |
| property_attr_decl: |
| '(' property_attrlist ')' |
| { |
| } |
| | /* NULL */ |
| ; |
| |
| property_declaration: |
| AT_PROPERTY |
| { |
| objc_property_attr_context = 1; |
| objc_set_property_attr (0, NULL_TREE); |
| } |
| property_attr_decl |
| { |
| objc_property_attr_context = 0; |
| } |
| component_decl ';' |
| { |
| /* Comma-separated properties are chained together in |
| reverse order; add them one by one. */ |
| tree prop = nreverse ($5); |
| |
| for (; prop; prop = TREE_CHAIN (prop)) |
| objc_add_property_variable (copy_node (prop)); |
| } |
| ; |
| /* APPLE LOCAL end C* property (Radar 4436866, 4591909) (in 4.2 s, except for 4591909) */ |
| /* APPLE LOCAL begin objc new property */ |
| property_synthesize_item: |
| IDENTIFIER |
| { |
| $$ = build_tree_list (NULL_TREE, $1); |
| } |
| | IDENTIFIER '=' IDENTIFIER |
| { |
| $$ = build_tree_list ($3, $1); |
| } |
| ; |
| |
| property_synthesize_list: |
| property_synthesize_item |
| | property_synthesize_list ',' property_synthesize_item |
| { |
| $$ = chainon ($1, $3); |
| } |
| ; |
| |
| property_implementation: |
| AT_SYNTHESIZE property_synthesize_list ';' |
| { |
| objc_declare_property_impl (1, $2); |
| } |
| | AT_DYNAMIC identifier_list ';' |
| { |
| objc_declare_property_impl (2, $2); |
| } |
| ; |
| /* APPLE LOCAL end objc new property */ |
| |
| /* APPLE LOCAL begin radar 4965989 */ |
| optidentifier: |
| { |
| $$ = NULL_TREE; |
| } |
| | identifier |
| { |
| $$ = $1; |
| } |
| ; |
| /* APPLE LOCAL end radar 4965989 */ |
| |
| classdef: |
| /* APPLE LOCAL begin radar 4548636 - class attributes. (in 4.2 p) */ |
| maybe_attribute AT_INTERFACE identifier superclass protocolrefs |
| { |
| objc_start_class_interface ($3, $4, $5, $1); |
| } |
| /* APPLE LOCAL end radar 4548636 - class attributes. (in 4.2 p) */ |
| class_ivars |
| { |
| objc_continue_interface (); |
| } |
| /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 q) */ |
| interfacedecllist AT_END |
| { |
| objc_finish_interface (); |
| } |
| |
| | AT_IMPLEMENTATION identifier superclass |
| { |
| objc_start_class_implementation ($2, $3); |
| } |
| class_ivars |
| { |
| objc_continue_implementation (); |
| } |
| |
| /* APPLE LOCAL begin radar 4548636 - class attributes. (in 4.2 t) */ |
| /* APPLE LOCAL radar 4965989 */ |
| | maybe_attribute AT_INTERFACE identifier '(' optidentifier ')' protocolrefs |
| { |
| if ($1) |
| error ("attributes may not be specified on a category"); |
| objc_start_category_interface ($3, $5, $7); |
| } |
| /* APPLE LOCAL end radar 4548636 - class attributes. (in 4.2 t) */ |
| /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 q) */ |
| interfacedecllist AT_END |
| { |
| objc_finish_interface (); |
| } |
| |
| | AT_IMPLEMENTATION identifier '(' identifier ')' |
| { |
| objc_start_category_implementation ($2, $4); |
| } |
| /* APPLE LOCAL begin radar 4533974 - ObjC new protocol (in 4.2 v) */ |
| | AT_IMPLEMENTATION non_empty_protocolrefs |
| { |
| objc_protocol_implementation ($2); |
| } |
| /* APPLE LOCAL end radar 4533974 - ObjC new protocol (in 4.2 v) */ |
| ; |
| |
| protocoldef: |
| AT_PROTOCOL identifier protocolrefs |
| { |
| objc_pq_context = 1; |
| objc_start_protocol ($2, $3); |
| } |
| /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 r) */ |
| interfacedecllist AT_END |
| { |
| objc_pq_context = 0; |
| objc_finish_interface (); |
| } |
| /* The @protocol forward-declaration production introduces a |
| reduce/reduce conflict on ';', which should be resolved in |
| favor of the production 'identifier_list -> identifier'. */ |
| | AT_PROTOCOL identifier_list ';' |
| { |
| objc_declare_protocols ($2); |
| } |
| ; |
| |
| protocolrefs: |
| /* empty */ |
| { |
| $$ = NULL_TREE; |
| } |
| | non_empty_protocolrefs |
| ; |
| |
| non_empty_protocolrefs: |
| ARITHCOMPARE identifier_list ARITHCOMPARE |
| { |
| if ($1 == LT_EXPR && $3 == GT_EXPR) |
| $$ = $2; |
| else |
| YYERROR1; |
| } |
| ; |
| |
| ivar_decl_list: |
| /* empty */ |
| | ivar_decl_list visibility_spec ivar_decls |
| ; |
| |
| visibility_spec: |
| /* empty */ |
| | AT_PRIVATE { objc_set_visibility (2); } |
| | AT_PROTECTED { objc_set_visibility (0); } |
| | AT_PUBLIC { objc_set_visibility (1); } |
| /* APPLE LOCAL radar 4564694 */ |
| | AT_PACKAGE { objc_set_visibility (3); } |
| ; |
| |
| ivar_decls: |
| /* empty */ |
| | ivar_decls ivar_decl ';' |
| | ivar_decls ';' |
| { |
| if (pedantic) |
| pedwarn ("extra semicolon in struct or union specified"); |
| } |
| ; |
| |
| ivar_decl: |
| component_decl |
| { |
| /* Comma-separated ivars are chained together in |
| reverse order; add them one by one. */ |
| tree ivar = nreverse ($1); |
| |
| for (; ivar; ivar = TREE_CHAIN (ivar)) |
| objc_add_instance_variable (copy_node (ivar)); |
| } |
| ; |
| |
| opt_semi: |
| /* NULL */ |
| | ';' |
| { |
| if (pedantic) |
| pedwarn ("extra semicolon in method definition specified"); |
| } |
| ; |
| |
| methodtype: |
| '+' |
| | '-' |
| ; |
| |
| methoddef: |
| methodtype |
| { |
| objc_set_method_type ($1); |
| objc_pq_context = 1; |
| } |
| methoddecl opt_semi |
| { |
| objc_pq_context = 0; |
| /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 a) */ |
| objc_start_method_definition ($3, objc_method_attributes); |
| objc_method_attributes = NULL_TREE; |
| /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 a) */ |
| } |
| compstmt_or_error |
| { |
| objc_finish_method_definition (current_function_decl); |
| } |
| ; |
| |
| /* the reason for the strange actions in this rule |
| is so that notype_initdecls when reached via datadef |
| can find a valid list of type and sc specs in $0. */ |
| |
| /* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 b) */ |
| interfacedecllist: |
| /* empty */ |
| | interfacedecllist methodproto |
| | interfacedecllist { $<ttype>$ = NULL_TREE; } datadef |
| | interfacedecllist property_declaration |
| /* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 b) */ |
| ; |
| |
| semi_or_error: |
| ';' |
| | error |
| ; |
| |
| methodproto: |
| /* APPLE LOCAL begin C* language (in 4.2 w) */ |
| AT_REQUIRED { objc_set_method_opt (0); } |
| | AT_OPTIONAL { objc_set_method_opt (1); } |
| | |
| /* APPLE LOCAL end C* language (in 4.2 w) */ |
| methodtype |
| { |
| objc_set_method_type ($1); |
| /* Remember protocol qualifiers in prototypes. */ |
| objc_pq_context = 1; |
| } |
| methoddecl |
| { |
| /* Forget protocol qualifiers here. */ |
| objc_pq_context = 0; |
| /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 c) */ |
| objc_add_method_declaration ($3, objc_method_attributes); |
| objc_method_attributes = NULL_TREE; |
| /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 c) */ |
| } |
| semi_or_error |
| ; |
| |
| methoddecl: |
| /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 y) */ |
| '(' objc_typename ')' unaryselector maybe_attribute |
| { |
| $$ = objc_build_method_signature ($2, $4, NULL_TREE); |
| objc_method_attributes = $5; |
| } |
| |
| | unaryselector maybe_attribute |
| { |
| $$ = objc_build_method_signature (NULL_TREE, $1, NULL_TREE); |
| objc_method_attributes = $2; |
| } |
| |
| | '(' objc_typename ')' keywordselector maybe_attribute optparmlist |
| { |
| $$ = objc_build_method_signature ($2, $4, $6); |
| /* Check for ... at the end. */ |
| if (!TREE_OVERFLOW ($6)) |
| objc_method_attributes = $5; |
| else if ($5) |
| error ("method attributes must be specified at the end only"); |
| } |
| |
| | keywordselector maybe_attribute optparmlist |
| { |
| $$ = objc_build_method_signature (NULL_TREE, $1, $3); |
| /* Check for ... at the end. */ |
| if (!TREE_OVERFLOW ($3)) |
| objc_method_attributes = $2; |
| else if ($2) |
| error ("method attributes must be specified at the end only"); |
| } |
| /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 y) */ |
| ; |
| |
| /* Optional ObjC method parameters follow the C syntax, and may include '...' |
| to denote a variable number of arguments. */ |
| |
| optparmlist: |
| optparms optellipsis |
| { |
| TREE_OVERFLOW ($$) = $2; |
| } |
| ; |
| |
| optparms: |
| /* NULL */ |
| { |
| $$ = make_node (TREE_LIST); |
| } |
| | optparms ',' parm |
| { |
| $$ = chainon ($1, build_tree_list (NULL_TREE, |
| grokparm ($3))); |
| } |
| ; |
| |
| optellipsis: |
| /* NULL */ |
| { |
| $$ = 0; |
| } |
| /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 y) */ |
| | ',' ELLIPSIS maybe_attribute |
| { |
| $$ = 1; |
| objc_method_attributes = $3; |
| } |
| /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 y) */ |
| ; |
| |
| unaryselector: |
| selector |
| ; |
| |
| keywordselector: |
| keyworddecl |
| |
| | keywordselector keyworddecl |
| { |
| $$ = chainon ($1, $2); |
| } |
| ; |
| |
| selector: |
| IDENTIFIER |
| | TYPENAME |
| | CLASSNAME |
| | reservedwords |
| ; |
| |
| reservedwords: |
| ENUM | STRUCT | UNION | IF | ELSE | WHILE | DO | FOR |
| | SWITCH | CASE | DEFAULT | BREAK | CONTINUE | RETURN |
| | GOTO | ASM_KEYWORD | SIZEOF | TYPEOF | ALIGNOF |
| | TYPESPEC | TYPE_QUAL | OBJC_TYPE_QUAL |
| ; |
| |
| objc_qual: |
| OBJC_TYPE_QUAL |
| ; |
| |
| objc_quals: |
| objc_quals objc_qual |
| { |
| /* APPLE LOCAL radar 4301047 (in 4.2 z) */ |
| $$ = chainon (build_tree_list (NULL_TREE, $2), $1); |
| } |
| | /* NULL */ |
| { |
| $$ = NULL_TREE; |
| } |
| ; |
| |
| objc_typename: |
| objc_quals typename |
| { |
| $$ = build_tree_list ($1, groktypename ($2)); |
| } |
| | objc_quals |
| { |
| $$ = build_tree_list ($1, NULL_TREE); |
| } |
| ; |
| |
| keyworddecl: |
| selector ':' '(' objc_typename ')' identifier |
| { |
| $$ = objc_build_keyword_decl ($1, $4, $6); |
| } |
| |
| | selector ':' identifier |
| { |
| $$ = objc_build_keyword_decl ($1, NULL_TREE, $3); |
| } |
| |
| | ':' '(' objc_typename ')' identifier |
| { |
| $$ = objc_build_keyword_decl (NULL_TREE, $3, $5); |
| } |
| |
| | ':' identifier |
| { |
| $$ = objc_build_keyword_decl (NULL_TREE, NULL_TREE, $2); |
| } |
| ; |
| |
| messageargs: |
| selector |
| | keywordarglist |
| ; |
| |
| keywordarglist: |
| keywordarg |
| | keywordarglist keywordarg |
| { |
| $$ = chainon ($1, $2); |
| } |
| ; |
| |
| |
| keywordexpr: |
| nonnull_exprlist |
| { |
| if (TREE_CHAIN ($1) == NULL_TREE) |
| /* just return the expr., remove a level of indirection */ |
| $$ = TREE_VALUE ($1); |
| else |
| /* we have a comma expr., we will collapse later */ |
| $$ = $1; |
| } |
| ; |
| |
| keywordarg: |
| selector ':' keywordexpr |
| { |
| $$ = build_tree_list ($1, $3); |
| } |
| | ':' keywordexpr |
| { |
| $$ = build_tree_list (NULL_TREE, $2); |
| } |
| ; |
| |
| receiver: |
| expr |
| { $$ = $1.value; } |
| | CLASSNAME |
| { |
| $$ = objc_get_class_reference ($1); |
| } |
| | TYPENAME |
| { |
| $$ = objc_get_class_reference ($1); |
| } |
| ; |
| |
| objcmessageexpr: |
| '[' receiver messageargs ']' |
| { $$ = build_tree_list ($2, $3); } |
| ; |
| |
| selectorarg: |
| selector |
| | keywordnamelist |
| ; |
| |
| keywordnamelist: |
| keywordname |
| | keywordnamelist keywordname |
| { |
| $$ = chainon ($1, $2); |
| } |
| ; |
| |
| keywordname: |
| selector ':' |
| { |
| $$ = build_tree_list ($1, NULL_TREE); |
| } |
| | ':' |
| { |
| $$ = build_tree_list (NULL_TREE, NULL_TREE); |
| } |
| ; |
| |
| objcselectorexpr: |
| AT_SELECTOR '(' selectorarg ')' |
| { |
| $$ = $3; |
| } |
| ; |
| |
| objcprotocolexpr: |
| AT_PROTOCOL '(' identifier ')' |
| { |
| $$ = $3; |
| } |
| ; |
| |
| /* extension to support C-structures in the archiver */ |
| |
| objcencodeexpr: |
| AT_ENCODE '(' typename ')' |
| { |
| $$ = groktypename ($3); |
| } |
| ; |
| |
| @@end_ifobjc |
| %% |
| |
| /* yylex() is a thin wrapper around c_lex(), all it does is translate |
| cpplib.h's token codes into yacc's token codes. */ |
| |
| static enum cpp_ttype last_token; |
| |
| /* The reserved keyword table. */ |
| struct resword |
| { |
| const char *word; |
| ENUM_BITFIELD(rid) rid : 16; |
| unsigned int disable : 16; |
| }; |
| |
| /* Disable mask. Keywords are disabled if (reswords[i].disable & mask) is |
| _true_. */ |
| #define D_C89 0x01 /* not in C89 */ |
| #define D_EXT 0x02 /* GCC extension */ |
| #define D_EXT89 0x04 /* GCC extension incorporated in C99 */ |
| #define D_OBJC 0x08 /* Objective C only */ |
| |
| static const struct resword reswords[] = |
| { |
| { "_Bool", RID_BOOL, 0 }, |
| { "_Complex", RID_COMPLEX, 0 }, |
| /* APPLE LOCAL CW asm blocks (in 4.2 h) */ |
| { "_asm", RID_ASM, 0 }, |
| { "__FUNCTION__", RID_FUNCTION_NAME, 0 }, |
| { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 }, |
| { "__alignof", RID_ALIGNOF, 0 }, |
| { "__alignof__", RID_ALIGNOF, 0 }, |
| { "__asm", RID_ASM, 0 }, |
| { "__asm__", RID_ASM, 0 }, |
| { "__attribute", RID_ATTRIBUTE, 0 }, |
| { "__attribute__", RID_ATTRIBUTE, 0 }, |
| { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 }, |
| { "__builtin_offsetof", RID_OFFSETOF, 0 }, |
| { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 }, |
| { "__builtin_va_arg", RID_VA_ARG, 0 }, |
| { "__complex", RID_COMPLEX, 0 }, |
| { "__complex__", RID_COMPLEX, 0 }, |
| { "__const", RID_CONST, 0 }, |
| { "__const__", RID_CONST, 0 }, |
| { "__extension__", RID_EXTENSION, 0 }, |
| { "__func__", RID_C99_FUNCTION_NAME, 0 }, |
| { "__imag", RID_IMAGPART, 0 }, |
| { "__imag__", RID_IMAGPART, 0 }, |
| { "__inline", RID_INLINE, 0 }, |
| { "__inline__", RID_INLINE, 0 }, |
| { "__label__", RID_LABEL, 0 }, |
| /* APPLE LOCAL private extern (in 4.2 i) */ |
| { "__private_extern__", RID_PRIVATE_EXTERN, 0 }, |
| { "__real", RID_REALPART, 0 }, |
| { "__real__", RID_REALPART, 0 }, |
| { "__restrict", RID_RESTRICT, 0 }, |
| { "__restrict__", RID_RESTRICT, 0 }, |
| { "__signed", RID_SIGNED, 0 }, |
| { "__signed__", RID_SIGNED, 0 }, |
| { "__thread", RID_THREAD, 0 }, |
| { "__typeof", RID_TYPEOF, 0 }, |
| { "__typeof__", RID_TYPEOF, 0 }, |
| { "__volatile", RID_VOLATILE, 0 }, |
| { "__volatile__", RID_VOLATILE, 0 }, |
| { "asm", RID_ASM, D_EXT }, |
| { "auto", RID_AUTO, 0 }, |
| { "break", RID_BREAK, 0 }, |
| { "case", RID_CASE, 0 }, |
| { "char", RID_CHAR, 0 }, |
| { "const", RID_CONST, 0 }, |
| { "continue", RID_CONTINUE, 0 }, |
| { "default", RID_DEFAULT, 0 }, |
| { "do", RID_DO, 0 }, |
| { "double", RID_DOUBLE, 0 }, |
| { "else", RID_ELSE, 0 }, |
| { "enum", RID_ENUM, 0 }, |
| { "extern", RID_EXTERN, 0 }, |
| { "float", RID_FLOAT, 0 }, |
| { "for", RID_FOR, 0 }, |
| { "goto", RID_GOTO, 0 }, |
| { "if", RID_IF, 0 }, |
| { "inline", RID_INLINE, D_EXT89 }, |
| { "int", RID_INT, 0 }, |
| { "long", RID_LONG, 0 }, |
| { "register", RID_REGISTER, 0 }, |
| { "restrict", RID_RESTRICT, D_C89 }, |
| { "return", RID_RETURN, 0 }, |
| { "short", RID_SHORT, 0 }, |
| { "signed", RID_SIGNED, 0 }, |
| { "sizeof", RID_SIZEOF, 0 }, |
| { "static", RID_STATIC, 0 }, |
| { "struct", RID_STRUCT, 0 }, |
| { "switch", RID_SWITCH, 0 }, |
| { "typedef", RID_TYPEDEF, 0 }, |
| { "typeof", RID_TYPEOF, D_EXT }, |
| { "union", RID_UNION, 0 }, |
| { "unsigned", RID_UNSIGNED, 0 }, |
| { "void", RID_VOID, 0 }, |
| { "volatile", RID_VOLATILE, 0 }, |
| { "while", RID_WHILE, 0 }, |
| |
| @@ifobjc |
| |
| /* These objc keywords are recognized only immediately after |
| an '@'. */ |
| { "class", RID_AT_CLASS, D_OBJC }, |
| { "compatibility_alias", RID_AT_ALIAS, D_OBJC }, |
| { "defs", RID_AT_DEFS, D_OBJC }, |
| { "encode", RID_AT_ENCODE, D_OBJC }, |
| { "end", RID_AT_END, D_OBJC }, |
| { "implementation", RID_AT_IMPLEMENTATION, D_OBJC }, |
| { "interface", RID_AT_INTERFACE, D_OBJC }, |
| /* APPLE LOCAL begin C* language (in 4.2 j) */ |
| { "optional", RID_AT_OPTIONAL, D_OBJC }, |
| { "required", RID_AT_REQUIRED, D_OBJC }, |
| /* APPLE LOCAL end C* language (in 4.2 j) */ |
| /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 k) */ |
| { "property", RID_AT_PROPERTY, D_OBJC }, |
| /* APPLE LOCAL radar 4564694 */ |
| { "package", RID_AT_PACKAGE, D_OBJC }, |
| { "private", RID_AT_PRIVATE, D_OBJC }, |
| { "protected", RID_AT_PROTECTED, D_OBJC }, |
| { "protocol", RID_AT_PROTOCOL, D_OBJC }, |
| { "public", RID_AT_PUBLIC, D_OBJC }, |
| { "selector", RID_AT_SELECTOR, D_OBJC }, |
| { "throw", RID_AT_THROW, D_OBJC }, |
| { "try", RID_AT_TRY, D_OBJC }, |
| { "catch", RID_AT_CATCH, D_OBJC }, |
| { "finally", RID_AT_FINALLY, D_OBJC }, |
| { "synchronized", RID_AT_SYNCHRONIZED, D_OBJC }, |
| /* These are recognized only in protocol-qualifier context |
| (see above) */ |
| { "bycopy", RID_BYCOPY, D_OBJC }, |
| { "byref", RID_BYREF, D_OBJC }, |
| { "in", RID_IN, D_OBJC }, |
| { "inout", RID_INOUT, D_OBJC }, |
| { "oneway", RID_ONEWAY, D_OBJC }, |
| { "out", RID_OUT, D_OBJC }, |
| /* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 l) */ |
| /* These are recognized inside a property attribute list */ |
| { "readonly", RID_READONLY, D_OBJC }, |
| /* APPLE LOCAL Radar 4591909 */ |
| { "dynamic", RID_DYNAMIC, D_OBJC }, |
| { "getter", RID_GETTER, D_OBJC }, |
| { "setter", RID_SETTER, D_OBJC }, |
| /* APPLE LOCAL radar 4621020 */ |
| { "weak", RID_WEAK, D_OBJC }, |
| { "ivar", RID_IVAR, D_OBJC }, |
| /* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 l)*/ |
| /* APPLE LOCAL begin objc new property */ |
| { "synthesize", RID_AT_SYNTHESIZE, D_OBJC }, |
| { "readwrite", RID_READWRITE, D_OBJC }, |
| { "assign", RID_ASSIGN, D_OBJC }, |
| { "retain", RID_RETAIN, D_OBJC }, |
| { "copy", RID_COPY, D_OBJC }, |
| /* APPLE LOCAL end objc new property */ |
| /* APPLE LOCAL radar 4947014 - objc atomic property */ |
| { "nonatomic", RID_NONATOMIC, D_OBJC }, |
| @@end_ifobjc |
| }; |
| #define N_reswords (sizeof reswords / sizeof (struct resword)) |
| |
| /* APPLE LOCAL begin keep tables in sync comment */ |
| /* Table mapping from RID_* constants to yacc token numbers. |
| Unfortunately we have to have entries for all the keywords in all |
| three languages (AND THEY MUST BE KEPT IN PARALLEL - see also |
| cp/lex.c). */ |
| /* APPLE LOCAL end keep tables in sync comment */ |
| static const short rid_to_yy[RID_MAX] = |
| { |
| /* RID_STATIC */ STATIC, |
| /* RID_UNSIGNED */ TYPESPEC, |
| /* RID_LONG */ TYPESPEC, |
| /* RID_CONST */ TYPE_QUAL, |
| /* RID_EXTERN */ SCSPEC, |
| /* RID_REGISTER */ SCSPEC, |
| /* RID_TYPEDEF */ SCSPEC, |
| /* RID_SHORT */ TYPESPEC, |
| /* RID_INLINE */ SCSPEC, |
| /* RID_VOLATILE */ TYPE_QUAL, |
| /* RID_SIGNED */ TYPESPEC, |
| /* RID_AUTO */ SCSPEC, |
| /* RID_RESTRICT */ TYPE_QUAL, |
| |
| /* C extensions */ |
| /* RID_COMPLEX */ TYPESPEC, |
| /* RID_THREAD */ SCSPEC, |
| /* APPLE LOCAL private extern (in 4.2 aa) */ |
| /* RID_PRIVATE_EXTERN */ SCSPEC, |
| |
| /* C++ */ |
| /* RID_FRIEND */ 0, |
| /* RID_VIRTUAL */ 0, |
| /* RID_EXPLICIT */ 0, |
| /* RID_EXPORT */ 0, |
| /* RID_MUTABLE */ 0, |
| |
| /* ObjC */ |
| /* RID_IN */ OBJC_TYPE_QUAL, |
| /* RID_OUT */ OBJC_TYPE_QUAL, |
| /* RID_INOUT */ OBJC_TYPE_QUAL, |
| /* RID_BYCOPY */ OBJC_TYPE_QUAL, |
| /* RID_BYREF */ OBJC_TYPE_QUAL, |
| /* RID_ONEWAY */ OBJC_TYPE_QUAL, |
| |
| /* C */ |
| /* RID_INT */ TYPESPEC, |
| /* RID_CHAR */ TYPESPEC, |
| /* RID_FLOAT */ TYPESPEC, |
| /* RID_DOUBLE */ TYPESPEC, |
| /* RID_VOID */ TYPESPEC, |
| /* RID_ENUM */ ENUM, |
| /* RID_STRUCT */ STRUCT, |
| /* RID_UNION */ UNION, |
| /* RID_IF */ IF, |
| /* RID_ELSE */ ELSE, |
| /* RID_WHILE */ WHILE, |
| /* RID_DO */ DO, |
| /* RID_FOR */ FOR, |
| /* RID_SWITCH */ SWITCH, |
| /* RID_CASE */ CASE, |
| /* RID_DEFAULT */ DEFAULT, |
| /* RID_BREAK */ BREAK, |
| /* RID_CONTINUE */ CONTINUE, |
| /* RID_RETURN */ RETURN, |
| /* RID_GOTO */ GOTO, |
| /* RID_SIZEOF */ SIZEOF, |
| |
| /* C extensions */ |
| /* RID_ASM */ ASM_KEYWORD, |
| /* RID_TYPEOF */ TYPEOF, |
| /* RID_ALIGNOF */ ALIGNOF, |
| /* RID_ATTRIBUTE */ ATTRIBUTE, |
| /* RID_VA_ARG */ VA_ARG, |
| /* RID_EXTENSION */ EXTENSION, |
| /* RID_IMAGPART */ IMAGPART, |
| /* RID_REALPART */ REALPART, |
| /* RID_LABEL */ LABEL, |
| |
| /* RID_CHOOSE_EXPR */ CHOOSE_EXPR, |
| /* RID_TYPES_COMPATIBLE_P */ TYPES_COMPATIBLE_P, |
| |
| /* RID_FUNCTION_NAME */ FUNC_NAME, |
| /* RID_PRETTY_FUNCTION_NAME */ FUNC_NAME, |
| /* RID_C99_FUNCTION_NAME */ FUNC_NAME, |
| |
| /* C++ */ |
| /* RID_BOOL */ TYPESPEC, |
| /* RID_WCHAR */ 0, |
| /* RID_CLASS */ 0, |
| /* RID_PUBLIC */ 0, |
| /* RID_PRIVATE */ 0, |
| /* RID_PROTECTED */ 0, |
| /* RID_TEMPLATE */ 0, |
| /* RID_NULL */ 0, |
| /* RID_CATCH */ 0, |
| /* RID_DELETE */ 0, |
| /* RID_FALSE */ 0, |
| /* RID_NAMESPACE */ 0, |
| /* RID_NEW */ 0, |
| /* RID_OFFSETOF */ OFFSETOF, |
| /* RID_OPERATOR */ 0, |
| /* RID_THIS */ 0, |
| /* RID_THROW */ 0, |
| /* RID_TRUE */ 0, |
| /* RID_TRY */ 0, |
| /* RID_TYPENAME */ 0, |
| /* RID_TYPEID */ 0, |
| /* RID_USING */ 0, |
| |
| /* casts */ |
| /* RID_CONSTCAST */ 0, |
| /* RID_DYNCAST */ 0, |
| /* RID_REINTCAST */ 0, |
| /* RID_STATCAST */ 0, |
| |
| /* Objective C */ |
| /* RID_AT_ENCODE */ AT_ENCODE, |
| /* RID_AT_END */ AT_END, |
| /* RID_AT_CLASS */ AT_CLASS, |
| /* RID_AT_ALIAS */ AT_ALIAS, |
| /* RID_AT_DEFS */ AT_DEFS, |
| /* APPLE LOCAL radar 4564694 */ |
| /* RID_AT_PACKAGE */ AT_PACKAGE, |
| /* RID_AT_PRIVATE */ AT_PRIVATE, |
| /* RID_AT_PROTECTED */ AT_PROTECTED, |
| /* RID_AT_PUBLIC */ AT_PUBLIC, |
| /* RID_AT_PROTOCOL */ AT_PROTOCOL, |
| /* RID_AT_SELECTOR */ AT_SELECTOR, |
| /* RID_AT_THROW */ AT_THROW, |
| /* RID_AT_TRY */ AT_TRY, |
| /* RID_AT_CATCH */ AT_CATCH, |
| /* RID_AT_FINALLY */ AT_FINALLY, |
| /* RID_AT_SYNCHRONIZED */ AT_SYNCHRONIZED, |
| /* RID_AT_INTERFACE */ AT_INTERFACE, |
| /* APPLE LOCAL begin C* language (in 4.2 not needed) */ |
| /* RID_AT_OPTIONAL */ AT_OPTIONAL, |
| /* RID_AT_REQUIRED */ AT_REQUIRED, |
| /* APPLE LOCAL end C* language (in 4.2 not needed) */ |
| /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 not needed) */ |
| /* RID_AT_PROPERTY */ AT_PROPERTY, |
| /* APPLE LOCAL begin objc new property */ |
| /* RID_AT_SYNTHESIZE */ AT_SYNTHESIZE, |
| /* RID_AT_DYNAMIC */ AT_DYNAMIC, |
| /* APPLE LOCAL end objc new property */ |
| /* RID_AT_IMPLEMENTATION */ AT_IMPLEMENTATION |
| }; |
| |
| static void |
| init_reswords (void) |
| { |
| unsigned int i; |
| tree id; |
| int mask = (flag_isoc99 ? 0 : D_C89) |
| | (flag_no_asm ? (flag_isoc99 ? D_EXT : D_EXT|D_EXT89) : 0); |
| |
| if (!c_dialect_objc ()) |
| mask |= D_OBJC; |
| |
| ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX); |
| for (i = 0; i < N_reswords; i++) |
| { |
| /* If a keyword is disabled, do not enter it into the table |
| and so create a canonical spelling that isn't a keyword. */ |
| if (reswords[i].disable & mask) |
| continue; |
| |
| id = get_identifier (reswords[i].word); |
| /* APPLE LOCAL begin objc new property */ |
| C_RID_CODE (id) = (!flag_objc_new_property || reswords[i].rid != RID_DYNAMIC) |
| ? reswords[i].rid : RID_AT_DYNAMIC; |
| /* APPLE LOCAL end objc new property */ |
| C_IS_RESERVED_WORD (id) = 1; |
| ridpointers [(int) reswords[i].rid] = id; |
| } |
| } |
| |
| #define NAME(type) cpp_type2name (type) |
| |
| static void |
| yyerror (const char *msgid) |
| { |
| c_parse_error (msgid, last_token, yylval.ttype); |
| } |
| |
| static int |
| yylexname (void) |
| { |
| tree decl; |
| |
| @@ifobjc |
| /* APPLE LOCAL begin Radar 4591909 */ |
| #define OBJC_IS_PATTR_EXT_KEYWORD(RID) (OBJC_IS_PATTR_KEYWORD(RID) \ |
| || (objc_property_attr_context \ |
| && ((unsigned int) (RID) == RID_BYCOPY \ |
| || (unsigned int) (RID) == RID_BYREF))) |
| /* APPLE LOCAL end Radar 4591909 */ |
| int objc_force_identifier = objc_need_raw_identifier; |
| OBJC_NEED_RAW_IDENTIFIER (0); |
| @@end_ifobjc |
| |
| if (C_IS_RESERVED_WORD (yylval.ttype)) |
| { |
| enum rid rid_code = C_RID_CODE (yylval.ttype); |
| |
| @@ifobjc |
| if (!OBJC_IS_AT_KEYWORD (rid_code) |
| /* APPLE LOCAL begin objc new property */ |
| && !OBJC_IS_NEW_AT_KEYWORD (rid_code) |
| && !OBJC_IS_NEW_PATTR_KEYWORD (rid_code) |
| /* APPLE LOCAL end objc new property */ |
| /* APPLE LOCAL C* property (Radar 4436866, 4591909) (in 4.2 ab, except for 4591909) */ |
| && !OBJC_IS_PATTR_EXT_KEYWORD (rid_code) |
| && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context)) |
| @@end_ifobjc |
| { |
| /* APPLE LOCAL begin CW asm blocks (in 4.2 ac) */ |
| /* Outside of function bodies, "asm" either indicates a CW asm |
| function, or a GNU asm statement, which must be immediately |
| followed by '(', so sniff the next token to see which kind |
| must be meant, and change the CW keyword to a different |
| token type so we don't have grammar problems. */ |
| int yycode = rid_to_yy[(int) rid_code]; |
| if (yycode == ASM_KEYWORD && current_function_decl == NULL) |
| { |
| tree next_tok; |
| /* Take a sneak peek at the next token in the stream. */ |
| enum cpp_ttype next_tok_type = c_lex (&next_tok); |
| /* Now put it back. */ |
| _cpp_backup_tokens (parse_in, 1); |
| /* Change the code. No need to change the name though, |
| won't matter to parser. */ |
| if (next_tok_type != CPP_OPEN_PAREN) |
| yycode = IASM_ASM_KEYWORD; |
| } |
| /* APPLE LOCAL end CW asm blocks (in 4.2 ac) */ |
| /* APPLE LOCAL begin CW asm blocks (in 4.2 ad) */ |
| if (IASM_SEE_OPCODE (TYPESPEC, yylval.ttype) == IDENTIFIER |
| && iasm_state >= iasm_decls |
| && iasm_in_operands == false) |
| { |
| /* If this was an opcode, prefer it. */ |
| return IDENTIFIER; |
| } |
| /* APPLE LOCAL end CW asm blocks (in 4.2 ad) */ |
| /* Return the canonical spelling for this keyword. */ |
| yylval.ttype = ridpointers[(int) rid_code]; |
| /* APPLE LOCAL CW asm blocks (in 4.2 not needed) */ |
| return yycode; |
| return rid_to_yy[(int) rid_code]; |
| } |
| /* APPLE LOCAL begin C* language (in 4.2 ae) */ |
| @@ifobjc |
| else if (c_dialect_objc () && |
| objc_foreach_context && rid_code == RID_IN) |
| { |
| tree next_tok; |
| /* Take a sneak peek at the next token in the stream. */ |
| enum cpp_ttype next_tok_type = c_lex (&next_tok); |
| /* Now put it back. */ |
| _cpp_backup_tokens (parse_in, 1); |
| switch (next_tok_type) |
| { |
| case CPP_NAME: |
| case CPP_OPEN_PAREN: |
| case CPP_MULT: |
| case CPP_PLUS: case CPP_PLUS_PLUS: |
| case CPP_MINUS: case CPP_MINUS_MINUS: |
| /* APPLE LOCAL radar 4529200 (in 4.2 af) */ |
| case CPP_OPEN_SQUARE: |
| return AT_IN; |
| |
| default: |
| break; |
| } |
| } |
| /* APPLE LOCAL begin C* property (Radar 4436866, 4591909) (in 4.2 ag, except for 4591909) */ |
| else if (c_dialect_objc () && |
| objc_property_attr_context && |
| /* APPLE LOCAL begin objc new property */ |
| (OBJC_IS_PATTR_EXT_KEYWORD (rid_code) || |
| (flag_objc_new_property && OBJC_IS_NEW_PATTR_KEYWORD (rid_code)))) |
| /* APPLE LOCAL end objc new property */ |
| { |
| tree next_tok; |
| enum cpp_ttype next_tok_type = c_lex (&next_tok); |
| /* Now put it back. */ |
| _cpp_backup_tokens (parse_in, 1); |
| if (rid_code == RID_READONLY) |
| return AT_READONLY; |
| if (rid_code == RID_BYCOPY) |
| return AT_PROP_BYCOPY; |
| if (rid_code == RID_BYREF) |
| return AT_PROP_BYREF; |
| if (rid_code == RID_DYNAMIC) |
| return AT_PROP_DYNAMIC; |
| if (rid_code == RID_IVAR) |
| return AT_IVAR; |
| /* APPLE LOCAL begin radar 4621020 */ |
| if (rid_code == RID_WEAK) |
| return AT_WEAK; |
| /* APPLE LOCAL end radar 4621020 */ |
| /* APPLE LOCAL begin objc new property */ |
| if (rid_code == RID_READWRITE) |
| return AT_READWRITE; |
| if (rid_code == RID_ASSIGN) |
| return AT_ASSIGN; |
| if (rid_code == RID_RETAIN) |
| return AT_RETAIN; |
| if (rid_code == RID_COPY) |
| return AT_COPY; |
| /* APPLE LOCAL end objc new property */ |
| /* APPLE LOCAL begin radar 4947014 - objc atomic property */ |
| if (rid_code == RID_NONATOMIC) |
| return AT_NONATOMIC; |
| /* APPLE LOCAL end radar 4947014 - objc atomic property */ |
| if (next_tok_type == CPP_EQ) |
| { |
| switch (rid_code) |
| { |
| case RID_GETTER: |
| return AT_GETTER; |
| case RID_SETTER: |
| return AT_SETTER; |
| |
| default: |
| break; |
| } |
| } |
| } |
| /* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 ag) */ |
| @@end_ifobjc |
| /* APPLE LOCAL end C* language (in 4.2 ae) */ |
| } |
| |
| decl = lookup_name (yylval.ttype); |
| if (decl) |
| { |
| if (TREE_CODE (decl) == TYPE_DECL) |
| return TYPENAME; |
| } |
| @@ifobjc |
| else |
| { |
| tree objc_interface_decl = objc_is_class_name (yylval.ttype); |
| /* ObjC class names are in the same namespace as variables and |
| typedefs, and hence are shadowed by local declarations. */ |
| if (objc_interface_decl |
| && (global_bindings_p () |
| || (!objc_force_identifier && !decl))) |
| { |
| yylval.ttype = objc_interface_decl; |
| return CLASSNAME; |
| } |
| } |
| @@end_ifobjc |
| |
| return IDENTIFIER; |
| } |
| |
| static inline int |
| _yylex (void) |
| { |
| get_next: |
| last_token = c_lex (&yylval.ttype); |
| switch (last_token) |
| { |
| case CPP_EQ: return '='; |
| case CPP_NOT: return '!'; |
| case CPP_GREATER: yylval.code = GT_EXPR; return ARITHCOMPARE; |
| case CPP_LESS: yylval.code = LT_EXPR; return ARITHCOMPARE; |
| case CPP_PLUS: yylval.code = PLUS_EXPR; return '+'; |
| case CPP_MINUS: yylval.code = MINUS_EXPR; return '-'; |
| case CPP_MULT: yylval.code = MULT_EXPR; return '*'; |
| case CPP_DIV: yylval.code = TRUNC_DIV_EXPR; return '/'; |
| case CPP_MOD: yylval.code = TRUNC_MOD_EXPR; return '%'; |
| case CPP_AND: yylval.code = BIT_AND_EXPR; return '&'; |
| case CPP_OR: yylval.code = BIT_IOR_EXPR; return '|'; |
| case CPP_XOR: yylval.code = BIT_XOR_EXPR; return '^'; |
| case CPP_RSHIFT: yylval.code = RSHIFT_EXPR; return RSHIFT; |
| case CPP_LSHIFT: yylval.code = LSHIFT_EXPR; return LSHIFT; |
| |
| case CPP_COMPL: return '~'; |
| case CPP_AND_AND: return ANDAND; |
| case CPP_OR_OR: return OROR; |
| case CPP_QUERY: return '?'; |
| case CPP_OPEN_PAREN: return '('; |
| case CPP_EQ_EQ: yylval.code = EQ_EXPR; return EQCOMPARE; |
| case CPP_NOT_EQ: yylval.code = NE_EXPR; return EQCOMPARE; |
| case CPP_GREATER_EQ:yylval.code = GE_EXPR; return ARITHCOMPARE; |
| case CPP_LESS_EQ: yylval.code = LE_EXPR; return ARITHCOMPARE; |
| |
| case CPP_PLUS_EQ: yylval.code = PLUS_EXPR; return ASSIGN; |
| case CPP_MINUS_EQ: yylval.code = MINUS_EXPR; return ASSIGN; |
| case CPP_MULT_EQ: yylval.code = MULT_EXPR; return ASSIGN; |
| case CPP_DIV_EQ: yylval.code = TRUNC_DIV_EXPR; return ASSIGN; |
| case CPP_MOD_EQ: yylval.code = TRUNC_MOD_EXPR; return ASSIGN; |
| case CPP_AND_EQ: yylval.code = BIT_AND_EXPR; return ASSIGN; |
| case CPP_OR_EQ: yylval.code = BIT_IOR_EXPR; return ASSIGN; |
| case CPP_XOR_EQ: yylval.code = BIT_XOR_EXPR; return ASSIGN; |
| case CPP_RSHIFT_EQ: yylval.code = RSHIFT_EXPR; return ASSIGN; |
| case CPP_LSHIFT_EQ: yylval.code = LSHIFT_EXPR; return ASSIGN; |
| |
| case CPP_OPEN_SQUARE: return '['; |
| case CPP_CLOSE_SQUARE: return ']'; |
| case CPP_OPEN_BRACE: return '{'; |
| case CPP_CLOSE_BRACE: return '}'; |
| case CPP_ELLIPSIS: return ELLIPSIS; |
| |
| case CPP_PLUS_PLUS: return PLUSPLUS; |
| case CPP_MINUS_MINUS: return MINUSMINUS; |
| case CPP_DEREF: return POINTSAT; |
| case CPP_DOT: return '.'; |
| |
| /* The following tokens may affect the interpretation of any |
| identifiers following, if doing Objective-C. */ |
| case CPP_COLON: OBJC_NEED_RAW_IDENTIFIER (0); return ':'; |
| case CPP_COMMA: OBJC_NEED_RAW_IDENTIFIER (0); return ','; |
| case CPP_CLOSE_PAREN: OBJC_NEED_RAW_IDENTIFIER (0); return ')'; |
| case CPP_SEMICOLON: OBJC_NEED_RAW_IDENTIFIER (0); return ';'; |
| |
| /* APPLE LOCAL begin CW asm blocks (in 4.2 not needed) */ |
| case CPP_ATSIGN: |
| /* If we're doing CW assembly, return this as a regular token |
| (indicates labels). */ |
| /* If we are not doing CW assembly and this symbol is seen. '@' has |
| not been consumed by the objc-lexer. This maybe because user forgot |
| to specify objc as the language or due to user error. Parser will decide. |
| */ |
| return '@'; |
| /* APPLE LOCAL end CW asm blocks */ |
| |
| case CPP_EOF: |
| return 0; |
| |
| case CPP_NAME: |
| return yylexname (); |
| |
| case CPP_AT_NAME: |
| /* This only happens in Objective-C; it must be a keyword. */ |
| return rid_to_yy [(int) C_RID_CODE (yylval.ttype)]; |
| |
| case CPP_NUMBER: |
| /* APPLE LOCAL begin CW asm blocks (in 4.2 ak) */ |
| if (cpp_get_options (parse_in)->h_suffix |
| && yylval.exprtype.value == error_mark_node) |
| { |
| /* This was previously deferred. */ |
| cpp_error (parse_in, CPP_DL_ERROR, "invalid suffix on integer constant"); |
| goto get_next; |
| } |
| /* APPLE LOCAL end CW asm blocks (in 4.2 ak) */ |
| case CPP_CHAR: |
| case CPP_WCHAR: |
| return CONSTANT; |
| |
| case CPP_STRING: |
| case CPP_WSTRING: |
| return STRING; |
| |
| /* APPLE LOCAL begin CW asm blocks (in 4.2 not needed) */ |
| /* Convert a lexer-returned beginning-of-line token into a |
| parser token. */ |
| case CPP_BOL: |
| return IASM_BOL; |
| case CPP_EOL: |
| return IASM_EOL; |
| /* APPLE LOCAL end CW asm blocks */ |
| |
| case CPP_OBJC_STRING: |
| return OBJC_STRING; |
| |
| /* These tokens are C++ specific (and will not be generated |
| in C mode, but let's be cautious). */ |
| case CPP_SCOPE: |
| case CPP_DEREF_STAR: |
| case CPP_DOT_STAR: |
| case CPP_MIN_EQ: |
| case CPP_MAX_EQ: |
| case CPP_MIN: |
| case CPP_MAX: |
| /* These tokens should not survive translation phase 4. */ |
| case CPP_HASH: |
| case CPP_PASTE: |
| /* APPLE LOCAL CW asm blocks C++ comments 4248139 */ |
| case CPP_OTHER: |
| error ("syntax error at %qs token", NAME(last_token)); |
| goto get_next; |
| |
| default: |
| abort (); |
| } |
| /* NOTREACHED */ |
| } |
| |
| static int |
| yylex (void) |
| { |
| int r; |
| timevar_push (TV_LEX); |
| r = _yylex(); |
| timevar_pop (TV_LEX); |
| return r; |
| } |
| |
| /* Function used when yydebug is set, to print a token in more detail. */ |
| |
| static void |
| yyprint (FILE *file, int yychar, YYSTYPE yyl) |
| { |
| tree t = yyl.ttype; |
| |
| fprintf (file, " [%s]", NAME(last_token)); |
| |
| switch (yychar) |
| { |
| case IDENTIFIER: |
| case TYPENAME: |
| case TYPESPEC: |
| case TYPE_QUAL: |
| case SCSPEC: |
| case STATIC: |
| if (IDENTIFIER_POINTER (t)) |
| fprintf (file, " '%s'", IDENTIFIER_POINTER (t)); |
| break; |
| |
| case CONSTANT: |
| fprintf (file, " %s", GET_MODE_NAME (TYPE_MODE (TREE_TYPE (t)))); |
| if (TREE_CODE (t) == INTEGER_CST) |
| { |
| fputs (" ", file); |
| fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, |
| TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t)); |
| } |
| break; |
| } |
| } |
| |
| /* This is not the ideal place to put this, but we have to get it out |
| of c-lex.c because cp/lex.c has its own version. */ |
| |
| /* Parse the file. */ |
| void |
| c_parse_file (void) |
| { |
| yyparse (); |
| |
| if (malloced_yyss) |
| { |
| free (malloced_yyss); |
| free (malloced_yyvs); |
| malloced_yyss = 0; |
| } |
| } |
| |
| /* APPLE LOCAL begin CW asm blocks (in 4.2 an) */ |
| static tree |
| c_parse_iasm_maybe_prefix (tree id) |
| { |
| tree prefix_list = NULL_TREE;; |
| |
| while (iasm_is_prefix (id)) |
| { |
| if (yychar == YYEMPTY) |
| yychar = YYLEX; |
| if (yychar == IDENTIFIER) |
| { |
| prefix_list = tree_cons (NULL_TREE, id, prefix_list); |
| id = yylval.ttype; |
| yychar = YYEMPTY; |
| } |
| else |
| break; |
| } |
| |
| if (prefix_list) |
| id = tree_cons (NULL_TREE, id, prefix_list); |
| |
| return id; |
| } |
| /* APPLE LOCAL end CW asm blocks */ |
| |
| #ifdef __XGETTEXT__ |
| /* Depending on the version of Bison used to compile this grammar, |
| it may issue generic diagnostics spelled "syntax error" or |
| "parse error". To prevent this from changing the translation |
| template randomly, we list all the variants of this particular |
| diagnostic here. Translators: there is no fine distinction |
| between diagnostics with "syntax error" in them, and diagnostics |
| with "parse error" in them. It's okay to give them both the same |
| translation. */ |
| const char d1[] = N_("syntax error"); |
| const char d2[] = N_("parse error"); |
| const char d3[] = N_("syntax error; also virtual memory exhausted"); |
| const char d4[] = N_("parse error; also virtual memory exhausted"); |
| const char d5[] = N_("syntax error: cannot back up"); |
| const char d6[] = N_("parse error: cannot back up"); |
| #endif |
| |
| #include "gt-c-parse.h" |