Quick Search:

Mode

Context

Displaying the whole file. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.374
 
1.375
 
MAIN:ragge:20140606162141
 
cgram.y
_>11 /*      $Id$    */
 22 
 33 /*
 44  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
 55  * All rights reserved.
 66  *
 77  * Redistribution and use in source and binary forms, with or without
 88  * modification, are permitted provided that the following conditions
 99  * are met:
 1010  * 1. Redistributions of source code must retain the above copyright
 1111  *    notice, this list of conditions and the following disclaimer.
 1212  * 2. Redistributions in binary form must reproduce the above copyright
 1313  *    notice, this list of conditions and the following disclaimer in the
 1414  *    documentation and/or other materials provided with the distribution.
 1515  *
 1616  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1717  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1818  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 1919  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 2020  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2121  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2222  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2323  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2424  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2525  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2626  */
 2727 
 2828 /*
 2929  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 3030  *
 3131  * Redistribution and use in source and binary forms, with or without
 3232  * modification, are permitted provided that the following conditions
 3333  * are met:
 3434  *
 3535  * Redistributions of source code and documentation must retain the above
 3636  * copyright notice, this list of conditions and the following disclaimer.
 3737  * Redistributions in binary form must reproduce the above copyright
 3838  * notice, this list of conditions and the following disclaimer in the
 3939  * documentation and/or other materials provided with the distribution.
 4040  * All advertising materials mentioning features or use of this software
 4141  * must display the following acknowledgement:
 4242  *      This product includes software developed or owned by Caldera
 4343  *      International, Inc.
 4444  * Neither the name of Caldera International, Inc. nor the names of other
 4545  * contributors may be used to endorse or promote products derived from
 4646  * this software without specific prior written permission.
 4747  *
 4848  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 4949  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 5050  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 5151  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 5252  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 5353  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 5454  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 5555  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 5656  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 5757  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 5858  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 5959  * POSSIBILITY OF SUCH DAMAGE.
 6060  */
 6161 
 6262 /*
 6363  * Comments for this grammar file. Ragge 021123
 6464  *
 6565  * ANSI support required rewrite of the function header and declaration
 6666  * rules almost totally.
 6767  *
 6868  * The lex/yacc shared keywords are now split from the keywords used
 6969  * in the rest of the compiler, to simplify use of other frontends.
 7070  */
 7171 
 7272 /*
 7373  * At last count, there were 5 shift/reduce and no reduce/reduce conflicts
 7474  * Four are accounted for;
 7575  * One is "dangling else"
 7676  * Two is in attribute parsing
 7777  * One is in ({ }) parsing
 7878  */
 7979 
 8080 /*
 8181  * Token used in C lex/yacc communications.
 8282  */
 8383 %token  C_STRING        /* a string constant */
 8484 %token  C_ICON          /* an integer constant */
 8585 %token  C_FCON          /* a floating point constant */
 8686 %token  C_NAME          /* an identifier */
 8787 %token  C_TYPENAME      /* a typedef'd name */
 8888 %token  C_ANDAND        /* && */
 8989 %token  C_OROR          /* || */
 9090 %token  C_GOTO          /* unconditional goto */
 9191 %token  C_RETURN        /* return from function */
 9292 %token  C_TYPE          /* a type */
 9393 %token  C_CLASS         /* a storage class */
 9494 %token  C_ASOP          /* assignment ops */
 9595 %token  C_RELOP         /* <=, <, >=, > */
 9696 %token  C_EQUOP         /* ==, != */
 9797 %token  C_DIVOP         /* /, % */
 9898 %token  C_SHIFTOP       /* <<, >> */
 9999 %token  C_INCOP         /* ++, -- */
 100100 %token  C_UNOP          /* !, ~ */
 101101 %token  C_STROP         /* ., -> */
 102102 %token  C_STRUCT
 103103 %token  C_IF
 104104 %token  C_ELSE
 105105 %token  C_SWITCH
 106106 %token  C_BREAK
 107107 %token  C_CONTINUE
 108108 %token  C_WHILE 
 109109 %token  C_DO
 110110 %token  C_FOR
 111111 %token  C_DEFAULT
 112112 %token  C_CASE
 113113 %token  C_SIZEOF
 114114 %token  C_ALIGNOF
 115115 %token  C_ENUM
 116116 %token  C_ELLIPSIS
 117117 %token  C_QUALIFIER
 118118 %token  C_FUNSPEC
 119119 %token  C_ASM
 120120 %token  NOMATCH
 121121 %token  C_TYPEOF        /* COMPAT_GCC */
 122122 %token  C_ATTRIBUTE     /* COMPAT_GCC */
 123123 %token  PCC_OFFSETOF
 124124 %token  GCC_DESIG
 125125 
 126126 /*
 127127  * Precedence
 128128  */
 129129 %left ','
 130130 %right '=' C_ASOP
 131131 %right '?' ':'
 132132 %left C_OROR
 133133 %left C_ANDAND
 134134 %left '|'
 135135 %left '^'
 136136 %left '&'
 137137 %left C_EQUOP
 138138 %left C_RELOP
 139139 %left C_SHIFTOP
 140140 %left '+' '-'
 141141 %left '*' C_DIVOP
 142142 %right C_UNOP
 143143 %right C_INCOP C_SIZEOF
 144144 %left '[' '(' C_STROP
 145145 %{
 146146 # include "pass1.h"
 147147 # include "unicode.h"
 148148 # include <stdarg.h>
 149149 # include <string.h>
 150150 # include <stdlib.h>
 151151 
 152152 int fun_inline; /* Reading an inline function */
 153153 int oldstyle;   /* Current function being defined */
 154154 static struct symtab *xnf;
 155155 extern int enummer, tvaloff, inattr;
 156156 extern struct rstack *rpole;
 157157 static int widestr, alwinl;
 158158 NODE *cftnod;
 159159 static int attrwarn = 1;
 160160 
 161161 #define NORETYP SNOCREAT /* no return type, save in unused field in symtab */
 162162 
 163163        NODE *bdty(int op, ...);
 164164 static void fend(void);
 165165 static void fundef(NODE *tp, NODE *p);
 166166 static void olddecl(NODE *p, NODE *a);
 167167 static struct symtab *init_declarator(NODE *tn, NODE *p, int assign, NODE *a,
 168168         char *as);
 169169 static void resetbc(int mask);
 170170 static void swend(void);
 171171 static void addcase(NODE *p);
 172172 #ifdef GCC_COMPAT
 173173 static void gcccase(NODE *p, NODE *);
 174174 #endif
 175175 static struct attr *gcc_attr_wrapper(NODE *p);
 176176 static void adddef(void);
 177177 static void savebc(void);
 178178 static void swstart(int, TWORD);
 179179 static void genswitch(int, TWORD, struct swents **, int);
 180180 static char *mkpstr(char *str);
 181181 static struct symtab *clbrace(NODE *);
 182182 static NODE *cmop(NODE *l, NODE *r);
 183183 static NODE *xcmop(NODE *out, NODE *in, NODE *str);
 184184 static void mkxasm(char *str, NODE *p);
 185185 static NODE *xasmop(char *str, NODE *p);
 186186 static char *stradd(char *old, char *new);
 187187 static NODE *biop(int op, NODE *l, NODE *r);
 188188 static void flend(void);
 189189 static char * simname(char *s);
 190190 static NODE *tyof(NODE *);      /* COMPAT_GCC */
 191191 static NODE *voidcon(void);
 192192 static NODE *funargs(NODE *p);
 193193 static void oldargs(NODE *p);
 194194 static void uawarn(NODE *p, char *s);
 195195 static int con_e(NODE *p);
 196196 static void dainit(NODE *d, NODE *a);
 197197 static NODE *tymfix(NODE *p);
 198198 static NODE *namekill(NODE *p, int clr);
 199199 static NODE *aryfix(NODE *p);
 200200 static void savlab(int);
 201201 extern int *mkclabs(void);
 202202 
 203203 #define TYMFIX(inp) { \
 204204         NODE *pp = inp; \
 205205         inp = tymerge(pp->n_left, pp->n_right); \
 206206         nfree(pp->n_left); nfree(pp); }
 207207 /*
 208208  * State for saving current switch state (when nested switches).
 209209  */
 210210 struct savbc {
 211211         struct savbc *next;
 212212         int brklab;
 213213         int contlab;
 214214         int flostat;
 215215         int swx;
 216216 } *savbc, *savctx;
 217217 
 218218 %}
 219219 
 220220 %union {
 221221         int intval;
 222222         NODE *nodep;
 223223         struct symtab *symp;
 224224         struct rstack *rp;
 225225         char *strp;
 226226 }
 227227 
 228228         /* define types */
 229229 %start ext_def_list
 230230 
 231231 %type <intval> ifelprefix ifprefix whprefix forprefix doprefix switchpart
 232232                 xbegin
 233233 %type <nodep> e .e term enum_dcl struct_dcl cast_type declarator
 234234                 elist type_sq cf_spec merge_attribs e2
 235235                 parameter_declaration abstract_declarator initializer
 236236                 parameter_type_list parameter_list
 237237                 declaration_specifiers designation
 238238                 specifier_qualifier_list merge_specifiers
 239239                 identifier_list arg_param_list type_qualifier_list
 240240                 designator_list designator xasm oplist oper cnstr funtype
 241241                 typeof attribute attribute_specifier /* COMPAT_GCC */
 242242                 attribute_list attr_spec_list attr_var /* COMPAT_GCC */
 243243 %type <strp>    string C_STRING GCC_DESIG
 244244 %type <rp>      str_head
 245245 %type <symp>    xnfdeclarator clbrace enum_head
 246246 
 247247 %type <intval>  C_STRUCT C_RELOP C_DIVOP C_SHIFTOP
 248248                 C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP
 249249 
 250250 %type <nodep>   C_TYPE C_QUALIFIER C_ICON C_FCON C_CLASS
 251251 %type <strp>    C_NAME C_TYPENAME
 252252 %%
 253253 
 254254 ext_def_list:      ext_def_list external_def
 255255                 | { ftnend(); }
 256256                 ;
 257257 
 258258 external_def:      funtype kr_args compoundstmt { fend(); }
 259259                 |  declaration  { blevel = 0; symclear(0); }
 260260                 |  asmstatement ';'
 261261                 |  ';'
 262262                 |  error { blevel = 0; }
 263263                 ;
 264264 
 265265 funtype:          /* no type given */ declarator {
 266266                     fundef(mkty(INT, 0, 0), $1);
 267267                     cftnsp->sflags |= NORETYP;
 268268                 }
 269269                 | declaration_specifiers declarator { fundef($1,$2); }
 270270                 ;
 271271 
 272272 kr_args:          /* empty */
 273273                 | arg_dcl_list
 274274                 ;
 275275 
 276276 /*
 277277  * Returns a node pointer or NULL, if no types at all given.
 278278  * Type trees are checked for correctness and merged into one
 279279  * type node in typenode().
 280280  */
 281281 declaration_specifiers:
 282282                    merge_attribs { $$ = typenode($1); }
 283283                 ;
 284284 
 285285 merge_attribs:     type_sq { $$ = $1; }
 286286                 |  type_sq merge_attribs { $$ = cmop($2, $1); }
 287287                 |  cf_spec { $$ = $1; }
 288288                 |  cf_spec merge_attribs { $$ = cmop($2, $1); }
 289289                 ;
 290290 
 291291 type_sq:           C_TYPE { $$ = $1; }
 292292                 |  C_TYPENAME {
 293293                         struct symtab *sp = lookup($1, 0);
 294294                         if (sp->stype == ENUMTY) {
 295295                                 sp->stype = strmemb(sp->sap)->stype;
 296296                         }
 297297                         $$ = mkty(sp->stype, sp->sdf, sp->sap);
 298298                         $$->n_sp = sp;
 299299                 }
 300300                 |  struct_dcl { $$ = $1; }
 301301                 |  enum_dcl { $$ = $1; }
 302302                 |  C_QUALIFIER { $$ = $1; }
 303303                 |  attribute_specifier { $$ = biop(ATTRIB, $1, 0); }
 304304                 |  typeof { $$ = $1; }
 305305                 ;
 306306 
 307307 cf_spec:           C_CLASS { $$ = $1; }
 308308                 |  C_FUNSPEC { fun_inline = 1;  /* XXX - hack */
 309309                         $$ = block(CLASS, NIL, NIL, 0, 0, 0); }
 310310                 ;
 311311 
 312312 typeof:            C_TYPEOF '(' e ')' { $$ = tyof(eve($3)); }
 313313                 |  C_TYPEOF '(' cast_type ')' { TYMFIX($3); $$ = tyof($3); }
 314314                 ;
 315315 
 316316 attribute_specifier :
 317317                    C_ATTRIBUTE '(' '(' attribute_list ')' ')' { $$ = $4; }
 318318  /*COMPAT_GCC*/ ;
 319319 
 320320 attribute_list:    attribute
 321321                 |  attribute ',' attribute_list { $$ = cmop($3, $1); }
 322322                 ;
 323323 
 324324 attribute:         {
 325325 #ifdef GCC_COMPAT
 326326                          $$ = voidcon();
 327327 #endif
 328328                 }
 329329                 |  C_NAME { $$ = bdty(NAME, $1); }
 330330                 |  C_NAME '(' elist ')' {
 331331                         $$ = bdty($3 == NIL ? UCALL : CALL, bdty(NAME, $1), $3);
 332332                 }
 333333                 ;
 334334 
 335335 /*
 336336  * Adds a pointer list to front of the declarators.
 337337  */
 338338 declarator:        '*' declarator { $$ = bdty(UMUL, $2); }
 339339                 |  '*' type_qualifier_list declarator {
 340340                         $$ = $2;
 341341                         $$->n_left = $3;
 342342                 }
 343343                 |  C_NAME { $$ = bdty(NAME, $1); }
 344344                 |  '(' attr_spec_list declarator ')' {
 345345                         $$ = $3;
 346346                         $$->n_ap = attr_add($$->n_ap, gcc_attr_wrapper($2));
 347347                 }
 348348                 |  '(' declarator ')' { $$ = $2; }
 349349                 |  declarator '[' e ']' { $$ = biop(LB, $1, $3); }
 350350                 |  declarator '[' C_CLASS e ']' {
 351351                         if ($3->n_type != STATIC)
 352352                                 uerror("bad class keyword");
 353353                         tfree($3); /* XXX - handle */
 354354                         $$ = biop(LB, $1, $4);
 355355                 }
 356356                 |  declarator '[' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); }
 357357                 |  declarator '[' '*' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); }
 358358                 |  declarator '(' parameter_type_list ')' {
 359359                         $$ = bdty(CALL, $1, $3);
 360360                 }
 361361                 |  declarator '(' identifier_list ')' {
 362362                         $$ = bdty(CALL, $1, $3);
 363363                         oldstyle = 1;
 364364                 }
 365365                 |  declarator '(' ')' { $$ = bdty(UCALL, $1); }
 366366                 ;
 367367 
 368368 type_qualifier_list:
 369369                    C_QUALIFIER { $$ = $1; $$->n_op = UMUL; }
 370370                 |  type_qualifier_list C_QUALIFIER {
 371371                         $$ = $1;
 372372                         $$->n_qual |= $2->n_qual;
 373373                         nfree($2);
 374374                 }
 375375                 |  attribute_specifier {
 376376                         $$ = block(UMUL, NIL, NIL, 0, 0, gcc_attr_wrapper($1));
 377377                 }
 378378                 |  type_qualifier_list attribute_specifier {
 379379                         $1->n_ap = attr_add($1->n_ap, gcc_attr_wrapper($2));
 380380                 }
 381381                 ;
 382382 
 383383 identifier_list:   C_NAME { $$ = bdty(NAME, $1); oldargs($$); }
 384384                 |  identifier_list ',' C_NAME {
 385385                         $$ = cmop($1, bdty(NAME, $3));
 386386                         oldargs($$->n_right);
 387387                 }
 388388                 ;
 389389 
 390390 /*
 391391  * Returns as parameter_list, but can add an additional ELLIPSIS node.
 392392  */
 393393 parameter_type_list:
 394394                    parameter_list { $$ = $1; }
 395395                 |  parameter_list ',' C_ELLIPSIS {
 396396                         $$ = cmop($1, biop(ELLIPSIS, NIL, NIL));
 397397                 }
 398398                 ;
 399399 
 400400 /*
 401401  * Returns a linked lists of nodes of op CM with parameters on
 402402  * its right and additional CM nodes of its left pointer.
 403403  * No CM nodes if only one parameter.
 404404  */
 405405 parameter_list:    parameter_declaration { $$ = $1; }
 406406                 |  parameter_list ',' parameter_declaration {
 407407                         $$ = cmop($1, $3);
 408408                 }
 409409                 ;
 410410 
 411411 /*
 412412  * Returns a node pointer to the declaration.
 413413  */
 414414 parameter_declaration:
 415415                    declaration_specifiers declarator attr_var {
 416416                         if ($1->n_lval != SNULL && $1->n_lval != REGISTER)
 417417                                 uerror("illegal parameter class");
 418418                         $$ = block(TYMERGE, $1, $2, INT, 0,
 419419                             gcc_attr_wrapper($3));
 420420                 }
 421421                 |  declaration_specifiers abstract_declarator {
 422422                         $1->n_ap = attr_add($1->n_ap, $2->n_ap);
 423423                         $$ = block(TYMERGE, $1, $2, INT, 0, 0);
 424424                 }
 425425                 |  declaration_specifiers {
 426426                         $$ = block(TYMERGE, $1, bdty(NAME, NULL), INT, 0, 0);
 427427                 }
 428428                 ;
 429429 
 430430 abstract_declarator:
 431431                    '*' { $$ = bdty(UMUL, bdty(NAME, NULL)); }
 432432                 |  '*' type_qualifier_list {
 433433                         $$ = $2;
 434434                         $$->n_left = bdty(NAME, NULL);
 435435                 }
 436436                 |  '*' abstract_declarator { $$ = bdty(UMUL, $2); }
 437437                 |  '*' type_qualifier_list abstract_declarator {
 438438                         $$ = $2;
 439439                         $$->n_left = $3;
 440440                 }
 441441                 |  '(' abstract_declarator ')' { $$ = $2; }
 442442                 |  '[' ']' attr_var {
 443443                         $$ = block(LB, bdty(NAME, NULL), bcon(NOOFFSET),
 444444                             INT, 0, gcc_attr_wrapper($3));
 445445                 }
 446446                 |  '[' e ']' attr_var {
 447447                         $$ = block(LB, bdty(NAME, NULL), $2,
 448448                             INT, 0, gcc_attr_wrapper($4));
 449449                 }
 450450                 |  abstract_declarator '[' ']' attr_var {
 451451                         $$ = block(LB, $1, bcon(NOOFFSET),
 452452                             INT, 0, gcc_attr_wrapper($4));
 453453                 }
 454454                 |  abstract_declarator '[' e ']' attr_var {
 455455                         $$ = block(LB, $1, $3, INT, 0, gcc_attr_wrapper($5));
 456456                 }
 457457                 |  '(' ')' attr_var {
 458458                         $$ = bdty(UCALL, bdty(NAME, NULL));
 459459                         $$->n_ap = gcc_attr_wrapper($3);
 460460                 }
 461461                 |  '(' ib2 parameter_type_list ')' attr_var {
 462462                         $$ = block(CALL, bdty(NAME, NULL), $3, INT, 0,
 463463                             gcc_attr_wrapper($5));
 464464                 }
 465465                 |  abstract_declarator '(' ')' attr_var {
 466466                         $$ = block(UCALL, $1, NIL, INT, 0, gcc_attr_wrapper($4));
 467467                 }
 468468                 |  abstract_declarator '(' ib2 parameter_type_list ')' attr_var {
 469469                         $$ = block(CALL, $1, $4, INT, 0, gcc_attr_wrapper($6));
 470470                 }
 471471                 ;
 472472 
 473473 ib2:              { }
 474474                 ;
 475475 /*
 476476  * K&R arg declaration, between ) and {
 477477  */
 478478 arg_dcl_list:      arg_declaration
 479479                 |  arg_dcl_list arg_declaration
 480480                 ;
 481481 
 482482 
 483483 arg_declaration:   declaration_specifiers arg_param_list ';' {
 484484                         nfree($1);
 485485                 }
 486486                 ;
 487487 
 488488 arg_param_list:    declarator attr_var {
 489489                         olddecl(block(TYMERGE, ccopy($<nodep>0), $1,
 490490                             INT, 0, 0), $2);
 491491                 }
 492492                 |  arg_param_list ',' declarator attr_var {
 493493                         olddecl(block(TYMERGE, ccopy($<nodep>0), $3,
 494494                             INT, 0, 0), $4);
 495495                 }
 496496                 ;
 497497 
 498498 /*
 499499  * Declarations in beginning of blocks.
 500500  */
 501501 block_item_list:   block_item
 502502                 |  block_item_list block_item
 503503                 ;
 504504 
 505505 block_item:        declaration
 506506                 |  statement
 507507                 ;
 508508 
 509509 /*
 510510  * Here starts the old YACC code.
 511511  */
 512512 
 513513 /*
 514514  * Variables are declared in init_declarator.
 515515  */
 516516 declaration:       declaration_specifiers ';' { tfree($1); fun_inline = 0; }
 517517                 |  declaration_specifiers init_declarator_list ';' {
 518518                         tfree($1);
 519519                         fun_inline = 0;
 520520                 }
 521521                 ;
 522522 
 523523 /*
 524524  * Normal declaration of variables. curtype contains the current type node.
 525525  * Returns nothing, variables are declared in init_declarator.
 526526  */
 527527 init_declarator_list:
 528528                    init_declarator { symclear(blevel); }
 529529                 |  init_declarator_list ',' attr_var { $<nodep>$ = $<nodep>0; } init_declarator {
 530530                         uawarn($3, "init_declarator");
 531531                         symclear(blevel);
 532532                 }
 533533                 ;
 534534 
 535535 enum_dcl:          enum_head '{' moe_list optcomma '}' { $$ = enumdcl($1); }
 536536                 |  C_ENUM C_NAME {  $$ = enumref($2); }
 537537                 ;
 538538 
 539539 enum_head:         C_ENUM { $$ = enumhd(NULL); }
 540540                 |  C_ENUM C_NAME {  $$ = enumhd($2); }
 541541                 ;
 542542 
 543543 moe_list:          moe
 544544                 |  moe_list ',' moe
 545545                 ;
 546546 
 547547 moe:               C_NAME {  moedef($1); }
 548548                 |  C_TYPENAME {  moedef($1); }
 549549                 |  C_NAME '=' e { enummer = con_e($3); moedef($1); }
 550550                 |  C_TYPENAME '=' e { enummer = con_e($3); moedef($1); }
 551551                 ;
 552552 
 553553 struct_dcl:        str_head '{' struct_dcl_list '}' {
 554554                         NODE *p;
 555555 
 556556                         $$ = dclstruct($1);
 557557                         if (pragma_allpacked) {
 558558                                 p = bdty(CALL, bdty(NAME, "packed"),
 559559                                     bcon(pragma_allpacked));
 560560                                 $$->n_ap = attr_add($$->n_ap,gcc_attr_wrapper(p)); }
 561561                 }
 562562                 |  C_STRUCT attr_var C_NAME {
 563563                         $$ = rstruct($3,$1);
 564564                         uawarn($2, "struct_dcl");
 565565                 }
 566566  /*COMPAT_GCC*/ |  str_head '{' '}' { $$ = dclstruct($1); }
 567567                 ;
 568568 
 569569 attr_var:          {    
 570570                         NODE *q, *p;
 571571 
 572572                         p = pragma_aligned ? bdty(CALL, bdty(NAME, "aligned"),
 573573                             bcon(pragma_aligned)) : NIL;
 574574                         if (pragma_packed) {
 575575                                 q = bdty(NAME, "packed");
 576576                                 p = (p == NIL ? q : cmop(p, q));
 577577                         }
 578578                         pragma_aligned = pragma_packed = 0;
 579579                         $$ = p;
 580580                 }
 581581  /*COMPAT_GCC*/ |  attr_spec_list
 582582                 ;
 583583 
 584584 attr_spec_list:    attribute_specifier
 585585                 |  attr_spec_list attribute_specifier { $$ = cmop($1, $2); }
 586586                 ;
 587587 
 588588 str_head:          C_STRUCT attr_var {  $$ = bstruct(NULL, $1, $2);  }
 589589                 |  C_STRUCT attr_var C_NAME {  $$ = bstruct($3, $1, $2);  }
 590590                 ;
 591591 
 592592 struct_dcl_list:   struct_declaration
 593593                 |  struct_dcl_list struct_declaration
 594594                 ;
 595595 
 596596 struct_declaration:
 597597                    specifier_qualifier_list struct_declarator_list optsemi {
 598598                         tfree($1);
 599599                 }
 600600                 ;
 601601 
 602602 optsemi:           ';' { }
 603603                 |  optsemi ';' { werror("extra ; in struct"); }
 604604                 ;
 605605 
 606606 specifier_qualifier_list:
 607607                    merge_specifiers { $$ = typenode($1); }
 608608                 ;
 609609 
 610610 merge_specifiers:  type_sq merge_specifiers { $$ = cmop($2, $1); }
 611611                 |  type_sq { $$ = $1; }
 612612                 ;
 613613 
 614614 struct_declarator_list:
 615615                    struct_declarator { symclear(blevel); }
 616616                 |  struct_declarator_list ',' { $<nodep>$=$<nodep>0; }
 617617                         struct_declarator { symclear(blevel); }
 618618                 ;
 619619 
 620620 struct_declarator: declarator attr_var {
 621621                         NODE *p;
 622622 
 623623                         $1 = aryfix($1);
 624624                         p = tymerge($<nodep>0, tymfix($1));
 625625                         if ($2)
 626626                                 p->n_ap = attr_add(p->n_ap, gcc_attr_wrapper($2));
 627627                         soumemb(p, (char *)$1->n_sp, 0);
 628628                         tfree(p);
 629629                 }
 630630                 |  ':' e {
 631631                         int ie = con_e($2);
 632632                         if (fldchk(ie))
 633633                                 ie = 1;
 634634                         falloc(NULL, ie, $<nodep>0);
 635635                 }
 636636                 |  declarator ':' e {
 637637                         int ie = con_e($3);
 638638                         if (fldchk(ie))
 639639                                 ie = 1;
 640640                         if ($1->n_op == NAME) {
 641641                                 /* XXX - tymfix() may alter $1 */
 642642                                 tymerge($<nodep>0, tymfix($1));
 643643                                 soumemb($1, (char *)$1->n_sp, FIELD | ie);
 644644                                 nfree($1);
 645645                         } else
 646646                                 uerror("illegal declarator");
 647647                 }
 648648                 |  declarator ':' e attr_spec_list {
 649649                         int ie = con_e($3);
 650650                         if (fldchk(ie))
 651651                                 ie = 1;
 652652                         if ($1->n_op == NAME) {
 653653                                 /* XXX - tymfix() may alter $1 */
 654654                                 tymerge($<nodep>0, tymfix($1));
 655655                                 if ($4)
 656656                                         $1->n_ap = attr_add($1->n_ap,
 657657                                             gcc_attr_wrapper($4));
 658658                                 soumemb($1, (char *)$1->n_sp, FIELD | ie);
 659659                                 nfree($1);
 660660                         } else
 661661                                 uerror("illegal declarator");
 662662                 }
 663663                 | /* unnamed member */ {
 664664                         NODE *p = $<nodep>0;
 665665                         char *c = permalloc(10);
 666666 
 667667                         if (p->n_type != STRTY && p->n_type != UNIONTY)
 668668                                 uerror("bad unnamed member type");
 669669                         snprintf(c, 10, "*%dFAKE", getlab());
 670670                         soumemb(p, c, 0);
 671671                 }
 672672                 ;
 673673 
 674674                 /* always preceeded by attributes */
 675675 xnfdeclarator:     declarator attr_var {
 676676                         $$ = xnf = init_declarator($<nodep>0, $1, 1, $2, 0);
 677677                 }
 678678                 |  declarator C_ASM '(' string ')' {
 679679                         $$ = xnf = init_declarator($<nodep>0, $1, 1, NULL,
 680680                             newstring($4, strlen($4)));
 681681                 }
 682682                 ;
 683683 
 684684 /*
 685685  * Handles declarations and assignments.
 686686  * Returns nothing.
 687687  */
 688688 init_declarator:   declarator attr_var {
 689689                         init_declarator($<nodep>0, $1, 0, $2, 0);
 690690                 }
 691691                 |  declarator C_ASM '(' string ')' attr_var {
 692692                         init_declarator($<nodep>0, $1, 0, $6,
 693693                             newstring($4, strlen($4)));
 694694                 }
 695695                 |  xnfdeclarator '=' e {
 696696                         if ($1->sclass == STATIC || $1->sclass == EXTDEF)
 697697                                 statinit++;
 698698                         simpleinit($1, eve($3));
 699699                         if ($1->sclass == STATIC || $1->sclass == EXTDEF)
 700700                                 statinit--;
 701701                         xnf = NULL;
 702702                 }
 703703                 |  xnfdeclarator '=' begbr init_list optcomma '}' {
 704704                         endinit(0);
 705705                         xnf = NULL;
 706706                 }
 707707  /*COMPAT_GCC*/ |  xnfdeclarator '=' begbr '}' { endinit(0); xnf = NULL; }
 708708                 ;
 709709 
 710710 begbr:             '{' { beginit($<symp>-1); }
 711711                 ;
 712712 
 713713 initializer:       e %prec ',' {  $$ = eve($1); }
 714714                 |  ibrace init_list optcomma '}' { $$ = NULL; }
 715715                 |  ibrace '}' { asginit(bcon(0)); $$ = NULL; }
 716716                 ;
 717717 
 718718 init_list:         designation initializer { dainit($1, $2); }
 719719                 |  init_list ','  designation initializer { dainit($3, $4); }
 720720                 ;
 721721 
 722722 designation:       designator_list '=' { desinit($1); $$ = NIL; }
 723723                 |  GCC_DESIG { desinit(bdty(NAME, $1)); $$ = NIL; }
 724724                 |  '[' e C_ELLIPSIS e ']' '=' { $$ = biop(CM, $2, $4); }
 725725                 |  { $$ = NIL; }
 726726                 ;
 727727 
 728728 designator_list:   designator { $$ = $1; }
 729729                 |  designator_list designator { $$ = $2; $$->n_left = $1; }
 730730                 ;
 731731 
 732732 designator:        '[' e ']' {
 733733                         int ie = con_e($2);
 734734                         if (ie < 0) {
 735735                                 uerror("designator must be non-negative");
 736736                                 ie = 0;
 737737                         }
 738738                         $$ = biop(LB, NIL, bcon(ie));
 739739                 }
 740740                 |  C_STROP C_TYPENAME {
 741741                         if ($1 != DOT)
 742742                                 uerror("invalid designator");
 743743                         $$ = bdty(NAME, $2);
 744744                 }
 745745                 |  C_STROP C_NAME {
 746746                         if ($1 != DOT)
 747747                                 uerror("invalid designator");
 748748                         $$ = bdty(NAME, $2);
 749749                 }
 750750                 ;
 751751 
 752752 optcomma        :       /* VOID */
 753753                 |  ','
 754754                 ;
 755755 
 756756 ibrace:            '{' {  ilbrace(); }
 757757                 ;
 758758 
 759759 /*      STATEMENTS      */
 760760 
 761761 compoundstmt:      begin block_item_list '}' { flend(); }
 762762                 |  begin '}' { flend(); }
 763763                 ;
 764764 
 765765 begin:            '{' {
 766766                         struct savbc *bc = tmpalloc(sizeof(struct savbc));
 767767                         if (blevel == 1) {
 768768 #ifdef STABS
 769769                                 if (gflag)
 770770                                         stabs_line(lineno);
 771771 #endif
 772772                                 dclargs();
 773773                         }
 774774 #ifdef STABS
 775775                         if (gflag && blevel > 1)
 776776                                 stabs_lbrac(blevel+1);
 777777 #endif
 778778                         ++blevel;
 779779                         oldstyle = 0;
 780780                         bc->contlab = autooff;
 781781                         bc->next = savctx;
 782782                         savctx = bc;
 783783                         if (!isinlining && sspflag && blevel == 2)
 784784                                 sspstart();
 785785                 }
 786786                 ;
 787787 
 788788 statement:         e ';' { ecomp(eve($1)); symclear(blevel); }
 789789                 |  compoundstmt
 790790                 |  ifprefix statement { plabel($1); reached = 1; }
 791791                 |  ifelprefix statement {
 792792                         if ($1 != NOLAB) {
 793793                                 plabel( $1);
 794794                                 reached = 1;
 795795                         }
 796796                 }
 797797                 |  whprefix statement {
 798798                         branch(contlab);
 799799                         plabel( brklab );
 800800                         if( (flostat&FBRK) || !(flostat&FLOOP))
 801801                                 reached = 1;
 802802                         else
 803803                                 reached = 0;
 804804                         resetbc(0);
 805805                 }
 806806                 |  doprefix statement C_WHILE '(' e ')' ';' {
 807807                         plabel(contlab);
 808808                         if (flostat & FCONT)
 809809                                 reached = 1;
 810810                         if (reached)
 811811                                 cbranch(buildtree(NE, eve($5), bcon(0)),
 812812                                     bcon($1));
 813813                         else
 814814                                 tfree(eve($5));
 815815                         plabel( brklab);
 816816                         reached = 1;
 817817                         resetbc(0);
 818818                 }
 819819                 |  forprefix .e ')' statement
 820820                         {  plabel( contlab );
 821821                             if( flostat&FCONT ) reached = 1;
 822822                             if( $2 ) ecomp( $2 );
 823823                             branch($1);
 824824                             plabel( brklab );
 825825                             if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;
 826826                             else reached = 0;
 827827                             resetbc(0);
 828828                             blevel--;
 829829                             symclear(blevel);
 830830                             }
 831831                 | switchpart statement
 832832                         { if( reached ) branch( brklab );
 833833                             plabel( $1 );
 834834                             swend();
 835835                             plabel( brklab);
 836836                             if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
 837837                             resetbc(FCONT);
 838838                             }
 839839                 |  C_BREAK  ';' {
 840840                         if (brklab == NOLAB)
 841841                                 uerror("illegal break");
 842842                         else if (reached)
 843843                                 branch(brklab);
 844844                         flostat |= FBRK;
 845845                         reached = 0;
 846846                 }
 847847                 |  C_CONTINUE  ';' {
 848848                         if (contlab == NOLAB)
 849849                                 uerror("illegal continue");
 850850                         else
 851851                                 branch(contlab);
 852852                         flostat |= FCONT;
 853853                         goto rch;
 854854                 }
 855855                 |  C_RETURN  ';' {
 856856                         branch(retlab);
 857857                         if (cftnsp->stype != VOID &&
 858858                             (cftnsp->sflags & NORETYP) == 0 &&
 859859                             cftnsp->stype != VOID+FTN)
 860860                                 uerror("return value required");
 861861                         rch:
 862862                         if (!reached)
 863863                                 warner(Wunreachable_code, NULL);
 864864                         reached = 0;
 865865                 }
 866866                 |  C_RETURN e  ';' {
 867867                         NODE *p, *q;
 868868 
 869869                         p = nametree(cftnsp);
 870870                         p->n_type = DECREF(p->n_type);
 871871                         q = eve($2);
 872872 #ifdef TARGET_TIMODE 
 873873                         NODE *r;
 874874                         if ((r = gcc_eval_ticast(RETURN, p, q)) != NULL)
 875875                                 q = r;
 876876 #endif
 877877 #ifndef NO_COMPLEX
 878878                         if (ANYCX(q) || ANYCX(p))
 879879                                 q = cxret(q, p);
 880880 #endif
 881881                         p = buildtree(RETURN, p, q);
 882882                         if (p->n_type == VOID) {
 883883                                 ecomp(p->n_right);
 884884                         } else {
 885885                                 if (cftnod == NIL)
 886886                                         cftnod = tempnode(0, p->n_type,
 887887                                             p->n_df, p->n_ap);
 888888                                 ecomp(buildtree(ASSIGN,
 889889                                     ccopy(cftnod), p->n_right));
 890890                         }
 891891                         tfree(p->n_left);
 892892                         nfree(p);
 893893                         branch(retlab);
 894894                         reached = 0;
 895895                 }
 896896                 |  C_GOTO C_NAME ';' { gotolabel($2); goto rch; }
 897897                 |  C_GOTO '*' e ';' { ecomp(biop(GOTO, eve($3), NIL)); }
 898898                 |  asmstatement ';'
 899899                 |   ';'
 900900                 |  error  ';'
 901901                 |  error '}'
 902902                 |  label statement
 903903                 ;
 904904 
 905905 asmstatement:      C_ASM mvol '(' string ')' { send_passt(IP_ASM, mkpstr($4)); }
 906906                 |  C_ASM mvol '(' string xasm ')' { mkxasm($4, $5); }
 907907                 ;
 908908 
 909909 mvol:              /* empty */
 910910                 |  C_QUALIFIER { nfree($1); }
 911911                 ;
 912912 
 913913 xasm:              ':' oplist { $$ = xcmop($2, NIL, NIL); }
 914914                 |  ':' oplist ':' oplist { $$ = xcmop($2, $4, NIL); }
 915915                 |  ':' oplist ':' oplist ':' cnstr { $$ = xcmop($2, $4, $6); }
 916916                 ;
 917917 
 918918 oplist:            /* nothing */ { $$ = NIL; }
 919919                 |  oper { $$ = $1; }
 920920                 ;
 921921 
 922922 oper:              string '(' e ')' { $$ = xasmop($1, pconvert(eve($3))); }
 923923                 |  oper ',' string '(' e ')' {
 924924                         $$ = cmop($1, xasmop($3, pconvert(eve($5))));
 925925                 }
 926926                 ;
 927927 
 928928 cnstr:             string { $$ = xasmop($1, bcon(0)); }
 929929                 |  cnstr ',' string { $$ = cmop($1, xasmop($3, bcon(0))); }
 930930                 ;
 931931 
 932932 label:             C_NAME ':' attr_var { deflabel($1, $3); reached = 1; }
 933933                 |  C_TYPENAME ':' attr_var { deflabel($1, $3); reached = 1; }
 934934                 |  C_CASE e ':' { addcase(eve($2)); reached = 1; }
 935935 /* COMPAT_GCC */|  C_CASE e C_ELLIPSIS e ':' {
 936936 #ifdef GCC_COMPAT
 937937                         gcccase(eve($2), eve($4)); reached = 1;
 938938 #endif
 939939                 }
 940940                 |  C_DEFAULT ':' { reached = 1; adddef(); flostat |= FDEF; }
 941941                 ;
 942942 
 943943 doprefix:       C_DO {
 944944                         savebc();
 945945                         brklab = getlab();
 946946                         contlab = getlab();
 947947                         plabel(  $$ = getlab());
 948948                         reached = 1;
 949949                 }
 950950                 ;
 951951 ifprefix:       C_IF '(' e ')' {
 952952                         cbranch(buildtree(NOT, eve($3), NIL), bcon($$ = getlab()));
 953953                         reached = 1;
 954954                 }
 955955                 ;
 956956 ifelprefix:       ifprefix statement C_ELSE {
 957957                         if (reached)
 958958                                 branch($$ = getlab());
 959959                         else
 960960                                 $$ = NOLAB;
 961961                         plabel( $1);
 962962                         reached = 1;
 963963                 }
 964964                 ;
 965965 
 966966 whprefix:         C_WHILE  '('  e  ')' {
 967967                         savebc();
 968968                         $3 = eve($3);
 969969                         if ($3->n_op == ICON && $3->n_lval != 0)
 970970                                 flostat = FLOOP;
 971971                         plabel( contlab = getlab());
 972972                         reached = 1;
 973973                         brklab = getlab();
 974974                         if (flostat == FLOOP)
 975975                                 tfree($3);
 976976                         else
 977977                                 cbranch(buildtree(NOT, $3, NIL), bcon(brklab));
 978978                 }
 979979                 ;
 980980 forprefix:        C_FOR  '('  .e  ';' .e  ';' {
 981981                         ++blevel;
 982982                         if ($3)
 983983                                 ecomp($3);
 984984                         savebc();
 985985                         contlab = getlab();
 986986                         brklab = getlab();
 987987                         plabel( $$ = getlab());
 988988                         reached = 1;
 989989                         if ($5)
 990990                                 cbranch(buildtree(NOT, $5, NIL), bcon(brklab));
 991991                         else
 992992                                 flostat |= FLOOP;
 993993                 }
 994994                 |  C_FOR '(' { ++blevel; } declaration .e ';' {
 995995                         savebc();
 996996                         contlab = getlab();
 997997                         brklab = getlab();
 998998                         plabel( $$ = getlab());
 999999                         reached = 1;
 10001000                         if ($5)
 10011001                                 cbranch(buildtree(NOT, $5, NIL), bcon(brklab));
 10021002                         else
 10031003                                 flostat |= FLOOP;
 10041004                 }
 10051005                 ;
 10061006 
 10071007 switchpart:        C_SWITCH  '('  e ')' {
 10081008                         NODE *p;
 10091009                         int num;
 10101010                         TWORD t;
 10111011 
 10121012                         savebc();
 10131013                         brklab = getlab();
 10141014                         $3 = eve($3);
 10151015                         if (!ISINTEGER($3->n_type)) {
 10161016                                 uerror("switch expression must have integer "
 10171017                                        "type");
 10181018                                 t = INT;
 10191019                         } else {
 10201020                                 $3 = intprom($3);
 10211021                                 t = $3->n_type;
 10221022                         }
 10231023                         p = tempnode(0, t, 0, 0);
 10241024                         num = regno(p);
 10251025                         ecomp(buildtree(ASSIGN, p, $3));
 10261026                         branch( $$ = getlab());
 10271027                         swstart(num, t);
 10281028                         reached = 0;
 10291029                 }
 10301030                 ;
 10311031 /*      EXPRESSIONS     */
 10321032 .e:                e { $$ = eve($1); }
 10331033                 |       { $$=0; }
 10341034                 ;
 10351035 
 10361036 elist:             { $$ = NIL; }
 10371037                 |  e2 { $$ = $1; }
 10381038                 ;
 10391039 
 10401040 e2:                e %prec ','
 10411041                 |  e2  ','  e { $$ = biop(CM, $1, $3); }
 10421042                 |  e2  ','  cast_type { /* hack for stdarg */
 10431043                         TYMFIX($3);
 10441044                         $3->n_op = TYPE;
 10451045                         $$ = biop(CM, $1, $3);
 10461046                 }
 10471047                 ;
 10481048 
 10491049 /*
 10501050  * Precedence order of operators.
 10511051  */
 10521052 e:                 e ',' e { $$ = biop(COMOP, $1, $3); }
 10531053                 |  e '=' e {  $$ = biop(ASSIGN, $1, $3); }
 10541054                 |  e C_ASOP e {  $$ = biop($2, $1, $3); }
 10551055                 |  e '?' e ':' e { $$=biop(QUEST, $1, biop(COLON, $3, $5)); }
 10561056 /* COMPAT_GCC */|  e '?' ':' e { $$ = biop(BIQUEST, $1, $4); }
 10571057                 |  e C_OROR e { $$ = biop($2, $1, $3); }
 10581058                 |  e C_ANDAND e { $$ = biop($2, $1, $3); }
 10591059                 |  e '|' e { $$ = biop(OR, $1, $3); }
 10601060                 |  e '^' e { $$ = biop(ER, $1, $3); }
 10611061                 |  e '&' e { $$ = biop(AND, $1, $3); }
 10621062                 |  e C_EQUOP  e { $$ = biop($2, $1, $3); }
 10631063                 |  e C_RELOP e { $$ = biop($2, $1, $3); }
 10641064                 |  e C_SHIFTOP e { $$ = biop($2, $1, $3); }
 10651065                 |  e '+' e { $$ = biop(PLUS, $1, $3); }
 10661066                 |  e '-' e { $$ = biop(MINUS, $1, $3); }
 10671067                 |  e C_DIVOP e { $$ = biop($2, $1, $3); }
 10681068                 |  e '*' e { $$ = biop(MUL, $1, $3); }
 10691069                 |  term
 10701070                 ;
 10711071 
 10721072 xbegin:            begin {
 10731073                         $$ = getlab(); getlab(); getlab();
 10741074                         branch($$); plabel(($$)+1); }
 10751075                 ;
 10761076 
 10771077 term:              term C_INCOP {  $$ = biop($2, $1, bcon(1)); }
 10781078                 |  '*' term { $$ = biop(UMUL, $2, NIL); }
 10791079                 |  '&' term { $$ = biop(ADDROF, $2, NIL); }
 10801080                 |  '-' term { $$ = biop(UMINUS, $2, NIL ); }
<>1081 -                |  '+' term { $$ = biop(PLUS, $2, bcon(0)); }
  1081+                |  '+' term { $$ = biop(UPLUS, $2, NIL ); }
10821082                 |  C_UNOP term { $$ = biop($1, $2, NIL); }
 10831083                 |  C_INCOP term {
 10841084                         $$ = biop($1 == INCR ? PLUSEQ : MINUSEQ, $2, bcon(1));
 10851085                 }
 10861086                 |  C_SIZEOF xa term { $$ = biop(SZOF, $3, bcon(0)); inattr = $<intval>2; }
 10871087                 |  '(' cast_type ')' term  %prec C_INCOP {
 10881088                         TYMFIX($2);
 10891089                         $$ = biop(CAST, $2, $4);
 10901090                 }
 10911091                 |  C_SIZEOF xa '(' cast_type ')'  %prec C_SIZEOF {
 10921092                         $$ = biop(SZOF, $4, bcon(1));
 10931093                         inattr = $<intval>2;
 10941094                 }
 10951095                 |  C_ALIGNOF xa '(' cast_type ')' {
 10961096                         int al;
 10971097                         TYMFIX($4);
 10981098                         al = talign($4->n_type, $4->n_ap);
 10991099                         $$ = bcon(al/SZCHAR);
 11001100                         inattr = $<intval>2;
 11011101                         tfree($4);
 11021102                 }
 11031103                 | '(' cast_type ')' clbrace init_list optcomma '}' {
 11041104                         endinit(0);
 11051105                         $$ = bdty(NAME, $4);
 11061106                         $$->n_op = CLOP;
 11071107                 }
 11081108                 | '(' cast_type ')' clbrace '}' {
 11091109                         endinit(0);
 11101110                         $$ = bdty(NAME, $4);
 11111111                         $$->n_op = CLOP;
 11121112                 }
 11131113                 |  term '[' e ']' { $$ = biop(LB, $1, $3); }
 11141114                 |  C_NAME  '(' elist ')' {
 11151115                         $$ = biop($3 ? CALL : UCALL, bdty(NAME, $1), $3);
 11161116                 }
 11171117                 |  term  '(' elist ')' { $$ = biop($3 ? CALL : UCALL, $1, $3); }
 11181118                 |  term C_STROP C_NAME { $$ = biop($2, $1, bdty(NAME, $3)); }
 11191119                 |  term C_STROP C_TYPENAME { $$ = biop($2, $1, bdty(NAME, $3));}
 11201120                 |  C_NAME %prec C_SIZEOF /* below ( */{ $$ = bdty(NAME, $1); }
 11211121                 |  PCC_OFFSETOF  '(' cast_type ',' term ')' {
 11221122                         TYMFIX($3);
 11231123                         $3->n_type = INCREF($3->n_type);
 11241124                         $3 = biop(CAST, $3, bcon(0));
 11251125                         if ($5->n_op == NAME) {
 11261126                                 $$ = biop(STREF, $3, $5);
 11271127                         } else {
 11281128                                 NODE *p = $5;
 11291129                                 while (p->n_left->n_op != NAME)
 11301130                                         p = p->n_left;
 11311131                                 p->n_left = biop(STREF, $3, p->n_left);
 11321132                                 $$ = $5;
 11331133                         }
 11341134                         $$ = biop(ADDROF, $$, NIL);
 11351135                         $3 = block(NAME, NIL, NIL, ENUNSIGN(INTPTR), 0, 0);
 11361136                         $$ = biop(CAST, $3, $$);
 11371137                 }
 11381138                 |  C_ICON { $$ = $1; }
 11391139                 |  C_FCON { $$ = $1; }
 11401140                 |  string { $$ = bdty(STRING, $1, widestr); }
 11411141                 |   '('  e  ')' { $$=$2; }
 11421142                 |  '(' xbegin block_item_list e ';' '}' ')' {
 11431143                         /* XXX - check recursive ({ }) statements */
 11441144                         branch(($2)+2);
 11451145                         plabel($2);
 11461146                         $$ = buildtree(COMOP,
 11471147                             biop(GOTO, bcon(($2)+1), NIL), eve($4));
 11481148                         flend();
 11491149                 }
 11501150                 |  '(' xbegin block_item_list '}' ')' {
 11511151                         /* XXX - check recursive ({ }) statements */
 11521152                         branch(($2)+2);
 11531153                         plabel($2);
 11541154                         $$ = buildtree(COMOP,
 11551155                             biop(GOTO, bcon(($2)+1), NIL), voidcon());
 11561156                         flend();
 11571157                 }
 11581158                 | C_ANDAND C_NAME {
 11591159                         struct symtab *s = lookup($2, SLBLNAME);
 11601160                         if (s->soffset == 0) {
 11611161                                 s->soffset = -getlab();
 11621162                                 s->sclass = STATIC;
 11631163                         }
 11641164                         savlab(s->soffset);
 11651165                         $$ = biop(ADDROF, bdty(GOTO, $2), NIL);
 11661166                 }
 11671167                 ;
 11681168 
 11691169 xa:               { $<intval>$ = inattr; inattr = 0; }
 11701170                 ;
 11711171 
 11721172 clbrace:           '{'  { NODE *q = $<nodep>-1; TYMFIX(q); $$ = clbrace(q); }
 11731173                 ;
 11741174 
 11751175 string:            C_STRING { widestr = 0; $$ = stradd("", $1); }
 11761176                 |  string C_STRING { $$ = stradd($1, $2); }
 11771177                 ;
 11781178 
 11791179 cast_type:         specifier_qualifier_list {
 11801180                         $$ = biop(TYMERGE, $1, bdty(NAME, NULL));
 11811181                 }
 11821182                 |  specifier_qualifier_list abstract_declarator {
 11831183                         $$ = biop(TYMERGE, $1, aryfix($2));
 11841184                 }
 11851185                 ;
 11861186 
 11871187 %%
 11881188 
 11891189 NODE *
 11901190 mkty(TWORD t, union dimfun *d, struct attr *sue)
 11911191 {
 11921192         return block(TYPE, NIL, NIL, t, d, sue);
 11931193 }
 11941194 
 11951195 NODE *
 11961196 bdty(int op, ...)
 11971197 {
 11981198         va_list ap;
 11991199         int val;
 12001200         register NODE *q;
 12011201 
 12021202         va_start(ap, op);
 12031203         q = biop(op, NIL, NIL);
 12041204 
 12051205         switch (op) {
 12061206         case UMUL:
 12071207         case UCALL:
 12081208                 q->n_left = va_arg(ap, NODE *);
 12091209                 q->n_rval = 0;
 12101210                 break;
 12111211 
 12121212         case CALL:
 12131213                 q->n_left = va_arg(ap, NODE *);
 12141214                 q->n_right = va_arg(ap, NODE *);
 12151215                 break;
 12161216 
 12171217         case LB:
 12181218                 q->n_left = va_arg(ap, NODE *);
 12191219                 if ((val = va_arg(ap, int)) <= 0) {
 12201220                         uerror("array size must be positive");
 12211221                         val = 1;
 12221222                 }
 12231223                 q->n_right = bcon(val);
 12241224                 break;
 12251225 
 12261226         case GOTO: /* for named labels */
 12271227                 q->n_label = SLBLNAME;
 12281228                 /* FALLTHROUGH */
 12291229         case NAME:
 12301230                 q->n_op = NAME;
 12311231                 q->n_sp = va_arg(ap, struct symtab *); /* XXX survive tymerge */
 12321232                 break;
 12331233 
 12341234         case STRING:
 12351235                 q->n_type = PTR|CHAR;
 12361236                 q->n_name = va_arg(ap, char *);
 12371237                 q->n_lval = va_arg(ap, int);
 12381238                 break;
 12391239 
 12401240         default:
 12411241                 cerror("bad bdty");
 12421242         }
 12431243         va_end(ap);
 12441244 
 12451245         return q;
 12461246 }
 12471247 
 12481248 static void
 12491249 flend(void)
 12501250 {
 12511251         if (!isinlining && sspflag && blevel == 2)
 12521252                 sspend();
 12531253 #ifdef STABS
 12541254         if (gflag && blevel > 2)
 12551255                 stabs_rbrac(blevel);
 12561256 #endif
 12571257         --blevel;
 12581258         if( blevel == 1 )
 12591259                 blevel = 0;
 12601260         symclear(blevel); /* Clean ut the symbol table */
 12611261         if (autooff > maxautooff)
 12621262                 maxautooff = autooff;
 12631263         autooff = savctx->contlab;
 12641264         savctx = savctx->next;
 12651265 }
 12661266 
 12671267 static void
 12681268 savebc(void)
 12691269 {
 12701270         struct savbc *bc = tmpalloc(sizeof(struct savbc));
 12711271 
 12721272         bc->brklab = brklab;
 12731273         bc->contlab = contlab;
 12741274         bc->flostat = flostat;
 12751275         bc->next = savbc;
 12761276         savbc = bc;
 12771277         flostat = 0;
 12781278 }
 12791279 
 12801280 static void
 12811281 resetbc(int mask)
 12821282 {
 12831283         flostat = savbc->flostat | (flostat&mask);
 12841284         contlab = savbc->contlab;
 12851285         brklab = savbc->brklab;
 12861286         savbc = savbc->next;
 12871287 }
 12881288 
 12891289 struct swdef {
 12901290         struct swdef *next;     /* Next in list */
 12911291         int deflbl;             /* Label for "default" */
 12921292         struct swents *ents;    /* Linked sorted list of case entries */
 12931293         int nents;              /* # of entries in list */
 12941294         int num;                /* Node value will end up in */
 12951295         TWORD type;             /* Type of switch expression */
 12961296 } *swpole;
 12971297 
 12981298 /*
 12991299  * add case to switch
 13001300  */
 13011301 static void
 13021302 addcase(NODE *p)
 13031303 {
 13041304         struct swents **put, *w, *sw = tmpalloc(sizeof(struct swents));
 13051305         CONSZ val;
 13061306 
 13071307         p = optloop(p);  /* change enum to ints */
 13081308         if (p->n_op != ICON || p->n_sp != NULL) {
 13091309                 uerror( "non-constant case expression");
 13101310                 return;
 13111311         }
 13121312         if (swpole == NULL) {
 13131313                 uerror("case not in switch");
 13141314                 return;
 13151315         }
 13161316 
 13171317         if (DEUNSIGN(swpole->type) != DEUNSIGN(p->n_type)) {
 13181318                 val = p->n_lval;
 13191319                 p = makety(p, swpole->type, 0, 0, 0);
 13201320                 if (p->n_op != ICON)
 13211321                         cerror("could not cast case value to type of switch "
 13221322                                "expression");
 13231323                 if (p->n_lval != val)
 13241324                         werror("case expression truncated");
 13251325         }
 13261326         sw->sval = p->n_lval;
 13271327         tfree(p);
 13281328         put = &swpole->ents;
 13291329         if (ISUNSIGNED(swpole->type)) {
 13301330                 for (w = swpole->ents;
 13311331                      w != NULL && (U_CONSZ)w->sval < (U_CONSZ)sw->sval;
 13321332                      w = w->next)
 13331333                         put = &w->next;
 13341334         } else {
 13351335                 for (w = swpole->ents; w != NULL && w->sval < sw->sval;
 13361336                      w = w->next)
 13371337                         put = &w->next;
 13381338         }
 13391339         if (w != NULL && w->sval == sw->sval) {
 13401340                 uerror("duplicate case in switch");
 13411341                 return;
 13421342         }
 13431343         plabel(sw->slab = getlab());
 13441344         *put = sw;
 13451345         sw->next = w;
 13461346         swpole->nents++;
 13471347 }
 13481348 
 13491349 #ifdef GCC_COMPAT
 13501350 void
 13511351 gcccase(NODE *ln, NODE *hn)
 13521352 {
 13531353         CONSZ i, l, h;
 13541354 
 13551355         l = icons(optim(ln));
 13561356         h = icons(optim(hn));
 13571357 
 13581358         if (h < l)
 13591359                 i = l, l = h, h = i;
 13601360 
 13611361         for (i = l; i <= h; i++)
 13621362                 addcase(xbcon(i, NULL, hn->n_type));
 13631363 }
 13641364 #endif
 13651365 
 13661366 /*
 13671367  * add default case to switch
 13681368  */
 13691369 static void
 13701370 adddef(void)
 13711371 {
 13721372         if (swpole == NULL)
 13731373                 uerror("default not inside switch");
 13741374         else if (swpole->deflbl != 0)
 13751375                 uerror("duplicate default in switch");
 13761376         else
 13771377                 plabel( swpole->deflbl = getlab());
 13781378 }
 13791379 
 13801380 static void
 13811381 swstart(int num, TWORD type)
 13821382 {
 13831383         struct swdef *sw = tmpalloc(sizeof(struct swdef));
 13841384 
 13851385         sw->deflbl = sw->nents = 0;
 13861386         sw->ents = NULL;
 13871387         sw->next = swpole;
 13881388         sw->num = num;
 13891389         sw->type = type;
 13901390         swpole = sw;
 13911391 }
 13921392 
 13931393 /*
 13941394  * end a switch block
 13951395  */
 13961396 static void
 13971397 swend(void)
 13981398 {
 13991399         struct swents *sw, **swp;
 14001400         int i;
 14011401 
 14021402         sw = tmpalloc(sizeof(struct swents));
 14031403         swp = tmpalloc(sizeof(struct swents *) * (swpole->nents+1));
 14041404 
 14051405         sw->slab = swpole->deflbl;
 14061406         swp[0] = sw;
 14071407 
 14081408         for (i = 1; i <= swpole->nents; i++) {
 14091409                 swp[i] = swpole->ents;
 14101410                 swpole->ents = swpole->ents->next;
 14111411         }
 14121412         genswitch(swpole->num, swpole->type, swp, swpole->nents);
 14131413 
 14141414         swpole = swpole->next;
 14151415 }
 14161416 
 14171417 /*
 14181418  * num: tempnode the value of the switch expression is in
 14191419  * type: type of the switch expression
 14201420  *
 14211421  * p points to an array of structures, each consisting
 14221422  * of a constant value and a label.
 14231423  * The first is >=0 if there is a default label;
 14241424  * its value is the label number
 14251425  * The entries p[1] to p[n] are the nontrivial cases
 14261426  * n is the number of case statements (length of list)
 14271427  */
 14281428 static void
 14291429 genswitch(int num, TWORD type, struct swents **p, int n)
 14301430 {
 14311431         NODE *r, *q;
 14321432         int i;
 14331433 
 14341434         if (mygenswitch(num, type, p, n))
 14351435                 return;
 14361436 
 14371437         /* simple switch code */
 14381438         for (i = 1; i <= n; ++i) {
 14391439                 /* already in 1 */
 14401440                 r = tempnode(num, type, 0, 0);
 14411441                 q = xbcon(p[i]->sval, NULL, type);
 14421442                 r = buildtree(NE, r, clocal(q));
 14431443                 cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab));
 14441444         }
 14451445         if (p[0]->slab > 0)
 14461446                 branch(p[0]->slab);
 14471447 }
 14481448 
 14491449 /*
 14501450  * Declare a variable or prototype.
 14511451  */
 14521452 static struct symtab *
 14531453 init_declarator(NODE *tn, NODE *p, int assign, NODE *a, char *as)
 14541454 {
 14551455         int class = tn->n_lval;
 14561456         struct symtab *sp;
 14571457 
 14581458         p = aryfix(p);
 14591459         p = tymerge(tn, p);
 14601460         if (a) {
 14611461                 struct attr *ap = gcc_attr_wrapper(a);
 14621462                 p->n_ap = attr_add(p->n_ap, ap);
 14631463         }
 14641464 
 14651465         p->n_sp = sp = lookup((char *)p->n_sp, 0); /* XXX */
 14661466 
 14671467         if (fun_inline && ISFTN(p->n_type))
 14681468                 sp->sflags |= SINLINE;
 14691469 
 14701470         if (!ISFTN(p->n_type)) {
 14711471                 if (assign) {
 14721472                         defid2(p, class, as);
 14731473                         sp = p->n_sp;
 14741474                         sp->sflags |= SASG;
 14751475                         if (sp->sflags & SDYNARRAY)
 14761476                                 uerror("can't initialize dynamic arrays");
 14771477                         lcommdel(sp);
 14781478                 } else
 14791479                         nidcl2(p, class, as);
 14801480         } else {
 14811481                 extern NODE *parlink;
 14821482                 if (assign)
 14831483                         uerror("cannot initialise function");
 14841484                 defid2(p, uclass(class), as);
 14851485                 sp = p->n_sp;
 14861486                 if (sp->sdf->dfun == 0 && !issyshdr)
 14871487                         warner(Wstrict_prototypes);
 14881488                 if (parlink) {
 14891489                         /* dynamic sized arrays in prototypes */
 14901490                         tfree(parlink); /* Free delayed tree */
 14911491                         parlink = NIL;
 14921492                 }
 14931493         }
 14941494         tfree(p);
 14951495         if (issyshdr)
 14961496                 sp->sflags |= SINSYS; /* declared in system header */
 14971497         return sp;
 14981498 }
 14991499 
 15001500 /*
 15011501  * Declare old-stype function arguments.
 15021502  */
 15031503 static void
 15041504 oldargs(NODE *p)
 15051505 {
 15061506         blevel++;
 15071507         p->n_op = TYPE;
 15081508         p->n_type = FARG;
 15091509         p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */
 15101510         defid(p, PARAM);
 15111511         blevel--;
 15121512 }
 15131513 
 15141514 /*
 15151515  * Set NAME nodes to a null name and index of LB nodes to NOOFFSET
 15161516  * unless clr is one, in that case preserve variable name.
 15171517  */
 15181518 static NODE *
 15191519 namekill(NODE *p, int clr)
 15201520 {
 15211521         NODE *q;
 15221522         int o = p->n_op;
 15231523 
 15241524         switch (coptype(o)) {
 15251525         case LTYPE:
 15261526                 if (o == NAME) {
 15271527                         if (clr)
 15281528                                 p->n_sp = NULL;
 15291529                         else
 15301530                                 p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */
 15311531                 }
 15321532                 break;
 15331533 
 15341534         case UTYPE:
 15351535                 p->n_left = namekill(p->n_left, clr);
 15361536                 break;
 15371537 
 15381538         case BITYPE:
 15391539                 p->n_left = namekill(p->n_left, clr);
 15401540                 if (o == LB) {
 15411541                         if (clr) {
 15421542                                 tfree(p->n_right);
 15431543                                 p->n_right = bcon(NOOFFSET);
 15441544                         } else
 15451545                                 p->n_right = eve(p->n_right);
 15461546                 } else if (o == CALL)
 15471547                         p->n_right = namekill(p->n_right, 1);
 15481548                 else
 15491549                         p->n_right = namekill(p->n_right, clr);
 15501550                 if (o == TYMERGE) {
 15511551                         q = tymerge(p->n_left, p->n_right);
 15521552                         q->n_ap = attr_add(q->n_ap, p->n_ap);
 15531553                         tfree(p->n_left);
 15541554                         nfree(p);
 15551555                         p = q;
 15561556                 }
 15571557                 break;
 15581558         }
 15591559         return p;
 15601560 }
 15611561 
 15621562 /*
 15631563  * Declare function arguments.
 15641564  */
 15651565 static NODE *
 15661566 funargs(NODE *p)
 15671567 {
 15681568         extern NODE *arrstk[10];
 15691569 
 15701570         if (p->n_op == ELLIPSIS)
 15711571                 return p;
 15721572 
 15731573         p = namekill(p, 0);
 15741574         if (ISFTN(p->n_type))
 15751575                 p->n_type = INCREF(p->n_type);
 15761576         if (ISARY(p->n_type)) {
 15771577                 p->n_type += (PTR-ARY);
 15781578                 if (p->n_df->ddim == -1)
 15791579                         tfree(arrstk[0]), arrstk[0] = NIL;
 15801580                 p->n_df++;
 15811581         }
 15821582         if (p->n_type == VOID && p->n_sp->sname == NULL)
 15831583                 return p; /* sanitycheck later */
 15841584         else if (p->n_sp->sname == NULL)
 15851585                 uerror("argument missing");
 15861586         else
 15871587                 defid(p, PARAM);
 15881588         return p;
 15891589 }
 15901590 
 15911591 static NODE *
 15921592 listfw(NODE *p, NODE * (*f)(NODE *))
 15931593 {
 15941594         if (p->n_op == CM) {
 15951595                 p->n_left = listfw(p->n_left, f);
 15961596                 p->n_right = (*f)(p->n_right);
 15971597         } else
 15981598                 p = (*f)(p);
 15991599         return p;
 16001600 }
 16011601 
 16021602 
 16031603 /*
 16041604  * Declare a function.
 16051605  */
 16061606 static void
 16071607 fundef(NODE *tp, NODE *p)
 16081608 {
 16091609         extern int prolab;
 16101610         struct symtab *s;
 16111611         NODE *q, *typ;
 16121612         int class = tp->n_lval, oclass, ctval;
 16131613         char *c;
 16141614 
 16151615         /*
 16161616          * We discard all names except for those needed for
 16171617          * parameter declaration. While doing that, also change
 16181618          * non-constant array sizes to unknown.
 16191619          */
 16201620         ctval = tvaloff;
 16211621         for (q = p; coptype(q->n_op) != LTYPE &&
 16221622             q->n_left->n_op != NAME; q = q->n_left) {
 16231623                 if (q->n_op == CALL)
 16241624                         q->n_right = namekill(q->n_right, 1);
 16251625         }
 16261626         if (q->n_op != CALL && q->n_op != UCALL) {
 16271627                 uerror("invalid function definition");
 16281628                 p = bdty(UCALL, p);
 16291629         } else if (q->n_op == CALL) {
 16301630                 blevel = 1;
 16311631                 argoff = ARGINIT;
 16321632                 if (oldstyle == 0)
 16331633                         q->n_right = listfw(q->n_right, funargs);
 16341634                 ftnarg(q);
 16351635                 blevel = 0;
 16361636         }
 16371637 
 16381638         p = typ = tymerge(tp, p);
 16391639 #ifdef GCC_COMPAT
 16401640         /* gcc seems to discard __builtin_ when declaring functions */
 16411641         if (strncmp("__builtin_", (char *)typ->n_sp, 10) == 0)
 16421642                 typ->n_sp = (struct symtab *)((char *)typ->n_sp + 10);
 16431643 #endif
 16441644         s = typ->n_sp = lookup((char *)typ->n_sp, 0); /* XXX */
 16451645 
 16461646         oclass = s->sclass;
 16471647         if (class == STATIC && oclass == EXTERN)
 16481648                 werror("%s was first declared extern, then static", s->sname);
 16491649 
 16501650         if (fun_inline) {
 16511651                 /* special syntax for inline functions */
 16521652                 if (! strcmp(s->sname,"main"))
 16531653                         uerror("cannot inline main()");
 16541654 
 16551655                 s->sflags |= SINLINE;
 16561656                 inline_start(s, class);
 16571657                 if (class == EXTERN)
 16581658                         class = EXTDEF;
 16591659         } else if (class == EXTERN)
 16601660                 class = SNULL; /* same result */
 16611661 
 16621662         cftnsp = s;
 16631663         defid(p, class);
 16641664         if (s->sdf->dfun == 0 && !issyshdr)
 16651665                 warner(Wstrict_prototypes);
 16661666 #ifdef GCC_COMPAT
 16671667         if (attr_find(p->n_ap, GCC_ATYP_ALW_INL)) {
 16681668                 /* Temporary turn on temps to make always_inline work */
 16691669                 alwinl = 1;
 16701670                 if (xtemps == 0) alwinl |= 2;
 16711671                 xtemps = 1;
 16721672         }
 16731673 #endif
 16741674         prolab = getlab();
 16751675         if ((c = cftnsp->soname) == NULL)
 16761676                 c = addname(exname(cftnsp->sname));
 16771677         send_passt(IP_PROLOG, -1, c, cftnsp->stype,
 16781678             cftnsp->sclass == EXTDEF, prolab, ctval);
 16791679         blevel++;
 16801680 #ifdef STABS
 16811681         if (gflag)
 16821682                 stabs_func(s);
 16831683 #endif
 16841684         tfree(tp);
 16851685         tfree(p);
 16861686 
 16871687 }
 16881688 
 16891689 static void
 16901690 fend(void)
 16911691 {
 16921692         if (blevel)
 16931693                 cerror("function level error");
 16941694         ftnend();
 16951695         fun_inline = 0;
 16961696         if (alwinl & 2) xtemps = 0;
 16971697         alwinl = 0;
 16981698         cftnsp = NULL;
 16991699 }
 17001700 
 17011701 NODE *
 17021702 structref(NODE *p, int f, char *name)
 17031703 {
 17041704         NODE *r;
 17051705 
 17061706         if (f == DOT)
 17071707                 p = buildtree(ADDROF, p, NIL);
 17081708         r = biop(NAME, NIL, NIL);
 17091709         r->n_name = name;
 17101710         r = buildtree(STREF, p, r);
 17111711         return r;
 17121712 }
 17131713 
 17141714 static void
 17151715 olddecl(NODE *p, NODE *a)
 17161716 {
 17171717         struct symtab *s;
 17181718 
 17191719         p = namekill(p, 0);
 17201720         s = p->n_sp;
 17211721         if (s->slevel != 1 || s->stype == UNDEF)
 17221722                 uerror("parameter '%s' not defined", s->sname);
 17231723         else if (s->stype != FARG)
 17241724                 uerror("parameter '%s' redefined", s->sname);
 17251725 
 17261726         s->stype = p->n_type;
 17271727         s->sdf = p->n_df;
 17281728         s->sap = p->n_ap;
 17291729         if (ISARY(s->stype)) {
 17301730                 s->stype += (PTR-ARY);
 17311731                 s->sdf++;
 17321732         } else if (s->stype == FLOAT)
 17331733                 s->stype = DOUBLE;
 17341734         if (a)
 17351735                 attr_add(s->sap, gcc_attr_wrapper(a));
 17361736         nfree(p);
 17371737 }
 17381738 
 17391739 void
 17401740 branch(int lbl)
 17411741 {
 17421742         int r = reached++;
 17431743         ecomp(biop(GOTO, bcon(lbl), NIL));
 17441744         reached = r;
 17451745 }
 17461746 
 17471747 /*
 17481748  * Create a printable string based on an encoded string.
 17491749  */
 17501750 static char *
 17511751 mkpstr(char *str)
 17521752 {
 17531753         char *s;
 17541754         int l = strlen(str) + 3; /* \t + \n + \0 */
 17551755 
 17561756         s = inlalloc(l);
 17571757         snprintf(s, l, "\t%s\n", str);
 17581758         return s;
 17591759 }
 17601760 
 17611761 /*
 17621762  * Convert string to utf-8 and append to old string.
 17631763  */
 17641764 static char *
 17651765 stradd(char *old, char *new)
 17661766 {
 17671767         char *rv;
 17681768     int newlen = strlen(new);
 17691769     int oldlen = strlen(old);
 17701770 
 17711771         if (*new == 'L' && new[1] == '\"')
 17721772         widestr = 1, new++, newlen--;
 17731773         if (*new == '\"') {
 17741774                 new++;                   /* remove first " */
 17751775         new[newlen-=2] = 0;/* remove last " */
 17761776         }
 17771777     rv=tmpalloc(oldlen + newlen + 1);
 17781778     strlcpy(rv, old, oldlen+1);
 17791779         char *p;
 17801780         for (p = rv + oldlen; *new; *p++=esc2char(&new));
 17811781         *p=0;
 17821782         return rv;
 17831783 }
 17841784 
 17851785 /*
 17861786  * Fake a symtab entry for compound literals.
 17871787  */
 17881788 static struct symtab *
 17891789 clbrace(NODE *p)
 17901790 {
 17911791         struct symtab *sp;
 17921792 
 17931793         sp = getsymtab(simname("cl"), STEMP);
 17941794         sp->stype = p->n_type;
 17951795         sp->squal = p->n_qual;
 17961796         sp->sdf = p->n_df;
 17971797         sp->sap = p->n_ap;
 17981798         tfree(p);
 17991799         if (blevel == 0 && xnf != NULL) {
 18001800                 sp->sclass = STATIC;
 18011801                 sp->slevel = 2;
 18021802                 sp->soffset = getlab();
 18031803         } else {
 18041804                 sp->sclass = blevel ? AUTO : STATIC;
 18051805                 if (!ISARY(sp->stype) || sp->sdf->ddim != NOOFFSET) {
 18061806                         sp->soffset = NOOFFSET;
 18071807                         oalloc(sp, &autooff);
 18081808                 }
 18091809         }
 18101810         beginit(sp);
 18111811         return sp;
 18121812 }
 18131813 
 18141814 char *
 18151815 simname(char *s)
 18161816 {
 18171817         int len = strlen(s) + 10 + 1;
 18181818         char *w = tmpalloc(len);
 18191819 
 18201820         snprintf(w, len, "%s%d", s, getlab());
 18211821         return w;
 18221822 }
 18231823 
 18241824 NODE *
 18251825 biop(int op, NODE *l, NODE *r)
 18261826 {
 18271827         return block(op, l, r, INT, 0, 0);
 18281828 }
 18291829 
 18301830 static NODE *
 18311831 cmop(NODE *l, NODE *r)
 18321832 {
 18331833         return biop(CM, l, r);
 18341834 }
 18351835 
 18361836 static NODE *
 18371837 voidcon(void)
 18381838 {
 18391839         return block(ICON, NIL, NIL, STRTY, 0, 0);
 18401840 }
 18411841 
 18421842 /* Support for extended assembler a' la' gcc style follows below */
 18431843 
 18441844 static NODE *
 18451845 xmrg(NODE *out, NODE *in)
 18461846 {
 18471847         NODE *p = in;
 18481848 
 18491849         if (p->n_op == XARG) {
 18501850                 in = cmop(out, p);
 18511851         } else {
 18521852                 while (p->n_left->n_op == CM)
 18531853                         p = p->n_left;
 18541854                 p->n_left = cmop(out, p->n_left);
 18551855         }
 18561856         return in;
 18571857 }
 18581858 
 18591859 /*
 18601860  * Put together in and out node lists in one list, and balance it with
 18611861  * the constraints on the right side of a CM node.
 18621862  */
 18631863 static NODE *
 18641864 xcmop(NODE *out, NODE *in, NODE *str)
 18651865 {
 18661866         NODE *p, *q;
 18671867 
 18681868         if (out) {
 18691869                 /* D out-list sanity check */
 18701870                 for (p = out; p->n_op == CM; p = p->n_left) {
 18711871                         q = p->n_right;
 18721872                         if (q->n_name[0] != '=' && q->n_name[0] != '+')
 18731873                                 uerror("output missing =");
 18741874                 }
 18751875                 if (p->n_name[0] != '=' && p->n_name[0] != '+')
 18761876                         uerror("output missing =");
 18771877                 if (in == NIL)
 18781878                         p = out;
 18791879                 else
 18801880                         p = xmrg(out, in);
 18811881         } else if (in) {
 18821882                 p = in;
 18831883         } else
 18841884                 p = voidcon();
 18851885 
 18861886         if (str == NIL)
 18871887                 str = voidcon();
 18881888         return cmop(p, str);
 18891889 }
 18901890 
 18911891 /*
 18921892  * Generate a XARG node based on a string and an expression.
 18931893  */
 18941894 static NODE *
 18951895 xasmop(char *str, NODE *p)
 18961896 {
 18971897 
 18981898         p = biop(XARG, p, NIL);
 18991899         p->n_name = isinlining ? newstring(str, strlen(str)) : str;
 19001900         return p;
 19011901 }
 19021902 
 19031903 /*
 19041904  * Generate a XASM node based on a string and an expression.
 19051905  */
 19061906 static void
 19071907 mkxasm(char *str, NODE *p)
 19081908 {
 19091909         NODE *q;
 19101910 
 19111911         q = biop(XASM, p->n_left, p->n_right);
 19121912         q->n_name = isinlining ? newstring(str, strlen(str)) : str;
 19131913         nfree(p);
 19141914         ecomp(optloop(q));
 19151915 }
 19161916 
 19171917 static struct attr *
 19181918 gcc_attr_wrapper(NODE *p)
 19191919 {
 19201920 #ifdef GCC_COMPAT
 19211921         return gcc_attr_parse(p);
 19221922 #else
 19231923         uerror("gcc attribute used");
 19241924         return NULL;
 19251925 #endif
 19261926 }
 19271927 
 19281928 #ifdef GCC_COMPAT
 19291929 static NODE *
 19301930 tyof(NODE *p)
 19311931 {
 19321932         static struct symtab spp;
 19331933         NODE *q = block(TYPE, NIL, NIL, p->n_type, p->n_df, p->n_ap);
 19341934         q->n_qual = p->n_qual;
 19351935         q->n_sp = &spp; /* for typenode */
 19361936         tfree(p);
 19371937         return q;
 19381938 }
 19391939 
 19401940 #else
 19411941 static NODE *
 19421942 tyof(NODE *p)
 19431943 {
 19441944         uerror("typeof gcc extension");
 19451945         return bcon(0);
 19461946 }
 19471947 #endif
 19481948 
 19491949 /*
 19501950  * Traverse an unhandled expression tree bottom-up and call buildtree()
 19511951  * or equivalent as needed.
 19521952  */
 19531953 NODE *
 19541954 eve(NODE *p)
 19551955 {
 19561956         struct symtab *sp;
 19571957         NODE *r, *p1, *p2;
 19581958         int x;
 19591959 
 19601960         p1 = p->n_left;
 19611961         p2 = p->n_right;
 19621962         switch (p->n_op) {
 19631963         case NAME:
 19641964                 sp = lookup((char *)p->n_sp, p->n_label);
 19651965                 if (sp->sflags & SINLINE)
 19661966                         inline_ref(sp);
 19671967                 r = nametree(sp);
 19681968                 if (sp->sflags & SDYNARRAY)
 19691969                         r = buildtree(UMUL, r, NIL);
 19701970 #ifdef GCC_COMPAT
 19711971                 if (attr_find(sp->sap, GCC_ATYP_DEPRECATED))
 19721972                         warner(Wdeprecated_declarations, sp->sname);
 19731973 #endif
 19741974                 break;
 19751975 
 19761976         case DOT:
 19771977         case STREF:
 19781978                 r = structref(eve(p1), p->n_op, (char *)p2->n_sp);
 19791979                 nfree(p2);
 19801980                 break;
 19811981 
 19821982         case CAST:
 19831983                 p2 = eve(p2);
 19841984 #ifndef NO_COMPLEX
 19851985                 if (ANYCX(p1) || ANYCX(p2)) {
 19861986                         r = cxcast(p1, p2);
 19871987                         break;
 19881988                 }
 19891989 #endif
 19901990 #ifdef TARGET_TIMODE
 19911991                 if ((r = gcc_eval_ticast(CAST, p1, p2)) != NULL)
 19921992                         break;
 19931993 #endif
 19941994                 p1 = buildtree(CAST, p1, p2);
 19951995                 nfree(p1->n_left);
 19961996                 r = p1->n_right;
 19971997                 nfree(p1);
 19981998                 break;
 19991999 
 20002000 
 20012001         case SZOF:
 20022002                 x = xinline; xinline = 0; /* XXX hack */
 20032003                 if (p2->n_lval == 0)
 20042004                         p1 = eve(p1);
 20052005                 else
 20062006                         TYMFIX(p1);
 20072007                 nfree(p2);
 20082008                 r = doszof(p1);
 20092009                 xinline = x;
 20102010                 break;
 20112011 
 20122012         case LB:
 20132013                 p1 = eve(p1);
 20142014                 p2 = eve(p2);
 20152015 #ifdef TARGET_TIMODE
 20162016                 if (isti(p2)) {
 20172017                         NODE *s = block(NAME, NIL, NIL, LONG, 0, 0);
 20182018                         if ((r = gcc_eval_ticast(CAST, s, p2)) != NULL)
 20192019                                 p2 = r;
 20202020                         nfree(s);
 20212021                 }
 20222022 #endif
 20232023                 r = buildtree(UMUL, buildtree(PLUS, p1, p2), NIL);
 20242024                 break;
 20252025 
 20262026         case COMPL:
 20272027 #ifndef NO_COMPLEX
 20282028                 p1 = eve(p1);
 20292029                 if (ANYCX(p1))
 20302030                         r = cxconj(p1);
 20312031                 else
 20322032                         r = buildtree(COMPL, p1, NIL);
 20332033                 break;
 20342034 #endif
<> 2035+        case UPLUS:
  2036+                r = eve(p1);
  2037+                if (r->n_op == FLD || r->n_type < INT)
  2038+                        r = buildtree(PLUS, r, bcon(0));
  2039+                break;
  2040+
<_20352041         case UMINUS:
 20362042 #ifndef NO_COMPLEX
 20372043                 p1 = eve(p1);
 20382044                 if (ANYCX(p1))
 20392045                         r = cxop(UMINUS, p1, p1);
 20402046                 else
 20412047                         r = buildtree(UMINUS, p1, NIL);
 20422048                 break;
 20432049 #endif
 20442050         case NOT:
 20452051         case UMUL:
 20462052                 p1 = eve(p1);
 20472053 #ifdef TARGET_TIMODE
 20482054                 if ((r = gcc_eval_tiuni(p->n_op, p1)) != NULL)
 20492055                         break;
 20502056 #endif
 20512057                 r = buildtree(p->n_op, p1, NIL);
 20522058                 break;
 20532059 
 20542060         case ADDROF:
 20552061                 r = eve(p1);
 20562062                 if (ISFTN(p->n_type)/* || ISARY(p->n_type) */){
 20572063 #ifdef notdef
 20582064                         werror( "& before array or function: ignored" );
 20592065 #endif
 20602066                 } else
 20612067                         r = buildtree(ADDROF, r, NIL);
 20622068                 break;
 20632069 
 20642070         case UCALL:
 20652071                 p2 = NIL;
 20662072                 /* FALLTHROUGH */
 20672073         case CALL:
 20682074                 if (p1->n_op == NAME) {
 20692075                         sp = lookup((char *)p1->n_sp, 0);
 20702076 #ifndef NO_C_BUILTINS
 20712077                         if (sp->sflags & SBUILTIN) {
 20722078                                 nfree(p1);
 20732079                                 r = builtin_check(sp, p2);
 20742080                                 break;
 20752081                         }
 20762082 #endif
 20772083                         if (sp->stype == UNDEF) {
 20782084                                 p1->n_type = FTN|INT;
 20792085                                 p1->n_sp = sp;
 20802086                                 p1->n_ap = NULL;
 20812087                                 defid(p1, EXTERN);
 20822088                         }
 20832089                         nfree(p1);
 20842090 #ifdef GCC_COMPAT
 20852091                         if (attr_find(sp->sap, GCC_ATYP_DEPRECATED))
 20862092                                 warner(Wdeprecated_declarations, sp->sname);
 20872093 #endif
 20882094                         if (p->n_op == CALL)
 20892095                                 p2 = eve(p2);
 20902096                         r = doacall(sp, nametree(sp), p2);
 20912097                 } else {
 20922098                         if (p->n_op == CALL)
 20932099                                 p2 = eve(p2);
 20942100                         r = doacall(NULL, eve(p1), p2);
 20952101                 }
 20962102                 break;
 20972103 
 20982104 #ifndef NO_COMPLEX
 20992105         case XREAL:
 21002106         case XIMAG:
 21012107                 p1 = eve(p1);
 21022108                 r = cxelem(p->n_op, p1);
 21032109                 break;
 21042110 #endif
 21052111 
 21062112         case MUL:
 21072113         case DIV:
 21082114         case PLUS:
 21092115         case MINUS:
 21102116         case ASSIGN:
 21112117         case EQ:
 21122118         case NE:
 21132119 #ifndef NO_COMPLEX
 21142120                 p1 = eve(p1);
 21152121                 p2 = eve(p2);
 21162122 #ifdef TARGET_TIMODE
 21172123                 if ((r = gcc_eval_timode(p->n_op, p1, p2)) != NULL)
 21182124                         break;
 21192125 #endif
 21202126                 if (ANYCX(p1) || ANYCX(p2)) {
 21212127                         r = cxop(p->n_op, p1, p2);
 21222128                 } else if (ISITY(p1->n_type) || ISITY(p2->n_type)) {
 21232129                         r = imop(p->n_op, p1, p2);
 21242130                 } else
 21252131                         r = buildtree(p->n_op, p1, p2);
 21262132                 break;
 21272133 #endif
 21282134         case MOD:
 21292135         case CM:
 21302136         case GT:
 21312137         case GE:
 21322138         case LT:
 21332139         case LE:
 21342140         case RS:
 21352141         case LS:
 21362142         case RSEQ:
 21372143         case LSEQ:
 21382144         case AND:
 21392145         case OR:
 21402146         case ER:
 21412147         case OROR:
 21422148         case ANDAND:
 21432149         case EREQ:
 21442150         case OREQ:
 21452151         case ANDEQ:
 21462152         case COLON:
 21472153         case QUEST:
 21482154                 p1 = eve(p1);
 21492155                 p2 = eve(p2);
 21502156 #ifdef TARGET_TIMODE
 21512157                 if ((r = gcc_eval_timode(p->n_op, p1, p2)) != NULL)
 21522158                         break;
 21532159 #endif
 21542160                 r = buildtree(p->n_op, p1, p2);
 21552161                 break;
 21562162 
 21572163         case BIQUEST: /* gcc e ?: e op */
 21582164                 p1 = eve(p1);
 21592165                 r = tempnode(0, p1->n_type, p1->n_df, p1->n_ap);
 21602166                 p2 = eve(biop(COLON, ccopy(r), p2));
 21612167                 r = buildtree(QUEST, buildtree(ASSIGN, r, p1), p2);
 21622168                 break;
 21632169 
 21642170         case INCR:
 21652171         case DECR:
 21662172         case MODEQ:
 21672173         case MINUSEQ:
 21682174         case PLUSEQ:
 21692175         case MULEQ:
 21702176         case DIVEQ:
 21712177                 p1 = eve(p1);
 21722178                 p2 = eve(p2);
 21732179 #ifdef TARGET_TIMODE
 21742180                 if ((r = gcc_eval_timode(p->n_op, p1, p2)) != NULL)
 21752181                         break;
 21762182 #endif
 21772183 #ifndef NO_COMPLEX
 21782184                 if (ANYCX(p1) || ANYCX(p2)) {
 21792185                         r = cxop(UNASG p->n_op, ccopy(p1), p2);
 21802186                         r = cxop(ASSIGN, p1, r);
 21812187                         break;
 21822188                 } else if (ISITY(p1->n_type) || ISITY(p2->n_type)) {
 21832189                         r = imop(UNASG p->n_op, ccopy(p1), p2);
 21842190                         r = cxop(ASSIGN, p1, r);
 21852191                         break;
 21862192                 }
 21872193                 /* FALLTHROUGH */
 21882194 #endif
 21892195                 r = buildtree(p->n_op, p1, p2);
 21902196                 break;
 21912197 
 21922198         case STRING:
 21932199                 r = strend(p->n_lval, p->n_name);
 21942200                 break;
 21952201 
 21962202         case COMOP:
 21972203                 if (p1->n_op == GOTO) {
 21982204                         /* inside ({ }), eve already called */
 21992205                         r = buildtree(p->n_op, p1, p2);
 22002206                 } else {
 22012207                         p1 = eve(p1);
 22022208                         r = buildtree(p->n_op, p1, eve(p2));
 22032209                 }
 22042210                 break;
 22052211 
 22062212         case TYPE:
 22072213         case ICON:
 22082214         case FCON:
 22092215         case TEMP:
 22102216                 return p;
 22112217 
 22122218         case CLOP:
 22132219                 r = nametree(p->n_sp);
 22142220                 break;
 22152221 
 22162222         default:
 22172223 #ifdef PCC_DEBUG
 22182224                 fwalk(p, eprint, 0);
 22192225 #endif
 22202226                 cerror("eve");
 22212227                 r = NIL;
 22222228         }
 22232229         nfree(p);
 22242230         return r;
 22252231 }
 22262232 
 22272233 int
 22282234 con_e(NODE *p)
 22292235 {
 22302236         return icons(optloop(eve(p)));
 22312237 }
 22322238 
 22332239 void
 22342240 uawarn(NODE *p, char *s)
 22352241 {
 22362242         if (p == 0)
 22372243                 return;
 22382244         if (attrwarn)
 22392245                 werror("unhandled %s attribute", s);
 22402246         tfree(p);
 22412247 }
 22422248 
 22432249 static void
 22442250 dainit(NODE *d, NODE *a)
 22452251 {
 22462252         if (d == NULL) {
 22472253                 asginit(a);
 22482254         } else if (d->n_op == CM) {
 22492255                 int is = con_e(d->n_left);
 22502256                 int ie = con_e(d->n_right);
 22512257                 int i;
 22522258 
 22532259                 nfree(d);
 22542260                 if (ie < is)
 22552261                         uerror("negative initializer range");
 22562262                 desinit(biop(LB, NIL, bcon(is)));
 22572263                 for (i = is; i < ie; i++)
 22582264                         asginit(ccopy(a));
 22592265                 asginit(a);
 22602266         } else {
 22612267                 cerror("dainit");
 22622268         }
 22632269 }
 22642270 
 22652271 /*
 22662272  * Traverse down and tymerge() where appropriate.
 22672273  */
 22682274 static NODE *
 22692275 tymfix(NODE *p)
 22702276 {
 22712277         NODE *q;
 22722278         int o = coptype(p->n_op);
 22732279 
 22742280         switch (o) {
 22752281         case LTYPE:
 22762282                 break;
 22772283         case UTYPE:
 22782284                 p->n_left = tymfix(p->n_left);
 22792285                 break;
 22802286         case BITYPE:
 22812287                 p->n_left = tymfix(p->n_left);
 22822288                 p->n_right = tymfix(p->n_right);
 22832289                 if (p->n_op == TYMERGE) {
 22842290                         q = tymerge(p->n_left, p->n_right);
 22852291                         q->n_ap = attr_add(q->n_ap, p->n_ap);
 22862292                         tfree(p->n_left);
 22872293                         nfree(p);
 22882294                         p = q;
 22892295                 }
 22902296                 break;
 22912297         }
 22922298         return p;
 22932299 }
 22942300 
 22952301 static NODE *
 22962302 aryfix(NODE *p)
 22972303 {
 22982304         NODE *q;
 22992305 
 23002306         for (q = p; q->n_op != NAME; q = q->n_left) {
 23012307                 if (q->n_op == LB) {
 23022308                         q->n_right = optloop(eve(q->n_right));
 23032309                         if ((blevel == 0 || rpole != NULL) &&
 23042310                             !nncon(q->n_right))
 23052311                                 uerror("array size not constant");
 23062312                         /*
 23072313                          * Checks according to 6.7.5.2 clause 1:
 23082314                          * "...the expression shall have an integer type."
 23092315                          * "If the expression is a constant expression, 
 23102316                          * it shall have a value greater than zero."
 23112317                          */
 23122318                         if (!ISINTEGER(q->n_right->n_type))
 23132319                                 werror("array size is not an integer");
 23142320                         else if (q->n_right->n_op == ICON &&
 23152321                             q->n_right->n_lval < 0 &&
 23162322                             q->n_right->n_lval != NOOFFSET) {
 23172323                                         uerror("array size cannot be negative");
 23182324                                         q->n_right->n_lval = 1;
 23192325                         }
 23202326                 } else if (q->n_op == CALL)
 23212327                         q->n_right = namekill(q->n_right, 1);
 23222328         }
 23232329         return p;
 23242330 }
 23252331 
 23262332 struct labs {
 23272333         struct labs *next;
 23282334         int lab;
 23292335 } *labp;
 23302336 
 23312337 static void
 23322338 savlab(int lab)
 23332339 {
 23342340         struct labs *l = tmpalloc(sizeof(struct labs));
 23352341         l->lab = lab < 0 ? -lab : lab;
 23362342         l->next = labp;
 23372343         labp = l;
 23382344 }
 23392345 
 23402346 int *
 23412347 mkclabs(void)
 23422348 {
 23432349         struct labs *l;
 23442350         int i, *rv;
 23452351 
 23462352         for (i = 0, l = labp; l; l = l->next, i++)
 23472353                 ;
 23482354         rv = tmpalloc((i+1)*sizeof(int));
 23492355         for (i = 0, l = labp; l; l = l->next, i++)
 23502356                 rv[i] = l->lab;
 23512357         rv[i] = 0;
 23522358         labp = 0;
 23532359         return rv;
 23542360 }
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-27 09:00 +0100