Annotation of gcc/c-parse.y, revision 1.1.1.9

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

unix.superglobalmegacorp.com

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