Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

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