Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.361
 
1.362
 
MAIN:plunky:20121022092540
 
pftn.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
 44  * All rights reserved.
 55  *
 66  * Redistribution and use in source and binary forms, with or without
 77  * modification, are permitted provided that the following conditions
 88  * are met:
 99  * 1. Redistributions of source code must retain the above copyright
 1010  *    notice, this list of conditions and the following disclaimer.
 1111  * 2. Redistributions in binary form must reproduce the above copyright
 1212  *    notice, this list of conditions and the following disclaimer in the
 1313  *    documentation and/or other materials provided with the distribution.
 1414  *
 1515  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1616  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1717  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 1818  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 1919  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2020  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2121  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2222  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2323  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2424  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2525  */
 2626 /*
 2727  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 2828  *
 2929  * Redistribution and use in source and binary forms, with or without
 3030  * modification, are permitted provided that the following conditions
 3131  * are met:
 3232  *
 3333  * Redistributions of source code and documentation must retain the above
 3434  * copyright notice, this list of conditions and the following disclaimer.
 3535  * Redistributions in binary form must reproduce the above copyright
 3636  * notice, this list of conditionsand the following disclaimer in the
 3737  * documentation and/or other materials provided with the distribution.
 3838  * All advertising materials mentioning features or use of this software
 3939  * must display the following acknowledgement:
 4040  *      This product includes software developed or owned by Caldera
 4141  *      International, Inc.
 4242  * Neither the name of Caldera International, Inc. nor the names of other
 4343  * contributors may be used to endorse or promote products derived from
 4444  * this software without specific prior written permission.
 4545  *
 4646  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 4747  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 4848  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 4949  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 5050  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 5151  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 5252  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 5353  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 5454  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 5555  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 5656  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 5757  * POSSIBILITY OF SUCH DAMAGE.
 5858  */
 5959 
 6060 /*
 6161  * Many changes from the 32V sources, among them:
 6262  * - New symbol table manager (moved to another file).
 6363  * - Prototype saving/checks.
 6464  */
 6565 
 6666 # include "pass1.h"
 6767 
 6868 #include "cgram.h"
 6969 
 7070 struct symtab *cftnsp;
 7171 int arglistcnt, dimfuncnt;      /* statistics */
 7272 int symtabcnt, suedefcnt;       /* statistics */
 7373 int autooff,            /* the next unused automatic offset */
 7474     maxautooff,         /* highest used automatic offset in function */
 7575     argoff;             /* the next unused argument offset */
 7676 int retlab = NOLAB;     /* return label for subroutine */
 7777 int brklab;
 7878 int contlab;
 7979 int flostat;
 8080 int blevel;
 8181 int reached, prolab;
 8282 
 8383 struct params;
 8484 
 8585 #define MKTY(p, t, d, s) r = talloc(); *r = *p; \
 8686         r = argcast(r, t, d, s); *p = *r; nfree(r);
 8787 
 8888 /*
 8989  * Linked list stack while reading in structs.
 9090  */
 9191 struct rstack {
 9292         struct  rstack *rnext;
 9393         int     rsou;
 9494         int     rstr;
 9595         struct  symtab *rsym;
 9696         struct  symtab *rb;
 9797         struct  attr *ap;
 9898         int     flags;
 9999 #define LASTELM 1
 100100 } *rpole;
 101101 
 102102 /*
 103103  * Linked list for parameter (and struct elements) declaration.
 104104  */
 105105 static struct params {
<>106 -        struct params *next, *prev;
  106+        struct params *prev;
107107         struct symtab *sym;
<>108 -} *lpole, *lparam;
  108+} *lparam;
109109 static int nparams;
 110110 
 111111 /* defines used for getting things off of the initialization stack */
 112112 
 113113 NODE *arrstk[10];
 114114 int arrstkp;
 115115 static int intcompare;
 116116 NODE *parlink;
 117117 
 118118 void fixtype(NODE *p, int class);
 119119 int fixclass(int class, TWORD type);
 120120 static void dynalloc(struct symtab *p, int *poff);
 121121 static void evalidx(struct symtab *p);
 122122 int isdyn(struct symtab *p);
 123123 void inforce(OFFSZ n);
 124124 void vfdalign(int n);
 125125 static void ssave(struct symtab *);
 126126 #ifdef PCC_DEBUG
 127127 static void alprint(union arglist *al, int in);
 128128 #endif
 129129 static void lcommadd(struct symtab *sp);
 130130 static NODE *mkcmplx(NODE *p, TWORD dt);
 131131 extern int fun_inline;
 132132 
 133133 void
 134134 defid(NODE *q, int class)
 135135 {
 136136         defid2(q, class, 0);
 137137 }
 138138 
 139139 /*
 140140  * Declaration of an identifier.  Handles redeclarations, hiding,
 141141  * incomplete types and forward declarations.
 142142  *
 143143  * q is a TYPE node setup after parsing with n_type, n_df and n_ap.
 144144  * n_sp is a pointer to the not-yet initalized symbol table entry
 145145  * unless it's a redeclaration or supposed to hide a variable.
 146146  */
 147147 
 148148 void
 149149 defid2(NODE *q, int class, char *astr)
 150150 {
 151151         struct attr *ap;
 152152         struct symtab *p;
 153153         TWORD type, qual;
 154154         TWORD stp, stq;
 155155         int scl;
 156156         union dimfun *dsym, *ddef;
 157157         int slev, temp, changed;
 158158 
 159159         if (q == NIL)
 160160                 return/* an error was detected */
 161161 
 162162 #ifdef GCC_COMPAT
 163163         gcc_modefix(q);
 164164 #endif
 165165         p = q->n_sp;
 166166 
 167167         if (p->sname == NULL)
 168168                 cerror("defining null identifier");
 169169 
 170170 #ifdef PCC_DEBUG
 171171         if (ddebug) {
 172172                 printf("defid(%s '%s'(%p), ", p->sname, p->soname , p);
 173173                 tprint(q->n_type, q->n_qual);
 174174                 printf(", %s, (%p)), level %d\n\t", scnames(class),
 175175                     q->n_df, blevel);
 176176                 dump_attr(q->n_ap);
 177177         }
 178178 #endif
 179179 
 180180         fixtype(q, class);
 181181 
 182182         type = q->n_type;
 183183         qual = q->n_qual;
 184184         class = fixclass(class, type);
 185185 
 186186         stp = p->stype;
 187187         stq = p->squal;
 188188         slev = p->slevel;
 189189 
 190190 #ifdef PCC_DEBUG
 191191         if (ddebug) {
 192192                 printf("        modified to ");
 193193                 tprint(type, qual);
 194194                 printf(", %s\n", scnames(class));
 195195                 printf("        previous def'n: ");
 196196                 tprint(stp, stq);
 197197                 printf(", %s, (%p,%p)), level %d\n",
 198198                     scnames(p->sclass), p->sdf, p->sap, slev);
 199199         }
 200200 #endif
 201201 
 202202         if (blevel == 1) {
 203203                 switch (class) {
 204204                 default:
 205205                         if (!(class&FIELD) && !ISFTN(type))
 206206                                 uerror("declared argument %s missing",
 207207                                     p->sname );
 208208                         break;
 209209                 case MOS:
 210210                 case MOU:
 211211                         cerror("field5");
 212212                 case TYPEDEF:
 213213                 case PARAM:
 214214                         break;
 215215                 }
 216216         }
 217217 
 218218         if (stp == UNDEF)
 219219                 goto enter; /* New symbol */
 220220 
 221221         if (type != stp)
 222222                 goto mismatch;
 223223 
 224224         if (blevel > slev && (class == AUTO || class == REGISTER))
 225225                 /* new scope */
 226226                 goto mismatch;
 227227 
 228228         /*
 229229          * test (and possibly adjust) dimensions.
 230230          * also check that prototypes are correct.
 231231          */
 232232         dsym = p->sdf;
 233233         ddef = q->n_df;
 234234         changed = 0;
 235235         for (temp = type; temp & TMASK; temp = DECREF(temp)) {
 236236                 if (ISARY(temp)) {
 237237                         if (dsym->ddim == NOOFFSET) {
 238238                                 dsym->ddim = ddef->ddim;
 239239                                 changed = 1;
 240240                         } else if (ddef->ddim != NOOFFSET &&
 241241                             dsym->ddim!=ddef->ddim) {
 242242                                 goto mismatch;
 243243                         }
 244244                         ++dsym;
 245245                         ++ddef;
 246246                 } else if (ISFTN(temp)) {
 247247                         /* add a late-defined prototype here */
 248248                         if (cftnsp == NULL && dsym->dfun == NULL)
 249249                                 dsym->dfun = ddef->dfun;
 250250                         if (!oldstyle && ddef->dfun != NULL &&
 251251                             chkftn(dsym->dfun, ddef->dfun))
 252252                                 uerror("declaration doesn't match prototype");
 253253                         dsym++, ddef++;
 254254                 }
 255255         }
 256256 #ifdef STABS
 257257         if (changed && gflag)
 258258                 stabs_chgsym(p); /* symbol changed */
 259259 #endif
 260260 
 261261         /* check that redeclarations are to the same structure */
 262262         if (temp == STRTY || temp == UNIONTY) {
 263263                 if (strmemb(p->sap) != strmemb(q->n_ap))
 264264                         goto mismatch;
 265265         }
 266266 
 267267         scl = p->sclass;
 268268 
 269269 #ifdef PCC_DEBUG
 270270         if (ddebug)
 271271                 printf("        previous class: %s\n", scnames(scl));
 272272 #endif
 273273 
 274274         /*
 275275          * Its allowed to add attributes to existing declarations.
 276276          * Be careful though not to trash existing attributes.
 277277          * XXX - code below is probably not correct.
 278278          */
 279279         if (p->sap && p->sap->atype <= ATTR_MAX) {
 280280                 /* nothing special, just overwrite */
 281281                 p->sap = q->n_ap;
 282282         } else {
 283283                 if (p->slevel == blevel) {
 284284                         for (ap = q->n_ap; ap; ap = ap->next) {
 285285                                 if (ap->atype > ATTR_MAX)
 286286                                         p->sap = attr_add(p->sap, attr_dup(ap, 3));
 287287                         }
 288288                 } else
 289289                         p->sap = q->n_ap;
 290290         }
 291291 
 292292         if (class & FIELD)
 293293                 cerror("field1");
 294294         switch(class) {
 295295 
 296296         case EXTERN:
 297297                 if (astr)
 298298                         p->soname = astr;
 299299                 switch( scl ){
 300300                 case STATIC:
 301301                 case USTATIC:
 302302                         if( slev==0 )
 303303                                 goto done;
 304304                         break;
 305305                 case EXTDEF:
 306306                 case EXTERN:
 307307                         goto done;
 308308                 case SNULL:
 309309                         if (p->sflags & SINLINE) {
 310310                                 p->sclass = EXTDEF;
 311311                                 inline_ref(p);
 312312                                 goto done;
 313313                         }
 314314                         break;
 315315                 }
 316316                 break;
 317317 
 318318         case STATIC:
 319319                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
 320320                         p->sclass = STATIC;
 321321                         goto done;
 322322                 }
 323323                 if (changed || (scl == STATIC && blevel == slev))
 324324                         goto done; /* identical redeclaration */
 325325                 break;
 326326 
 327327         case USTATIC:
 328328                 if (scl==STATIC || scl==USTATIC)
 329329                         goto done;
 330330                 break;
 331331 
 332332         case TYPEDEF:
 333333                 if (scl == class)
 334334                         goto done;
 335335                 break;
 336336 
 337337         case MOU:
 338338         case MOS:
 339339                 cerror("field6");
 340340 
 341341         case EXTDEF:
 342342                 switch (scl) {
 343343                 case EXTERN:
 344344                         p->sclass = EXTDEF;
 345345                         goto done;
 346346                 case USTATIC:
 347347                         p->sclass = STATIC;
 348348                         goto done;
 349349                 case SNULL:
 350350                         /*
 351351                          * Handle redeclarations of inlined functions.
 352352                          * This is allowed if the previous declaration is of
 353353                          * type gnu_inline.
 354354                          */
 355355                         if (attr_find(p->sap, GCC_ATYP_GNU_INLINE))
 356356                                 goto done;
 357357                         break;
 358358                 }
 359359                 break;
 360360 
 361361         case AUTO:
 362362         case REGISTER:
 363363                 break/* mismatch.. */
 364364         case SNULL:
 365365                 if (fun_inline && ISFTN(type)) {
 366366                         if (scl == EXTERN) {
 367367                                 p->sclass = EXTDEF;
 368368                                 inline_ref(p);
 369369                         }
 370370                         goto done;
 371371                 }
 372372                 break;
 373373         }
 374374 
 375375         mismatch:
 376376 
 377377         /*
 378378          * Only allowed for automatic variables.
 379379          */
 380380         if ((blevel == 2 && slev == 1) || blevel <= slev || class == EXTERN) {
 381381                 uerror("redeclaration of %s", p->sname);
 382382                 return;
 383383         }
 384384         q->n_sp = p = hide(p);
 385385 
 386386         enter/* make a new entry */
 387387 
 388388 #ifdef PCC_DEBUG
 389389         if(ddebug)
 390390                 printf("        new entry made\n");
 391391 #endif
 392392         p->stype = type;
 393393         p->squal = qual;
 394394         p->sclass = (char)class;
 395395         p->slevel = (char)blevel;
 396396         p->soffset = NOOFFSET;
 397397         if (q->n_ap)
 398398                 p->sap = attr_add(q->n_ap, p->sap);
 399399 
 400400         /* copy dimensions */
 401401         p->sdf = q->n_df;
 402402         /* Do not save param info for old-style functions */
 403403         if (ISFTN(type) && oldstyle)
 404404                 p->sdf->dfun = NULL;
 405405 
 406406         if (arrstkp)
 407407                 evalidx(p);
 408408 
 409409         /* allocate offsets */
 410410         if (class&FIELD) {
 411411                 cerror("field2");  /* new entry */
 412412         } else switch (class) {
 413413 
 414414         case REGISTER:
 415415                 if (astr != NULL)
 416416                         werror("no register assignment (yet)");
 417417                 p->sclass = class = AUTO;
 418418                 /* FALLTHROUGH */
 419419         case AUTO:
 420420                 if (isdyn(p)) {
 421421                         p->sflags |= SDYNARRAY;
 422422                         dynalloc(p, &autooff);
 423423                 } else
 424424                         oalloc(p, &autooff);
 425425                 break;
 426426 
 427427         case PARAM:
 428428                 if (q->n_type != FARG)
 429429                         oalloc(p, &argoff);
 430430                 break;
 431431                 
 432432         case STATIC:
 433433         case EXTDEF:
 434434         case EXTERN:
 435435                 p->soffset = getlab();
 436436                 if (astr)
 437437                         p->soname = astr;
 438438                 break;
 439439 
 440440         case MOU:
 441441         case MOS:
 442442                 cerror("field7");
 443443         case SNULL:
 444444 #ifdef notdef
 445445                 if (fun_inline) {
 446446                         p->slevel = 1;
 447447                         p->soffset = getlab();
 448448                 }
 449449 #endif
 450450                 break;
 451451         }
 452452 
 453453 #ifdef STABS
 454454         if (gflag && p->stype != FARG)
 455455                 stabs_newsym(p);
 456456 #endif
 457457 
 458458 done:
 459459         fixdef(p);      /* Leave last word to target */
 460460 #ifndef HAVE_WEAKREF
 461461         {
 462462                 struct attr *at;
 463463 
 464464                 /* Refer renamed function */
 465465                 if ((at = attr_find(p->sap, GCC_ATYP_WEAKREF)))
 466466                         p->soname = at->sarg(0);
 467467         }
 468468 #endif
 469469 #ifdef PCC_DEBUG
 470470         if (ddebug) {
 471471                 printf( "       sdf, offset: %p, %d\n\t",
 472472                     p->sdf, p->soffset);
 473473                 dump_attr(p->sap);
 474474         }
 475475 #endif
 476476 }
 477477 
 478478 void
 479479 ssave(struct symtab *sym)
 480480 {
 481481         struct params *p;
 482482 
 483483         p = tmpalloc(sizeof(struct params));
<>484 -        p->next = NULL;
  484+        p->prev = lparam;
485485         p->sym = sym;
<>486 -
 487 -        if ((p->prev = lparam) == NULL)
 488 -                lpole = p;
 489 -        else
 490 -                lparam->next = p;
<_491486         lparam = p;
 492487 }
 493488 
 494489 /*
 495490  * end of function
 496491  */
 497492 void
 498493 ftnend(void)
 499494 {
 500495         struct attr *gc, *gd;
 501496         extern int *mkclabs(void);
 502497         extern NODE *cftnod;
 503498         extern struct savbc *savbc;
 504499         extern struct swdef *swpole;
 505500         extern int tvaloff;
 506501         char *c;
 507502 
 508503         if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
 509504                 plabel(retlab);
 510505                 if (cftnod)
 511506                         ecomp(buildtree(FORCE, cftnod, NIL));
 512507                 efcode(); /* struct return handled here */
 513508                 if ((c = cftnsp->soname) == NULL)
 514509                         c = addname(exname(cftnsp->sname));
 515510                 SETOFF(maxautooff, ALCHAR);
 516511                 send_passt(IP_EPILOG, maxautooff/SZCHAR, c,
 517512                     cftnsp->stype, cftnsp->sclass == EXTDEF,
 518513                     retlab, tvaloff, mkclabs());
 519514         }
 520515 
 521516         cftnod = NIL;
 522517         tcheck();
 523518         brklab = contlab = retlab = NOLAB;
 524519         flostat = 0;
 525520         if (nerrors == 0) {
 526521                 if (savbc != NULL)
 527522                         cerror("bcsave error");
 528523                 if (lparam != NULL)
 529524                         cerror("parameter reset error");
 530525                 if (swpole != NULL)
 531526                         cerror("switch error");
 532527         }
 533528         if (cftnsp) {
 534529                 gc = attr_find(cftnsp->sap, GCC_ATYP_CONSTRUCTOR);
 535530                 gd = attr_find(cftnsp->sap, GCC_ATYP_DESTRUCTOR);
 536531                 if (gc || gd) {
 537532                         struct symtab sts = *cftnsp;
 538533                         NODE *p;
 539534                         sts.stype = INCREF(sts.stype);
 540535                         p = nametree(&sts);
 541536                         p->n_op = ICON;
 542537                         if (gc) {
 543538                                 locctr(CTORS, &sts);
 544539                                 inval(0, SZPOINT(0), p);
 545540                         }
 546541                         if (gd) {
 547542                                 locctr(DTORS, &sts);
 548543                                 inval(0, SZPOINT(0), p);
 549544                         }
 550545                         tfree(p);
 551546                 }
 552547         }
 553548         savbc = NULL;
 554549         lparam = NULL;
 555550         cftnsp = NULL;
 556551         maxautooff = autooff = AUTOINIT;
 557552         reached = 1;
 558553 
 559554         if (isinlining)
 560555                 inline_end();
 561556         inline_prtout();
 562557 
 563558         tmpfree(); /* Release memory resources */
 564559 }
 565560 
 566561 static struct symtab nulsym = {
 567562         NULL, 0, 0, 0, 0, "null", "null", INT, 0, NULL, NULL
 568563 };
 569564 
 570565 void
 571566 dclargs(void)
 572567 {
 573568         union dimfun *df;
 574569         union arglist *al, *al2, *alb;
 575570         struct params *a;
 576571         struct symtab *p, **parr = NULL; /* XXX gcc */
 577572         int i;
 578573 
 579574         /*
 580575          * Deal with fun(void) properly.
 581576          */
 582577         if (nparams == 1 && lparam->sym && lparam->sym->stype == VOID)
 583578                 goto done;
 584579 
 585580         /*
 586581          * Generate a list for bfcode().
 587582          * Parameters were pushed in reverse order.
 588583          */
 589584         if (nparams != 0)
 590585                 parr = tmpalloc(sizeof(struct symtab *) * nparams);
 591586 
 592587         if (nparams)
 593588             for (a = lparam, i = 0; a != NULL; a = a->prev) {
 594589                 p = a->sym;
 595590                 parr[i++] = p;
 596591                 if (p == NULL) {
 597592                         uerror("parameter %d name missing", i);
 598593                         p = &nulsym; /* empty symtab */
 599594                 }
 600595                 if (p->stype == FARG)
 601596                         p->stype = INT;
 602597                 if (ISARY(p->stype)) {
 603598                         p->stype += (PTR-ARY);
 604599                         p->sdf++;
 605600                 } else if (ISFTN(p->stype)) {
 606601                         werror("function declared as argument");
 607602                         p->stype = INCREF(p->stype);
 608603                 }
 609604 #ifdef STABS
 610605                 if (gflag)
 611606                         stabs_newsym(p);
 612607 #endif
 613608         }
 614609         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
 615610                 /*
 616611                  * Check against prototype of oldstyle function.
 617612                  */
 618613                 alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
 619614                 for (i = 0; i < nparams; i++) {
 620615                         TWORD type = parr[i]->stype;
 621616                         (al2++)->type = type;
 622617                         if (ISSOU(BTYPE(type)))
 623618                                 (al2++)->sap = parr[i]->sap;
 624619                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
 625620                                 type = DECREF(type);
 626621                         if (type > BTMASK)
 627622                                 (al2++)->df = parr[i]->sdf;
 628623                 }
 629624                 al2->type = TNULL;
 630625                 intcompare = 1;
 631626                 if (chkftn(al, alb))
 632627                         uerror("function doesn't match prototype");
 633628                 intcompare = 0;
 634629 
 635630         }
 636631 
 637632         if (oldstyle && nparams) {
 638633                 /* Must recalculate offset for oldstyle args here */
 639634                 argoff = ARGINIT;
 640635                 for (i = 0; i < nparams; i++) {
 641636                         parr[i]->soffset = NOOFFSET;
 642637                         oalloc(parr[i], &argoff);
 643638                 }
 644639         }
 645640 
 646641 done:   autooff = AUTOINIT;
 647642 
 648643         plabel(prolab); /* after prolog, used in optimization */
 649644         retlab = getlab();
 650645         bfcode(parr, nparams);
 651646         if (fun_inline &&
 652647             (xinline || attr_find(cftnsp->sap, GCC_ATYP_ALW_INL)))
 653648                 inline_args(parr, nparams);
 654649         plabel(getlab()); /* used when spilling */
 655650         if (parlink)
 656651                 ecomp(parlink);
 657652         parlink = NIL;
 658653         lparam = NULL;
 659654         nparams = 0;
 660655         symclear(1);    /* In case of function pointer args */
 661656 }
 662657 
 663658 /*
 664659  * basic attributes for structs and enums
 665660  */
 666661 static struct attr *
 667662 seattr(void)
 668663 {
 669664         return attr_add(attr_new(GCC_ATYP_ALIGNED, 4), attr_new(ATTR_STRUCT, 2));
 670665 }
 671666 
 672667 /*
 673668  * Struct/union/enum symtab construction.
 674669  */
 675670 static void
 676671 defstr(struct symtab *sp, int class)
 677672 {
 678673         sp->sclass = (char)class;
 679674         if (class == STNAME)
 680675                 sp->stype = STRTY;
 681676         else if (class == UNAME)
 682677                 sp->stype = UNIONTY;
 683678         else if (class == ENAME)
 684679                 sp->stype = ENUMTY;
 685680 }
 686681 
 687682 /*
 688683  * Declare a struct/union/enum tag.
 689684  * If not found, create a new tag with UNDEF type.
 690685  */
 691686 static struct symtab *
 692687 deftag(char *name, int class)
 693688 {
 694689         struct symtab *sp;
 695690 
 696691         if ((sp = lookup(name, STAGNAME))->sap == NULL) {
 697692                 /* New tag */
 698693                 defstr(sp, class);
 699694         } else if (sp->sclass != class)
 700695                 uerror("tag %s redeclared", name);
 701696         return sp;
 702697 }
 703698 
 704699 /*
 705700  * reference to a structure or union, with no definition
 706701  */
 707702 NODE *
 708703 rstruct(char *tag, int soru)
 709704 {
 710705         struct symtab *sp;
 711706 
 712707         sp = deftag(tag, soru);
 713708         if (sp->sap == NULL)
 714709                 sp->sap = seattr();
 715710         return mkty(sp->stype, 0, sp->sap);
 716711 }
 717712 
 718713 static int enumlow, enumhigh;
 719714 int enummer;
 720715 
 721716 /*
 722717  * Declare a member of enum.
 723718  */
 724719 void
 725720 moedef(char *name)
 726721 {
 727722         struct symtab *sp;
 728723 
 729724         sp = lookup(name, SNORMAL);
 730725         if (sp->stype == UNDEF || (sp->slevel < blevel)) {
 731726                 if (sp->stype != UNDEF)
 732727                         sp = hide(sp);
 733728                 sp->stype = INT; /* always */
 734729                 sp->sclass = MOE;
 735730                 sp->soffset = enummer;
 736731         } else
 737732                 uerror("%s redeclared", name);
 738733         if (enummer < enumlow)
 739734                 enumlow = enummer;
 740735         if (enummer > enumhigh)
 741736                 enumhigh = enummer;
 742737         enummer++;
 743738 }
 744739 
 745740 /*
 746741  * Declare an enum tag.  Complain if already defined.
 747742  */
 748743 struct symtab *
 749744 enumhd(char *name)
 750745 {
 751746         struct attr *ap;
 752747         struct symtab *sp;
 753748 
 754749         enummer = enumlow = enumhigh = 0;
 755750         if (name == NULL)
 756751                 return NULL;
 757752 
 758753         sp = deftag(name, ENAME);
 759754         if (sp->stype != ENUMTY) {
 760755                 if (sp->slevel == blevel)
 761756                         uerror("%s redeclared", name);
 762757                 sp = hide(sp);
 763758                 defstr(sp, ENAME);
 764759         }
 765760         if (sp->sap == NULL)
 766761                 ap = sp->sap = attr_new(ATTR_STRUCT, 4);
 767762         else
 768763                 ap = attr_find(sp->sap, ATTR_STRUCT);
 769764         ap->amlist = sp;
 770765         return sp;
 771766 }
 772767 
 773768 /*
 774769  * finish declaration of an enum
 775770  */
 776771 NODE *
 777772 enumdcl(struct symtab *sp)
 778773 {
 779774         NODE *p;
 780775         TWORD t;
 781776 
 782777 #ifdef ENUMSIZE
 783778         t = ENUMSIZE(enumhigh, enumlow);
 784779 #else
 785780         t = ctype(enumlow < 0 ? INT : UNSIGNED);
 786781 #ifdef notdef
 787782         if (enumhigh <= MAX_CHAR && enumlow >= MIN_CHAR)
 788783                 t = ctype(CHAR);
 789784         else if (enumhigh <= MAX_SHORT && enumlow >= MIN_SHORT)
 790785                 t = ctype(SHORT);
 791786         else
 792787                 t = ctype(INT);
 793788 #endif
 794789 #endif
 795790         
 796791         if (sp)
 797792                 sp->stype = t;
 798793         p = mkty(t, 0, 0);
 799794         p->n_sp = sp;
 800795         return p;
 801796 }
 802797 
 803798 /*
 804799  * Handle reference to an enum
 805800  */
 806801 NODE *
 807802 enumref(char *name)
 808803 {
 809804         struct symtab *sp;
 810805         NODE *p;
 811806 
 812807         sp = lookup(name, STAGNAME);
 813808 
 814809 #ifdef notdef
 815810         /*
 816811          * 6.7.2.3 Clause 2:
 817812          * "A type specifier of the form 'enum identifier' without an
 818813          *  enumerator list shall only appear after the type it specifies
 819814          *  is complete."
 820815          */
 821816         if (sp->sclass != ENAME)
 822817                 uerror("enum %s undeclared", name);
 823818 #endif
 824819         if (sp->sclass == SNULL) {
 825820                 /* declare existence of enum */
 826821                 sp = enumhd(name);
 827822                 sp->stype = ENUMTY;
 828823         }
 829824 
 830825         p = mkty(sp->stype, 0, sp->sap);
 831826         p->n_sp = sp;
 832827         return p;
 833828 }
 834829 
 835830 /*
 836831  * begining of structure or union declaration
 837832  * It's an error if this routine is called twice with the same struct.
 838833  */
 839834 struct rstack *
 840835 bstruct(char *name, int soru, NODE *gp)
 841836 {
 842837         struct rstack *r;
 843838         struct symtab *sp;
 844839         struct attr *ap, *gap;
 845840 
 846841         gap = gp ? gcc_attr_parse(gp) : NULL;
 847842 
 848843         if (name != NULL) {
 849844                 sp = deftag(name, soru);
 850845                 if (sp->sap == NULL)
 851846                         sp->sap = seattr();
 852847                 ap = attr_find(sp->sap, GCC_ATYP_ALIGNED);
 853848                 if (ap->iarg(0) != 0) {
 854849                         if (sp->slevel < blevel) {
 855850                                 sp = hide(sp);
 856851                                 defstr(sp, soru);
 857852                                 sp->sap = seattr();
 858853                         } else
 859854                                 uerror("%s redeclared", name);
 860855                 }
 861856                 gap = sp->sap = attr_add(sp->sap, gap);
 862857         } else {
 863858                 gap = attr_add(seattr(), gap);
 864859                 sp = NULL;
 865860         }
 866861 
 867862         r = tmpcalloc(sizeof(struct rstack));
 868863         r->rsou = soru;
 869864         r->rsym = sp;
 870865         r->rb = NULL;
 871866         r->ap = gap;
 872867         r->rnext = rpole;
 873868         rpole = r;
 874869 
 875870         return r;
 876871 }
 877872 
 878873 /*
 879874  * Called after a struct is declared to restore the environment.
 880875  * - If ALSTRUCT is defined, this will be the struct alignment and the
 881876  *   struct size will be a multiple of ALSTRUCT, otherwise it will use
 882877  *   the alignment of the largest struct member.
 883878  */
 884879 NODE *
 885880 dclstruct(struct rstack *r)
 886881 {
 887882         NODE *n;
 888883         struct attr *aps, *apb;
 889884         struct symtab *sp;
 890885         int al, sa, sz;
 891886 
 892887         apb = attr_find(r->ap, GCC_ATYP_ALIGNED);
 893888         aps = attr_find(r->ap, ATTR_STRUCT);
 894889         aps->amlist = r->rb;
 895890 
 896891 #ifdef ALSTRUCT
 897892         al = ALSTRUCT;
 898893 #else
 899894         al = ALCHAR;
 900895 #endif
 901896 
 902897         /*
 903898          * extract size and alignment, calculate offsets
 904899          */
 905900         for (sp = r->rb; sp; sp = sp->snext) {
 906901                 sa = talign(sp->stype, sp->sap);
 907902                 if (sp->sclass & FIELD)
 908903                         sz = sp->sclass&FLDSIZ;
 909904                 else
 910905                         sz = (int)tsize(sp->stype, sp->sdf, sp->sap);
 911906                 if (sz > rpole->rstr)
 912907                         rpole->rstr = sz/* for use with unions */
 913908                 /*
 914909                  * set al, the alignment, to the lcm of the alignments
 915910                  * of the members.
 916911                  */
 917912                 SETOFF(al, sa);
 918913         }
 919914 
 920915         SETOFF(rpole->rstr, al);
 921916 
 922917         aps->amsize = rpole->rstr;
 923918         apb->iarg(0) = al;
 924919 
 925920 #ifdef PCC_DEBUG
 926921         if (ddebug) {
 927922                 printf("dclstruct(%s): size=%d, align=%d\n",
 928923                     r->rsym ? r->rsym->sname : "??",
 929924                     aps->amsize, apb->iarg(0));
 930925         }
 931926         if (ddebug>1) {
 932927                 printf("\tsize %d align %d link %p\n",
 933928                     aps->amsize, apb->iarg(0), aps->amlist);
 934929                 for (sp = aps->amlist; sp != NULL; sp = sp->snext) {
 935930                         printf("\tmember %s(%p)\n", sp->sname, sp);
 936931                 }
 937932         }
 938933 #endif
 939934 
 940935 #ifdef STABS
 941936         if (gflag)
 942937                 stabs_struct(r->rsym, r->ap);
 943938 #endif
 944939 
 945940         rpole = r->rnext;
 946941         n = mkty(r->rsou == STNAME ? STRTY : UNIONTY, 0, r->ap);
 947942         n->n_sp = r->rsym;
 948943 
 949944         n->n_qual |= 1; /* definition place XXX used by attributes */
 950945         return n;
 951946 }
 952947 
 953948 /*
 954949  * Add a new member to the current struct or union being declared.
 955950  */
 956951 void
 957952 soumemb(NODE *n, char *name, int class)
 958953 {
 959954         struct symtab *sp, *lsp;
 960955         int incomp, tsz, al;
 961956         TWORD t;
 962957  
 963958         if (rpole == NULL)
 964959                 cerror("soumemb");
 965960  
 966961         /* check if tag name exists */
 967962         lsp = NULL;
 968963         for (sp = rpole->rb; sp != NULL; lsp = sp, sp = sp->snext)
 969964                 if (*name != '*' && sp->sname == name)
 970965                         uerror("redeclaration of %s", name);
 971966 
 972967         sp = getsymtab(name, SMOSNAME);
 973968         if (rpole->rb == NULL)
 974969                 rpole->rb = sp;
 975970         else
 976971                 lsp->snext = sp;
 977972 
 978973         n->n_sp = sp;
 979974         sp->stype = n->n_type;
 980975         sp->squal = n->n_qual;
 981976         sp->slevel = blevel;
 982977         sp->sap = n->n_ap;
 983978         sp->sdf = n->n_df;
 984979 
 985980         if (class & FIELD) {
 986981                 sp->sclass = (char)class;
 987982                 falloc(sp, class&FLDSIZ, NIL);
 988983         } else if (rpole->rsou == STNAME || rpole->rsou == UNAME) {
 989984                 sp->sclass = rpole->rsou == STNAME ? MOS : MOU;
 990985                 if (sp->sclass == MOU)
 991986                         rpole->rstr = 0;
 992987                 al = talign(sp->stype, sp->sap);
 993988                 tsz = (int)tsize(sp->stype, sp->sdf, sp->sap);
 994989                 sp->soffset = upoff(tsz, al, &rpole->rstr);
 995990         }
 996991 
 997992         /*
 998993          * 6.7.2.1 clause 16:
 999994          * "...the last member of a structure with more than one
 1000995          *  named member may have incomplete array type;"
 1001996          */
 1002997         if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
 1003998                 incomp = 1;
 1004999         else
 10051000                 incomp = 0;
 10061001         if ((rpole->flags & LASTELM) || (rpole->rb == sp && incomp == 1))
 10071002                 uerror("incomplete array in struct");
 10081003         if (incomp == 1)
 10091004                 rpole->flags |= LASTELM;
 10101005 
 10111006         /*
 10121007          * 6.7.2.1 clause 2:
 10131008          * "...such a structure shall not be a member of a structure
 10141009          *  or an element of an array."
 10151010          */
 10161011         t = sp->stype;
 10171012         if (rpole->rsou != STNAME || BTYPE(t) != STRTY)
 10181013                 return; /* not for unions */
 10191014         while (ISARY(t))
 10201015                 t = DECREF(t);
 10211016         if (ISPTR(t))
 10221017                 return;
 10231018 
 10241019         if ((lsp = strmemb(sp->sap)) != NULL) {
 10251020                 for (; lsp->snext; lsp = lsp->snext)
 10261021                         ;
 10271022                 if (ISARY(lsp->stype) && lsp->snext &&
 10281023                     lsp->sdf->ddim == NOOFFSET)
 10291024                         uerror("incomplete struct in struct");
 10301025         }
 10311026 }
 10321027 
 10331028 /*
 10341029  * error printing routine in parser
 10351030  */
 10361031 void
 10371032 yyerror(char *s)
 10381033 {
 10391034         uerror(s);
 10401035 }
 10411036 
 10421037 void yyaccpt(void);
 10431038 void
 10441039 yyaccpt(void)
 10451040 {
 10461041         ftnend();
 10471042 }
 10481043 
 10491044 /*
 10501045  * p is top of type list given to tymerge later.
 10511046  * Find correct CALL node and declare parameters from there.
 10521047  */
 10531048 void
 10541049 ftnarg(NODE *p)
 10551050 {
 10561051         NODE *q;
 10571052 
 10581053 #ifdef PCC_DEBUG
 10591054         if (ddebug > 2)
 10601055                 printf("ftnarg(%p)\n", p);
 10611056 #endif
 10621057         /*
 10631058          * Push argument symtab entries onto param stack in reverse order,
 10641059          * due to the nature of the stack it will be reclaimed correct.
 10651060          */
 10661061         for (; p->n_op != NAME; p = p->n_left) {
 10671062                 if (p->n_op == UCALL && p->n_left->n_op == NAME)
 10681063                         return/* Nothing to enter */
 10691064                 if (p->n_op == CALL && p->n_left->n_op == NAME)
 10701065                         break;
 10711066         }
 10721067 
 10731068         p = p->n_right;
 10741069         while (p->n_op == CM) {
 10751070                 q = p->n_right;
 10761071                 if (q->n_op != ELLIPSIS) {
 10771072                         ssave(q->n_sp);
 10781073                         nparams++;
 10791074 #ifdef PCC_DEBUG
 10801075                         if (ddebug > 2)
 10811076                                 printf("        saving sym %s (%p) from (%p)\n",
 10821077                                     q->n_sp->sname, q->n_sp, q);
 10831078 #endif
 10841079                 }
 10851080                 p = p->n_left;
 10861081         }
 10871082         ssave(p->n_sp);
 10881083         if (p->n_type != VOID)
 10891084                 nparams++;
 10901085 
 10911086 #ifdef PCC_DEBUG
 10921087         if (ddebug > 2)
 10931088                 printf("        saving sym %s (%p) from (%p)\n",
 10941089                     nparams ? p->n_sp->sname : "<noname>", p->n_sp, p);
 10951090 #endif
 10961091 }
 10971092 
 10981093 /*
 10991094  * compute the alignment of an object with type ty, sizeoff index s
 11001095  */
 11011096 int
 11021097 talign(unsigned int ty, struct attr *apl)
 11031098 {
 11041099         struct attr *al;
 11051100         int a;
 11061101 
 11071102         for (; ty > BTMASK; ty = DECREF(ty)) {
 11081103                 switch (ty & TMASK) {
 11091104                 case PTR:
 11101105                         return(ALPOINT);
 11111106                 case ARY:
 11121107                         continue;
 11131108                 case FTN:
 11141109                         cerror("compiler takes alignment of function");
 11151110                 }
 11161111         }
 11171112 
 11181113         /* check for alignment attribute */
 11191114         if ((al = attr_find(apl, GCC_ATYP_ALIGNED))) {
 11201115                 if ((a = al->iarg(0)) == 0) {
 11211116                         uerror("no alignment");
 11221117                         a = ALINT;
 11231118                 }
 11241119                 return a;
 11251120         }
 11261121 
 11271122         ty = BTYPE(ty);
 11281123         if (ty >= CHAR && ty <= ULONGLONG && ISUNSIGNED(ty))
 11291124                 ty = DEUNSIGN(ty);
 11301125 
 11311126         switch (ty) {
 11321127         case BOOL: a = ALBOOL; break;
 11331128         case CHAR: a = ALCHAR; break;
 11341129         case SHORT: a = ALSHORT; break;
 11351130         case INT: a = ALINT; break;
 11361131         case LONG: a = ALLONG; break;
 11371132         case LONGLONG: a = ALLONGLONG; break;
 11381133         case FLOAT: a = ALFLOAT; break;
 11391134         case DOUBLE: a = ALDOUBLE; break;
 11401135         case LDOUBLE: a = ALLDOUBLE; break;
 11411136         default:
 11421137                 uerror("no alignment");
 11431138                 a = ALINT;
 11441139         }
 11451140         return a;
 11461141 }
 11471142 
 11481143 short sztable[] = { 0, SZBOOL, SZCHAR, SZCHAR, SZSHORT, SZSHORT, SZINT, SZINT,
 11491144         SZLONG, SZLONG, SZLONGLONG, SZLONGLONG, SZFLOAT, SZDOUBLE, SZLDOUBLE };
 11501145 
 11511146 /* compute the size associated with type ty,
 11521147  *  dimoff d, and sizoff s */
 11531148 /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
 11541149 OFFSZ
 11551150 tsize(TWORD ty, union dimfun *d, struct attr *apl)
 11561151 {
 11571152         struct attr *ap, *ap2;
 11581153         OFFSZ mult, sz;
 11591154 
 11601155         mult = 1;
 11611156 
 11621157         for (; ty > BTMASK; ty = DECREF(ty)) {
 11631158                 switch (ty & TMASK) {
 11641159 
 11651160                 case FTN:
 11661161                         uerror( "cannot take size of function");
 11671162                 case PTR:
 11681163                         return( SZPOINT(ty) * mult );
 11691164                 case ARY:
 11701165                         if (d->ddim == NOOFFSET)
 11711166                                 return 0;
 11721167                         if (d->ddim < 0)
 11731168                                 cerror("tsize: dynarray");
 11741169                         mult *= d->ddim;
 11751170                         d++;
 11761171                 }
 11771172         }
 11781173 
 11791174         if (ty == VOID)
 11801175                 ty = CHAR;
 11811176         if (ty <= LDOUBLE)
 11821177                 sz = sztable[ty];
 11831178         else if (ISSOU(ty)) {
 11841179                 if ((ap = strattr(apl)) == NULL ||
 11851180                     (ap2 = attr_find(apl, GCC_ATYP_ALIGNED)) == NULL ||
 11861181                     (ap2->iarg(0) == 0)) {
 11871182                         uerror("unknown structure/union/enum");
 11881183                         sz = SZINT;
 11891184                 } else
 11901185                         sz = ap->amsize;
 11911186         } else {
 11921187                 uerror("unknown type");
 11931188                 sz = SZINT;
 11941189         }
 11951190 
 11961191         return((unsigned int)sz * mult);
 11971192 }
 11981193 
 11991194 /*
 12001195  * Save string (and print it out).  If wide then wide string.
 12011196  */
 12021197 NODE *
 12031198 strend(int wide, char *str)
 12041199 {
 12051200         struct symtab *sp;
 12061201         NODE *p;
 12071202 
 12081203         /* If an identical string is already emitted, just forget this one */
 12091204         if (wide) {
 12101205                 /* Do not save wide strings, at least not now */
 12111206                 sp = getsymtab(str, SSTRING|STEMP);
 12121207         } else {
 12131208                 str = addstring(str);   /* enter string in string table */
 12141209                 sp = lookup(str, SSTRING);      /* check for existance */
 12151210         }
 12161211 
 12171212         if (sp->soffset == 0) { /* No string */
 12181213                 char *wr;
 12191214                 int i;
 12201215 
 12211216                 sp->sclass = STATIC;
 12221217                 sp->slevel = 1;
 12231218                 sp->soffset = getlab();
 12241219                 sp->squal = (CON >> TSHIFT);
 12251220                 sp->sdf = permalloc(sizeof(union dimfun));
 12261221                 if (wide) {
 12271222                         sp->stype = WCHAR_TYPE+ARY;
 12281223                 } else {
 12291224                         if (xuchar) {
 12301225                                 sp->stype = UCHAR+ARY;
 12311226                         } else {
 12321227                                 sp->stype = CHAR+ARY;
 12331228                         }
 12341229                 }
 12351230                 for (wr = sp->sname, i = 1; *wr; i++)
 12361231                         if (*wr++ == '\\')
 12371232                                 (void)esccon(&wr);
 12381233 
 12391234                 sp->sdf->ddim = i;
 12401235                 if (wide)
 12411236                         inwstring(sp);
 12421237                 else
 12431238                         instring(sp);
 12441239         }
 12451240 
 12461241         p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
 12471242         p->n_sp = sp;
 12481243         return(clocal(p));
 12491244 }
 12501245 
 12511246 /*
 12521247  * Print out a wide string by calling ninval().
 12531248  */
 12541249 void
 12551250 inwstring(struct symtab *sp)
 12561251 {
 12571252         char *s = sp->sname;
 12581253         NODE *p;
 12591254 
 12601255         locctr(STRNG, sp);
 12611256         defloc(sp);
 12621257         p = xbcon(0, NULL, WCHAR_TYPE);
 12631258         do {
 12641259                 if (*s++ == '\\')
 12651260                         p->n_lval = esccon(&s);
 12661261                 else
 12671262                         p->n_lval = (unsigned char)s[-1];
 12681263                 inval(0, tsize(WCHAR_TYPE, NULL, NULL), p);
 12691264         } while (s[-1] != 0);
 12701265         nfree(p);
 12711266 }
 12721267 
 12731268 #ifndef MYINSTRING
 12741269 /*
 12751270  * Print out a string of characters.
 12761271  * Assume that the assembler understands C-style escape
 12771272  * sequences.
 12781273  */
 12791274 void
 12801275 instring(struct symtab *sp)
 12811276 {
 12821277         char *s, *str;
 12831278 
 12841279         locctr(STRNG, sp);
 12851280         defloc(sp);
 12861281         str = sp->sname;
 12871282 
 12881283         /* be kind to assemblers and avoid long strings */
 12891284         printf("\t.ascii \"");
 12901285         for (s = str; *s != 0; ) {
 12911286                 if (*s++ == '\\') {
 12921287                         (void)esccon(&s);
 12931288                 }
 12941289                 if (s - str > 60) {
 12951290                         fwrite(str, 1, s - str, stdout);
 12961291                         printf("\"\n\t.ascii \"");
 12971292                         str = s;
 12981293                 }
 12991294         }
 13001295         fwrite(str, 1, s - str, stdout);
 13011296         printf("\\0\"\n");
 13021297 }
 13031298 #endif
 13041299 
 13051300 /*
 13061301  * update the offset pointed to by poff; return the
 13071302  * offset of a value of size `size', alignment `alignment',
 13081303  * given that off is increasing
 13091304  */
 13101305 int
 13111306 upoff(int size, int alignment, int *poff)
 13121307 {
 13131308         int off;
 13141309 
 13151310         off = *poff;
 13161311         SETOFF(off, alignment);
 13171312         if (off < 0)
 13181313                 cerror("structure or stack overgrown"); /* wrapped */
 13191314         *poff = off+size;
 13201315         return (off);
 13211316 }
 13221317 
 13231318 /*
 13241319  * allocate p with offset *poff, and update *poff
 13251320  */
 13261321 int
 13271322 oalloc(struct symtab *p, int *poff )
 13281323 {
 13291324         int al, off, tsz;
 13301325         int noff;
 13311326 
 13321327         /*
 13331328          * Only generate tempnodes if we are optimizing,
 13341329          * and only for integers, floats or pointers,
 13351330          * and not if the type on this level is volatile.
 13361331          */
 13371332         if (xtemps && ((p->sclass == AUTO) || (p->sclass == REGISTER)) &&
 13381333             (p->stype < STRTY || ISPTR(p->stype)) &&
 13391334             !(cqual(p->stype, p->squal) & VOL) && cisreg(p->stype)) {
 13401335                 NODE *tn = tempnode(0, p->stype, p->sdf, p->sap);
 13411336                 p->soffset = regno(tn);
 13421337                 p->sflags |= STNODE;
 13431338                 nfree(tn);
 13441339                 return 0;
 13451340         }
 13461341 
 13471342         al = talign(p->stype, p->sap);
 13481343         noff = off = *poff;
 13491344         tsz = (int)tsize(p->stype, p->sdf, p->sap);
 13501345 #ifdef BACKAUTO
 13511346         if (p->sclass == AUTO) {
 13521347                 noff = off + tsz;
 13531348                 if (noff < 0)
 13541349                         cerror("stack overflow");
 13551350                 SETOFF(noff, al);
 13561351                 off = -noff;
 13571352         } else
 13581353 #endif
 13591354         if (p->sclass == PARAM && (p->stype == CHAR || p->stype == UCHAR ||
 13601355             p->stype == SHORT || p->stype == USHORT || p->stype == BOOL)) {
 13611356                 off = upoff(SZINT, ALINT, &noff);
 13621357 #if TARGET_ENDIAN == TARGET_BE
 13631358                 off = noff - tsz;
 13641359 #endif
 13651360         } else {
 13661361                 off = upoff(tsz, al, &noff);
 13671362         }
 13681363 
 13691364         if (p->sclass != REGISTER) {
 13701365         /* in case we are allocating stack space for register arguments */
 13711366                 if (p->soffset == NOOFFSET)
 13721367                         p->soffset = off;
 13731368                 else if(off != p->soffset)
 13741369                         return(1);
 13751370         }
 13761371 
 13771372         *poff = noff;
 13781373         return(0);
 13791374 }
 13801375 
 13811376 /*
 13821377  * Delay emission of code generated in argument headers.
 13831378  */
 13841379 static void
 13851380 edelay(NODE *p)
 13861381 {
 13871382         if (blevel == 1) {
 13881383                 /* Delay until after declarations */
 13891384                 if (parlink == NULL)
 13901385                         parlink = p;
 13911386                 else
 13921387                         parlink = block(COMOP, parlink, p, 0, 0, 0);
 13931388         } else
 13941389                 ecomp(p);
 13951390 }
 13961391 
 13971392 /*
 13981393  * Traverse through the array args, evaluate them and put the
 13991394  * resulting temp numbers in the dim fields.
 14001395  */
 14011396 static void
 14021397 evalidx(struct symtab *sp)
 14031398 {
 14041399         union dimfun *df;
 14051400         NODE *p;
 14061401         TWORD t;
 14071402         int astkp = 0;
 14081403 
 14091404         if (arrstk[0] == NIL)
 14101405                 astkp++; /* for parameter arrays */
 14111406 
 14121407         if (isdyn(sp))
 14131408                 sp->sflags |= SDYNARRAY;
 14141409 
 14151410         df = sp->sdf;
 14161411         for (t = sp->stype; t > BTMASK; t = DECREF(t)) {
 14171412                 if (!ISARY(t))
 14181413                         continue;
 14191414                 if (df->ddim == -1) {
 14201415                         p = tempnode(0, INT, 0, 0);
 14211416                         df->ddim = -regno(p);
 14221417                         edelay(buildtree(ASSIGN, p, arrstk[astkp++]));
 14231418                 }
 14241419                 df++;
 14251420         }
 14261421         arrstkp = 0;
 14271422 }
 14281423 
 14291424 /*
 14301425  * Return 1 if dynamic array, 0 otherwise.
 14311426  */
 14321427 int
 14331428 isdyn(struct symtab *sp)
 14341429 {
 14351430         union dimfun *df = sp->sdf;
 14361431         TWORD t;
 14371432 
 14381433         for (t = sp->stype; t > BTMASK; t = DECREF(t)) {
 14391434                 if (!ISARY(t))
 14401435                         return 0;
 14411436                 if (df->ddim < 0 && df->ddim != NOOFFSET)
 14421437                         return 1;
 14431438                 df++;
 14441439         }
 14451440         return 0;
 14461441 }
 14471442 
 14481443 /*
 14491444  * Allocate space on the stack for dynamic arrays (or at least keep track
 14501445  * of the index).
 14511446  * Strategy is as follows:
 14521447  * - first entry is a pointer to the dynamic datatype.
 14531448  * - if it's a one-dimensional array this will be the only entry used.
 14541449  * - if it's a multi-dimensional array the following (numdim-1) integers
 14551450  *   will contain the sizes to multiply the indexes with.
 14561451  * - code to write the dimension sizes this will be generated here.
 14571452  * - code to allocate space on the stack will be generated here.
 14581453  */
 14591454 static void
 14601455 dynalloc(struct symtab *p, int *poff)
 14611456 {
 14621457         union dimfun *df;
 14631458         NODE *n, *tn, *pol;
 14641459         TWORD t;
 14651460 
 14661461         /*
 14671462          * The pointer to the array is not necessarily stored in a
 14681463          * TEMP node, but if it is, its number is in the soffset field;
 14691464          */
 14701465         t = p->stype;
 14711466         p->sflags |= STNODE;
 14721467         p->stype = INCREF(p->stype); /* Make this an indirect pointer */
 14731468         tn = tempnode(0, p->stype, p->sdf, p->sap);
 14741469         p->soffset = regno(tn);
 14751470 
 14761471         df = p->sdf;
 14771472 
 14781473         pol = bcon(1);
 14791474         for (; t > BTMASK; t = DECREF(t)) {
 14801475                 if (!ISARY(t))
 14811476                         break;
 14821477                 if (df->ddim < 0)
 14831478                         n = tempnode(-df->ddim, INT, 0, 0);
 14841479                 else
 14851480                         n = bcon(df->ddim);
 14861481 
 14871482                 pol = buildtree(MUL, pol, n);
 14881483                 df++;
 14891484         }
 14901485         /* Create stack gap */
 14911486         spalloc(tn, pol, tsize(t, 0, p->sap));
 14921487 }
 14931488 
 14941489 /*
 14951490  * allocate a field of width w
 14961491  * new is 0 if new entry, 1 if redefinition, -1 if alignment
 14971492  */
 14981493 int
 14991494 falloc(struct symtab *p, int w, NODE *pty)
 15001495 {
 15011496         TWORD otype, type;
 15021497         int al,sz;
 15031498 
 15041499         otype = type = p ? p->stype : pty->n_type;
 15051500 
 15061501         if (type == BOOL)
 15071502                 type = BOOL_TYPE;
 15081503         if (!ISINTEGER(type)) {
 15091504                 uerror("illegal field type");
 15101505                 type = INT;
 15111506         }
 15121507 
 15131508         al = talign(type, NULL);
 15141509         sz = tsize(type, NULL, NULL);
 15151510 
 15161511         if (w > sz) {
 15171512                 uerror("field too big");
 15181513                 w = sz;
 15191514         }
 15201515 
 15211516         if (w == 0) { /* align only */
 15221517                 SETOFF(rpole->rstr, al);
 15231518                 if (p != NULL)
 15241519                         uerror("zero size field");
 15251520                 return(0);
 15261521         }
 15271522 
 15281523         if (rpole->rstr%al + w > sz)
 15291524                 SETOFF(rpole->rstr, al);
 15301525         if (p == NULL) {
 15311526                 rpole->rstr += w/* we know it will fit */
 15321527                 return(0);
 15331528         }
 15341529 
 15351530         /* establish the field */
 15361531 
 15371532         p->soffset = rpole->rstr;
 15381533         rpole->rstr += w;
 15391534         p->stype = otype;
 15401535         fldty(p);
 15411536         return(0);
 15421537 }
 15431538 
 15441539 /*
 15451540  * Check if this symbol should be a common or must be handled in data seg.
 15461541  */
 15471542 static void
 15481543 commchk(struct symtab *sp)
 15491544 {
 15501545         if ((sp->sflags & STLS) || attr_find(sp->sap, GCC_ATYP_SECTION)) {
 15511546                 /* TLS handled in data segment */
 15521547                 if (sp->sclass == EXTERN)
 15531548                         sp->sclass = EXTDEF;
 15541549                 beginit(sp);
 15551550                 endinit(1);
 15561551         } else {
 15571552                 symdirec(sp);
 15581553                 defzero(sp);
 15591554         }
 15601555 }
 15611556 
 15621557 void
 15631558 nidcl(NODE *p, int class)
 15641559 {
 15651560         nidcl2(p, class, 0);
 15661561 }
 15671562 
 15681563 /*
 15691564  * handle unitialized declarations assumed to be not functions:
 15701565  * int a;
 15711566  * extern int a;
 15721567  * static int a;
 15731568  */
 15741569 void
 15751570 nidcl2(NODE *p, int class, char *astr)
 15761571 {
 15771572         struct symtab *sp;
 15781573         int commflag = 0;
 15791574 
 15801575         /* compute class */
 15811576         if (class == SNULL) {
 15821577                 if (blevel > 1)
 15831578                         class = AUTO;
 15841579                 else if (blevel != 0 || rpole)
 15851580                         cerror( "nidcl error" );
 15861581                 else /* blevel = 0 */
 15871582                         commflag = 1, class = EXTERN;
 15881583         }
 15891584 
 15901585         defid2(p, class, astr);
 15911586 
 15921587         sp = p->n_sp;
 15931588         /* check if forward decl */
 15941589         if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
 15951590                 return;
 15961591 
 15971592         if (sp->sflags & SASG)
 15981593                 return; /* already initialized */
 15991594 
 16001595         switch (class) {
 16011596         case EXTDEF:
 16021597                 /* simulate initialization by 0 */
 16031598                 simpleinit(p->n_sp, bcon(0));
 16041599                 break;
 16051600         case EXTERN:
 16061601                 if (commflag)
 16071602                         lcommadd(p->n_sp);
 16081603                 else
 16091604                         extdec(p->n_sp);
 16101605                 break;
 16111606         case STATIC:
 16121607                 if (blevel == 0)
 16131608                         lcommadd(p->n_sp);
 16141609                 else
 16151610                         commchk(p->n_sp);
 16161611                 break;
 16171612         }
 16181613 }
 16191614 
 16201615 struct lcd {
 16211616         SLIST_ENTRY(lcd) next;
 16221617         struct symtab *sp;
 16231618 };
 16241619 
 16251620 static SLIST_HEAD(, lcd) lhead = { NULL, &lhead.q_forw};
 16261621 
 16271622 /*
 16281623  * Add a local common statement to the printout list.
 16291624  */
 16301625 void
 16311626 lcommadd(struct symtab *sp)
 16321627 {
 16331628         struct lcd *lc, *lcp;
 16341629 
 16351630         lcp = NULL;
 16361631         SLIST_FOREACH(lc, &lhead, next) {
 16371632                 if (lc->sp == sp)
 16381633                         return; /* already exists */
 16391634                 if (lc->sp == NULL && lcp == NULL)
 16401635                         lcp = lc;
 16411636         }
 16421637         if (lcp == NULL) {
 16431638                 lc = permalloc(sizeof(struct lcd));
 16441639                 lc->sp = sp;
 16451640                 SLIST_INSERT_LAST(&lhead, lc, next);
 16461641         } else
 16471642                 lcp->sp = sp;
 16481643 }
 16491644 
 16501645 /*
 16511646  * Delete a local common statement.
 16521647  */
 16531648 void
 16541649 lcommdel(struct symtab *sp)
 16551650 {
 16561651         struct lcd *lc;
 16571652 
 16581653         SLIST_FOREACH(lc, &lhead, next) {
 16591654                 if (lc->sp == sp) {
 16601655                         lc->sp = NULL;
 16611656                         return;
 16621657                 }
 16631658         }
 16641659 }
 16651660 
 16661661 /*
 16671662  * Print out the remaining common statements.
 16681663  */
 16691664 void
 16701665 lcommprint(void)
 16711666 {
 16721667         struct lcd *lc;
 16731668 
 16741669         SLIST_FOREACH(lc, &lhead, next) {
 16751670                 if (lc->sp != NULL)
 16761671                         commchk(lc->sp);
 16771672         }
 16781673 }
 16791674 
 16801675 /*
 16811676  * Merge given types to a single node.
 16821677  * Any type can end up here.
 16831678  * p is the old node, q is the old (if any).
 16841679  * CLASS is AUTO, EXTERN, REGISTER, STATIC or TYPEDEF.
 16851680  * QUALIFIER is VOL or CON
 16861681  * TYPE is CHAR, SHORT, INT, LONG, SIGNED, UNSIGNED, VOID, BOOL, FLOAT,
 16871682  *      DOUBLE, STRTY, UNIONTY.
 16881683  */
 16891684 struct typctx {
 16901685         int class, qual, sig, uns, cmplx, imag, err;
 16911686         TWORD type;
 16921687         NODE *saved;
 16931688         struct attr *pre, *post;
 16941689 };
 16951690 
 16961691 static void
 16971692 typwalk(NODE *p, void *arg)
 16981693 {
 16991694         struct typctx *tc = arg;
 17001695 
 17011696 #define cmop(x,y) block(CM, x, y, INT, 0, 0)
 17021697         switch (p->n_op) {
 17031698         case ATTRIB:
 17041699                 if (tc->saved && (tc->saved->n_qual & 1)) {
 17051700                         tc->post = attr_add(tc->post,gcc_attr_parse(p->n_left));
 17061701                 } else {
 17071702                         tc->pre = attr_add(tc->pre, gcc_attr_parse(p->n_left));
 17081703                 }
 17091704                 p->n_left = bcon(0); /* For tfree() */
 17101705                 break;
 17111706         case CLASS:
 17121707                 if (tc->class)
 17131708                         tc->err = 1; /* max 1 class */
 17141709                 tc->class = p->n_type;
 17151710                 break;
 17161711 
 17171712         case QUALIFIER:
 17181713 #if 0
 17191714                 if (p->n_qual == 0)
 17201715                         uerror("invalid use of 'restrict'");
 17211716 #endif
 17221717                 tc->qual |= p->n_qual >> TSHIFT;
 17231718                 break;
 17241719 
 17251720         case TYPE:
 17261721                 if (p->n_sp != NULL || ISSOU(p->n_type)) {
 17271722                         /* typedef, enum or struct/union */
 17281723                         if (tc->saved || tc->type)
 17291724                                 tc->err = 1;
 17301725 #ifdef GCC_COMPAT
 17311726                         if (ISSOU(p->n_type) && p->n_left) {
 17321727                                 if (tc->post)
 17331728                                         cerror("typwalk");
 17341729                                 tc->post = gcc_attr_parse(p->n_left);
 17351730                         }
 17361731 #endif
 17371732                         tc->saved = ccopy(p);
 17381733                         break;
 17391734                 }
 17401735 
 17411736                 switch (p->n_type) {
 17421737                 case BOOL:
 17431738                 case CHAR:
 17441739                 case FLOAT:
 17451740                 case VOID:
 17461741                         if (tc->type)
 17471742                                 tc->err = 1;
 17481743                         tc->type = p->n_type;
 17491744                         break;
 17501745                 case DOUBLE:
 17511746                         if (tc->type == 0)
 17521747                                 tc->type = DOUBLE;
 17531748                         else if (tc->type == LONG)
 17541749                                 tc->type = LDOUBLE;
 17551750                         else
 17561751                                 tc->err = 1;
 17571752                         break;
 17581753                 case SHORT:
 17591754                         if (tc->type == 0 || tc->type == INT)
 17601755                                 tc->type = SHORT;
 17611756                         else
 17621757                                 tc->err = 1;
 17631758                         break;
 17641759                 case INT:
 17651760                         if (tc->type == SHORT || tc->type == LONG ||
 17661761                             tc->type == LONGLONG)
 17671762                                 break;
 17681763                         else if (tc->type == 0)
 17691764                                 tc->type = INT;
 17701765                         else
 17711766                                 tc->err = 1;
 17721767                         break;
 17731768                 case LONG:
 17741769                         if (tc->type == 0)
 17751770                                 tc->type = LONG;
 17761771                         else if (tc->type == INT)
 17771772                                 break;
 17781773                         else if (tc->type == LONG)
 17791774                                 tc->type = LONGLONG;
 17801775                         else if (tc->type == DOUBLE)
 17811776                                 tc->type = LDOUBLE;
 17821777                         else
 17831778                                 tc->err = 1;
 17841779                         break;
 17851780                 case SIGNED:
 17861781                         if (tc->sig || tc->uns)
 17871782                                 tc->err = 1;
 17881783                         tc->sig = 1;
 17891784                         break;
 17901785                 case UNSIGNED:
 17911786                         if (tc->sig || tc->uns)
 17921787                                 tc->err = 1;
 17931788                         tc->uns = 1;
 17941789                         break;
 17951790                 case COMPLEX:
 17961791                         tc->cmplx = 1;
 17971792                         break;
 17981793                 case IMAG:
 17991794                         tc->imag = 1;
 18001795                         break;
 18011796                 default:
 18021797                         cerror("typwalk");
 18031798                 }
 18041799         }
 18051800 
 18061801 }
 18071802 
 18081803 NODE *
 18091804 typenode(NODE *p)
 18101805 {
 18111806         struct symtab *sp;
 18121807         struct typctx tc;
 18131808         NODE *q;
 18141809         char *c;
 18151810 
 18161811         memset(&tc, 0, sizeof(struct typctx));
 18171812 
 18181813         flist(p, typwalk, &tc);
 18191814         tfree(p);
 18201815 
 18211816         if (tc.err)
 18221817                 goto bad;
 18231818 
 18241819         if (tc.cmplx || tc.imag) {
 18251820                 if (tc.type == 0)
 18261821                         tc.type = DOUBLE;
 18271822                 if ((tc.cmplx && tc.imag) || tc.sig || tc.uns ||
 18281823                     !ISFTY(tc.type))
 18291824                         goto bad;
 18301825                 if (tc.cmplx) {
 18311826                         c = tc.type == DOUBLE ? "0d" :
 18321827                             tc.type == FLOAT ? "0f" : "0l";
 18331828                         sp = lookup(addname(c), 0);
 18341829                         tc.type = STRTY;
 18351830                         tc.saved = mkty(tc.type, sp->sdf, sp->sap);
 18361831                         tc.saved->n_sp = sp;
 18371832                         tc.type = 0;
 18381833                 } else
 18391834                         tc.type += (FIMAG-FLOAT);
 18401835         }
 18411836 
 18421837         if (tc.saved && tc.type)
 18431838                 goto bad;
 18441839         if (tc.sig || tc.uns) {
 18451840                 if (tc.type == 0)
 18461841                         tc.type = tc.sig ? INT : UNSIGNED;
 18471842                 if (tc.type > ULONGLONG)
 18481843                         goto bad;
 18491844                 if (tc.uns)
 18501845                         tc.type = ENUNSIGN(tc.type);
 18511846         }
 18521847 
 18531848         if (xuchar && tc.type == CHAR && tc.sig == 0)
 18541849                 tc.type = UCHAR;
 18551850 
 18561851 #ifdef GCC_COMPAT
 18571852         if (pragma_packed) {
 18581853                 q = bdty(CALL, bdty(NAME, "packed"), bcon(pragma_packed));
 18591854                 tc.post = attr_add(tc.post, gcc_attr_parse(q));
 18601855         }
 18611856         if (pragma_aligned) {
 18621857                 /* Deal with relevant pragmas */
 18631858                 q = bdty(CALL, bdty(NAME, "aligned"), bcon(pragma_aligned));
 18641859                 tc.post = attr_add(tc.post, gcc_attr_parse(q));
 18651860         }
 18661861         pragma_aligned = pragma_packed = 0;
 18671862 #endif
 18681863         if ((q = tc.saved) == NULL) {
 18691864                 TWORD t;
 18701865                 if ((t = BTYPE(tc.type)) > LDOUBLE && t != VOID &&
 18711866                     t != BOOL && !(t >= FIMAG && t <= LIMAG))
 18721867                         cerror("typenode2 t %x", tc.type);
 18731868                 if (t == UNDEF) {
 18741869                         t = INT;
 18751870                         MODTYPE(tc.type, INT);
 18761871                 }
 18771872                 qmkty(tc.type, 0, 0);
 18781873         }
 18791874         q->n_ap = attr_add(q->n_ap, tc.post);
 18801875         q->n_qual = tc.qual;
 18811876         q->n_lval = tc.class;
 18821877 #ifdef GCC_COMPAT
 18831878         if (tc.post) {
 18841879                 /* Can only occur for TYPEDEF, STRUCT or UNION */
 18851880                 if (tc.saved == NULL)
 18861881                         cerror("typenode");
 18871882                 if (tc.saved->n_sp) /* trailer attributes for structs */
 18881883                         tc.saved->n_sp->sap = q->n_ap;
 18891884         }
 18901885         if (tc.pre)
 18911886                 q->n_ap = attr_add(q->n_ap, tc.pre);
 18921887         gcc_tcattrfix(q);
 18931888 #endif
 18941889         return q;
 18951890 
 18961891 bad:    uerror("illegal type combination");
 18971892         return mkty(INT, 0, 0);
 18981893 }
 18991894 
 19001895 struct tylnk {
 19011896         struct tylnk *next;
 19021897         union dimfun df;
 19031898 };
 19041899 
 19051900 /*
 19061901  * Retrieve all CM-separated argument types, sizes and dimensions and
 19071902  * put them in an array.
 19081903  * XXX - can only check first type level, side effects?
 19091904  */
 19101905 static union arglist *
 19111906 arglist(NODE *n)
 19121907 {
 19131908         union arglist *al;
 19141909         NODE *w = n, **ap;
 19151910         int num, cnt, i, j, k;
 19161911         TWORD ty;
 19171912 
 19181913 #ifdef PCC_DEBUG
 19191914         if (pdebug) {
 19201915                 printf("arglist %p\n", n);
 19211916                 fwalk(n, eprint, 0);
 19221917         }
 19231918 #endif
 19241919         /* First: how much to allocate */
 19251920         for (num = cnt = 0, w = n; w->n_op == CM; w = w->n_left) {
 19261921                 cnt++;  /* Number of levels */
 19271922                 num++;  /* At least one per step */
 19281923                 if (w->n_right->n_op == ELLIPSIS)
 19291924                         continue;
 19301925                 ty = w->n_right->n_type;
 19311926                 if (ty == ENUMTY) {
 19321927                         uerror("arg %d enum undeclared", cnt);
 19331928                         ty = w->n_right->n_type = INT;
 19341929                 }
 19351930                 if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
 19361931                         num++;
 19371932                 while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
 19381933                         ty = DECREF(ty);
 19391934                 if (ty > BTMASK)
 19401935                         num++;
 19411936         }
 19421937         cnt++;
 19431938         ty = w->n_type;
 19441939         if (ty == ENUMTY) {
 19451940                 uerror("arg %d enum undeclared", cnt);
 19461941                 ty = w->n_type = INT;
 19471942         }
 19481943         if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
 19491944                 num++;
 19501945         while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
 19511946                 ty = DECREF(ty);
 19521947         if (ty > BTMASK)
 19531948                 num++;
 19541949         num += 2; /* TEND + last arg type */
 19551950 
 19561951         /* Second: Create list to work on */
 19571952         ap = tmpalloc(sizeof(NODE *) * cnt);
 19581953         al = permalloc(sizeof(union arglist) * num);
 19591954         arglistcnt += num;
 19601955 
 19611956         for (w = n, i = 0; w->n_op == CM; w = w->n_left)
 19621957                 ap[i++] = w->n_right;
 19631958         ap[i] = w;
 19641959 
 19651960         /* Third: Create actual arg list */
 19661961         for (k = 0, j = i; j >= 0; j--) {
 19671962                 if (ap[j]->n_op == ELLIPSIS) {
 19681963                         al[k++].type = TELLIPSIS;
 19691964                         ap[j]->n_op = ICON; /* for tfree() */
 19701965                         continue;
 19711966                 }
 19721967                 /* Convert arrays to pointers */
 19731968                 if (ISARY(ap[j]->n_type)) {
 19741969                         ap[j]->n_type += (PTR-ARY);
 19751970                         ap[j]->n_df++;
 19761971                 }
 19771972                 /* Convert (silently) functions to pointers */
 19781973                 if (ISFTN(ap[j]->n_type))
 19791974                         ap[j]->n_type = INCREF(ap[j]->n_type);
 19801975                 ty = ap[j]->n_type;
 19811976 #ifdef GCC_COMPAT
 19821977                 if (ty == UNIONTY &&
 19831978                     attr_find(ap[j]->n_ap, GCC_ATYP_TRANSP_UNION)){
 19841979                         /* transparent unions must have compatible types
 19851980                          * shortcut here: if pointers, set void *,
 19861981                          * otherwise btype.
 19871982                          */
 19881983                         struct symtab *sp = strmemb(ap[j]->n_ap);
 19891984                         ty = ISPTR(sp->stype) ? PTR|VOID : sp->stype;
 19901985                 }
 19911986 #endif
 19921987                 al[k++].type = ty;
 19931988                 if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
 19941989                         al[k++].sap = ap[j]->n_ap;
 19951990                 while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
 19961991                         ty = DECREF(ty);
 19971992                 if (ty > BTMASK)
 19981993                         al[k++].df = ap[j]->n_df;
 19991994         }
 20001995         al[k++].type = TNULL;
 20011996         if (k > num)
 20021997                 cerror("arglist: k%d > num%d", k, num);
 20031998         tfree(n);
 20041999 #ifdef PCC_DEBUG
 20052000         if (pdebug)
 20062001                 alprint(al, 0);
 20072002 #endif
 20082003         return al;
 20092004 }
 20102005 
 20112006 static void
 20122007 tylkadd(union dimfun dim, struct tylnk **tylkp, int *ntdim)
 20132008 {
 20142009         (*tylkp)->next = tmpalloc(sizeof(struct tylnk));
 20152010         *tylkp = (*tylkp)->next;
 20162011         (*tylkp)->next = NULL;
 20172012         (*tylkp)->df = dim;
 20182013         (*ntdim)++;
 20192014 }
 20202015 
 20212016 /*
 20222017  * build a type, and stash away dimensions,
 20232018  * from a parse tree of the declaration
 20242019  * the type is build top down, the dimensions bottom up
 20252020  */
 20262021 static void
 20272022 tyreduce(NODE *p, struct tylnk **tylkp, int *ntdim)
 20282023 {
 20292024         union dimfun dim;
 20302025         NODE *r = NULL;
 20312026         int o;
 20322027         TWORD t, q;
 20332028 
 20342029         o = p->n_op;
 20352030         if (o == NAME) {
 20362031                 p->n_qual = DECQAL(p->n_qual);
 20372032                 return;
 20382033         }
 20392034 
 20402035         t = INCREF(p->n_type);
 20412036         q = p->n_qual;
 20422037         switch (o) {
 20432038         case CALL:
 20442039                 t += (FTN-PTR);
 20452040                 dim.dfun = arglist(p->n_right);
 20462041                 break;
 20472042         case UCALL:
 20482043                 t += (FTN-PTR);
 20492044                 dim.dfun = NULL;
 20502045                 break;
 20512046         case LB:
 20522047                 t += (ARY-PTR);
 20532048                 if (p->n_right->n_op != ICON) {
 20542049                         r = p->n_right;
 20552050                         o = RB;
 20562051                 } else {
 20572052                         dim.ddim = (int)p->n_right->n_lval;
 20582053                         nfree(p->n_right);
 20592054 #ifdef notdef
 20602055         /* XXX - check dimensions at usage time */
 20612056                         if (dim.ddim == NOOFFSET && p->n_left->n_op == LB)
 20622057                                 uerror("null dimension");
 20632058 #endif
 20642059                 }
 20652060                 break;
 20662061         }
 20672062 
 20682063         p->n_left->n_type = t;
 20692064         p->n_left->n_qual = INCQAL(q) | p->n_left->n_qual;
 20702065         tyreduce(p->n_left, tylkp, ntdim);
 20712066 
 20722067         if (o == LB || o == UCALL || o == CALL)
 20732068                 tylkadd(dim, tylkp, ntdim);
 20742069         if (o == RB) {
 20752070                 dim.ddim = -1;
 20762071                 tylkadd(dim, tylkp, ntdim);
 20772072                 arrstk[arrstkp++] = r;
 20782073         }
 20792074 
 20802075         p->n_sp = p->n_left->n_sp;
 20812076         p->n_type = p->n_left->n_type;
 20822077         p->n_qual = p->n_left->n_qual;
 20832078 }
 20842079 
 20852080 /*
 20862081  * merge type typ with identifier idp.
 20872082  * idp is returned as a NAME node with correct types,
 20882083  * typ is untouched since multiple declarations uses it.
 20892084  * typ has type attributes, idp can never carry such attributes
 20902085  * so on return just a pointer to the typ attributes is returned.
 20912086  */
 20922087 NODE *
 20932088 tymerge(NODE *typ, NODE *idp)
 20942089 {
 20952090         TWORD t;
 20962091         NODE *p;
 20972092         union dimfun *j;
 20982093         struct tylnk *base, tylnk, *tylkp;
 20992094         struct attr *bap;
 21002095         int ntdim, i;
 21012096 
 21022097 #ifdef PCC_DEBUG
 21032098         if (ddebug > 2) {
 21042099                 printf("tymerge(%p,%p)\n", typ, idp);
 21052100                 fwalk(typ, eprint, 0);
 21062101                 fwalk(idp, eprint, 0);
 21072102         }
 21082103 #endif
 21092104 
 21102105         if (typ->n_op != TYPE)
 21112106                 cerror("tymerge: arg 1");
 21122107 
 21132108         bap = typ->n_ap;
 21142109 
 21152110         idp->n_type = typ->n_type;
 21162111         idp->n_qual |= typ->n_qual;
 21172112 
 21182113         tylkp = &tylnk;
 21192114         tylkp->next = NULL;
 21202115         ntdim = 0;
 21212116 
 21222117         tyreduce(idp, &tylkp, &ntdim);
 21232118 
 21242119         for (t = typ->n_type, j = typ->n_df; t&TMASK; t = DECREF(t))
 21252120                 if (ISARY(t) || ISFTN(t))
 21262121                         tylkadd(*j++, &tylkp, &ntdim);
 21272122 
 21282123         if (ntdim) {
 21292124                 union dimfun *a = permalloc(sizeof(union dimfun) * ntdim);
 21302125                 dimfuncnt += ntdim;
 21312126                 for (i = 0, base = tylnk.next; base; base = base->next, i++)
 21322127                         a[i] = base->df;
 21332128                 idp->n_df = a;
 21342129         } else
 21352130                 idp->n_df = NULL;
 21362131 
 21372132         /* now idp is a single node: fix up type */
 21382133         if ((t = ctype(idp->n_type)) != idp->n_type)
 21392134                 idp->n_type = t;
 21402135         
 21412136         if (idp->n_op != NAME) {
 21422137                 for (p = idp->n_left; p->n_op != NAME; p = p->n_left)
 21432138                         nfree(p);
 21442139                 nfree(p);
 21452140                 idp->n_op = NAME;
 21462141         }
 21472142         idp->n_ap = bap;
 21482143 
 21492144         return(idp);
 21502145 }
 21512146 
 21522147 static NODE *
 21532148 argcast(NODE *p, TWORD t, union dimfun *d, struct attr *ap)
 21542149 {
 21552150         NODE *u, *r = talloc();
 21562151 
 21572152         r->n_op = NAME;
 21582153         r->n_type = t;
 21592154         r->n_qual = 0; /* XXX */
 21602155         r->n_df = d;
 21612156         r->n_ap = ap;
 21622157 
 21632158         u = buildtree(CAST, r, p);
 21642159         nfree(u->n_left);
 21652160         r = u->n_right;
 21662161         nfree(u);
 21672162         return r;
 21682163 }
 21692164 
 21702165 #ifdef PCC_DEBUG
 21712166 /*
 21722167  * Print a prototype.
 21732168  */
 21742169 static void
 21752170 alprint(union arglist *al, int in)
 21762171 {
 21772172         TWORD t;
 21782173         int i = 0, j;
 21792174 
 21802175         for (; al->type != TNULL; al++) {
 21812176                 for (j = in; j > 0; j--)
 21822177                         printf("  ");
 21832178                 printf("arg %d: ", i++);
 21842179                 t = al->type;
 21852180                 tprint(t, 0);
 21862181                 while (t > BTMASK) {
 21872182                         if (ISARY(t)) {
 21882183                                 al++;
 21892184                                 printf(" dim %d ", al->df->ddim);
 21902185                         } else if (ISFTN(t)) {
 21912186                                 al++;
 21922187                                 if (al->df->dfun) {
 21932188                                         printf("\n");
 21942189                                         alprint(al->df->dfun, in+1);
 21952190                                 }
 21962191                         }
 21972192                         t = DECREF(t);
 21982193                 }
 21992194                 if (ISSOU(t)) {
 22002195                         al++;
 22012196                         printf(" (size %d align %d)", (int)tsize(t, 0, al->sap),
 22022197                             (int)talign(t, al->sap));
 22032198                 }
 22042199                 printf("\n");
 22052200         }
 22062201         if (in == 0)
 22072202                 printf("end arglist\n");
 22082203 }
 22092204 #endif
 22102205 
 22112206 int
 22122207 suemeq(struct attr *s1, struct attr *s2)
 22132208 {
 22142209 
 22152210         return (strmemb(s1) == strmemb(s2));
 22162211 }
 22172212 
 22182213 /*
 22192214  * Sanity-check old-style args.
 22202215  */
 22212216 static NODE *
 22222217 oldarg(NODE *p)
 22232218 {
 22242219         if (p->n_op == TYPE)
 22252220                 uerror("type is not an argument");
 22262221         if (p->n_type == FLOAT)
 22272222                 return cast(p, DOUBLE, p->n_qual);
 22282223         return p;
 22292224 }
 22302225 
 22312226 /*
 22322227  * Do prototype checking and add conversions before calling a function.
 22332228  * Argument f is function and a is a CM-separated list of arguments.
 22342229  * Returns a merged node (via buildtree() of function and arguments.
 22352230  */
 22362231 NODE *
 22372232 doacall(struct symtab *sp, NODE *f, NODE *a)
 22382233 {
 22392234         NODE *w, *r;
 22402235         union arglist *al;
 22412236         struct ap {
 22422237                 struct ap *next;
 22432238                 NODE *node;
 22442239         } *at, *apole = NULL;
 22452240         int argidx/* , hasarray = 0*/;
 22462241         TWORD type, arrt;
 22472242 
 22482243 #ifdef PCC_DEBUG
 22492244         if (ddebug) {
 22502245                 printf("doacall.\n");
 22512246                 fwalk(f, eprint, 0);
 22522247                 if (a)
 22532248                         fwalk(a, eprint, 0);
 22542249         }
 22552250 #endif
 22562251 
 22572252         /* First let MD code do something */
 22582253         calldec(f, a);
 22592254 /* XXX XXX hack */
 22602255         if ((f->n_op == CALL) &&
 22612256             f->n_left->n_op == ADDROF &&
 22622257             f->n_left->n_left->n_op == NAME &&
 22632258             (f->n_left->n_left->n_type & 0x7e0) == 0x4c0)
 22642259                 goto build;
 22652260 /* XXX XXX hack */
 22662261 
 22672262         /* Check for undefined or late defined enums */
 22682263         if (BTYPE(f->n_type) == ENUMTY) {
 22692264                 /* not-yet check if declared enum */
 22702265                 struct symtab *sq = strmemb(f->n_ap);
 22712266                 if (sq->stype != ENUMTY)
 22722267                         MODTYPE(f->n_type, sq->stype);
 22732268                 if (BTYPE(f->n_type) == ENUMTY)
 22742269                         uerror("enum %s not declared", sq->sname);
 22752270         }
 22762271 
 22772272         /*
 22782273          * Do some basic checks.
 22792274          */
 22802275         if (f->n_df == NULL || (al = f->n_df[0].dfun) == NULL) {
 22812276                 /*
 22822277                  * Handle non-prototype declarations.
 22832278                  */
 22842279                 if (f->n_op == NAME && f->n_sp != NULL) {
 22852280                         if (strncmp(f->n_sp->sname, "__builtin", 9) != 0 &&
 22862281                             (f->n_sp->sflags & SINSYS) == 0)
 22872282                                 warner(Wmissing_prototypes, f->n_sp->sname);
 22882283                 } else
 22892284                         warner(Wmissing_prototypes, "<pointer>");
 22902285 
 22912286                 /* floats must be cast to double */
 22922287                 if (a == NULL)
 22932288                         goto build;
 22942289                 if (a->n_op != CM) {
 22952290                         a = oldarg(a);
 22962291                 } else {
 22972292                         for (w = a; w->n_left->n_op == CM; w = w->n_left)
 22982293                                 w->n_right = oldarg(w->n_right);
 22992294                         w->n_left = oldarg(w->n_left);
 23002295                         w->n_right = oldarg(w->n_right);
 23012296                 }
 23022297                 goto build;
 23032298         }
 23042299         if (al->type == VOID) {
 23052300                 if (a != NULL)
 23062301                         uerror("function takes no arguments");
 23072302                 goto build; /* void function */
 23082303         } else {
 23092304                 if (a == NULL) {
 23102305                         uerror("function needs arguments");
 23112306                         goto build;
 23122307                 }
 23132308         }
 23142309 #ifdef PCC_DEBUG
 23152310         if (pdebug) {
 23162311                 printf("arglist for %s\n",
 23172312                     f->n_sp != NULL ? f->n_sp->sname : "function pointer");
 23182313                 alprint(al, 0);
 23192314         }
 23202315 #endif
 23212316 
 23222317         /*
 23232318          * Create a list of pointers to the nodes given as arg.
 23242319          */
 23252320         for (w = a; w->n_op == CM; w = w->n_left) {
 23262321                 at = tmpalloc(sizeof(struct ap));
 23272322                 at->node = w->n_right;
 23282323                 at->next = apole;
 23292324                 apole = at;
 23302325         }
 23312326         at = tmpalloc(sizeof(struct ap));
 23322327         at->node = w;
 23332328         at->next = apole;
 23342329         apole = at;
 23352330 
 23362331         /*
 23372332          * Do the typechecking by walking up the list.
 23382333          */
 23392334         argidx = 1;
 23402335         while (al->type != TNULL) {
 23412336                 if (al->type == TELLIPSIS) {
 23422337                         /* convert the rest of float to double */
 23432338                         for (; apole; apole = apole->next) {
 23442339                                 if (apole->node->n_type != FLOAT)
 23452340                                         continue;
 23462341                                 MKTY(apole->node, DOUBLE, 0, 0);
 23472342                         }
 23482343                         goto build;
 23492344                 }
 23502345                 if (apole == NULL) {
 23512346                         uerror("too few arguments to function");
 23522347                         goto build;
 23532348                 }
 23542349 /* al = prototyp, apole = argument till ftn */
 23552350 /* type = argumentets typ, arrt = prototypens typ */
 23562351                 type = apole->node->n_type;
 23572352                 arrt = al->type;
 23582353 #if 0
 23592354                 if ((hasarray = ISARY(arrt)))
 23602355                         arrt += (PTR-ARY);
 23612356 #endif
 23622357                 /* Taking addresses of arrays are meaningless in expressions */
 23632358                 /* but people tend to do that and also use in prototypes */
 23642359                 /* this is mostly a problem with typedefs */
 23652360                 if (ISARY(type)) {
 23662361                         if (ISPTR(arrt) && ISARY(DECREF(arrt)))
 23672362                                 type = INCREF(type);
 23682363                         else
 23692364                                 type += (PTR-ARY);
 23702365                 } else if (ISPTR(type) && !ISARY(DECREF(type)) &&
 23712366                     ISPTR(arrt) && ISARY(DECREF(arrt))) {
 23722367                         type += (ARY-PTR);
 23732368                         type = INCREF(type);
 23742369                 }
 23752370 
 23762371                 /* Check structs */
 23772372                 if (type <= BTMASK && arrt <= BTMASK) {
 23782373                         if (type != arrt) {
 23792374                                 if (ISSOU(BTYPE(type)) || ISSOU(BTYPE(arrt))) {
 23802375 incomp:                                 uerror("incompatible types for arg %d",
 23812376                                             argidx);
 23822377                                 } else {
 23832378                                         MKTY(apole->node, arrt, 0, 0)
 23842379                                 }
 23852380 #ifndef NO_COMPLEX
 23862381                         } else if (type == STRTY &&
 23872382                             attr_find(apole->node->n_ap, ATTR_COMPLEX) &&
 23882383                             attr_find(al[1].sap, ATTR_COMPLEX)) {
 23892384                                 /* Both are complex */
 23902385                                 if (strmemb(apole->node->n_ap)->stype !=
 23912386                                     strmemb(al[1].sap)->stype) {
 23922387                                         /* must convert to correct type */
 23932388                                         w = talloc();
 23942389                                         *w = *apole->node;
 23952390                                         w = mkcmplx(w,
 23962391                                             strmemb(al[1].sap)->stype);
 23972392                                         *apole->node = *w;
 23982393                                         nfree(w);
 23992394                                 }
 24002395                                 goto out;
 24012396 #endif
 24022397                         } else if (ISSOU(BTYPE(type))) {
 24032398                                 if (!suemeq(apole->node->n_ap, al[1].sap))
 24042399                                         goto incomp;
 24052400                         }
 24062401                         goto out;
 24072402                 }
 24082403 
 24092404                 /* XXX should (recusively) check return type and arg list of
 24102405                    func ptr arg XXX */
 24112406                 if (ISFTN(DECREF(arrt)) && ISFTN(type))
 24122407                         type = INCREF(type);
 24132408 
 24142409                 /* Hereafter its only pointers (or arrays) left */
 24152410                 /* Check for struct/union intermixing with other types */
 24162411                 if (((type <= BTMASK) && ISSOU(BTYPE(type))) ||
 24172412                     ((arrt <= BTMASK) && ISSOU(BTYPE(arrt))))
 24182413                         goto incomp;
 24192414 
 24202415                 /* Check for struct/union compatibility */
 24212416                 if (type == arrt) {
 24222417                         if (ISSOU(BTYPE(type))) {
 24232418                                 if (suemeq(apole->node->n_ap, al[1].sap))
 24242419                                         goto out;
 24252420                         } else
 24262421                                 goto out;
 24272422                 }
 24282423                 if (BTYPE(arrt) == VOID && type > BTMASK)
 24292424                         goto skip; /* void *f = some pointer */
 24302425                 if (arrt > BTMASK && BTYPE(type) == VOID)
 24312426                         goto skip; /* some *f = void pointer */
 24322427                 if (apole->node->n_op == ICON && apole->node->n_lval == 0)
 24332428                         goto skip; /* Anything assigned a zero */
 24342429 
 24352430                 if ((type & ~BTMASK) == (arrt & ~BTMASK)) {
 24362431                         /* do not complain for pointers with signedness */
 24372432                         if ((DEUNSIGN(BTYPE(type)) == DEUNSIGN(BTYPE(arrt))) &&
 24382433                             (BTYPE(type) != BTYPE(arrt))) {
 24392434                                 warner(Wpointer_sign, NULL);
 24402435                                 goto skip;
 24412436                         }
 24422437                 }
 24432438 
 24442439                 werror("implicit conversion of argument %d due to prototype",
 24452440                     argidx);
 24462441 
 24472442 skip:           if (ISSOU(BTYPE(arrt))) {
 24482443                         MKTY(apole->node, arrt, 0, al[1].sap)
 24492444                 } else {
 24502445                         MKTY(apole->node, arrt, 0, 0)
 24512446                 }
 24522447 
 24532448 out:            al++;
 24542449                 if (ISSOU(BTYPE(arrt)))
 24552450                         al++;
 24562451 #if 0
 24572452                 while (arrt > BTMASK && !ISFTN(arrt))
 24582453                         arrt = DECREF(arrt);
 24592454                 if (ISFTN(arrt) || hasarray)
 24602455                         al++;
 24612456 #else
 24622457                 while (arrt > BTMASK) {
 24632458                         if (ISARY(arrt) || ISFTN(arrt)) {
 24642459                                 al++;
 24652460                                 break;
 24662461                         }
 24672462                         arrt = DECREF(arrt);
 24682463                 }
 24692464 #endif
 24702465                 apole = apole->next;
 24712466                 argidx++;
 24722467         }
 24732468         if (apole != NULL)
 24742469                 uerror("too many arguments to function");
 24752470 
 24762471 build:  if (sp != NULL && (sp->sflags & SINLINE) && (w = inlinetree(sp, f, a)))
 24772472                 return w;
 24782473         return buildtree(a == NIL ? UCALL : CALL, f, a);
 24792474 }
 24802475 
 24812476 static int
 24822477 chk2(TWORD type, union dimfun *dsym, union dimfun *ddef)
 24832478 {
 24842479         while (type > BTMASK) {
 24852480                 switch (type & TMASK) {
 24862481                 case ARY:
 24872482                         /* may be declared without dimension */
 24882483                         if (dsym->ddim == NOOFFSET)
 24892484                                 dsym->ddim = ddef->ddim;
 24902485                         if (dsym->ddim < 0 && ddef->ddim < 0)
 24912486                                 ; /* dynamic arrays as arguments */
 24922487                         else if (ddef->ddim > 0 && dsym->ddim != ddef->ddim)
 24932488                                 return 1;
 24942489                         dsym++, ddef++;
 24952490                         break;
 24962491                 case FTN:
 24972492                         /* old-style function headers with function pointers
 24982493                          * will most likely not have a prototype.
 24992494                          * This is not considered an error.  */
 25002495                         if (ddef->dfun == NULL) {
 25012496 #ifdef notyet
 25022497                                 werror("declaration not a prototype");
 25032498 #endif
 25042499                         } else if (chkftn(dsym->dfun, ddef->dfun))
 25052500                                 return 1;
 25062501                         dsym++, ddef++;
 25072502                         break;
 25082503                 }
 25092504                 type = DECREF(type);
 25102505         }
 25112506         return 0;
 25122507 }
 25132508 
 25142509 /*
 25152510  * Compare two function argument lists to see if they match.
 25162511  */
 25172512 int
 25182513 chkftn(union arglist *usym, union arglist *udef)
 25192514 {
 25202515         TWORD t2;
 25212516         int ty, tyn;
 25222517 
 25232518         if (usym == NULL)
 25242519                 return 0;
 25252520         if (cftnsp != NULL && udef == NULL && usym->type == VOID)
 25262521                 return 0; /* foo() { function with foo(void); prototype */
 25272522         if (udef == NULL && usym->type != TNULL)
 25282523                 return 1;
 25292524         while (usym->type != TNULL) {
 25302525                 if (usym->type == udef->type)
 25312526                         goto done;
 25322527                 /*
 25332528                  * If an old-style declaration, then all types smaller than
 25342529                  * int are given as int parameters.
 25352530                  */
 25362531                 if (intcompare) {
 25372532                         ty = BTYPE(usym->type);
 25382533                         tyn = BTYPE(udef->type);
 25392534                         if (ty == tyn || ty != INT)
 25402535                                 return 1;
 25412536                         if (tyn == CHAR || tyn == UCHAR ||
 25422537                             tyn == SHORT || tyn == USHORT)
 25432538                                 goto done;
 25442539                         return 1;
 25452540                 } else
 25462541                         return 1;
 25472542 
 25482543 done:           ty = BTYPE(usym->type);
 25492544                 t2 = usym->type;
 25502545                 if (ISSOU(ty)) {
 25512546                         usym++, udef++;
 25522547                         if (suemeq(usym->sap, udef->sap) == 0)
 25532548                                 return 1;
 25542549                 }
 25552550 
 25562551                 while (!ISFTN(t2) && !ISARY(t2) && t2 > BTMASK)
 25572552                         t2 = DECREF(t2);
 25582553                 if (t2 > BTMASK) {
 25592554                         usym++, udef++;
 25602555                         if (chk2(t2, usym->df, udef->df))
 25612556                                 return 1;
 25622557                 }
 25632558                 usym++, udef++;
 25642559         }
 25652560         if (usym->type != udef->type)
 25662561                 return 1;
 25672562         return 0;
 25682563 }
 25692564 
 25702565 void
 25712566 fixtype(NODE *p, int class)
 25722567 {
 25732568         unsigned int t, type;
 25742569         int mod1, mod2;
 25752570         /* fix up the types, and check for legality */
 25762571&n