Annotation of gcc/parse.y, revision 1.1.1.5

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.