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