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

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

unix.superglobalmegacorp.com

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