|
|
1.1 root 1: /* YACC parser for C syntax. 1.1.1.2 ! root 2: Copyright (C) 1987, 1988 Free Software Foundation, Inc. 1.1 root 3: 4: This file is part of GNU CC. 5: 6: GNU CC is distributed in the hope that it will be useful, 7: but WITHOUT ANY WARRANTY. No author or distributor 8: accepts responsibility to anyone for the consequences of using it 9: or for whether it serves any particular purpose or works at all, 10: unless he says so in writing. Refer to the GNU CC General Public 11: License for full details. 12: 13: Everyone is granted permission to copy, modify and redistribute 14: GNU CC, but only under the conditions described in the 15: GNU CC General Public License. A copy of this license is 16: supposed to have been given to you along with GNU CC so you 17: can know your rights and responsibilities. It should be in a 18: file named COPYING. Among other things, the copyright notice 19: and this notice must be preserved on all copies. */ 20: 21: 22: /* To whomever it may concern: I have heard that such a thing was once 23: written by AT&T, but I have never seen it. */ 24: 1.1.1.2 ! root 25: %expect 19 ! 26: ! 27: /* These are the 19 conflicts you should get in parse.output; ! 28: the state numbers may vary if minor changes in the grammar are made. ! 29: ! 30: State 41 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 31: State 96 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 32: State 100 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 33: State 116 contains 1 shift/reduce conflict. (See comment at component_decl.) ! 34: State 166 contains 2 shift/reduce conflicts. (make notype_declarator longer.) ! 35: State 241 contains 2 shift/reduce conflicts. (make absdcl1 longer if poss.) ! 36: State 275 contains 2 shift/reduce conflicts. (same for after_type_declarator). ! 37: State 306 contains 2 shift/reduce conflicts. (similar for absdcl1 again.) ! 38: State 314 contains 2 shift/reduce conflicts. (like 241, other context.) ! 39: State 318 contains 2 shift/reduce conflicts. (like 241, other context.) ! 40: State 362 contains 1 shift/reduce conflict. (dangling else.) ! 41: State 369 contains 2 shift/reduce conflicts. (like 166 for parm_declarator). ! 42: */ ! 43: 1.1 root 44: %{ 45: #include "config.h" 46: #include "tree.h" 47: #include "parse.h" 48: #include "c-tree.h" 1.1.1.2 ! root 49: #include "flags.h" ! 50: ! 51: #include <stdio.h> ! 52: ! 53: /* Cause the `yydebug' variable to be defined. */ ! 54: #define YYDEBUG 1.1 root 55: %} 56: 57: %start program 58: 1.1.1.2 ! root 59: %union {long itype; tree ttype; enum tree_code code; char *cptr; } 1.1 root 60: 1.1.1.2 ! root 61: /* All identifiers that are not reserved words 1.1 root 62: and are not declared typedefs in the current block */ 63: %token IDENTIFIER 1.1.1.2 ! root 64: ! 65: /* All identifiers that are declared typedefs in the current block. 1.1 root 66: In some contexts, they are treated just like IDENTIFIER, 67: but they can also serve as typespecs in declarations. */ 68: %token TYPENAME 69: 1.1.1.2 ! root 70: /* Reserved words that specify storage class. ! 71: yylval contains an IDENTIFIER_NODE which indicates which one. */ 1.1 root 72: %token SCSPEC 73: 1.1.1.2 ! root 74: /* Reserved words that specify type. ! 75: yylval contains an IDENTIFIER_NODE which indicates which one. */ 1.1 root 76: %token TYPESPEC 77: 1.1.1.2 ! root 78: /* Reserved words that qualify type: "const" or "volatile". ! 79: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 80: %token TYPE_QUAL 1.1 root 81: 1.1.1.2 ! root 82: /* Character or numeric constants. 1.1 root 83: yylval is the node for the constant. */ 84: %token CONSTANT 85: 86: /* String constants in raw form. 87: yylval is a STRING_CST node. */ 88: %token STRING 89: 90: /* "...", used for functions with variable arglists. */ 91: %token ELLIPSIS 92: 93: /* the reserved words */ 94: %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT 1.1.1.2 ! root 95: %token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF 1.1 root 96: 97: /* Define the operator tokens and their precedences. 98: The value is an integer because, if used, it is the tree code 99: to use in the expression made from the operator. */ 100: 101: %right <code> ASSIGN '=' 102: %right <code> '?' ':' 103: %left <code> OROR 104: %left <code> ANDAND 105: %left <code> '|' 106: %left <code> '^' 107: %left <code> '&' 108: %left <code> EQCOMPARE 109: %left <code> ARITHCOMPARE 110: %left <code> LSHIFT RSHIFT 111: %left <code> '+' '-' 112: %left <code> '*' '/' '%' 113: %right <code> UNARY PLUSPLUS MINUSMINUS 114: %left HYPERUNARY 115: %left <code> POINTSAT '.' 116: 117: %type <code> unop 118: 119: %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist 120: %type <ttype> expr_no_commas primary string STRING 1.1.1.2 ! root 121: %type <ttype> typed_declspecs reserved_declspecs ! 122: %type <ttype> typed_typespecs reserved_typespecquals ! 123: %type <ttype> declmods typespec typespecqual_reserved ! 124: %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual 1.1 root 125: %type <ttype> initdecls notype_initdecls initdcl notype_initdcl 1.1.1.2 ! root 126: %type <ttype> init initlist maybeasm ! 127: %type <ttype> asm_operands asm_operand 1.1 root 128: 129: %type <ttype> declarator 130: %type <ttype> notype_declarator after_type_declarator 1.1.1.2 ! root 131: %type <ttype> parm_declarator 1.1 root 132: 133: %type <ttype> structsp component_decl_list component_decl components component_declarator 134: %type <ttype> enumlist enumerator 1.1.1.2 ! root 135: %type <ttype> typename absdcl absdcl1 type_quals ! 136: %type <ttype> xexpr parms parm identifiers ! 137: ! 138: %type <ttype> parmlist parmlist_1 parmlist_2 ! 139: %type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1 ! 140: ! 141: %type <itype> setspecs 1.1 root 142: 143: %{ 144: /* the declaration found for the last IDENTIFIER token read in. 145: yylex must look this up to detect typedefs, which get token type TYPENAME, 146: so it is left around in case the identifier is not a typedef but is 147: used in a context which makes it a reference to a variable. */ 148: static tree lastiddecl; 149: 150: static tree make_pointer_declarator (); 151: static tree combine_strings (); 1.1.1.2 ! root 152: static void reinit_parse_for_function (); 1.1 root 153: 1.1.1.2 ! root 154: extern double atof (); ! 155: ! 156: /* List of types and structure classes of the current declaration */ 1.1 root 157: tree current_declspecs; 158: 1.1.1.2 ! root 159: char *input_filename; /* source file current line is coming from */ ! 160: char *main_input_filename; /* top-level source file */ 1.1 root 161: %} 162: 163: %% 1.1.1.2 ! root 164: program: /* empty */ ! 165: | extdefs 1.1 root 166: ; 167: 168: /* the reason for the strange actions in this rule 169: is so that notype_initdecls when reached via datadef 170: can find a valid list of type and sc specs in $0. */ 171: 172: extdefs: 1.1.1.2 ! root 173: {$<ttype>$ = NULL_TREE; } extdef ! 174: | extdefs {$<ttype>$ = NULL_TREE; } extdef 1.1 root 175: ; 176: 177: extdef: 178: fndef 179: | datadef 1.1.1.2 ! root 180: | ASM '(' string ')' ';' ! 181: { if (pedantic) ! 182: warning ("ANSI C forbids use of `asm' keyword"); ! 183: if (TREE_CHAIN ($3)) $3 = combine_strings ($3); ! 184: assemble_asm ($3); } 1.1 root 185: ; 186: 187: datadef: 188: setspecs notype_initdecls ';' 1.1.1.2 ! root 189: { if (pedantic) ! 190: error ("ANSI C forbids data definition lacking type or storage class"); ! 191: else ! 192: warning ("data definition lacks type or storage class"); } ! 193: | declmods setspecs notype_initdecls ';' 1.1 root 194: {} 195: | typed_declspecs setspecs initdecls ';' 196: {} 1.1.1.2 ! root 197: | declmods ';' ! 198: { error ("empty declaration"); } 1.1 root 199: | typed_declspecs ';' 200: { shadow_tag ($1); } 201: | error ';' 202: | error '}' 203: | ';' 204: ; 205: 206: fndef: 207: typed_declspecs setspecs declarator 208: { if (! start_function ($1, $3)) 1.1.1.2 ! root 209: YYFAIL; ! 210: reinit_parse_for_function (); } 1.1 root 211: xdecls 212: { store_parm_decls (); } 213: compstmt 1.1.1.2 ! root 214: { finish_function (input_filename, @7.first_line); } 1.1 root 215: | typed_declspecs setspecs declarator error 216: { } 1.1.1.2 ! root 217: | declmods setspecs notype_declarator 1.1 root 218: { if (! start_function ($1, $3)) 1.1.1.2 ! root 219: YYFAIL; ! 220: reinit_parse_for_function (); } 1.1 root 221: xdecls 222: { store_parm_decls (); } 223: compstmt 1.1.1.2 ! root 224: { finish_function (input_filename, @7.first_line); } ! 225: | declmods setspecs notype_declarator error 1.1 root 226: { } 227: | setspecs notype_declarator 228: { if (! start_function (0, $2)) 1.1.1.2 ! root 229: YYFAIL; ! 230: reinit_parse_for_function (); } 1.1 root 231: xdecls 232: { store_parm_decls (); } 233: compstmt 1.1.1.2 ! root 234: { finish_function (input_filename, @6.first_line); } 1.1 root 235: | setspecs notype_declarator error 1.1.1.2 ! root 236: { } 1.1 root 237: ; 238: 239: identifier: 240: IDENTIFIER 241: | TYPENAME 242: ; 243: 244: unop: '&' 245: { $$ = ADDR_EXPR; } 246: | '-' 247: { $$ = NEGATE_EXPR; } 248: | '+' 249: { $$ = CONVERT_EXPR; } 250: | PLUSPLUS 251: { $$ = PREINCREMENT_EXPR; } 252: | MINUSMINUS 253: { $$ = PREDECREMENT_EXPR; } 254: | '~' 255: { $$ = BIT_NOT_EXPR; } 256: | '!' 257: { $$ = TRUTH_NOT_EXPR; } 258: ; 259: 260: expr: nonnull_exprlist 1.1.1.2 ! root 261: { $$ = build_compound_expr ($1); } 1.1 root 262: ; 263: 264: exprlist: 265: /* empty */ 266: { $$ = NULL_TREE; } 267: | nonnull_exprlist 268: ; 269: 270: nonnull_exprlist: 271: expr_no_commas 272: { $$ = build_tree_list (NULL_TREE, $1); } 273: | nonnull_exprlist ',' expr_no_commas 274: { chainon ($1, build_tree_list (NULL_TREE, $3)); } 275: ; 276: 277: expr_no_commas: 278: primary 279: | '*' expr_no_commas %prec UNARY 1.1.1.2 ! root 280: { $$ = build_indirect_ref ($2, "unary *"); } 1.1 root 281: | unop expr_no_commas %prec UNARY 282: { $$ = build_unary_op ($1, $2, 0); } 283: | '(' typename ')' expr_no_commas %prec UNARY 1.1.1.2 ! root 284: { tree type = groktypename ($2); ! 285: $$ = build_c_cast (type, $4); } ! 286: | '(' typename ')' '{' initlist maybecomma '}' %prec UNARY ! 287: { tree type = groktypename ($2); ! 288: if (pedantic) ! 289: warning ("ANSI C forbids constructor-expressions"); ! 290: $$ = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5)), 0); ! 291: if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) ! 292: { ! 293: int failure = complete_array_type (type, $$, 1); ! 294: if (failure) ! 295: abort (); ! 296: } ! 297: } 1.1 root 298: | SIZEOF expr_no_commas %prec UNARY 1.1.1.2 ! root 299: { if (TREE_CODE ($2) == COMPONENT_REF ! 300: && TREE_PACKED (TREE_OPERAND ($2, 1))) ! 301: error ("sizeof applied to a bit-field"); ! 302: $$ = c_sizeof (TREE_TYPE ($2)); } 1.1 root 303: | SIZEOF '(' typename ')' %prec HYPERUNARY 1.1.1.2 ! root 304: { $$ = c_sizeof (groktypename ($3)); } ! 305: | ALIGNOF expr_no_commas %prec UNARY ! 306: { if (TREE_CODE ($2) == COMPONENT_REF ! 307: && TREE_PACKED (TREE_OPERAND ($2, 1))) ! 308: error ("__alignof applied to a bit-field"); ! 309: $$ = c_alignof (TREE_TYPE ($2)); } ! 310: | ALIGNOF '(' typename ')' %prec HYPERUNARY ! 311: { $$ = c_alignof (groktypename ($3)); } 1.1 root 312: | expr_no_commas '+' expr_no_commas 313: { $$ = build_binary_op ($2, $1, $3); } 314: | expr_no_commas '-' expr_no_commas 315: { $$ = build_binary_op ($2, $1, $3); } 316: | expr_no_commas '*' expr_no_commas 317: { $$ = build_binary_op ($2, $1, $3); } 318: | expr_no_commas '/' expr_no_commas 319: { $$ = build_binary_op ($2, $1, $3); } 320: | expr_no_commas '%' expr_no_commas 321: { $$ = build_binary_op ($2, $1, $3); } 322: | expr_no_commas LSHIFT expr_no_commas 323: { $$ = build_binary_op ($2, $1, $3); } 324: | expr_no_commas RSHIFT expr_no_commas 325: { $$ = build_binary_op ($2, $1, $3); } 326: | expr_no_commas ARITHCOMPARE expr_no_commas 327: { $$ = build_binary_op ($2, $1, $3); } 328: | expr_no_commas EQCOMPARE expr_no_commas 329: { $$ = build_binary_op ($2, $1, $3); } 330: | expr_no_commas '&' expr_no_commas 331: { $$ = build_binary_op ($2, $1, $3); } 332: | expr_no_commas '|' expr_no_commas 333: { $$ = build_binary_op ($2, $1, $3); } 334: | expr_no_commas '^' expr_no_commas 335: { $$ = build_binary_op ($2, $1, $3); } 336: | expr_no_commas ANDAND expr_no_commas 337: { $$ = build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); } 338: | expr_no_commas OROR expr_no_commas 339: { $$ = build_binary_op (TRUTH_ORIF_EXPR, $1, $3); } 1.1.1.2 ! root 340: | expr_no_commas '?' xexpr ':' expr_no_commas ! 341: { $$ = build_conditional_expr ($1, $3, $5); } 1.1 root 342: | expr_no_commas '=' expr_no_commas 1.1.1.2 ! root 343: { $$ = build_modify_expr ($1, NOP_EXPR, $3); } 1.1 root 344: | expr_no_commas ASSIGN expr_no_commas 1.1.1.2 ! root 345: { $$ = build_modify_expr ($1, $2, $3); } 1.1 root 346: ; 347: 348: primary: 349: IDENTIFIER 350: { $$ = lastiddecl; 351: if (!$$) 352: { 353: if (yychar == YYEMPTY) 354: yychar = YYLEX; 355: if (yychar == '(') 1.1.1.2 ! root 356: $$ = implicitly_declare ($1); 1.1 root 357: else 358: { 1.1.1.2 ! root 359: if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node) ! 360: error ("undeclared variable `%s' (first use here)", ! 361: IDENTIFIER_POINTER ($1)); 1.1 root 362: $$ = error_mark_node; 1.1.1.2 ! root 363: /* Prevent repeated error messages. */ ! 364: IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node; 1.1 root 365: } 366: } 367: if (TREE_CODE ($$) == CONST_DECL) 368: $$ = DECL_INITIAL ($$); 369: } 370: | CONSTANT 371: | string 372: { $$ = combine_strings ($1); } 373: | '(' expr ')' 374: { $$ = $2; } 375: | '(' error ')' 376: { $$ = error_mark_node; } 1.1.1.2 ! root 377: | '(' ! 378: { if (current_function_decl == 0) ! 379: { ! 380: error ("braced-group within expression allowed only inside a function"); ! 381: YYFAIL; ! 382: } ! 383: expand_start_stmt_expr (); } ! 384: compstmt ')' ! 385: { if (pedantic) ! 386: warning ("ANSI C forbids braced-groups within expressions"); ! 387: $$ = get_last_expr (); ! 388: expand_end_stmt_expr (); } 1.1 root 389: | primary '(' exprlist ')' %prec '.' 390: { $$ = build_function_call ($1, $3); } 391: | primary '[' expr ']' %prec '.' 392: { $$ = build_array_ref ($1, $3); } 393: | primary '.' identifier 1.1.1.2 ! root 394: { $$ = build_component_ref ($1, $3); } 1.1 root 395: | primary POINTSAT identifier 1.1.1.2 ! root 396: { $$ = build_component_ref (build_indirect_ref ($1, "->"), $3); } 1.1 root 397: | primary PLUSPLUS 398: { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); } 399: | primary MINUSMINUS 400: { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); } 401: ; 402: 403: /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */ 404: string: 405: STRING 406: | string STRING 407: { $$ = chainon ($1, $2); } 408: ; 409: 410: xdecls: 411: /* empty */ 412: | decls 413: ; 414: 415: decls: 416: decl 417: | errstmt 418: | decls decl 419: | decl errstmt 420: ; 421: 422: /* records the type and storage class specs to use for processing 423: the declarators that follow */ 424: setspecs: /* empty */ 1.1.1.2 ! root 425: { current_declspecs = $<ttype>0; ! 426: $$ = suspend_momentary (); } 1.1 root 427: ; 428: 429: decl: 430: typed_declspecs setspecs initdecls ';' 1.1.1.2 ! root 431: { resume_momentary ($2); } ! 432: | declmods setspecs notype_initdecls ';' ! 433: { resume_momentary ($2); } 1.1 root 434: | typed_declspecs ';' 435: { shadow_tag ($1); } 1.1.1.2 ! root 436: | declmods ';' 1.1 root 437: { warning ("empty declaration"); } 438: ; 439: 1.1.1.2 ! root 440: /* Declspecs which contain at least one type specifier or typedef name. ! 441: (Just `const' or `volatile' is not enough.) 1.1 root 442: A typedef'd name following these is taken as a name to be declared. */ 1.1.1.2 ! root 443: 1.1 root 444: typed_declspecs: 1.1.1.2 ! root 445: typespec reserved_declspecs ! 446: { $$ = tree_cons (NULL_TREE, $1, $2); } ! 447: | declmods typespec reserved_declspecs ! 448: { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); } ! 449: ; ! 450: ! 451: reserved_declspecs: /* empty */ ! 452: { $$ = NULL_TREE; } ! 453: | reserved_declspecs typespecqual_reserved 1.1 root 454: { $$ = tree_cons (NULL_TREE, $2, $1); } 1.1.1.2 ! root 455: | reserved_declspecs SCSPEC 1.1 root 456: { $$ = tree_cons (NULL_TREE, $2, $1); } 1.1.1.2 ! root 457: ; ! 458: ! 459: /* List of just storage classes and type modifiers. ! 460: A declaration can start with just this, but then it cannot be used ! 461: to redeclare a typedef-name. */ ! 462: ! 463: declmods: ! 464: TYPE_QUAL ! 465: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 466: | SCSPEC ! 467: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 468: | declmods TYPE_QUAL 1.1 root 469: { $$ = tree_cons (NULL_TREE, $2, $1); } 1.1.1.2 ! root 470: | declmods SCSPEC 1.1 root 471: { $$ = tree_cons (NULL_TREE, $2, $1); } 472: ; 473: 1.1.1.2 ! root 474: ! 475: /* Used instead of declspecs where storage classes are not allowed ! 476: (that is, for typenames and structure components). ! 477: Don't accept a typedef-name if anything but a modifier precedes it. */ ! 478: ! 479: typed_typespecs: ! 480: typespec reserved_typespecquals ! 481: { $$ = tree_cons (NULL_TREE, $1, $2); } ! 482: | nonempty_type_quals typespec reserved_typespecquals ! 483: { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); } 1.1 root 484: ; 485: 1.1.1.2 ! root 486: reserved_typespecquals: /* empty */ ! 487: { $$ = NULL_TREE; } ! 488: | reserved_typespecquals typespecqual_reserved 1.1 root 489: { $$ = tree_cons (NULL_TREE, $2, $1); } 490: ; 491: 1.1.1.2 ! root 492: /* A typespec (but not a type qualifier). ! 493: Once we have seen one of these in a declaration, ! 494: if a typedef name appears then it is being redeclared. */ ! 495: 1.1 root 496: typespec: TYPESPEC 497: | structsp 498: | TYPENAME 1.1.1.2 ! root 499: | TYPEOF '(' expr ')' ! 500: { $$ = TREE_TYPE ($3); ! 501: if (pedantic) ! 502: warning ("ANSI C forbids `typeof'") } ! 503: | TYPEOF '(' typename ')' ! 504: { $$ = groktypename ($3); ! 505: if (pedantic) ! 506: warning ("ANSI C forbids `typeof'") } ! 507: ; ! 508: ! 509: /* A typespec that is a reserved word, or a type qualifier. */ ! 510: ! 511: typespecqual_reserved: TYPESPEC ! 512: | TYPE_QUAL ! 513: | structsp 1.1 root 514: ; 515: 516: initdecls: 517: initdcl 518: | initdecls ',' initdcl 519: ; 520: 521: notype_initdecls: 522: notype_initdcl 523: | notype_initdecls ',' initdcl 524: ; 525: 1.1.1.2 ! root 526: maybeasm: ! 527: /* empty */ ! 528: { $$ = NULL_TREE; } ! 529: | ASM '(' string ')' ! 530: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); ! 531: $$ = $3; ! 532: if (pedantic) ! 533: warning ("ANSI C forbids use of `asm' keyword"); ! 534: } ! 535: ; ! 536: 1.1 root 537: initdcl: 1.1.1.2 ! root 538: declarator maybeasm '=' 1.1 root 539: { $<ttype>$ = start_decl ($1, current_declspecs, 1); } 540: init 541: /* Note how the declaration of the variable is in effect while its init is parsed! */ 1.1.1.2 ! root 542: { finish_decl ($<ttype>4, $5, $2); } ! 543: | declarator maybeasm 1.1 root 544: { tree d = start_decl ($1, current_declspecs, 0); 1.1.1.2 ! root 545: finish_decl (d, NULL_TREE, $2); } 1.1 root 546: ; 547: 548: notype_initdcl: 1.1.1.2 ! root 549: notype_declarator maybeasm '=' 1.1 root 550: { $<ttype>$ = start_decl ($1, current_declspecs, 1); } 551: init 552: /* Note how the declaration of the variable is in effect while its init is parsed! */ 1.1.1.2 ! root 553: { finish_decl ($<ttype>4, $5, $2); } ! 554: | notype_declarator maybeasm 1.1 root 555: { tree d = start_decl ($1, current_declspecs, 0); 1.1.1.2 ! root 556: finish_decl (d, NULL_TREE, $2); } 1.1 root 557: ; 558: 559: init: 560: expr_no_commas 561: | '{' initlist '}' 1.1.1.2 ! root 562: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); } 1.1 root 563: | '{' initlist ',' '}' 1.1.1.2 ! root 564: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); } ! 565: | error ! 566: { $$ = NULL_TREE; } 1.1 root 567: ; 568: 569: /* This chain is built in reverse order, 570: and put in forward order where initlist is used. */ 571: initlist: 572: init 573: { $$ = build_tree_list (NULL_TREE, $1); } 574: | initlist ',' init 1.1.1.2 ! root 575: { $$ = tree_cons (NULL_TREE, $3, $1); } 1.1 root 576: ; 577: 578: /* Any kind of declarator (thus, all declarators allowed 579: after an explicit typespec). */ 580: 581: declarator: 582: after_type_declarator 583: | notype_declarator 584: ; 585: 586: /* A declarator that is allowed only after an explicit typespec. */ 587: 588: after_type_declarator: 1.1.1.2 ! root 589: '(' after_type_declarator ')' ! 590: { $$ = $2; } ! 591: | after_type_declarator '(' parmlist_or_identifiers %prec '.' ! 592: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 593: /* | after_type_declarator '(' error ')' %prec '.' ! 594: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); ! 595: poplevel (0, 0, 0); } */ 1.1 root 596: | after_type_declarator '[' expr ']' %prec '.' 1.1.1.2 ! root 597: { $$ = build_nt (ARRAY_REF, $1, $3); } 1.1 root 598: | after_type_declarator '[' ']' %prec '.' 1.1.1.2 ! root 599: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 600: | '*' type_quals after_type_declarator %prec UNARY ! 601: { $$ = make_pointer_declarator ($2, $3); } ! 602: | TYPENAME ! 603: ; ! 604: ! 605: /* Kinds of declarator that can appear in a parameter list ! 606: in addition to notype_declarator. This is like after_type_declarator ! 607: but does not allow a typedef name in parentheses as an identifier ! 608: (because it would conflict with a function with that typedef as arg). */ ! 609: ! 610: parm_declarator: ! 611: parm_declarator '(' parmlist_or_identifiers %prec '.' ! 612: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 613: /* | parm_declarator '(' error ')' %prec '.' ! 614: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); ! 615: poplevel (0, 0, 0); } */ ! 616: | parm_declarator '[' expr ']' %prec '.' ! 617: { $$ = build_nt (ARRAY_REF, $1, $3); } ! 618: | parm_declarator '[' ']' %prec '.' ! 619: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 620: | '*' type_quals parm_declarator %prec UNARY ! 621: { $$ = make_pointer_declarator ($2, $3); } 1.1 root 622: | TYPENAME 623: ; 624: 625: /* A declarator allowed whether or not there has been 626: an explicit typespec. These cannot redeclare a typedef-name. */ 627: 628: notype_declarator: 1.1.1.2 ! root 629: notype_declarator '(' parmlist_or_identifiers %prec '.' ! 630: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 631: /* | notype_declarator '(' error ')' %prec '.' ! 632: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); ! 633: poplevel (0, 0, 0); } */ 1.1 root 634: | '(' notype_declarator ')' 635: { $$ = $2; } 1.1.1.2 ! root 636: | '*' type_quals notype_declarator %prec UNARY 1.1 root 637: { $$ = make_pointer_declarator ($2, $3); } 638: | notype_declarator '[' expr ']' %prec '.' 1.1.1.2 ! root 639: { $$ = build_nt (ARRAY_REF, $1, $3); } 1.1 root 640: | notype_declarator '[' ']' %prec '.' 1.1.1.2 ! root 641: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } 1.1 root 642: | IDENTIFIER 643: ; 644: 645: structsp: 1.1.1.2 ! root 646: STRUCT identifier '{' ! 647: { $$ = start_struct (RECORD_TYPE, $2); ! 648: /* Start scope of tag before parsing components. */ ! 649: } ! 650: component_decl_list '}' ! 651: { $$ = finish_struct ($<ttype>4, $5); ! 652: /* Really define the structure. */ ! 653: } 1.1 root 654: | STRUCT '{' component_decl_list '}' 1.1.1.2 ! root 655: { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE), ! 656: $3); } 1.1 root 657: | STRUCT identifier 1.1.1.2 ! root 658: { $$ = xref_tag (RECORD_TYPE, $2); } ! 659: | UNION identifier '{' ! 660: { $$ = start_struct (UNION_TYPE, $2); } ! 661: component_decl_list '}' ! 662: { $$ = finish_struct ($<ttype>4, $5); } 1.1 root 663: | UNION '{' component_decl_list '}' 1.1.1.2 ! root 664: { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE), ! 665: $3); } 1.1 root 666: | UNION identifier 1.1.1.2 ! root 667: { $$ = xref_tag (UNION_TYPE, $2); } 1.1 root 668: | ENUM identifier '{' 1.1.1.2 ! root 669: { $<itype>3 = suspend_momentary (); ! 670: $$ = start_enum ($2); } ! 671: enumlist maybecomma '}' ! 672: { $$ = finish_enum ($<ttype>4, nreverse ($5)); ! 673: resume_momentary ($<itype>3); } 1.1 root 674: | ENUM '{' 1.1.1.2 ! root 675: { $<itype>2 = suspend_momentary (); ! 676: $$ = start_enum (NULL_TREE); } ! 677: enumlist maybecomma '}' ! 678: { $$ = finish_enum ($<ttype>3, nreverse ($4)); ! 679: resume_momentary ($<itype>2); } 1.1 root 680: | ENUM identifier 1.1.1.2 ! root 681: { $$ = xref_tag (ENUMERAL_TYPE, $2); } ! 682: ; ! 683: ! 684: maybecomma: ! 685: /* empty */ ! 686: | ',' 1.1 root 687: ; 688: 689: component_decl_list: /* empty */ 690: { $$ = NULL_TREE; } 1.1.1.2 ! root 691: | component_decl_list component_decl ';' ! 692: { $$ = chainon ($1, $2); } 1.1 root 693: | component_decl_list ';' 1.1.1.2 ! root 694: { if (pedantic) ! 695: warning ("extra semicolon in struct or union specified"); } 1.1 root 696: ; 697: 1.1.1.2 ! root 698: /* There is a shift-reduce conflict here, because `components' may ! 699: start with a `typename'. It happens that shifting (the default resolution) ! 700: does the right thing, because it treats the `typename' as part of ! 701: a `typed_typespecs'. ! 702: ! 703: It is possible that this same technique would allow the distinction ! 704: between `notype_initdecls' and `initdecls' to be eliminated. ! 705: But I am being cautious and not trying it. */ ! 706: 1.1 root 707: component_decl: 1.1.1.2 ! root 708: typed_typespecs setspecs components ! 709: { $$ = $3; ! 710: resume_momentary ($2); } ! 711: | nonempty_type_quals setspecs components ! 712: { $$ = $3; ! 713: resume_momentary ($2); } 1.1 root 714: | error 1.1.1.2 ! root 715: { $$ = NULL_TREE; } 1.1 root 716: ; 717: 718: components: 719: /* empty */ 720: { $$ = NULL_TREE; } 721: | component_declarator 722: | components ',' component_declarator 723: { $$ = chainon ($1, $3); } 724: ; 725: 726: component_declarator: 727: declarator 728: { $$ = grokfield (input_filename, @1.first_line, $1, current_declspecs, NULL_TREE); } 729: | declarator ':' expr_no_commas 730: { $$ = grokfield (input_filename, @1.first_line, $1, current_declspecs, $3); } 731: | ':' expr_no_commas 732: { $$ = grokfield (input_filename, @1.first_line, NULL_TREE, current_declspecs, $2); } 733: ; 734: 735: /* We chain the enumerators in reverse order. 736: They are put in forward order where enumlist is used. 737: (The order used to be significant, but no longer is so. 738: However, we still maintain the order, just to be clean.) */ 739: 740: enumlist: 741: enumerator 742: | enumlist ',' enumerator 743: { $$ = chainon ($3, $1); } 744: ; 745: 746: 747: enumerator: 748: identifier 749: { $$ = build_enumerator ($1, NULL_TREE); } 750: | identifier '=' expr_no_commas 751: { $$ = build_enumerator ($1, $3); } 752: ; 753: 754: typename: 1.1.1.2 ! root 755: typed_typespecs absdcl ! 756: { $$ = build_tree_list ($1, $2); } ! 757: | nonempty_type_quals absdcl 1.1 root 758: { $$ = build_tree_list ($1, $2); } 759: ; 760: 761: absdcl: /* an absolute declarator */ 762: /* empty */ 763: { $$ = NULL_TREE; } 764: | absdcl1 765: ; 766: 1.1.1.2 ! root 767: nonempty_type_quals: ! 768: TYPE_QUAL ! 769: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 770: | nonempty_type_quals TYPE_QUAL ! 771: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 772: ; ! 773: ! 774: type_quals: 1.1 root 775: /* empty */ 776: { $$ = NULL_TREE; } 1.1.1.2 ! root 777: | type_quals TYPE_QUAL 1.1 root 778: { $$ = tree_cons (NULL_TREE, $2, $1); } 779: ; 780: 781: absdcl1: /* a nonempty absolute declarator */ 782: '(' absdcl1 ')' 783: { $$ = $2; } 1.1.1.2 ! root 784: /* `(typedef)1' is `int'. */ ! 785: | '*' type_quals absdcl1 %prec UNARY 1.1 root 786: { $$ = make_pointer_declarator ($2, $3); } 1.1.1.2 ! root 787: | '*' type_quals %prec UNARY 1.1 root 788: { $$ = make_pointer_declarator ($2, NULL_TREE); } 1.1.1.2 ! root 789: | absdcl1 '(' parmlist %prec '.' ! 790: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } 1.1 root 791: | absdcl1 '[' expr ']' %prec '.' 1.1.1.2 ! root 792: { $$ = build_nt (ARRAY_REF, $1, $3); } 1.1 root 793: | absdcl1 '[' ']' %prec '.' 1.1.1.2 ! root 794: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 795: | '(' parmlist %prec '.' ! 796: { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); } 1.1 root 797: | '[' expr ']' %prec '.' 1.1.1.2 ! root 798: { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); } 1.1 root 799: | '[' ']' %prec '.' 1.1.1.2 ! root 800: { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); } 1.1 root 801: ; 802: 803: /* at least one statement, the first of which parses without error. */ 804: /* stmts is used only after decls, so an invalid first statement 805: is actually regarded as an invalid decl and part of the decls. */ 806: 807: stmts: 808: stmt 809: | stmts stmt 810: | stmts errstmt 811: ; 812: 1.1.1.2 ! root 813: xstmts: ! 814: /* empty */ ! 815: | stmts 1.1 root 816: ; 817: 1.1.1.2 ! root 818: errstmt: error ';' ! 819: ; 1.1 root 820: 821: pushlevel: /* empty */ 1.1.1.2 ! root 822: { pushlevel (0); ! 823: clear_last_expr (); ! 824: push_momentary (); ! 825: expand_start_bindings (0); } 1.1 root 826: ; 827: 828: compstmt: '{' '}' 1.1.1.2 ! root 829: | '{' pushlevel decls xstmts '}' ! 830: { expand_end_bindings (getdecls (), 1); ! 831: poplevel (1, 1, 0); ! 832: pop_momentary (); } 1.1 root 833: | '{' pushlevel error '}' 1.1.1.2 ! root 834: { expand_end_bindings (getdecls (), 0); ! 835: poplevel (0, 0, 0); ! 836: pop_momentary (); } 1.1 root 837: | '{' pushlevel stmts '}' 1.1.1.2 ! root 838: { expand_end_bindings (getdecls (), 0); ! 839: poplevel (0, 0, 0); ! 840: pop_momentary (); } 1.1 root 841: ; 842: 1.1.1.2 ! root 843: simple_if: ! 844: IF '(' expr ')' ! 845: { emit_note (input_filename, @1.first_line); ! 846: expand_start_cond (truthvalue_conversion ($3), 0); } ! 847: stmt ! 848: ; ! 849: ! 850: stmt: ! 851: compstmt 1.1 root 852: | expr ';' 1.1.1.2 ! root 853: { emit_note (input_filename, @1.first_line); ! 854: expand_expr_stmt ($1); ! 855: clear_momentary (); } ! 856: | simple_if ELSE ! 857: { expand_start_else (); } ! 858: stmt ! 859: { expand_end_else (); } ! 860: | simple_if ! 861: { expand_end_cond (); } 1.1 root 862: | WHILE 1.1.1.2 ! root 863: { emit_note (input_filename, @1.first_line); ! 864: expand_start_loop (1); } ! 865: '(' expr ')' ! 866: { expand_exit_loop_if_false (truthvalue_conversion ($4)); } ! 867: stmt ! 868: { expand_end_loop (); } 1.1 root 869: | DO 1.1.1.2 ! root 870: { emit_note (input_filename, @1.first_line); ! 871: expand_start_loop_continue_elsewhere (1); } ! 872: stmt WHILE ! 873: { expand_loop_continue_here (); } ! 874: '(' expr ')' ';' ! 875: { emit_note (input_filename, @7.first_line); ! 876: expand_exit_loop_if_false (truthvalue_conversion ($7)); ! 877: expand_end_loop (); ! 878: clear_momentary (); } 1.1 root 879: | FOR 1.1.1.2 ! root 880: '(' xexpr ';' ! 881: { emit_note (input_filename, @1.first_line); ! 882: if ($3) expand_expr_stmt ($3); ! 883: expand_start_loop_continue_elsewhere (1); } ! 884: xexpr ';' ! 885: { emit_note (input_filename, @6.first_line); ! 886: if ($6) ! 887: expand_exit_loop_if_false (truthvalue_conversion ($6)); } ! 888: xexpr ')' ! 889: /* Don't let the tree nodes for $9 be discarded ! 890: by clear_momentary during the parsing of the next stmt. */ ! 891: { push_momentary (); } ! 892: stmt ! 893: { emit_note (input_filename, @9.first_line); ! 894: expand_loop_continue_here (); ! 895: if ($9) ! 896: { ! 897: expand_expr_stmt ($9); ! 898: } ! 899: pop_momentary (); ! 900: expand_end_loop (); } 1.1 root 901: | SWITCH '(' expr ')' 1.1.1.2 ! root 902: { emit_note (input_filename, @1.first_line); ! 903: c_expand_start_case ($3); ! 904: /* Don't let the tree nodes for $3 be discarded by ! 905: clear_momentary during the parsing of the next stmt. */ ! 906: push_momentary (); } 1.1 root 907: stmt 1.1.1.2 ! root 908: { expand_end_case (); ! 909: pop_momentary (); } ! 910: | CASE expr ':' ! 911: { register tree value = fold ($2); ! 912: register tree label ! 913: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); 1.1 root 914: 1.1.1.2 ! root 915: if (TREE_CODE (value) != INTEGER_CST ! 916: && value != error_mark_node) 1.1 root 917: { 1.1.1.2 ! root 918: error ("case label does not reduce to an integer constant"); 1.1 root 919: value = error_mark_node; 920: } 921: else 1.1.1.2 ! root 922: /* Promote char or short to int. */ ! 923: value = default_conversion (value); ! 924: if (value != error_mark_node) 1.1 root 925: { 1.1.1.2 ! root 926: int success = pushcase (value, label); ! 927: if (success == 1) ! 928: error ("case label not within a switch statement"); ! 929: else if (success == 2) ! 930: error ("duplicate case value"); ! 931: else if (success == 3) ! 932: warning ("case value out of range"); 1.1 root 933: } 934: } 1.1.1.2 ! root 935: stmt ! 936: | DEFAULT ':' ! 937: { ! 938: register tree label ! 939: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 940: int success = pushcase (NULL_TREE, label); ! 941: if (success == 1) ! 942: error ("default label not within a switch statement"); ! 943: else if (success == 2) ! 944: error ("multiple default labels in one switch"); 1.1 root 945: } 1.1.1.2 ! root 946: stmt ! 947: | BREAK ';' ! 948: { emit_note (input_filename, @1.first_line); ! 949: if ( ! expand_exit_something ()) ! 950: error ("break statement not within loop or switch"); } ! 951: | CONTINUE ';' ! 952: { emit_note (input_filename, @1.first_line); ! 953: if (! expand_continue_loop ()) ! 954: error ("continue statement not within a loop"); } 1.1 root 955: | RETURN ';' 1.1.1.2 ! root 956: { emit_note (input_filename, @1.first_line); ! 957: c_expand_return (NULL_TREE); } 1.1 root 958: | RETURN expr ';' 1.1.1.2 ! root 959: { emit_note (input_filename, @1.first_line); ! 960: c_expand_return ($2); } ! 961: | ASM maybe_type_qual '(' string ')' ';' ! 962: { if (pedantic) ! 963: warning ("ANSI C forbids use of `asm' keyword"); ! 964: emit_note (input_filename, @1.first_line); ! 965: if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 966: expand_asm ($4); } ! 967: /* This is the case with just output operands. */ ! 968: | ASM maybe_type_qual '(' string ':' asm_operands ')' ';' ! 969: { if (pedantic) ! 970: warning ("ANSI C forbids use of `asm' keyword"); ! 971: emit_note (input_filename, @1.first_line); ! 972: if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 973: c_expand_asm_operands ($4, $6, NULL_TREE, ! 974: $2 == ridpointers[(int)RID_VOLATILE]); } ! 975: /* This is the case with input operands as well. */ ! 976: | ASM maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';' ! 977: { if (pedantic) ! 978: warning ("ANSI C forbids use of `asm' keyword"); ! 979: emit_note (input_filename, @1.first_line); ! 980: if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 981: c_expand_asm_operands ($4, $6, $8, ! 982: $2 == ridpointers[(int)RID_VOLATILE]); } 1.1 root 983: | GOTO identifier ';' 1.1.1.2 ! root 984: { tree decl; ! 985: emit_note (input_filename, @1.first_line); ! 986: decl = lookup_label ($2); ! 987: expand_goto (decl); } ! 988: | identifier ':' ! 989: { tree label = define_label (input_filename, @1.first_line, $1); ! 990: if (label) ! 991: expand_label (label); } ! 992: stmt 1.1 root 993: | ';' 1.1.1.2 ! root 994: ; ! 995: ! 996: maybe_type_qual: ! 997: /* empty */ ! 998: | TYPE_QUAL 1.1 root 999: ; 1000: 1001: xexpr: 1002: /* empty */ 1003: { $$ = NULL_TREE; } 1004: | expr 1005: ; 1006: 1.1.1.2 ! root 1007: /* These are the operands other than the first string and comma ! 1008: in asm ("addextend %2,%1", "=dm" (x), "0" (y), "g" (*x)) */ ! 1009: asm_operands: asm_operand ! 1010: | asm_operands ',' asm_operand ! 1011: { $$ = chainon ($1, $3); } ! 1012: ; ! 1013: ! 1014: asm_operand: ! 1015: | STRING '(' expr ')' ! 1016: { $$ = build_tree_list ($1, $3); } ! 1017: ; ! 1018: 1.1 root 1019: /* This is what appears inside the parens in a function declarator. 1.1.1.2 ! root 1020: Its value is a list of ..._TYPE nodes. ! 1021: The caller must do `poplevel (0, 0, 0);' after return from this. ! 1022: (The caller does it so that error recovery to the closeparen ! 1023: can also do it.) */ ! 1024: parmlist: ! 1025: { pushlevel (0); } ! 1026: parmlist_1 ! 1027: { $$ = $2; poplevel (0); } ! 1028: ; ! 1029: ! 1030: /* This is referred to where either a parmlist or an identifier list is ok. ! 1031: Its value is a list of ..._TYPE nodes or a list of identifiers. ! 1032: The caller must do `poplevel (0, 0, 0);' after return from this. */ ! 1033: parmlist_or_identifiers: ! 1034: { pushlevel (0); } ! 1035: parmlist_or_identifiers_1 ! 1036: { $$ = $2; poplevel (0, 0, 0); } ! 1037: ; ! 1038: ! 1039: parmlist_or_identifiers_1: ! 1040: parmlist_2 ')' ! 1041: | identifiers ')' ! 1042: | error ')' ! 1043: { $$ = NULL_TREE; } ! 1044: ; ! 1045: ! 1046: parmlist_1: ! 1047: parmlist_2 ')' ! 1048: | error ')' 1.1 root 1049: { $$ = NULL_TREE; } 1.1.1.2 ! root 1050: ; ! 1051: ! 1052: /* This is what appears inside the parens in a function declarator. ! 1053: Is value is represented in the format that grokdeclarator expects. */ ! 1054: parmlist_2: /* empty */ ! 1055: { $$ = get_parm_types (0); } 1.1 root 1056: | parms 1.1.1.2 ! root 1057: { $$ = get_parm_types (1); } 1.1 root 1058: | parms ',' ELLIPSIS 1.1.1.2 ! root 1059: { $$ = get_parm_types (0); } 1.1 root 1060: ; 1061: 1062: parms: 1063: parm 1.1.1.2 ! root 1064: { push_parm_decl ($1); } 1.1 root 1065: | parms ',' parm 1.1.1.2 ! root 1066: { push_parm_decl ($3); } 1.1 root 1067: ; 1068: 1.1.1.2 ! root 1069: /* A single parameter declaration or parameter type name, ! 1070: as found in a parmlist. */ 1.1 root 1071: parm: 1.1.1.2 ! root 1072: typed_declspecs parm_declarator ! 1073: { $$ = build_tree_list ($1, $2) ; } ! 1074: | typed_declspecs notype_declarator 1.1 root 1075: { $$ = build_tree_list ($1, $2) ; } 1.1.1.2 ! root 1076: | typed_declspecs absdcl ! 1077: { $$ = build_tree_list ($1, $2); } ! 1078: | declmods notype_declarator ! 1079: { $$ = build_tree_list ($1, $2) ; } ! 1080: | declmods absdcl 1.1 root 1081: { $$ = build_tree_list ($1, $2); } 1082: ; 1083: 1084: /* A nonempty list of identifiers. */ 1085: identifiers: 1086: IDENTIFIER 1087: { $$ = build_tree_list (NULL_TREE, $1); } 1088: | identifiers ',' IDENTIFIER 1089: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } 1090: ; 1091: %% 1092: 1093: /* Return something to represent absolute declarators containing a *. 1094: TARGET is the absolute declarator that the * contains. 1.1.1.2 ! root 1095: TYPE_QUALS is a list of modifiers such as const or volatile 1.1 root 1096: to apply to the pointer type, represented as identifiers. 1097: 1098: We return an INDIRECT_REF whose "contents" are TARGET 1099: and whose type is the modifier list. */ 1100: 1101: static tree 1.1.1.2 ! root 1102: make_pointer_declarator (type_quals, target) ! 1103: tree type_quals, target; 1.1 root 1104: { 1.1.1.2 ! root 1105: return build (INDIRECT_REF, type_quals, target); 1.1 root 1106: } 1107: 1108: /* Given a chain of STRING_CST nodes, 1109: concatenate them into one STRING_CST 1.1.1.2 ! root 1110: and give it a suitable array-of-chars data type. */ 1.1 root 1111: 1112: static tree 1113: combine_strings (strings) 1114: tree strings; 1115: { 1116: register tree value, t; 1.1.1.2 ! root 1117: register int length = 1; ! 1118: int wide_length = 0; ! 1119: int wide_flag = 0; 1.1 root 1120: 1121: if (TREE_CHAIN (strings)) 1122: { 1123: /* More than one in the chain, so concatenate. */ 1124: register char *p, *q; 1125: 1126: /* Don't include the \0 at the end of each substring, 1.1.1.2 ! root 1127: except for the last one. ! 1128: Count wide strings and ordinary strings separately. */ 1.1 root 1129: for (t = strings; t; t = TREE_CHAIN (t)) 1.1.1.2 ! root 1130: { ! 1131: if (TREE_TYPE (t) == int_array_type_node) ! 1132: { ! 1133: wide_length += (TREE_STRING_LENGTH (t) - 1); ! 1134: wide_flag = 1; ! 1135: } ! 1136: else ! 1137: length += (TREE_STRING_LENGTH (t) - 1); ! 1138: } ! 1139: ! 1140: /* If anything is wide, the non-wides will be converted, ! 1141: which makes them take more space. */ ! 1142: if (wide_flag) ! 1143: length = length * UNITS_PER_WORD + wide_length; 1.1 root 1144: 1145: p = (char *) oballoc (length); 1146: 1.1.1.2 ! root 1147: /* Copy the individual strings into the new combined string. ! 1148: If the combined string is wide, convert the chars to ints ! 1149: for any individual strings that are not wide. */ ! 1150: 1.1 root 1151: q = p; 1152: for (t = strings; t; t = TREE_CHAIN (t)) 1153: { 1.1.1.2 ! root 1154: int len = TREE_STRING_LENGTH (t) - 1; ! 1155: if ((TREE_TYPE (t) == int_array_type_node) == wide_flag) ! 1156: { ! 1157: bcopy (TREE_STRING_POINTER (t), q, len); ! 1158: q += len; ! 1159: } ! 1160: else ! 1161: { ! 1162: int i; ! 1163: for (i = 0; i < len; i++) ! 1164: ((int *) q)[i] = TREE_STRING_POINTER (t)[i]; ! 1165: q += len * UNITS_PER_WORD; ! 1166: } 1.1 root 1167: } 1168: *q = 0; 1169: 1170: value = make_node (STRING_CST); 1171: TREE_STRING_POINTER (value) = p; 1172: TREE_STRING_LENGTH (value) = length; 1173: TREE_LITERAL (value) = 1; 1174: } 1175: else 1.1.1.2 ! root 1176: { ! 1177: value = strings; ! 1178: length = TREE_STRING_LENGTH (value); ! 1179: if (TREE_TYPE (value) == int_array_type_node) ! 1180: wide_flag = 1; ! 1181: } 1.1 root 1182: 1.1.1.2 ! root 1183: TREE_TYPE (value) ! 1184: = build_array_type (wide_flag ? integer_type_node : char_type_node, ! 1185: make_index_type (build_int_2 (length - 1, 0))); 1.1 root 1186: TREE_LITERAL (value) = 1; 1.1.1.2 ! root 1187: TREE_STATIC (value) = 1; 1.1 root 1188: return value; 1189: } 1190: 1191: int lineno; /* current line number in file being read */ 1192: 1193: FILE *finput; /* input file. 1194: Normally a pipe from the preprocessor. */ 1195: 1196: /* lexical analyzer */ 1197: 1.1.1.2 ! root 1198: static int maxtoken; /* Current nominal length of token buffer */ ! 1199: static char *token_buffer; /* Pointer to token buffer. ! 1200: Actual allocated length is maxtoken + 2. */ ! 1201: static dollar_seen = 0; /* Nonzero if have warned about `$'. */ 1.1 root 1202: 1203: #define MAXRESERVED 9 1204: 1.1.1.2 ! root 1205: /* frw[I] is index in `reswords' of the first word whose length is I; ! 1206: frw[I+1] is one plus the index of the last word whose length is I. ! 1207: The length of frw must be MAXRESERVED + 2 so there is an element ! 1208: at MAXRESERVED+1 for the case I == MAXRESERVED. */ ! 1209: ! 1210: static char frw[MAXRESERVED+2] = ! 1211: { 0, 0, 0, 2, 5, 13, 19, 29, 32, 36, 37 }; ! 1212: ! 1213: /* Table of reserved words. */ ! 1214: ! 1215: struct resword { char *name; short token; enum rid rid;}; ! 1216: ! 1217: #define NORID RID_UNUSED ! 1218: ! 1219: static struct resword reswords[] ! 1220: = {{"if", IF, NORID}, ! 1221: {"do", DO, NORID}, ! 1222: {"int", TYPESPEC, RID_INT}, ! 1223: {"for", FOR, NORID}, ! 1224: {"asm", ASM, NORID}, ! 1225: {"case", CASE, NORID}, ! 1226: {"char", TYPESPEC, RID_CHAR}, ! 1227: {"auto", SCSPEC, RID_AUTO}, ! 1228: {"goto", GOTO, NORID}, ! 1229: {"else", ELSE, NORID}, ! 1230: {"long", TYPESPEC, RID_LONG}, ! 1231: {"void", TYPESPEC, RID_VOID}, ! 1232: {"enum", ENUM, NORID}, ! 1233: {"float", TYPESPEC, RID_FLOAT}, ! 1234: {"short", TYPESPEC, RID_SHORT}, ! 1235: {"union", UNION, NORID}, ! 1236: {"break", BREAK, NORID}, ! 1237: {"while", WHILE, NORID}, ! 1238: {"const", TYPE_QUAL, RID_CONST}, ! 1239: {"double", TYPESPEC, RID_DOUBLE}, ! 1240: {"static", SCSPEC, RID_STATIC}, ! 1241: {"extern", SCSPEC, RID_EXTERN}, ! 1242: {"struct", STRUCT, NORID}, ! 1243: {"return", RETURN, NORID}, ! 1244: {"sizeof", SIZEOF, NORID}, ! 1245: {"typeof", TYPEOF, NORID}, ! 1246: {"switch", SWITCH, NORID}, ! 1247: {"signed", TYPESPEC, RID_SIGNED}, ! 1248: {"inline", SCSPEC, RID_INLINE}, ! 1249: {"typedef", SCSPEC, RID_TYPEDEF}, ! 1250: {"default", DEFAULT, NORID}, ! 1251: {"noalias", TYPE_QUAL, RID_NOALIAS}, ! 1252: {"unsigned", TYPESPEC, RID_UNSIGNED}, ! 1253: {"continue", CONTINUE, NORID}, ! 1254: {"register", SCSPEC, RID_REGISTER}, ! 1255: {"volatile", TYPE_QUAL, RID_VOLATILE}, ! 1256: {"__alignof", ALIGNOF, NORID}}; 1.1 root 1257: 1258: /* The elements of `ridpointers' are identifier nodes 1.1.1.2 ! root 1259: for the reserved type names and storage classes. ! 1260: It is indexed by a RID_... value. */ 1.1 root 1261: 1262: tree ridpointers[(int) RID_MAX]; 1263: 1264: static tree line_identifier; /* The identifier node named "line" */ 1265: 1.1.1.2 ! root 1266: void check_newline (); 1.1 root 1267: 1268: void 1.1.1.2 ! root 1269: init_lex () 1.1 root 1270: { 1.1.1.2 ! root 1271: extern char *malloc (); 1.1 root 1272: 1.1.1.2 ! root 1273: /* Start it at 0, because check_newline is called at the very beginning 1.1 root 1274: and will increment it to 1. */ 1275: lineno = 0; 1.1.1.2 ! root 1276: line_identifier = get_identifier ("line"); 1.1 root 1277: 1278: maxtoken = 40; 1.1.1.2 ! root 1279: token_buffer = malloc (maxtoken + 2); ! 1280: ridpointers[(int) RID_INT] = get_identifier ("int"); ! 1281: ridpointers[(int) RID_CHAR] = get_identifier ("char"); ! 1282: ridpointers[(int) RID_VOID] = get_identifier ("void"); ! 1283: ridpointers[(int) RID_FLOAT] = get_identifier ("float"); ! 1284: ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); ! 1285: ridpointers[(int) RID_SHORT] = get_identifier ("short"); ! 1286: ridpointers[(int) RID_LONG] = get_identifier ("long"); ! 1287: ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); ! 1288: ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); ! 1289: ridpointers[(int) RID_INLINE] = get_identifier ("inline"); ! 1290: ridpointers[(int) RID_CONST] = get_identifier ("const"); ! 1291: ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); ! 1292: ridpointers[(int) RID_AUTO] = get_identifier ("auto"); ! 1293: ridpointers[(int) RID_STATIC] = get_identifier ("static"); ! 1294: ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); ! 1295: ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); ! 1296: ridpointers[(int) RID_REGISTER] = get_identifier ("register"); ! 1297: } ! 1298: ! 1299: static void ! 1300: reinit_parse_for_function () ! 1301: { 1.1 root 1302: } 1303: 1304: static int 1.1.1.2 ! root 1305: skip_white_space () 1.1 root 1306: { 1307: register int c; 1308: register int inside; 1309: 1.1.1.2 ! root 1310: c = getc (finput); 1.1 root 1311: 1312: for (;;) 1313: { 1314: switch (c) 1315: { 1316: case '/': 1.1.1.2 ! root 1317: c = getc (finput); 1.1 root 1318: if (c != '*') 1319: { 1.1.1.2 ! root 1320: ungetc (c, finput); 1.1 root 1321: return '/'; 1322: } 1323: 1.1.1.2 ! root 1324: c = getc (finput); 1.1 root 1325: 1326: inside = 1; 1327: while (inside) 1328: { 1329: if (c == '*') 1330: { 1331: while (c == '*') 1.1.1.2 ! root 1332: c = getc (finput); 1.1 root 1333: 1334: if (c == '/') 1335: { 1336: inside = 0; 1.1.1.2 ! root 1337: c = getc (finput); 1.1 root 1338: } 1339: } 1340: else if (c == '\n') 1341: { 1342: lineno++; 1.1.1.2 ! root 1343: c = getc (finput); 1.1 root 1344: } 1345: else if (c == EOF) 1.1.1.2 ! root 1346: { ! 1347: error ("unterminated comment"); ! 1348: break; ! 1349: } 1.1 root 1350: else 1.1.1.2 ! root 1351: c = getc (finput); 1.1 root 1352: } 1353: 1354: break; 1355: 1356: case '\n': 1.1.1.2 ! root 1357: check_newline (); 1.1 root 1358: 1359: case ' ': 1360: case '\t': 1361: case '\f': 1362: case '\r': 1363: case '\b': 1.1.1.2 ! root 1364: c = getc (finput); 1.1 root 1365: break; 1366: 1367: case '\\': 1.1.1.2 ! root 1368: c = getc (finput); 1.1 root 1369: if (c == '\n') 1370: lineno++; 1371: else 1.1.1.2 ! root 1372: error ("stray '\\' in program"); ! 1373: c = getc (finput); 1.1 root 1374: break; 1375: 1376: default: 1377: return (c); 1378: } 1379: } 1380: } 1381: 1382: 1383: 1.1.1.2 ! root 1384: /* Make the token buffer longer, preserving the data in it. ! 1385: P should point to just beyond the last valid character in the old buffer. ! 1386: The value we return is a pointer to the new buffer ! 1387: at a place corresponding to P. */ 1.1 root 1388: 1389: static char * 1.1.1.2 ! root 1390: extend_token_buffer (p) ! 1391: char *p; 1.1 root 1392: { 1.1.1.2 ! root 1393: int offset = p - token_buffer; 1.1 root 1394: 1.1.1.2 ! root 1395: maxtoken = maxtoken * 2 + 10; ! 1396: token_buffer = (char *) realloc (token_buffer, maxtoken + 2); ! 1397: if (token_buffer == 0) ! 1398: fatal ("virtual memory exceeded"); 1.1 root 1399: 1.1.1.2 ! root 1400: return token_buffer + offset; 1.1 root 1401: } 1402: 1.1.1.2 ! root 1403: /* At the beginning of a line, increment the line number 1.1 root 1404: and handle a #line directive immediately following */ 1405: 1406: void 1407: check_newline () 1408: { 1409: register int c; 1410: register int token; 1411: 1412: while (1) 1413: { 1414: lineno++; 1415: 1.1.1.2 ! root 1416: /* Read first nonwhite char on the line. */ ! 1417: ! 1418: c = getc (finput); ! 1419: while (c == ' ' || c == '\t') ! 1420: c = getc (finput); ! 1421: 1.1 root 1422: if (c != '#') 1423: { 1.1.1.2 ! root 1424: /* If not #, unread it. */ 1.1 root 1425: ungetc (c, finput); 1426: return; 1427: } 1428: 1.1.1.2 ! root 1429: /* Read first nonwhite char after the `#'. */ 1.1 root 1430: 1.1.1.2 ! root 1431: c = getc (finput); ! 1432: while (c == ' ' || c == '\t') ! 1433: c = getc (finput); ! 1434: ! 1435: /* If a letter follows, then if the word here is `line', skip ! 1436: it and ignore it; otherwise, ignore the line, with an error ! 1437: if the word isn't `pragma'. */ ! 1438: ! 1439: if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) 1.1 root 1440: { 1.1.1.2 ! root 1441: if (c == 'p') ! 1442: { ! 1443: if (getc (finput) == 'r' ! 1444: && getc (finput) == 'a' ! 1445: && getc (finput) == 'g' ! 1446: && getc (finput) == 'm' ! 1447: && getc (finput) == 'a' ! 1448: && ((c = getc (finput)) == ' ' || c == '\t')) ! 1449: goto noerror; ! 1450: } ! 1451: ! 1452: else if (c == 'l') ! 1453: { ! 1454: if (getc (finput) == 'i' ! 1455: && getc (finput) == 'n' ! 1456: && getc (finput) == 'e' ! 1457: && ((c = getc (finput)) == ' ' || c == '\t')) ! 1458: goto linenum; ! 1459: } ! 1460: ! 1461: error ("undefined or invalid # directive"); ! 1462: noerror: ! 1463: ! 1464: while ((c = getc (finput)) && c != '\n'); ! 1465: ! 1466: continue; 1.1 root 1467: } 1468: 1.1.1.2 ! root 1469: linenum: ! 1470: /* Here we have either `#line' or `# <nonletter>'. ! 1471: In either case, it should be a line number; a digit should follow. ! 1472: ! 1473: while (c == ' ' || c == '\t') ! 1474: c = getc (finput); ! 1475: 1.1 root 1476: /* If the # is the only nonwhite char on the line, 1477: just ignore it. Check the new newline. */ 1478: if (c == '\n') 1479: continue; 1480: 1481: /* Something follows the #; read a token. */ 1482: 1483: ungetc (c, finput); 1484: token = yylex (); 1485: 1486: if (token == CONSTANT 1487: && TREE_CODE (yylval.ttype) == INTEGER_CST) 1488: { 1489: /* subtract one, because it is the following line that 1490: gets the specified number */ 1491: 1492: int l = TREE_INT_CST_LOW (yylval.ttype) - 1; 1493: 1.1.1.2 ! root 1494: /* Is this the last nonwhite stuff on the line? */ ! 1495: c = getc (finput); ! 1496: while (c == ' ' || c == '\t') ! 1497: c = getc (finput); ! 1498: if (c == '\n') ! 1499: { ! 1500: /* No more: store the line number and check following line. */ ! 1501: lineno = l; ! 1502: continue; ! 1503: } ! 1504: ungetc (c, finput); ! 1505: ! 1506: /* More follows: it must be a string constant (filename). */ ! 1507: 1.1 root 1508: token = yylex (); 1509: if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) 1.1.1.2 ! root 1510: { ! 1511: error ("invalid #line"); ! 1512: return; ! 1513: } 1.1 root 1514: 1515: input_filename 1516: = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1); 1517: strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype)); 1518: lineno = l; 1.1.1.2 ! root 1519: ! 1520: if (main_input_filename == 0) ! 1521: main_input_filename = input_filename; 1.1 root 1522: } 1523: else 1.1.1.2 ! root 1524: error ("invalid #line"); 1.1 root 1525: 1526: /* skip the rest of this line. */ 1527: while ((c = getc (finput)) != '\n'); 1528: } 1529: } 1530: 1531: 1532: 1533: #define isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9')) 1534: #define isdigit(char) (char >= '0' && char <= '9') 1535: #define ENDFILE -1 /* token that represents end-of-file */ 1536: 1537: 1538: static int 1539: readescape () 1540: { 1541: register int c = getc (finput); 1542: register int count, code; 1543: 1544: switch (c) 1545: { 1546: case 'x': 1547: code = 0; 1548: count = 0; 1549: while (1) 1550: { 1551: c = getc (finput); 1552: if (!(c >= 'a' && c <= 'f') 1553: && !(c >= 'A' && c <= 'F') 1554: && !(c >= '0' && c <= '9')) 1555: { 1556: ungetc (c, finput); 1557: break; 1558: } 1559: code *= 16; 1560: if (c >= 'a' && c <= 'f') 1561: code += c - 'a' + 10; 1562: if (c >= 'A' && c <= 'F') 1563: code += c - 'A' + 10; 1564: if (c >= '0' && c <= '9') 1565: code += c - '0'; 1566: count++; 1567: } 1568: if (count == 0) 1.1.1.2 ! root 1569: error ("\\x used with no following hex digits"); 1.1 root 1570: return code; 1571: 1572: case '0': case '1': case '2': case '3': case '4': 1573: case '5': case '6': case '7': 1574: code = 0; 1575: count = 0; 1576: while ((c <= '7') && (c >= '0') && (count++ < 3)) 1577: { 1578: code = (code * 8) + (c - '0'); 1579: c = getc (finput); 1580: } 1581: ungetc (c, finput); 1582: return code; 1583: 1584: case '\\': case '\'': case '"': 1585: return c; 1586: 1587: case '\n': 1588: lineno++; 1589: return -1; 1590: 1591: case 'n': 1592: return TARGET_NEWLINE; 1593: 1594: case 't': 1595: return TARGET_TAB; 1596: 1597: case 'r': 1598: return TARGET_CR; 1599: 1600: case 'f': 1601: return TARGET_FF; 1602: 1603: case 'b': 1604: return TARGET_BS; 1605: 1606: case 'a': 1607: return TARGET_BELL; 1608: 1609: case 'v': 1610: return TARGET_VT; 1.1.1.2 ! root 1611: ! 1612: case 'E': ! 1613: return 033; ! 1614: ! 1615: case '?': ! 1616: return c; 1.1 root 1617: } 1.1.1.2 ! root 1618: if (c >= 040 && c <= 0177) ! 1619: warning ("unknown escape sequence `\\%c'", c); ! 1620: else ! 1621: warning ("unknown escape sequence: `\\' followed by char code 0x%x", c); 1.1 root 1622: return c; 1623: } 1624: 1.1.1.2 ! root 1625: void ! 1626: yyerror () ! 1627: { ! 1628: /* We can't print string and character constants well ! 1629: because the token_buffer contains the result of processing escapes. */ ! 1630: if (token_buffer[0] == 0) ! 1631: error ("parse error at end of input"); ! 1632: else if (token_buffer[0] == '"') ! 1633: error ("parse error at string constant"); ! 1634: else if (token_buffer[0] == '\'') ! 1635: error ("parse error at character constant"); ! 1636: else ! 1637: error ("parse error at `%s'", token_buffer); ! 1638: } 1.1 root 1639: 1640: static int 1.1.1.2 ! root 1641: yylex () 1.1 root 1642: { 1643: register int c; 1644: register char *p; 1645: register int value; 1.1.1.2 ! root 1646: int wide_flag = 0; 1.1 root 1647: 1.1.1.2 ! root 1648: token_buffer[0] = c = skip_white_space (); ! 1649: token_buffer[1] = 0; 1.1 root 1650: 1651: yylloc.first_line = lineno; 1652: 1653: switch (c) 1654: { 1655: case EOF: 1.1.1.2 ! root 1656: token_buffer[0] = 0; ! 1657: value = ENDFILE; ! 1658: break; ! 1659: ! 1660: case 'L': ! 1661: /* Capital L may start a wide-string or wide-character constant. */ ! 1662: { ! 1663: register int c = getc (finput); ! 1664: if (c == '\'') ! 1665: { ! 1666: wide_flag = 1; ! 1667: goto char_constant; ! 1668: } ! 1669: if (c == '"') ! 1670: { ! 1671: wide_flag = 1; ! 1672: goto string_constant; ! 1673: } ! 1674: ungetc (c, finput); ! 1675: } 1.1 root 1676: 1677: case 'A': case 'B': case 'C': case 'D': case 'E': 1678: case 'F': case 'G': case 'H': case 'I': case 'J': 1.1.1.2 ! root 1679: case 'K': case 'M': case 'N': case 'O': 1.1 root 1680: case 'P': case 'Q': case 'R': case 'S': case 'T': 1681: case 'U': case 'V': case 'W': case 'X': case 'Y': 1682: case 'Z': 1683: case 'a': case 'b': case 'c': case 'd': case 'e': 1684: case 'f': case 'g': case 'h': case 'i': case 'j': 1685: case 'k': case 'l': case 'm': case 'n': case 'o': 1686: case 'p': case 'q': case 'r': case 's': case 't': 1687: case 'u': case 'v': case 'w': case 'x': case 'y': 1688: case 'z': 1689: case '_': 1.1.1.2 ! root 1690: case '$': 1.1 root 1691: p = token_buffer; 1.1.1.2 ! root 1692: while (isalnum (c) || c == '_' || c == '$') 1.1 root 1693: { 1694: if (p >= token_buffer + maxtoken) 1.1.1.2 ! root 1695: p = extend_token_buffer (p); ! 1696: if (c == '$') ! 1697: { ! 1698: if (pedantic) ! 1699: { ! 1700: if (! dollar_seen) ! 1701: warning ("ANSI C forbids `$' (first use here)"); ! 1702: dollar_seen = 1; ! 1703: } ! 1704: } ! 1705: 1.1 root 1706: *p++ = c; 1.1.1.2 ! root 1707: c = getc (finput); 1.1 root 1708: } 1709: 1710: *p = 0; 1.1.1.2 ! root 1711: ungetc (c, finput); 1.1 root 1712: 1713: value = IDENTIFIER; 1714: yylval.itype = 0; 1715: 1.1.1.2 ! root 1716: /* Try to recognize a keyword. */ ! 1717: 1.1 root 1718: if (p - token_buffer <= MAXRESERVED) 1719: { 1720: register int lim = frw [p - token_buffer + 1]; 1.1.1.2 ! root 1721: register int i = frw[p - token_buffer]; ! 1722: register struct resword *p = &reswords[i]; 1.1 root 1723: 1.1.1.2 ! root 1724: for (; i < lim; i++, p++) ! 1725: if (p->name[0] == token_buffer[0] ! 1726: && !strcmp (p->name, token_buffer)) 1.1 root 1727: { 1.1.1.2 ! root 1728: if (p->rid) ! 1729: yylval.ttype = ridpointers[(int) p->rid]; ! 1730: if ((! flag_no_asm ! 1731: || ((int) p->token != ASM ! 1732: && (int) p->token != TYPEOF ! 1733: && strcmp (p->name, "inline"))) ! 1734: /* -ftraditional means don't recognize ! 1735: typeof, const, volatile, noalias, signed or inline. */ ! 1736: && (! flag_traditional ! 1737: || ((int) p->token != TYPE_QUAL ! 1738: && (int) p->token != TYPEOF ! 1739: && strcmp (p->name, "signed") ! 1740: && strcmp (p->name, "inline")))) ! 1741: value = (int) p->token; 1.1 root 1742: break; 1743: } 1744: } 1745: 1.1.1.2 ! root 1746: /* If we did not find a keyword, look for an identifier ! 1747: (or a typename). */ ! 1748: 1.1 root 1749: if (value == IDENTIFIER) 1750: { 1.1.1.2 ! root 1751: yylval.ttype = get_identifier (token_buffer); 1.1 root 1752: lastiddecl = lookup_name (yylval.ttype); 1753: 1754: if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL) 1755: value = TYPENAME; 1756: } 1757: 1758: break; 1759: 1760: case '0': case '1': case '2': case '3': case '4': 1761: case '5': case '6': case '7': case '8': case '9': 1762: case '.': 1763: { 1764: int base = 10; 1765: int count = 0; 1.1.1.2 ! root 1766: int largest_digit = 0; ! 1767: int numdigits = 0; ! 1768: /* for multi-precision arithmetic, ! 1769: we store only 8 live bits in each short, 1.1 root 1770: giving us 64 bits of reliable precision */ 1771: short shorts[8]; 1.1.1.2 ! root 1772: int floatflag = 0; /* Set 1 if we learn this is a floating constant */ 1.1 root 1773: 1774: for (count = 0; count < 8; count++) 1775: shorts[count] = 0; 1776: 1777: p = token_buffer; 1778: *p++ = c; 1779: 1780: if (c == '0') 1781: { 1.1.1.2 ! root 1782: *p++ = (c = getc (finput)); 1.1 root 1783: if ((c == 'x') || (c == 'X')) 1784: { 1785: base = 16; 1.1.1.2 ! root 1786: *p++ = (c = getc (finput)); 1.1 root 1787: } 1788: else 1789: { 1790: base = 8; 1.1.1.2 ! root 1791: numdigits++; 1.1 root 1792: } 1793: } 1794: 1.1.1.2 ! root 1795: /* Read all the digits-and-decimal-points. */ ! 1796: 1.1 root 1797: while (c == '.' 1798: || (isalnum (c) && (c != 'l') && (c != 'L') 1.1.1.2 ! root 1799: && (c != 'u') && (c != 'U') ! 1800: && (!floatflag || ((c != 'f') && (c != 'F'))))) 1.1 root 1801: { 1802: if (c == '.') 1803: { 1.1.1.2 ! root 1804: if (base == 16) ! 1805: error ("floating constant may not be in radix 16"); ! 1806: floatflag = 1; ! 1807: base = 10; ! 1808: *p++ = c = getc (finput); 1.1 root 1809: /* Accept '.' as the start of a floating-point number 1810: only when it is followed by a digit. 1811: Otherwise, unread the following non-digit 1812: and use the '.' as a structural token. */ 1.1.1.2 ! root 1813: if (p == token_buffer + 2 && !isdigit (c)) 1.1 root 1814: { 1815: if (c == '.') 1816: { 1817: c = getc (finput); 1818: if (c == '.') 1.1.1.2 ! root 1819: { ! 1820: *p++ = c; ! 1821: *p = 0; ! 1822: return ELLIPSIS; ! 1823: } ! 1824: error ("parse error at `..'"); 1.1 root 1825: } 1826: ungetc (c, finput); 1.1.1.2 ! root 1827: token_buffer[1] = 0; ! 1828: value = '.'; ! 1829: goto done; 1.1 root 1830: } 1831: } 1832: else 1833: { 1.1.1.2 ! root 1834: /* It is not a decimal point. ! 1835: It should be a digit (perhaps a hex digit). */ ! 1836: ! 1837: if (isdigit (c)) 1.1 root 1838: { 1839: c = c - '0'; 1840: } 1841: else if (base <= 10) 1842: { 1843: if ((c&~040) == 'E') 1844: { 1.1.1.2 ! root 1845: base = 10; ! 1846: floatflag = 1; 1.1 root 1847: break; /* start of exponent */ 1848: } 1.1.1.2 ! root 1849: error ("nondigits in number and not hexadecimal"); 1.1 root 1850: c = 0; 1851: } 1852: else if (c >= 'a') 1853: { 1854: c = c - 'a' + 10; 1855: } 1856: else 1857: { 1858: c = c - 'A' + 10; 1859: } 1.1.1.2 ! root 1860: if (c >= largest_digit) ! 1861: largest_digit = c; ! 1862: numdigits++; 1.1 root 1863: 1864: for (count = 0; count < 8; count++) 1865: { 1866: (shorts[count] *= base); 1867: if (count) 1868: { 1869: shorts[count] += (shorts[count-1] >> 8); 1870: shorts[count-1] &= (1<<8)-1; 1871: } 1872: else shorts[0] += c; 1873: } 1874: 1.1.1.2 ! root 1875: if (p >= token_buffer + maxtoken - 3) ! 1876: p = extend_token_buffer (p); ! 1877: *p++ = (c = getc (finput)); 1.1 root 1878: } 1879: } 1880: 1.1.1.2 ! root 1881: if (numdigits == 0) ! 1882: error ("numeric constant with no digits"); ! 1883: ! 1884: if (largest_digit >= base) ! 1885: error ("numeric constant contains digits beyond the radix"); ! 1886: 1.1 root 1887: /* Remove terminating char from the token buffer and delimit the string */ 1888: *--p = 0; 1889: 1890: if (floatflag) 1891: { 1892: tree type = double_type_node; 1.1.1.2 ! root 1893: char f_seen = 0; ! 1894: char l_seen = 0; 1.1 root 1895: 1.1.1.2 ! root 1896: /* Read explicit exponent if any, and put it in tokenbuf. */ 1.1 root 1897: 1898: if ((c == 'e') || (c == 'E')) 1899: { 1.1.1.2 ! root 1900: if (p >= token_buffer + maxtoken - 3) ! 1901: p = extend_token_buffer (p); ! 1902: *p++ = c; ! 1903: c = getc (finput); 1.1 root 1904: if ((c == '+') || (c == '-')) 1905: { 1.1.1.2 ! root 1906: *p++ = c; ! 1907: c = getc (finput); 1.1 root 1908: } 1.1.1.2 ! root 1909: if (! isdigit (c)) ! 1910: error ("floating constant exponent has no digits"); ! 1911: while (isdigit (c)) 1.1 root 1912: { 1.1.1.2 ! root 1913: if (p >= token_buffer + maxtoken - 3) ! 1914: p = extend_token_buffer (p); ! 1915: *p++ = c; ! 1916: c = getc (finput); 1.1 root 1917: } 1918: } 1919: 1.1.1.2 ! root 1920: *p = 0; ! 1921: yylval.ttype = build_real (atof (token_buffer)); ! 1922: 1.1 root 1923: while (1) 1924: { 1925: if (c == 'f' || c == 'F') 1.1.1.2 ! root 1926: { ! 1927: if (f_seen) ! 1928: error ("two `f's in floating constant"); ! 1929: f_seen = 1; ! 1930: type = float_type_node; ! 1931: } 1.1 root 1932: else if (c == 'l' || c == 'L') 1.1.1.2 ! root 1933: { ! 1934: if (l_seen) ! 1935: error ("two `l's in floating constant"); ! 1936: l_seen = 1; ! 1937: type = long_double_type_node; ! 1938: } ! 1939: else ! 1940: { ! 1941: if (isalnum (c)) ! 1942: { ! 1943: error ("garbage at end of number"); ! 1944: while (isalnum (c)) ! 1945: { ! 1946: if (p >= token_buffer + maxtoken - 3) ! 1947: p = extend_token_buffer (p); ! 1948: *p++ = c; ! 1949: c = getc (finput); ! 1950: } ! 1951: } ! 1952: break; ! 1953: } ! 1954: if (p >= token_buffer + maxtoken - 3) ! 1955: p = extend_token_buffer (p); ! 1956: *p++ = c; 1.1 root 1957: c = getc (finput); 1958: } 1959: 1.1.1.2 ! root 1960: ungetc (c, finput); ! 1961: *p = 0; 1.1 root 1962: 1963: TREE_TYPE (yylval.ttype) = type; 1964: } 1965: else 1966: { 1967: tree type; 1968: int spec_unsigned = 0; 1969: int spec_long = 0; 1970: 1971: while (1) 1972: { 1973: if (c == 'u' || c == 'U') 1974: { 1.1.1.2 ! root 1975: if (spec_unsigned) ! 1976: error ("two `u's in integer constant"); 1.1 root 1977: spec_unsigned = 1; 1978: } 1979: else if (c == 'l' || c == 'L') 1980: { 1.1.1.2 ! root 1981: if (spec_long) ! 1982: error ("two `l's in integer constant"); 1.1 root 1983: spec_long = 1; 1984: } 1.1.1.2 ! root 1985: else ! 1986: { ! 1987: if (isalnum (c)) ! 1988: { ! 1989: error ("garbage at end of number"); ! 1990: while (isalnum (c)) ! 1991: { ! 1992: if (p >= token_buffer + maxtoken - 3) ! 1993: p = extend_token_buffer (p); ! 1994: *p++ = c; ! 1995: c = getc (finput); ! 1996: } ! 1997: } ! 1998: break; ! 1999: } ! 2000: if (p >= token_buffer + maxtoken - 3) ! 2001: p = extend_token_buffer (p); ! 2002: *p++ = c; ! 2003: c = getc (finput); 1.1 root 2004: } 2005: 2006: ungetc (c, finput); 2007: 1.1.1.2 ! root 2008: if (shorts[7] | shorts[6] | shorts[5] | shorts[4]) ! 2009: warning ("integer constant out of range"); ! 2010: 1.1 root 2011: /* This is simplified by the fact that our constant 2012: is always positive. */ 2013: yylval.ttype 2014: = build_int_2 ((shorts[3]<<24) + (shorts[2]<<16) + (shorts[1]<<8) + shorts[0], 1.1.1.2 ! root 2015: 0); 1.1 root 2016: 2017: if (!spec_long && !spec_unsigned 2018: && int_fits_type_p (yylval.ttype, integer_type_node)) 2019: type = integer_type_node; 2020: 2021: else if (!spec_long && base != 10 2022: && int_fits_type_p (yylval.ttype, unsigned_type_node)) 2023: type = unsigned_type_node; 2024: 2025: else if (!spec_unsigned 2026: && int_fits_type_p (yylval.ttype, long_integer_type_node)) 2027: type = long_integer_type_node; 2028: 2029: else 1.1.1.2 ! root 2030: { ! 2031: type = long_unsigned_type_node; ! 2032: if (! int_fits_type_p (yylval.ttype, long_unsigned_type_node)) ! 2033: warning ("integer constant out of range"); ! 2034: } 1.1 root 2035: TREE_TYPE (yylval.ttype) = type; 2036: } 2037: 2038: value = CONSTANT; break; 2039: } 2040: 2041: case '\'': 1.1.1.2 ! root 2042: char_constant: ! 2043: c = getc (finput); 1.1 root 2044: { 2045: register int code = 0; 2046: 2047: tryagain: 2048: 2049: if (c == '\\') 2050: { 2051: c = readescape (); 2052: if (c < 0) 2053: goto tryagain; 2054: } 1.1.1.2 ! root 2055: else if (c == '\n') ! 2056: { ! 2057: if (pedantic) ! 2058: warning ("ANSI C forbids newline in character constant"); ! 2059: lineno++; ! 2060: } ! 2061: 1.1 root 2062: code = c; 1.1.1.2 ! root 2063: token_buffer[1] = c; ! 2064: token_buffer[2] = '\''; ! 2065: token_buffer[3] = 0; ! 2066: 1.1 root 2067: c = getc (finput); 2068: if (c != '\'') 1.1.1.2 ! root 2069: error ("malformatted character constant"); 1.1 root 2070: 1.1.1.2 ! root 2071: /* If char type is signed, sign-extend the constant. */ ! 2072: if (TREE_UNSIGNED (char_type_node) ! 2073: || ((code >> (BITS_PER_UNIT - 1)) & 1) == 0) ! 2074: yylval.ttype = build_int_2 (code & ((1 << BITS_PER_UNIT) - 1), 0); 1.1 root 2075: else 1.1.1.2 ! root 2076: yylval.ttype = build_int_2 (code | ((-1) << BITS_PER_UNIT), -1); 1.1 root 2077: 1.1.1.2 ! root 2078: TREE_TYPE (yylval.ttype) = integer_type_node; 1.1 root 2079: value = CONSTANT; break; 2080: } 2081: 2082: case '"': 1.1.1.2 ! root 2083: string_constant: 1.1 root 2084: { 1.1.1.2 ! root 2085: c = getc (finput); ! 2086: p = token_buffer + 1; 1.1 root 2087: 2088: while (c != '"') 2089: { 2090: if (c == '\\') 2091: { 2092: c = readescape (); 2093: if (c < 0) 2094: goto skipnewline; 2095: } 2096: else if (c == '\n') 2097: { 1.1.1.2 ! root 2098: if (pedantic) ! 2099: warning ("ANSI C forbids newline in string constant"); 1.1 root 2100: lineno++; 2101: } 2102: 2103: if (p == token_buffer + maxtoken) 1.1.1.2 ! root 2104: p = extend_token_buffer (p); 1.1 root 2105: *p++ = c; 2106: 2107: skipnewline: 2108: c = getc (finput); 2109: } 2110: 1.1.1.2 ! root 2111: *p = 0; ! 2112: ! 2113: if (wide_flag) ! 2114: { ! 2115: /* If this is a L"..." wide-string, convert each char ! 2116: to an int, making a vector of ints. */ ! 2117: int *widebuf = (int *) alloca (p - token_buffer); ! 2118: char *p1 = token_buffer + 1; ! 2119: for (; p1 == p; p1++) ! 2120: widebuf[p1 - token_buffer - 1] = *p1; ! 2121: yylval.ttype = build_string ((p - token_buffer) * sizeof (int), ! 2122: widebuf); ! 2123: TREE_TYPE (yylval.ttype) = int_array_type_node; ! 2124: } ! 2125: else ! 2126: { ! 2127: yylval.ttype = build_string (p - token_buffer, token_buffer + 1); ! 2128: TREE_TYPE (yylval.ttype) = char_array_type_node; ! 2129: } 1.1 root 2130: 1.1.1.2 ! root 2131: *p++ = '"'; ! 2132: *p = 0; 1.1 root 2133: 2134: value = STRING; break; 2135: } 2136: 2137: case '+': 2138: case '-': 2139: case '&': 2140: case '|': 2141: case '<': 2142: case '>': 2143: case '*': 2144: case '/': 2145: case '%': 2146: case '^': 2147: case '!': 2148: case '=': 2149: { 2150: register int c1; 2151: 2152: combine: 2153: 2154: switch (c) 2155: { 2156: case '+': 2157: yylval.code = PLUS_EXPR; break; 2158: case '-': 2159: yylval.code = MINUS_EXPR; break; 2160: case '&': 2161: yylval.code = BIT_AND_EXPR; break; 2162: case '|': 2163: yylval.code = BIT_IOR_EXPR; break; 2164: case '*': 2165: yylval.code = MULT_EXPR; break; 2166: case '/': 2167: yylval.code = TRUNC_DIV_EXPR; break; 2168: case '%': 2169: yylval.code = TRUNC_MOD_EXPR; break; 2170: case '^': 2171: yylval.code = BIT_XOR_EXPR; break; 2172: case LSHIFT: 2173: yylval.code = LSHIFT_EXPR; break; 2174: case RSHIFT: 2175: yylval.code = RSHIFT_EXPR; break; 2176: case '<': 2177: yylval.code = LT_EXPR; break; 2178: case '>': 2179: yylval.code = GT_EXPR; break; 2180: } 2181: 1.1.1.2 ! root 2182: token_buffer[1] = c1 = getc (finput); ! 2183: token_buffer[2] = 0; 1.1 root 2184: 2185: if (c1 == '=') 2186: { 2187: switch (c) 2188: { 2189: case '<': 2190: value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; 2191: case '>': 2192: value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; 2193: case '!': 2194: value = EQCOMPARE; yylval.code = NE_EXPR; goto done; 2195: case '=': 2196: value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; 2197: } 2198: value = ASSIGN; goto done; 2199: } 2200: else if (c == c1) 2201: switch (c) 2202: { 2203: case '+': 2204: value = PLUSPLUS; goto done; 2205: case '-': 2206: value = MINUSMINUS; goto done; 2207: case '&': 2208: value = ANDAND; goto done; 2209: case '|': 2210: value = OROR; goto done; 2211: case '<': 2212: c = LSHIFT; 2213: goto combine; 2214: case '>': 2215: c = RSHIFT; 2216: goto combine; 2217: } 2218: else if ((c == '-') && (c1 == '>')) 2219: { value = POINTSAT; goto done; } 2220: ungetc (c1, finput); 1.1.1.2 ! root 2221: token_buffer[1] = 0; 1.1 root 2222: 2223: if ((c == '<') || (c == '>')) 2224: value = ARITHCOMPARE; 2225: else value = c; 2226: goto done; 2227: } 2228: 2229: default: 2230: value = c; 2231: } 2232: 2233: done: 2234: yylloc.last_line = lineno; 2235: 1.1.1.2 ! root 2236: return value; 1.1 root 2237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.