Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.374
 
1.375
 
MAIN:plunky:20140620070448
 
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 #include "unicode.h"
 6868 
 6969 #include "cgram.h"
 7070 
 7171 struct symtab *cftnsp;
 7272 int arglistcnt, dimfuncnt;      /* statistics */
 7373 int symtabcnt, suedefcnt;       /* statistics */
 7474 int autooff,            /* the next unused automatic offset */
 7575     maxautooff,         /* highest used automatic offset in function */
 7676     argoff;             /* the next unused argument offset */
 7777 int retlab = NOLAB;     /* return label for subroutine */
 7878 int brklab;
 7979 int contlab;
 8080 int flostat;
 8181 int blevel;
 8282 int reached, prolab;
 8383 
 8484 struct params;
 8585 
 8686 #define MKTY(p, t, d, s) r = talloc(); *r = *p; \
 8787         r = argcast(r, t, d, s); *p = *r; nfree(r);
 8888 
 8989 /*
 9090  * Linked list stack while reading in structs.
 9191  */
 9292 struct rstack {
 9393         struct  rstack *rnext;
 9494         int     rsou;
 9595         int     rstr;
 9696         struct  symtab *rsym;
 9797         struct  symtab *rb;
 9898         struct  attr *ap;
 9999         int     flags;
 100100 #define LASTELM 1
 101101 } *rpole;
 102102 
 103103 /*
 104104  * Linked list for parameter (and struct elements) declaration.
 105105  */
 106106 static struct params {
 107107         struct params *prev;
 108108         struct symtab *sym;
 109109 } *lparam;
 110110 static int nparams;
 111111 
 112112 /* defines used for getting things off of the initialization stack */
 113113 
 114114 NODE *arrstk[10];
 115115 int arrstkp;
 116116 static int intcompare;
 117117 NODE *parlink;
 118118 
 119119 void fixtype(NODE *p, int class);
 120120 int fixclass(int class, TWORD type);
 121121 static void dynalloc(struct symtab *p, int *poff);
 122122 static void evalidx(struct symtab *p);
 123123 int isdyn(struct symtab *p);
 124124 void inforce(OFFSZ n);
 125125 void vfdalign(int n);
 126126 static void ssave(struct symtab *);
 127127 #ifdef PCC_DEBUG
 128128 static void alprint(union arglist *al, int in);
 129129 #endif
 130130 static void lcommadd(struct symtab *sp);
 131131 static NODE *mkcmplx(NODE *p, TWORD dt);
 132132 extern int fun_inline;
 133133 
 134134 void
 135135 defid(NODE *q, int class)
 136136 {
 137137         defid2(q, class, 0);
 138138 }
 139139 
 140140 /*
 141141  * Declaration of an identifier.  Handles redeclarations, hiding,
 142142  * incomplete types and forward declarations.
 143143  *
 144144  * q is a TYPE node setup after parsing with n_type, n_df and n_ap.
 145145  * n_sp is a pointer to the not-yet initalized symbol table entry
 146146  * unless it's a redeclaration or supposed to hide a variable.
 147147  */
 148148 
 149149 void
 150150 defid2(NODE *q, int class, char *astr)
 151151 {
 152152         struct attr *ap;
 153153         struct symtab *p;
 154154         TWORD type, qual;
 155155         TWORD stp, stq;
 156156         int scl;
 157157         union dimfun *dsym, *ddef;
 158158         int slev, temp, changed;
 159159 
 160160         if (q == NIL)
 161161                 return/* an error was detected */
 162162 
 163163 #ifdef GCC_COMPAT
 164164         gcc_modefix(q);
 165165 #endif
 166166         p = q->n_sp;
 167167 
 168168         if (p->sname == NULL)
 169169                 cerror("defining null identifier");
 170170 
 171171 #ifdef PCC_DEBUG
 172172         if (ddebug) {
 173173                 printf("defid(%s '%s'(%p), ", p->sname, p->soname , p);
 174174                 tprint(q->n_type, q->n_qual);
 175175                 printf(", %s, (%p)), level %d\n\t", scnames(class),
 176176                     q->n_df, blevel);
 177177 #ifdef GCC_COMPAT
 178178                 dump_attr(q->n_ap);
 179179 #endif
 180180         }
 181181 #endif
 182182 
 183183         fixtype(q, class);
 184184 
 185185         type = q->n_type;
 186186         qual = q->n_qual;
 187187         class = fixclass(class, type);
 188188 
 189189         stp = p->stype;
 190190         stq = p->squal;
 191191         slev = p->slevel;
 192192 
 193193 #ifdef PCC_DEBUG
 194194         if (ddebug) {
 195195                 printf("        modified to ");
 196196                 tprint(type, qual);
 197197                 printf(", %s\n", scnames(class));
 198198                 printf("        previous def'n: ");
 199199                 tprint(stp, stq);
 200200                 printf(", %s, (%p,%p)), level %d\n",
 201201                     scnames(p->sclass), p->sdf, p->sap, slev);
 202202         }
 203203 #endif
 204204 
 205205         if (blevel == 1) {
 206206                 switch (class) {
 207207                 default:
 208208                         if (!(class&FIELD) && !ISFTN(type))
 209209                                 uerror("declared argument %s missing",
 210210                                     p->sname );
 211211                         break;
 212212                 case MOS:
 213213                 case MOU:
 214214                         cerror("field5");
 215215                 case TYPEDEF:
 216216                 case PARAM:
 217217                         break;
 218218                 }
 219219         }
 220220 
 221221         if (stp == UNDEF)
 222222                 goto enter; /* New symbol */
 223223 
 224224         if (type != stp)
 225225                 goto mismatch;
 226226 
 227227         if (blevel > slev && (class == AUTO || class == REGISTER))
 228228                 /* new scope */
 229229                 goto mismatch;
 230230 
 231231         /*
 232232          * test (and possibly adjust) dimensions.
 233233          * also check that prototypes are correct.
 234234          */
 235235         dsym = p->sdf;
 236236         ddef = q->n_df;
 237237         changed = 0;
 238238         for (temp = type; temp & TMASK; temp = DECREF(temp)) {
 239239                 if (ISARY(temp)) {
 240240                         if (dsym->ddim == NOOFFSET) {
 241241                                 dsym->ddim = ddef->ddim;
 242242                                 changed = 1;
 243243                         } else if (ddef->ddim != NOOFFSET &&
 244244                             dsym->ddim!=ddef->ddim) {
 245245                                 goto mismatch;
 246246                         }
 247247                         ++dsym;
 248248                         ++ddef;
 249249                 } else if (ISFTN(temp)) {
 250250                         /* add a late-defined prototype here */
 251251                         if (!oldstyle && dsym->dfun == NULL)
 252252                                 dsym->dfun = ddef->dfun;
 253253                         if (!oldstyle && ddef->dfun != NULL &&
 254254                             chkftn(dsym->dfun, ddef->dfun))
 255255                                 uerror("declaration doesn't match prototype");
 256256                         dsym++, ddef++;
 257257                 }
 258258         }
 259259 #ifdef STABS
 260260         if (changed && gflag)
 261261                 stabs_chgsym(p); /* symbol changed */
 262262 #endif
 263263 
 264264         /* check that redeclarations are to the same structure */
 265265         if (temp == STRTY || temp == UNIONTY) {
 266266                 if (strmemb(p->sap) != strmemb(q->n_ap))
 267267                         goto mismatch;
 268268         }
 269269 
 270270         scl = p->sclass;
 271271 
 272272 #ifdef PCC_DEBUG
 273273         if (ddebug)
 274274                 printf("        previous class: %s\n", scnames(scl));
 275275 #endif
 276276 
 277277         /*
 278278          * Its allowed to add attributes to existing declarations.
 279279          * Be careful though not to trash existing attributes.
 280280          * XXX - code below is probably not correct.
 281281          */
 282282         if (p->sap && p->sap->atype <= ATTR_MAX) {
 283283                 /* nothing special, just overwrite */
 284284                 p->sap = q->n_ap;
 285285         } else {
 286286                 if (p->slevel == blevel) {
 287287                         for (ap = q->n_ap; ap; ap = ap->next) {
 288288                                 if (ap->atype > ATTR_MAX)
 289289                                         p->sap = attr_add(p->sap, attr_dup(ap, 3));
 290290                         }
 291291                 } else
 292292                         p->sap = q->n_ap;
 293293         }
 294294 
 295295         if (class & FIELD)
 296296                 cerror("field1");
 297297         switch(class) {
 298298 
 299299         case EXTERN:
 300300                 if (astr)
 301301                         p->soname = astr;
 302302                 switch( scl ){
 303303                 case STATIC:
 304304                 case USTATIC:
 305305                         if( slev==0 )
 306306                                 goto done;
 307307                         break;
 308308                 case EXTDEF:
 309309                 case EXTERN:
 310310                         goto done;
 311311                 case SNULL:
 312312                         if (p->sflags & SINLINE) {
 313313                                 p->sclass = EXTDEF;
 314314                                 inline_ref(p);
 315315                                 goto done;
 316316                         }
 317317                         break;
 318318                 }
 319319                 break;
 320320 
 321321         case STATIC:
 322322                 if (astr)
 323323                         p->soname = astr;
 324324                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
 325325                         p->sclass = STATIC;
 326326                         goto done;
 327327                 }
 328328                 if (changed || (scl == STATIC && blevel == slev))
 329329                         goto done; /* identical redeclaration */
 330330                 break;
 331331 
 332332         case USTATIC:
 333333                 if (scl==STATIC || scl==USTATIC)
 334334                         goto done;
 335335                 break;
 336336 
 337337         case TYPEDEF:
 338338                 if (scl == class)
 339339                         goto done;
 340340                 break;
 341341 
 342342         case MOU:
 343343         case MOS:
 344344                 cerror("field6");
 345345 
 346346         case EXTDEF:
 347347                 switch (scl) {
 348348                 case EXTERN:
 349349                         p->sclass = EXTDEF;
 350350                         goto done;
 351351                 case USTATIC:
 352352                         p->sclass = STATIC;
 353353                         goto done;
 354354                 case SNULL:
 355355 #ifdef GCC_COMPAT
 356356                         /*
 357357                          * Handle redeclarations of inlined functions.
 358358                          * This is allowed if the previous declaration is of
 359359                          * type gnu_inline.
 360360                          */
 361361                         if (attr_find(p->sap, GCC_ATYP_GNU_INLINE))
 362362                                 goto done;
 363363 #endif
 364364                         break;
 365365                 }
 366366                 break;
 367367 
 368368         case AUTO:
 369369         case REGISTER:
 370370                 break/* mismatch.. */
 371371         case SNULL:
 372372                 if (fun_inline && ISFTN(type)) {
 373373                         if (scl == EXTERN) {
 374374                                 p->sclass = EXTDEF;
 375375                                 inline_ref(p);
 376376                         }
 377377                         goto done;
 378378                 }
 379379                 break;
 380380         }
 381381 
 382382         mismatch:
 383383 
 384384         /*
 385385          * Only allowed for automatic variables.
 386386          */
 387387         if ((blevel == 2 && slev == 1) || blevel <= slev || class == EXTERN) {
 388388                 uerror("redeclaration of %s", p->sname);
 389389                 return;
 390390         }
 391391         q->n_sp = p = hide(p);
 392392 
 393393         enter/* make a new entry */
 394394 
 395395 #ifdef PCC_DEBUG
 396396         if(ddebug)
 397397                 printf("        new entry made\n");
 398398 #endif
 399399         p->stype = type;
 400400         p->squal = qual;
 401401         p->sclass = (char)class;
 402402         p->slevel = (char)blevel;
 403403         p->soffset = NOOFFSET;
 404404         if (q->n_ap)
 405405                 p->sap = attr_add(q->n_ap, p->sap);
 406406 
 407407         /* copy dimensions */
 408408         p->sdf = q->n_df;
 409409         /* Do not save param info for old-style functions */
 410410         if (ISFTN(type) && oldstyle)
 411411                 p->sdf->dfun = NULL;
 412412 
 413413         if (arrstkp)
 414414                 evalidx(p);
 415415 
 416416         /* allocate offsets */
 417417         if (class&FIELD) {
 418418                 cerror("field2");  /* new entry */
 419419         } else switch (class) {
 420420 
 421421         case REGISTER:
 422422                 if (astr != NULL)
 423423                         werror("no register assignment (yet)");
 424424                 p->sclass = class = AUTO;
 425425                 /* FALLTHROUGH */
 426426         case AUTO:
 427427                 if (isdyn(p)) {
 428428                         p->sflags |= SDYNARRAY;
 429429                         dynalloc(p, &autooff);
 430430                 } else
 431431                         oalloc(p, &autooff);
 432432                 break;
 433433 
 434434         case PARAM:
 435435                 if (q->n_type != FARG)
 436436                         oalloc(p, &argoff);
 437437                 break;
 438438                 
 439439         case STATIC:
 440440         case EXTDEF:
 441441         case EXTERN:
 442442                 p->soffset = getlab();
 443443                 /* FALLTHROUGH */
 444444         case USTATIC:
 445445                 if (astr)
 446446                         p->soname = astr;
 447447                 break;
 448448 
 449449         case MOU:
 450450         case MOS:
 451451                 cerror("field7");
 452452         case SNULL:
 453453 #ifdef notdef
 454454                 if (fun_inline) {
 455455                         p->slevel = 1;
 456456                         p->soffset = getlab();
 457457                 }
 458458 #endif
 459459                 break;
 460460         }
 461461 
 462462 #ifdef STABS
 463463         if (gflag && p->stype != FARG)
 464464                 stabs_newsym(p);
 465465 #endif
 466466 
 467467 done:
 468468         fixdef(p);      /* Leave last word to target */
 469469 #ifndef HAVE_WEAKREF
 470470         {
 471471                 struct attr *at;
 472472 
 473473                 /* Refer renamed function */
 474474                 if ((at = attr_find(p->sap, GCC_ATYP_WEAKREF)))
 475475                         p->soname = at->sarg(0);
 476476         }
 477477 #endif
 478478 #ifdef PCC_DEBUG
 479479         if (ddebug) {
 480480                 printf( "       sdf, offset: %p, %d\n\t",
 481481                     p->sdf, p->soffset);
 482482 #ifdef GCC_COMPAT
 483483                 dump_attr(p->sap);
 484484 #endif
 485485         }
 486486 #endif
 487487 }
 488488 
 489489 void
 490490 ssave(struct symtab *sym)
 491491 {
 492492         struct params *p;
 493493 
 494494         p = tmpalloc(sizeof(struct params));
 495495         p->prev = lparam;
 496496         p->sym = sym;
 497497         lparam = p;
 498498 }
 499499 
 500500 /*
 501501  * end of function
 502502  */
 503503 void
 504504 ftnend(void)
 505505 {
 506506 #ifdef GCC_COMPAT
 507507         struct attr *gc, *gd;
 508508 #endif
 509509         extern int *mkclabs(void);
 510510         extern NODE *cftnod;
 511511         extern struct savbc *savbc;
 512512         extern struct swdef *swpole;
 513513         extern int tvaloff;
 514514         char *c;
 515515 
 516516         if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
 517517                 plabel(retlab);
 518518                 if (cftnod)
 519519                         ecomp(buildtree(FORCE, cftnod, NIL));
 520520                 efcode(); /* struct return handled here */
 521521                 if ((c = cftnsp->soname) == NULL)
 522522                         c = addname(exname(cftnsp->sname));
 523523                 SETOFF(maxautooff, ALCHAR);
 524524                 send_passt(IP_EPILOG, maxautooff/SZCHAR, c,
 525525                     cftnsp->stype, cftnsp->sclass == EXTDEF,
 526526                     retlab, tvaloff, mkclabs());
 527527         }
 528528 
 529529         cftnod = NIL;
 530530         tcheck();
 531531         brklab = contlab = retlab = NOLAB;
 532532         flostat = 0;
 533533         if (nerrors == 0) {
 534534                 if (savbc != NULL)
 535535                         cerror("bcsave error");
 536536                 if (lparam != NULL)
 537537                         cerror("parameter reset error");
 538538                 if (swpole != NULL)
 539539                         cerror("switch error");
 540540         }
 541541 #ifdef GCC_COMPAT
 542542         if (cftnsp) {
 543543                 gc = attr_find(cftnsp->sap, GCC_ATYP_CONSTRUCTOR);
 544544                 gd = attr_find(cftnsp->sap, GCC_ATYP_DESTRUCTOR);
 545545                 if (gc || gd) {
 546546                         struct symtab sts = *cftnsp;
 547547                         NODE *p;
 548548                         sts.stype = INCREF(sts.stype);
 549549                         p = nametree(&sts);
 550550                         p->n_op = ICON;
 551551                         if (gc) {
 552552                                 locctr(CTORS, NULL);
 553553                                 inval(0, SZPOINT(0), p);
 554554                         }
 555555                         if (gd) {
 556556                                 locctr(DTORS, NULL);
 557557                                 inval(0, SZPOINT(0), p);
 558558                         }
 559559                         tfree(p);
 560560                 }
 561561         }
 562562 #endif
 563563         savbc = NULL;
 564564         lparam = NULL;
 565565         cftnsp = NULL;
 566566         maxautooff = autooff = AUTOINIT;
 567567         reached = 1;
 568568 
 569569         if (isinlining)
 570570                 inline_end();
 571571         inline_prtout();
 572572 
 573573         tmpfree(); /* Release memory resources */
 574574 }
 575575 
 576576 static struct symtab nulsym = {
 577577         NULL, 0, 0, 0, 0, "null", "null", INT, 0, NULL, NULL
 578578 };
 579579 
 580580 void
 581581 dclargs(void)
 582582 {
 583583         union dimfun *df;
 584584         union arglist *al, *al2, *alb;
 585585         struct params *a;
 586586         struct symtab *p, **parr = NULL; /* XXX gcc */
 587587         int i;
 588588 
 589589         /*
 590590          * Deal with fun(void) properly.
 591591          */
 592592         if (nparams == 1 && lparam->sym && lparam->sym->stype == VOID)
 593593                 goto done;
 594594 
 595595         /*
 596596          * Generate a list for bfcode().
 597597          * Parameters were pushed in reverse order.
 598598          */
 599599         if (nparams != 0)
 600600                 parr = tmpalloc(sizeof(struct symtab *) * nparams);
 601601 
 602602         if (nparams)
 603603             for (a = lparam, i = 0; a != NULL; a = a->prev) {
 604604                 p = a->sym;
 605605                 parr[i++] = p;
 606606                 if (p == NULL) {
 607607                         uerror("parameter %d name missing", i);
 608608                         p = &nulsym; /* empty symtab */
 609609                 }
 610610                 if (p->stype == FARG)
 611611                         p->stype = INT;
 612612                 if (ISARY(p->stype)) {
 613613                         p->stype += (PTR-ARY);
 614614                         p->sdf++;
 615615                 } else if (ISFTN(p->stype)) {
 616616                         werror("function declared as argument");
 617617                         p->stype = INCREF(p->stype);
 618618                 }
 619619 #ifdef STABS
 620620                 if (gflag)
 621621                         stabs_newsym(p);
 622622 #endif
 623623         }
 624624         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
 625625                 /*
 626626                  * Check against prototype of oldstyle function.
 627627                  */
 628628                 alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
 629629                 for (i = 0; i < nparams; i++) {
 630630                         TWORD type = parr[i]->stype;
 631631                         (al2++)->type = type;
 632632                         if (ISSOU(BTYPE(type)))
 633633                                 (al2++)->sap = parr[i]->sap;
 634634                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
 635635                                 type = DECREF(type);
 636636                         if (type > BTMASK)
 637637                                 (al2++)->df = parr[i]->sdf;
 638638                 }
 639639                 al2->type = TNULL;
 640640                 intcompare = 1;
 641641                 if (chkftn(al, alb))
 642642                         uerror("function doesn't match prototype");
 643643                 intcompare = 0;
 644644 
 645645         }
 646646 
 647647         if (oldstyle && nparams) {
 648648                 /* Must recalculate offset for oldstyle args here */
 649649                 argoff = ARGINIT;
 650650                 for (i = 0; i < nparams; i++) {
 651651                         parr[i]->soffset = NOOFFSET;
 652652                         oalloc(parr[i], &argoff);
 653653                 }
 654654         }
 655655 
 656656 done:   autooff = AUTOINIT;
 657657 
 658658         plabel(prolab); /* after prolog, used in optimization */
 659659         retlab = getlab();
 660660         bfcode(parr, nparams);
 661661         if (fun_inline && (xinline
 662662 #ifdef GCC_COMPAT
 663663  || attr_find(cftnsp->sap, GCC_ATYP_ALW_INL)
 664664 #endif
 665665                 ))
 666666                 inline_args(parr, nparams);
 667667         plabel(getlab()); /* used when spilling */
 668668         if (parlink)
 669669                 ecomp(parlink);
 670670         parlink = NIL;
 671671         lparam = NULL;
 672672         nparams = 0;
 673673         symclear(1);    /* In case of function pointer args */
 674674 }
 675675 
 676676 /*
 677677  * basic attributes for structs and enums
 678678  */
 679679 static struct attr *
 680680 seattr(void)
 681681 {
 682682         return attr_add(attr_new(ATTR_ALIGNED, 4), attr_new(ATTR_STRUCT, 2));
 683683 }
 684684 
 685685 /*
 686686  * Struct/union/enum symtab construction.
 687687  */
 688688 static void
 689689 defstr(struct symtab *sp, int class)
 690690 {
 691691         sp->sclass = (char)class;
 692692         if (class == STNAME)
 693693                 sp->stype = STRTY;
 694694         else if (class == UNAME)
 695695                 sp->stype = UNIONTY;
 696696         else if (class == ENAME)
 697697                 sp->stype = ENUMTY;
 698698 }
 699699 
 700700 /*
 701701  * Declare a struct/union/enum tag.
 702702  * If not found, create a new tag with UNDEF type.
 703703  */
 704704 static struct symtab *
 705705 deftag(char *name, int class)
 706706 {
 707707         struct symtab *sp;
 708708 
 709709         if ((sp = lookup(name, STAGNAME))->sap == NULL) {
 710710                 /* New tag */
 711711                 defstr(sp, class);
 712712         } else if (sp->sclass != class)
 713713                 uerror("tag %s redeclared", name);
 714714         return sp;
 715715 }
 716716 
 717717 /*
 718718  * reference to a structure or union, with no definition
 719719  */
 720720 NODE *
 721721 rstruct(char *tag, int soru)
 722722 {
 723723         struct symtab *sp;
 724724 
 725725         sp = deftag(tag, soru);
 726726         if (sp->sap == NULL)
 727727                 sp->sap = seattr();
 728728         return mkty(sp->stype, 0, sp->sap);
 729729 }
 730730 
 731731 static int enumlow, enumhigh;
 732732 int enummer;
 733733 
 734734 /*
 735735  * Declare a member of enum.
 736736  */
 737737 void
 738738 moedef(char *name)
 739739 {
 740740         struct symtab *sp;
 741741 
 742742         sp = lookup(name, SNORMAL);
 743743         if (sp->stype == UNDEF || (sp->slevel < blevel)) {
 744744                 if (sp->stype != UNDEF)
 745745                         sp = hide(sp);
 746746                 sp->stype = INT; /* always */
 747747                 sp->sclass = MOE;
 748748                 sp->soffset = enummer;
 749749         } else
 750750                 uerror("%s redeclared", name);
 751751         if (enummer < enumlow)
 752752                 enumlow = enummer;
 753753         if (enummer > enumhigh)
 754754                 enumhigh = enummer;
 755755         enummer++;
 756756 }
 757757 
 758758 /*
 759759  * Declare an enum tag.  Complain if already defined.
 760760  */
 761761 struct symtab *
 762762 enumhd(char *name)
 763763 {
 764764         struct attr *ap;
 765765         struct symtab *sp;
 766766 
 767767         enummer = enumlow = enumhigh = 0;
 768768         if (name == NULL)
 769769                 return NULL;
 770770 
 771771         sp = deftag(name, ENAME);
 772772         if (sp->stype != ENUMTY) {
 773773                 if (sp->slevel == blevel)
 774774                         uerror("%s redeclared", name);
 775775                 sp = hide(sp);
 776776                 defstr(sp, ENAME);
 777777         }
 778778         if (sp->sap == NULL)
 779779                 ap = sp->sap = attr_new(ATTR_STRUCT, 4);
 780780         else
 781781                 ap = attr_find(sp->sap, ATTR_STRUCT);
 782782         ap->amlist = sp;
 783783         return sp;
 784784 }
 785785 
 786786 /*
 787787  * finish declaration of an enum
 788788  */
 789789 NODE *
 790790 enumdcl(struct symtab *sp)
 791791 {
 792792         NODE *p;
 793793         TWORD t;
 794794 
 795795 #ifdef ENUMSIZE
 796796         t = ENUMSIZE(enumhigh, enumlow);
 797797 #else
 798798         t = ctype(enumlow < 0 ? INT : UNSIGNED);
 799799 #ifdef notdef
 800800         if (enumhigh <= MAX_CHAR && enumlow >= MIN_CHAR)
 801801                 t = ctype(CHAR);
 802802         else if (enumhigh <= MAX_SHORT && enumlow >= MIN_SHORT)
 803803                 t = ctype(SHORT);
 804804         else
 805805                 t = ctype(INT);
 806806 #endif
 807807 #endif
 808808         
 809809         if (sp)
 810810                 sp->stype = t;
 811811         p = mkty(t, 0, 0);
 812812         p->n_sp = sp;
 813813         return p;
 814814 }
 815815 
 816816 /*
 817817  * Handle reference to an enum
 818818  */
 819819 NODE *
 820820 enumref(char *name)
 821821 {
 822822         struct symtab *sp;
 823823         NODE *p;
 824824 
 825825         sp = lookup(name, STAGNAME);
 826826 
 827827 #ifdef notdef
 828828         /*
 829829          * 6.7.2.3 Clause 2:
 830830          * "A type specifier of the form 'enum identifier' without an
 831831          *  enumerator list shall only appear after the type it specifies
 832832          *  is complete."
 833833          */
 834834         if (sp->sclass != ENAME)
 835835                 uerror("enum %s undeclared", name);
 836836 #endif
 837837         if (sp->sclass == SNULL) {
 838838                 /* declare existence of enum */
 839839                 sp = enumhd(name);
 840840                 sp->stype = ENUMTY;
 841841         }
 842842 
 843843         p = mkty(sp->stype, 0, sp->sap);
 844844         p->n_sp = sp;
 845845         return p;
 846846 }
 847847 
 848848 /*
 849849  * begining of structure or union declaration
 850850  * It's an error if this routine is called twice with the same struct.
 851851  */
 852852 struct rstack *
 853853 bstruct(char *name, int soru, NODE *gp)
 854854 {
 855855         struct rstack *r;
 856856         struct symtab *sp;
 857857         struct attr *ap, *gap;
 858858 
 859859 #ifdef GCC_COMPAT
 860860         gap = gp ? gcc_attr_parse(gp) : NULL;
 861861 #else
 862862         gap = NULL;
 863863 #endif
 864864 
 865865         if (name != NULL) {
 866866                 sp = deftag(name, soru);
 867867                 if (sp->sap == NULL)
 868868                         sp->sap = seattr();
 869869                 ap = attr_find(sp->sap, ATTR_ALIGNED);
 870870                 if (ap->iarg(0) != 0) {
 871871                         if (sp->slevel < blevel) {
 872872                                 sp = hide(sp);
 873873                                 defstr(sp, soru);
 874874                                 sp->sap = seattr();
 875875                         } else
 876876                                 uerror("%s redeclared", name);
 877877                 }
 878878                 gap = sp->sap = attr_add(sp->sap, gap);
 879879         } else {
 880880                 gap = attr_add(seattr(), gap);
 881881                 sp = NULL;
 882882         }
 883883 
 884884         r = tmpcalloc(sizeof(struct rstack));
 885885         r->rsou = soru;
 886886         r->rsym = sp;
 887887         r->rb = NULL;
 888888         r->ap = gap;
 889889         r->rnext = rpole;
 890890         rpole = r;
 891891 
 892892         return r;
 893893 }
 894894 
 895895 /*
 896896  * Called after a struct is declared to restore the environment.
 897897  * - If ALSTRUCT is defined, this will be the struct alignment and the
 898898  *   struct size will be a multiple of ALSTRUCT, otherwise it will use
 899899  *   the alignment of the largest struct member.
 900900  */
 901901 NODE *
 902902 dclstruct(struct rstack *r)
 903903 {
 904904         NODE *n;
 905905         struct attr *aps, *apb;
 906906         struct symtab *sp;
 907907         int al, sa, sz;
 908908 
 909909         apb = attr_find(r->ap, ATTR_ALIGNED);
 910910         aps = attr_find(r->ap, ATTR_STRUCT);
 911911         aps->amlist = r->rb;
 912912 
 913913 #ifdef ALSTRUCT
 914914         al = ALSTRUCT;
 915915 #else
 916916         al = ALCHAR;
 917917 #endif
 918918 
 919919         /*
 920920          * extract size and alignment, calculate offsets
 921921          */
 922922         for (sp = r->rb; sp; sp = sp->snext) {
 923923                 sa = talign(sp->stype, sp->sap);
 924924                 if (sp->sclass & FIELD)
 925925                         sz = sp->sclass&FLDSIZ;
 926926                 else
 927927                         sz = (int)tsize(sp->stype, sp->sdf, sp->sap);
 928928                 if (sz > rpole->rstr)
 929929                         rpole->rstr = sz/* for use with unions */
 930930                 /*
 931931                  * set al, the alignment, to the lcm of the alignments
 932932                  * of the members.
 933933                  */
 934934                 SETOFF(al, sa);
 935935         }
 936936 
 937937         SETOFF(rpole->rstr, al);
 938938 
 939939         aps->amsize = rpole->rstr;
 940940         apb->iarg(0) = al;
 941941 
 942942 #ifdef PCC_DEBUG
 943943         if (ddebug) {
 944944                 printf("dclstruct(%s): size=%d, align=%d\n",
 945945                     r->rsym ? r->rsym->sname : "??",
 946946                     aps->amsize, apb->iarg(0));
 947947         }
 948948         if (ddebug>1) {
 949949                 printf("\tsize %d align %d link %p\n",
 950950                     aps->amsize, apb->iarg(0), aps->amlist);
 951951                 for (sp = aps->amlist; sp != NULL; sp = sp->snext) {
 952952                         printf("\tmember %s(%p)\n", sp->sname, sp);
 953953                 }
 954954         }
 955955 #endif
 956956 
 957957 #ifdef STABS
 958958         if (gflag)
 959959                 stabs_struct(r->rsym, r->ap);
 960960 #endif
 961961 
 962962         rpole = r->rnext;
 963963         n = mkty(r->rsou == STNAME ? STRTY : UNIONTY, 0, r->ap);
 964964         n->n_sp = r->rsym;
 965965 
 966966         n->n_qual |= 1; /* definition place XXX used by attributes */
 967967         return n;
 968968 }
 969969 
 970970 /*
 971971  * Add a new member to the current struct or union being declared.
 972972  */
 973973 void
 974974 soumemb(NODE *n, char *name, int class)
 975975 {
 976976         struct symtab *sp, *lsp;
 977977         int incomp, tsz, al;
 978978         TWORD t;
 979979  
 980980         if (rpole == NULL)
 981981                 cerror("soumemb");
 982982  
 983983         /* check if tag name exists */
 984984         lsp = NULL;
 985985         for (sp = rpole->rb; sp != NULL; lsp = sp, sp = sp->snext)
 986986                 if (*name != '*' && sp->sname == name)
 987987                         uerror("redeclaration of %s", name);
 988988 
 989989         sp = getsymtab(name, SMOSNAME);
 990990         if (rpole->rb == NULL)
 991991                 rpole->rb = sp;
 992992         else
 993993                 lsp->snext = sp;
 994994 
 995995         n->n_sp = sp;
 996996         sp->stype = n->n_type;
 997997         sp->squal = n->n_qual;
 998998         sp->slevel = blevel;
 999999         sp->sap = n->n_ap;
 10001000         sp->sdf = n->n_df;
 10011001 
 10021002         if (class & FIELD) {
 10031003                 sp->sclass = (char)class;
 10041004                 falloc(sp, class&FLDSIZ, NIL);
 10051005         } else if (rpole->rsou == STNAME || rpole->rsou == UNAME) {
 10061006                 sp->sclass = rpole->rsou == STNAME ? MOS : MOU;
 10071007                 if (sp->sclass == MOU)
 10081008                         rpole->rstr = 0;
 10091009                 al = talign(sp->stype, sp->sap);
 10101010                 tsz = (int)tsize(sp->stype, sp->sdf, sp->sap);
 10111011                 sp->soffset = upoff(tsz, al, &rpole->rstr);
 10121012         }
 10131013 
 10141014         /*
 10151015          * 6.7.2.1 clause 16:
 10161016          * "...the last member of a structure with more than one
 10171017          *  named member may have incomplete array type;"
 10181018          */
 10191019         if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
 10201020                 incomp = 1;
 10211021         else
 10221022                 incomp = 0;
 10231023         if ((rpole->flags & LASTELM) || (rpole->rb == sp && incomp == 1))
 10241024                 uerror("incomplete array in struct");
 10251025         if (incomp == 1)
 10261026                 rpole->flags |= LASTELM;
 10271027 
 10281028         /*
 10291029          * 6.7.2.1 clause 2:
 10301030          * "...such a structure shall not be a member of a structure
 10311031          *  or an element of an array."
 10321032          */
 10331033         t = sp->stype;
 10341034         if (rpole->rsou != STNAME || BTYPE(t) != STRTY)
 10351035                 return; /* not for unions */
 10361036         while (ISARY(t))
 10371037                 t = DECREF(t);
 10381038         if (ISPTR(t))
 10391039                 return;
 10401040 
 10411041         if ((lsp = strmemb(sp->sap)) != NULL) {
 10421042                 for (; lsp->snext; lsp = lsp->snext)
 10431043                         ;
 10441044                 if (ISARY(lsp->stype) && lsp->snext &&
 10451045                     lsp->sdf->ddim == NOOFFSET)
 10461046                         uerror("incomplete struct in struct");
 10471047         }
 10481048 }
 10491049 
 10501050 /*
 10511051  * error printing routine in parser
 10521052  */
 10531053 void
 10541054 yyerror(char *s)
 10551055 {
 10561056         uerror(s);
 10571057 }
 10581058 
 10591059 void yyaccpt(void);
 10601060 void
 10611061 yyaccpt(void)
 10621062 {
 10631063         ftnend();
 10641064 }
 10651065 
 10661066 /*
 10671067  * p is top of type list given to tymerge later.
 10681068  * Find correct CALL node and declare parameters from there.
 10691069  */
 10701070 void
 10711071 ftnarg(NODE *p)
 10721072 {
 10731073         NODE *q;
 10741074 
 10751075 #ifdef PCC_DEBUG
 10761076         if (ddebug > 2)
 10771077                 printf("ftnarg(%p)\n", p);
 10781078 #endif
 10791079         /*
 10801080          * Push argument symtab entries onto param stack in reverse order,
 10811081          * due to the nature of the stack it will be reclaimed correct.
 10821082          */
 10831083         for (; p->n_op != NAME; p = p->n_left) {
 10841084                 if (p->n_op == UCALL && p->n_left->n_op == NAME)
 10851085                         return/* Nothing to enter */
 10861086                 if (p->n_op == CALL && p->n_left->n_op == NAME)
 10871087                         break;
 10881088         }
 10891089 
 10901090         p = p->n_right;
 10911091         while (p->n_op == CM) {
 10921092                 q = p->n_right;
 10931093                 if (q->n_op != ELLIPSIS) {
 10941094                         ssave(q->n_sp);
 10951095                         nparams++;
 10961096 #ifdef PCC_DEBUG
 10971097                         if (ddebug > 2)
 10981098                                 printf("        saving sym %s (%p) from (%p)\n",
 10991099                                     q->n_sp->sname, q->n_sp, q);
 11001100 #endif
 11011101                 }
 11021102                 p = p->n_left;
 11031103         }
 11041104         ssave(p->n_sp);
 11051105         if (p->n_type != VOID)
 11061106                 nparams++;
 11071107 
 11081108 #ifdef PCC_DEBUG
 11091109         if (ddebug > 2)
 11101110                 printf("        saving sym %s (%p) from (%p)\n",
 11111111                     nparams ? p->n_sp->sname : "<noname>", p->n_sp, p);
 11121112 #endif
 11131113 }
 11141114 
 11151115 /*
 11161116  * compute the alignment of an object with type ty, sizeoff index s
 11171117  */
 11181118 int
 11191119 talign(unsigned int ty, struct attr *apl)
 11201120 {
 11211121         struct attr *al;
 11221122         int a;
 11231123 
 11241124         for (; ty > BTMASK; ty = DECREF(ty)) {
 11251125                 switch (ty & TMASK) {
 11261126                 case PTR:
 11271127                         return(ALPOINT);
 11281128                 case ARY:
 11291129                         continue;
 11301130                 case FTN:
 11311131                         cerror("compiler takes alignment of function");
 11321132                 }
 11331133         }
 11341134 
 11351135         /* check for alignment attribute */
 11361136         if ((al = attr_find(apl, ATTR_ALIGNED))) {
 11371137                 if ((a = al->iarg(0)) == 0) {
 11381138                         uerror("no alignment");
 11391139                         a = ALINT;
 11401140                 }
 11411141                 return a;
 11421142         }
 11431143 
 11441144 #ifndef NO_COMPLEX
 11451145         if (ISITY(ty))
 11461146                 ty -= (FIMAG-FLOAT);
 11471147 #endif
 11481148         ty = BTYPE(ty);
 11491149         if (ty >= CHAR && ty <= ULONGLONG && ISUNSIGNED(ty))
 11501150                 ty = DEUNSIGN(ty);
 11511151 
 11521152         switch (ty) {
 11531153         case BOOL: a = ALBOOL; break;
 11541154         case CHAR: a = ALCHAR; break;
 11551155         case SHORT: a = ALSHORT; break;
 11561156         case INT: a = ALINT; break;
 11571157         case LONG: a = ALLONG; break;
 11581158         case LONGLONG: a = ALLONGLONG; break;
 11591159         case FLOAT: a = ALFLOAT; break;
 11601160         case DOUBLE: a = ALDOUBLE; break;
 11611161         case LDOUBLE: a = ALLDOUBLE; break;
 11621162         default:
 11631163                 uerror("no alignment");
 11641164                 a = ALINT;
 11651165         }
 11661166         return a;
 11671167 }
 11681168 
 11691169 short sztable[] = { 0, SZBOOL, SZCHAR, SZCHAR, SZSHORT, SZSHORT, SZINT, SZINT,
 11701170         SZLONG, SZLONG, SZLONGLONG, SZLONGLONG, SZFLOAT, SZDOUBLE, SZLDOUBLE };
 11711171 
 11721172 /* compute the size associated with type ty,
 11731173  *  dimoff d, and sizoff s */
 11741174 /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
 11751175 OFFSZ
 11761176 tsize(TWORD ty, union dimfun *d, struct attr *apl)
 11771177 {
 11781178         struct attr *ap, *ap2;
 11791179         OFFSZ mult, sz;
 11801180 
 11811181         mult = 1;
 11821182 
 11831183         for (; ty > BTMASK; ty = DECREF(ty)) {
 11841184                 switch (ty & TMASK) {
 11851185 
 11861186                 case FTN:
 11871187                         uerror( "cannot take size of function");
 11881188                 case PTR:
 11891189                         return( SZPOINT(ty) * mult );
 11901190                 case ARY:
 11911191                         if (d->ddim == NOOFFSET)
 11921192                                 return 0;
 11931193                         if (d->ddim < 0)
 11941194                                 cerror("tsize: dynarray");
 11951195                         mult *= d->ddim;
 11961196                         d++;
 11971197                 }
 11981198         }
 11991199 
 12001200 #ifndef NO_COMPLEX
 12011201         if (ISITY(ty))
 12021202                 ty -= (FIMAG-FLOAT);
 12031203 #endif
 12041204 
 12051205         if (ty == VOID)
 12061206                 ty = CHAR;
 12071207         if (ty <= LDOUBLE)
 12081208                 sz = sztable[ty];
 12091209         else if (ISSOU(ty)) {
 12101210                 if ((ap = strattr(apl)) == NULL ||
 12111211                     (ap2 = attr_find(apl, ATTR_ALIGNED)) == NULL ||
 12121212                     (ap2->iarg(0) == 0)) {
 12131213                         uerror("unknown structure/union/enum");
 12141214                         sz = SZINT;
 12151215                 } else
 12161216                         sz = ap->amsize;
 12171217         } else {
 12181218                 uerror("unknown type");
 12191219                 sz = SZINT;
 12201220         }
 12211221 
 12221222         return((unsigned int)sz * mult);
 12231223 }
 12241224 
 12251225 /*
 12261226  * Save string (and print it out).  If wide then wide string.
 12271227  */
 12281228 NODE *
 12291229 strend(int wide, char *str)
 12301230 {
 12311231         struct symtab *sp;
 12321232         NODE *p;
 12331233 
 12341234         /* If an identical string is already emitted, just forget this one */
 12351235         if (wide) {
 12361236                 /* Do not save wide strings, at least not now */
 12371237                 sp = getsymtab(str, SSTRING|STEMP);
 12381238         } else {
 12391239                 str = addstring(str);   /* enter string in string table */
<>1240 -                sp = lookup(str, SSTRING);      /* check for existance */
  1240+                sp = lookup(str, SSTRING);      /* check for existence */
<_12411241         }
 12421242 
 12431243         if (sp->soffset == 0) { /* No string */
 12441244                 char *wr;
 12451245                 int i;
 12461246 
 12471247                 sp->sclass = STATIC;
 12481248                 sp->slevel = 1;
 12491249                 sp->soffset = getlab();
 12501250                 sp->squal = (CON >> TSHIFT);
 12511251                 sp->sdf = permalloc(sizeof(union dimfun));
 12521252                 if (wide) {
 12531253                         sp->stype = WCHAR_TYPE+ARY;
 12541254                 } else {
 12551255                         if (xuchar) {
 12561256                                 sp->stype = UCHAR+ARY;
 12571257                         } else {
 12581258                                 sp->stype = CHAR+ARY;
 12591259                         }
 12601260                 }
 12611261                 if (wide) {
 12621262                         for (wr = sp->sname, i = 1; *wr; i++) u82cp(&wr);
 12631263                 sp->sdf->ddim = i;
 12641264                         inwstring(sp);
 12651265                 } else {
 12661266                         sp->sdf->ddim = strlen(sp->sname)+1;
 12671267                         instring(sp);
 12681268         }
 12691269         }
 12701270 
 12711271         p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
 12721272         p->n_sp = sp;
 12731273         return(clocal(p));
 12741274 }
 12751275 
 12761276 /*
 12771277  * Print out a wide string by calling ninval().
 12781278  */
 12791279 void
 12801280 inwstring(struct symtab *sp)
 12811281 {
 12821282         char *s = sp->sname;
 12831283         NODE *p;
 12841284 
 12851285         locctr(STRNG, sp);
 12861286         defloc(sp);
 12871287         p = xbcon(0, NULL, WCHAR_TYPE);
 12881288         do {
 12891289                 p->n_lval=u82cp(&s);
 12901290                 inval(0, tsize(WCHAR_TYPE, NULL, NULL), p);
 12911291         } while (s[-1] != 0);
 12921292         nfree(p);
 12931293 }
 12941294 
 12951295 #ifndef MYINSTRING
 12961296 /*
 12971297  * Print out a string of characters.
 12981298  * Assume that the assembler understands C-style escape
 12991299  * sequences.
 13001300  * Do not break UTF-8 sequences between lines and ensure
 13011301  * the code path is 8-bit clean.
 13021302  */
 13031303 void
 13041304 instring(struct symtab *sp)
 13051305 {
 13061306         char *s = sp->sname;
 13071307 
 13081308         locctr(STRNG, sp);
 13091309         defloc(sp);
 13101310 
 13111311         char line[70], *t = line;
 13121312         printf("\t.ascii \"");
 13131313         while(s[0] != 0) {
 13141314                 unsigned int c=(unsigned char)*s++;
 13151315                 if(c<' ') t+=sprintf(t,"\\%03o",c);
 13161316                 else if(c=='\\') *t++='\\', *t++='\\';
 13171317                 else if(c=='\"') *t++='\\', *t++='\"';
 13181318                 else if(c=='\'') *t++='\\', *t++='\'';
 13191319                 else {
 13201320                         *t++=c;
 13211321                         int sz=u8len(&s[-1]);
 13221322                         int i;
 13231323                         for(i=1;i<sz;i++) *t++=*s++;
 13241324                 }
 13251325                 if(t>=&line[60]) {
 13261326                         fwrite(line, 1, t-&line[0], stdout);
 13271327                         printf("\"\n\t.ascii \"");
 13281328                         t = line;
 13291329                 }
 13301330         }
 13311331         fwrite(line, 1, t-&line[0], stdout);
 13321332         printf("\\0\"\n");
 13331333 }
 13341334 #endif
 13351335 
 13361336 /*
 13371337  * update the offset pointed to by poff; return the
 13381338  * offset of a value of size `size', alignment `alignment',
 13391339  * given that off is increasing
 13401340  */
 13411341 int
 13421342 upoff(int size, int alignment, int *poff)
 13431343 {
 13441344         int off;
 13451345 
 13461346         off = *poff;
 13471347         SETOFF(off, alignment);
 13481348         if (off < 0)
 13491349                 cerror("structure or stack overgrown"); /* wrapped */
 13501350         *poff = off+size;
 13511351         return (off);
 13521352 }
 13531353 
 13541354 /*
 13551355  * allocate p with offset *poff, and update *poff
 13561356  */
 13571357 int
 13581358 oalloc(struct symtab *p, int *poff )
 13591359 {
 13601360         int al, off, tsz;
 13611361         int noff;
 13621362 
 13631363         /*
 13641364          * Only generate tempnodes if we are optimizing,
 13651365          * and only for integers, floats or pointers,
 13661366          * and not if the type on this level is volatile.
 13671367          */
 13681368         if (xtemps && ((p->sclass == AUTO) || (p->sclass == REGISTER)) &&
 13691369             (p->stype < STRTY || ISPTR(p->stype)) &&
 13701370             !(cqual(p->stype, p->squal) & VOL) && cisreg(p->stype)) {
 13711371                 NODE *tn = tempnode(0, p->stype, p->sdf, p->sap);
 13721372                 p->soffset = regno(tn);
 13731373                 p->sflags |= STNODE;
 13741374                 nfree(tn);
 13751375                 return 0;
 13761376         }
 13771377 
 13781378         al = talign(p->stype, p->sap);
 13791379         noff = off = *poff;
 13801380         tsz = (int)tsize(p->stype, p->sdf, p->sap);
 13811381 #ifdef BACKAUTO
 13821382         if (p->sclass == AUTO) {
 13831383                 noff = off + tsz;
 13841384                 if (noff < 0)
 13851385                         cerror("stack overflow");
 13861386                 SETOFF(noff, al);
 13871387                 off = -noff;
 13881388         } else
 13891389 #endif
 13901390         if (p->sclass == PARAM && (p->stype == CHAR || p->stype == UCHAR ||
 13911391             p->stype == SHORT || p->stype == USHORT || p->stype == BOOL)) {
 13921392                 off = upoff(SZINT, ALINT, &noff);
 13931393 #if TARGET_ENDIAN == TARGET_BE
 13941394                 off = noff - tsz;
 13951395 #endif
 13961396         } else {
 13971397                 off = upoff(tsz, al, &noff);
 13981398         }
 13991399 
 14001400         if (p->sclass != REGISTER) {
 14011401         /* in case we are allocating stack space for register arguments */
 14021402                 if (p->soffset == NOOFFSET)
 14031403                         p->soffset = off;
 14041404                 else if(off != p->soffset)
 14051405                         return(1);
 14061406         }
 14071407 
 14081408         *poff = noff;
 14091409         return(0);
 14101410 }
 14111411 
 14121412 /*
 14131413  * Delay emission of code generated in argument headers.
 14141414  */
 14151415 static void
 14161416 edelay(NODE *p)
 14171417 {
 14181418         if (blevel == 1) {
 14191419                 /* Delay until after declarations */
 14201420                 if (parlink == NULL)
 14211421                         parlink = p;
 14221422                 else
 14231423                         parlink = block(COMOP, parlink, p, 0, 0, 0);
 14241424         } else
 14251425                 ecomp(p);
 14261426 }
 14271427 
 14281428 /*
 14291429  * Traverse through the array args, evaluate them and put the
 14301430  * resulting temp numbers in the dim fields.
 14311431  */
 14321432 static void
 14331433 evalidx(struct symtab *sp)
 14341434 {
 14351435         union dimfun *df;
 14361436         NODE *p;
 14371437         TWORD t;
 14381438         int astkp = 0;
 14391439 
 14401440         if (arrstk[0] == NIL)
 14411441                 astkp++; /* for parameter arrays */
 14421442 
 14431443         if (isdyn(sp))
 14441444                 sp->sflags |= SDYNARRAY;
 14451445 
 14461446         df = sp->sdf;
 14471447         for (t = sp->stype; t > BTMASK; t = DECREF(t)) {
 14481448                 if (!ISARY(t))
 14491449                         continue;
 14501450                 if (df->ddim == -1) {
 14511451                         p = tempnode(0, INT, 0, 0);
 14521452                         df->ddim = -regno(p);
 14531453                         edelay(buildtree(ASSIGN, p, arrstk[astkp++]));
 14541454                 }
 14551455                 df++;
 14561456         }
 14571457         arrstkp = 0;
 14581458 }
 14591459 
 14601460 /*
 14611461  * Return 1 if dynamic array, 0 otherwise.
 14621462  */
 14631463 int
 14641464 isdyn(struct symtab *sp)
 14651465 {
 14661466         union dimfun *df = sp->sdf;
 14671467         TWORD t;
 14681468 
 14691469         for (t = sp->stype; t > BTMASK; t = DECREF(t)) {
 14701470                 if (!ISARY(t))
 14711471                         return 0;
 14721472                 if (df->ddim < 0 && df->ddim != NOOFFSET)
 14731473                         return 1;
 14741474                 df++;
 14751475         }
 14761476         return 0;
 14771477 }
 14781478 
 14791479 /*
 14801480  * Allocate space on the stack for dynamic arrays (or at least keep track
 14811481  * of the index).
 14821482  * Strategy is as follows:
 14831483  * - first entry is a pointer to the dynamic datatype.
 14841484  * - if it's a one-dimensional array this will be the only entry used.
 14851485  * - if it's a multi-dimensional array the following (numdim-1) integers
 14861486  *   will contain the sizes to multiply the indexes with.
 14871487  * - code to write the dimension sizes this will be generated here.
 14881488  * - code to allocate space on the stack will be generated here.
 14891489  */
 14901490 static void
 14911491 dynalloc(struct symtab *p, int *poff)
 14921492 {
 14931493         union dimfun *df;
 14941494         NODE *n, *tn, *pol;
 14951495         TWORD t;
 14961496 
 14971497         /*
 14981498          * The pointer to the array is not necessarily stored in a
 14991499          * TEMP node, but if it is, its number is in the soffset field;
 15001500          */
 15011501         t = p->stype;
 15021502         p->sflags |= STNODE;
 15031503         p->stype = INCREF(p->stype); /* Make this an indirect pointer */
 15041504         tn = tempnode(0, p->stype, p->sdf, p->sap);
 15051505         p->soffset = regno(tn);
 15061506 
 15071507         df = p->sdf;
 15081508 
 15091509         pol = bcon(1);
 15101510         for (; t > BTMASK; t = DECREF(t)) {
 15111511                 if (!ISARY(t))
 15121512                         break;
 15131513                 if (df->ddim < 0)
 15141514                         n = tempnode(-df->ddim, INT, 0, 0);
 15151515                 else
 15161516                         n = bcon(df->ddim);
 15171517 
 15181518                 pol = buildtree(MUL, pol, n);
 15191519                 df++;
 15201520         }
 15211521         /* Create stack gap */
 15221522         spalloc(tn, pol, tsize(t, 0, p->sap));
 15231523 }
 15241524 
 15251525 /*
 15261526  * allocate a field of width w
 15271527  * new is 0 if new entry, 1 if redefinition, -1 if alignment
 15281528  */
 15291529 int
 15301530 falloc(struct symtab *p, int w, NODE *pty)
 15311531 {
 15321532         TWORD otype, type;
 15331533         int al,sz;
 15341534 
 15351535         otype = type = p ? p->stype : pty->n_type;
 15361536 
 15371537         if (type == BOOL)
 15381538                 type = BOOL_TYPE;
 15391539         if (!ISINTEGER(type)) {
 15401540                 uerror("illegal field type");
 15411541                 type = INT;
 15421542         }
 15431543 
 15441544         al = talign(type, NULL);
 15451545         sz = tsize(type, NULL, NULL);
 15461546 
 15471547         if (w > sz) {
 15481548                 uerror("field too big");
 15491549                 w = sz;
 15501550         }
 15511551 
 15521552         if (w == 0) { /* align only */
 15531553                 SETOFF(rpole->rstr, al);
 15541554                 if (p != NULL)
 15551555                         uerror("zero size field");
 15561556                 return(0);
 15571557         }
 15581558 
 15591559         if (rpole->rstr%al + w > sz)
 15601560                 SETOFF(rpole->rstr, al);
 15611561         if (p == NULL) {
 15621562                 rpole->rstr += w/* we know it will fit */
 15631563                 return(0);
 15641564         }
 15651565 
 15661566         /* establish the field */
 15671567 
 15681568         p->soffset = rpole->rstr;
 15691569         rpole->rstr += w;
 15701570         p->stype = otype;
 15711571         fldty(p);
 15721572         return(0);
 15731573 }
 15741574 
 15751575 /*
 15761576  * Check if this symbol should be a common or must be handled in data seg.
 15771577  */
 15781578 static void
 15791579 commchk(struct symtab *sp)
 15801580 {
 15811581         if ((sp->sflags & STLS)
 15821582 #ifdef GCC_COMPAT
 15831583                 || attr_find(sp->sap, GCC_ATYP_SECTION)
 15841584 #endif
 15851585             ) {
 15861586                 /* TLS handled in data segment */
 15871587                 if (sp->sclass == EXTERN)
 15881588                         sp->sclass = EXTDEF;
 15891589                 beginit(sp);
 15901590                 endinit(1);
 15911591         } else {
 15921592                 symdirec(sp);
 15931593                 defzero(sp);
 15941594         }
 15951595 }
 15961596 
 15971597 void
 15981598 nidcl(NODE *p, int class)
 15991599 {
 16001600         nidcl2(p, class, 0);
 16011601 }
 16021602 
 16031603 /*
 16041604  * handle unitialized declarations assumed to be not functions:
 16051605  * int a;
 16061606  * extern int a;
 16071607  * static int a;
 16081608  */
 16091609 void
 16101610 nidcl2(NODE *p, int class, char *astr)
 16111611 {
 16121612         struct symtab *sp;
 16131613         int commflag = 0;
 16141614 
 16151615         /* compute class */
 16161616         if (class == SNULL) {
 16171617                 if (blevel > 1)
 16181618                         class = AUTO;
 16191619                 else if (blevel != 0 || rpole)
 16201620                         cerror( "nidcl error" );
 16211621                 else /* blevel = 0 */
 16221622                         commflag = 1, class = EXTERN;
 16231623         }
 16241624 
 16251625         defid2(p, class, astr);
 16261626 
 16271627         sp = p->n_sp;
 16281628         /* check if forward decl */
 16291629         if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
 16301630                 return;
 16311631 
 16321632         if (sp->sflags & SASG)
 16331633                 return; /* already initialized */
 16341634 
 16351635         switch (class) {
 16361636         case EXTDEF:
 16371637                 /* simulate initialization by 0 */
 16381638                 simpleinit(p->n_sp, bcon(0));
 16391639                 break;
 16401640         case EXTERN:
 16411641                 if (commflag)
 16421642                         lcommadd(p->n_sp);
 16431643                 else
 16441644                         extdec(p->n_sp);
 16451645                 break;
 16461646         case STATIC:
 16471647                 if (blevel == 0)
 16481648                         lcommadd(p->n_sp);
 16491649                 else
 16501650                         commchk(p->n_sp);
 16511651                 break;
 16521652         }
 16531653 }
 16541654 
 16551655 struct lcd {
 16561656         SLIST_ENTRY(lcd) next;
 16571657         struct symtab *sp;
 16581658 };
 16591659 
 16601660 static SLIST_HEAD(, lcd) lhead = { NULL, &lhead.q_forw};
 16611661 
 16621662 /*
 16631663  * Add a local common statement to the printout list.
 16641664  */
 16651665 void
 16661666 lcommadd(struct symtab *sp)
 16671667 {
 16681668         struct lcd *lc, *lcp;
 16691669 
 16701670         lcp = NULL;
 16711671         SLIST_FOREACH(lc, &lhead, next) {
 16721672                 if (lc->sp == sp)
 16731673                         return; /* already exists */
 16741674                 if (lc->sp == NULL && lcp == NULL)
 16751675                         lcp = lc;
 16761676         }
 16771677         if (lcp == NULL) {
 16781678                 lc = permalloc(sizeof(struct lcd));
 16791679                 lc->sp = sp;
 16801680                 SLIST_INSERT_LAST(&lhead, lc, next);
 16811681         } else
 16821682                 lcp->sp = sp;
 16831683 }
 16841684 
 16851685 /*
 16861686  * Delete a local common statement.
 16871687  */
 16881688 void
 16891689 lcommdel(struct symtab *sp)
 16901690 {
 16911691         struct lcd *lc;
 16921692 
 16931693         SLIST_FOREACH(lc, &lhead, next) {
 16941694                 if (lc->sp == sp) {
 16951695                         lc->sp = NULL;
 16961696                         return;
 16971697                 }
 16981698         }
 16991699 }
 17001700 
 17011701 /*
 17021702  * Print out the remaining common statements.
 17031703  */
 17041704 void
 17051705 lcommprint(void)
 17061706 {
 17071707         struct lcd *lc;
 17081708 
 17091709         SLIST_FOREACH(lc, &lhead, next) {
 17101710                 if (lc->sp != NULL)
 17111711                         commchk(lc->sp);
 17121712         }
 17131713 }
 17141714 
 17151715 /*
 17161716  * Merge given types to a single node.
 17171717  * Any type can end up here.
 17181718  * p is the old node, q is the old (if any).
 17191719  * CLASS is AUTO, EXTERN, REGISTER, STATIC or TYPEDEF.
 17201720  * QUALIFIER is VOL or CON
 17211721  * TYPE is CHAR, SHORT, INT, LONG, SIGNED, UNSIGNED, VOID, BOOL, FLOAT,
 17221722  *      DOUBLE, STRTY, UNIONTY.
 17231723  */
 17241724 struct typctx {
 17251725         int class, qual, sig, uns, cmplx, imag, err;
 17261726         TWORD type;
 17271727         NODE *saved;
 17281728         struct attr *pre, *post;
 17291729 };
 17301730 
 17311731 static void
 17321732 typwalk(NODE *p, void *arg)
 17331733 {
 17341734         struct typctx *tc = arg;
 17351735 
 17361736 #define cmop(x,y) block(CM, x, y, INT, 0, 0)
 17371737         switch (p->n_op) {
 17381738         case ATTRIB:
 17391739 #ifdef GCC_COMPAT
 17401740                 if (tc->saved && (tc->saved->n_qual & 1)) {
 17411741                         tc->post = attr_add(tc->post,gcc_attr_parse(p->n_left));
 17421742                 } else {
 17431743                         tc->pre = attr_add(tc->pre, gcc_attr_parse(p->n_left));
 17441744                 }
 17451745                 p->n_left = bcon(0); /* For tfree() */
 17461746 #else
 17471747                 uerror("gcc type attribute used");
 17481748 #endif
 17491749                 break;
 17501750         case CLASS:
 17511751                 if (p->n_type == 0)
 17521752                         break;  /* inline hack */
 17531753                 if (tc->class)
 17541754                         tc->err = 1; /* max 1 class */
 17551755                 tc->class = p->n_type;
 17561756                 break;
 17571757 
 17581758         case QUALIFIER:
 17591759                 if (p->n_qual == 0 && tc->saved && !ISPTR(tc->saved->n_type))
 17601760                         uerror("invalid use of 'restrict'");
 17611761                 tc->qual |= p->n_qual >> TSHIFT;
 17621762                 break;
 17631763 
 17641764         case TYPE:
 17651765                 if (p->n_sp != NULL || ISSOU(p->n_type)) {
 17661766                         /* typedef, enum or struct/union */
 17671767                         if (tc->saved || tc->type)
 17681768                                 tc->err = 1;
 17691769 #ifdef GCC_COMPAT
 17701770                         if (ISSOU(p->n_type) && p->n_left) {
 17711771                                 if (tc->post)
 17721772                                         cerror("typwalk");
 17731773                                 tc->post = gcc_attr_parse(p->n_left);
 17741774                         }
 17751775 #endif
 17761776                         tc->saved = ccopy(p);
 17771777                         break;
 17781778                 }
 17791779 
 17801780                 switch (p->n_type) {
 17811781                 case BOOL:
 17821782                 case CHAR:
 17831783                 case FLOAT:
 17841784                 case VOID:
 17851785                         if (tc->type)
 17861786                                 tc->err = 1;
 17871787                         tc->type = p->n_type;
 17881788                         break;
 17891789                 case DOUBLE:
 17901790                         if (tc->type == 0)
 17911791                                 tc->type = DOUBLE;
 17921792                         else if (tc->type == LONG)
 17931793                                 tc->type = LDOUBLE;
 17941794                         else
 17951795                                 tc->err = 1;
 17961796                         break;
 17971797                 case SHORT:
 17981798                         if (tc->type == 0 || tc->type == INT)
 17991799                                 tc->type = SHORT;
 18001800                         else
 18011801                                 tc->err = 1;
 18021802                         break;
 18031803                 case INT:
 18041804                         if (tc->type == SHORT || tc->type == LONG ||
 18051805                             tc->type == LONGLONG)
 18061806                                 break;
 18071807                         else if (tc->type == 0)
 18081808                                 tc->type = INT;
 18091809                         else
 18101810                                 tc->err = 1;
 18111811                         break;
 18121812                 case LONG:
 18131813                         if (tc->type == 0)
 18141814                                 tc->type = LONG;
 18151815                         else if (tc->type == INT)
 18161816                                 break;
 18171817                         else if (tc->type == LONG)
 18181818                                 tc->type = LONGLONG;
 18191819                         else if (tc->type == DOUBLE)
 18201820                                 tc->type = LDOUBLE;
 18211821                         else
 18221822                                 tc->err = 1;
 18231823                         break;
 18241824                 case SIGNED:
 18251825                         if (tc->sig || tc->uns)
 18261826                                 tc->err = 1;
 18271827                         tc->sig = 1;
 18281828                         break;
 18291829                 case UNSIGNED:
 18301830                         if (tc->sig || tc->uns)
 18311831                                 tc->err = 1;
 18321832                         tc->uns = 1;
 18331833                         break;
 18341834                 case COMPLEX:
 18351835                         tc->cmplx = 1;
 18361836                         break;
 18371837                 case IMAG:
 18381838                         tc->imag = 1;
 18391839                         break;
 18401840                 default:
 18411841                         cerror("typwalk");
 18421842                 }
 18431843         }
 18441844 
 18451845 }
 18461846 
 18471847 NODE *
 18481848 typenode(NODE *p)
 18491849 {
 18501850         struct symtab *sp;
 18511851         struct typctx tc;
 18521852         NODE *q;
 18531853         char *c;
 18541854 
 18551855         memset(&tc, 0, sizeof(struct typctx));
 18561856 
 18571857         flist(p, typwalk, &tc);
 18581858         tfree(p);
 18591859 
 18601860         if (tc.err)
 18611861                 goto bad;
 18621862 
 18631863         if (tc.cmplx || tc.imag) {
 18641864                 if (tc.type == 0)
 18651865                         tc.type = DOUBLE;
 18661866                 if ((tc.cmplx && tc.imag) || tc.sig || tc.uns ||
 18671867                     !ISFTY(tc.type))
 18681868                         goto bad;
 18691869                 if (tc.cmplx) {
 18701870                         c = tc.type == DOUBLE ? "0d" :
 18711871                             tc.type == FLOAT ? "0f" : "0l";
 18721872                         sp = lookup(addname(c), 0);
 18731873                         tc.type = STRTY;
 18741874                         tc.saved = mkty(tc.type, sp->sdf, sp->sap);
 18751875                         tc.saved->n_sp = sp;
 18761876                         tc.type = 0;
 18771877                 } else
 18781878                         tc.type += (FIMAG-FLOAT);
 18791879         }
 18801880 
 18811881         if (tc.saved && tc.type)
 18821882                 goto bad;
 18831883         if (tc.sig || tc.uns) {
 18841884                 if (tc.type == 0)
 18851885                         tc.type = tc.sig ? INT : UNSIGNED;
 18861886                 if (tc.type > ULONGLONG)
 18871887                         goto bad;
 18881888                 if (tc.uns)
 18891889                         tc.type = ENUNSIGN(tc.type);
 18901890         }
 18911891 
 18921892         if (xuchar && tc.type == CHAR && tc.sig == 0)
 18931893                 tc.type = UCHAR;
 18941894 
 18951895 #ifdef GCC_COMPAT
 18961896         if (pragma_packed) {
 18971897                 q = bdty(CALL, bdty(NAME, "packed"), bcon(pragma_packed));
 18981898                 tc.post = attr_add(tc.post, gcc_attr_parse(q));
 18991899         }
 19001900         if (pragma_aligned) {
 19011901                 /* Deal with relevant pragmas */
 19021902                 q = bdty(CALL, bdty(NAME, "aligned"), bcon(pragma_aligned));
 19031903                 tc.post = attr_add(tc.post, gcc_attr_parse(q));
 19041904         }
 19051905         pragma_aligned = pragma_packed = 0;
 19061906 #endif
 19071907         if ((q = tc.saved) == NULL) {
 19081908                 TWORD t;
 19091909                 if ((t = BTYPE(tc.type)) > LDOUBLE && t != VOID &&
 19101910                     t != BOOL && !(t >= FIMAG && t <= LIMAG))
 19111911                         cerror("typenode2 t %x", tc.type);
 19121912                 if (t == UNDEF) {
 19131913                         t = INT;
 19141914                         MODTYPE(tc.type, INT);
 19151915                 }
 19161916                 qmkty(tc.type, 0, 0);
 19171917         }
 19181918         q->n_ap = attr_add(q->n_ap, tc.post);
 19191919         q->n_qual = tc.qual;
 19201920         q->n_lval = tc.class;
 19211921 #ifdef GCC_COMPAT
 19221922         if (tc.post) {
 19231923                 /* Can only occur for TYPEDEF, STRUCT or UNION */
 19241924                 if (tc.saved == NULL)
 19251925                         cerror("typenode");
 19261926                 if (tc.saved->n_sp) /* trailer attributes for structs */
 19271927                         tc.saved->n_sp->sap = q->n_ap;
 19281928         }
 19291929         if (tc.pre)
 19301930                 q->n_ap = attr_add(q->n_ap, tc.pre);
 19311931         gcc_tcattrfix(q);
 19321932 #endif
 19331933         return q;
 19341934 
 19351935 bad:    uerror("illegal type combination");
 19361936         return mkty(INT, 0, 0);
 19371937 }
 19381938 
 19391939 struct tylnk {
 19401940         struct tylnk *next;
 19411941         union dimfun df;
 19421942 };
 19431943 
 19441944 /*
 19451945  * Retrieve all CM-separated argument types, sizes and dimensions and
 19461946  * put them in an array.
 19471947  * XXX - can only check first type level, side effects?
 19481948  */
 19491949 static union arglist *
 19501950 arglist(NODE *n)
 19511951 {
 19521952         union arglist *al;
 19531953         NODE *w = n, **ap;
 19541954         int num, cnt, i, j, k;
 19551955         TWORD ty;
 19561956 
 19571957 #ifdef PCC_DEBUG
 19581958         if (pdebug) {
 19591959                 printf("arglist %p\n", n);
 19601960                 fwalk(n, eprint, 0);
 19611961         }
 19621962 #endif
 19631963         /* First: how much to allocate */
 19641964         for (num = cnt = 0, w = n; w->n_op == CM; w = w->n_left) {
 19651965                 cnt++;  /* Number of levels */
 19661966                 num++;  /* At least one per step */
 19671967                 if (w->n_right->n_op == ELLIPSIS)
 19681968                         continue;
 19691969                 ty = w->n_right->n_type;
 19701970                 if (ty == ENUMTY) {
 19711971                         uerror("arg %d enum undeclared", cnt);
 19721972                         ty = w->n_right->n_type = INT;
 19731973                 }
 19741974                 if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
 19751975                         num++;
 19761976                 while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
 19771977                         ty = DECREF(ty);
 19781978                 if (ty > BTMASK)
 19791979                         num++;
 19801980         }
 19811981         cnt++;
 19821982         ty = w->n_type;
 19831983         if (ty == ENUMTY) {
 19841984                 uerror("arg %d enum undeclared", cnt);
 19851985                 ty = w->n_type = INT;
 19861986         }
 19871987         if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
 19881988                 num++;
 19891989         while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
 19901990                 ty = DECREF(ty);
 19911991         if (ty > BTMASK)
 19921992                 num++;
 19931993         num += 2; /* TEND + last arg type */
 19941994 
 19951995         /* Second: Create list to work on */
 19961996         ap = tmpalloc(sizeof(NODE *) * cnt);
 19971997         al = permalloc(sizeof(union arglist) * num);
 19981998         arglistcnt += num;
 19991999 
 20002000         for (w = n, i = 0; w->n_op == CM; w = w->n_left)
 20012001                 ap[i++] = w->n_right;
 20022002         ap[i] = w;
 20032003 
 20042004         /* Third: Create actual arg list */
 20052005         for (k = 0, j = i; j >= 0; j--) {
 20062006                 if (ap[j]->n_op == ELLIPSIS) {
 20072007                         al[k++].type = TELLIPSIS;
 20082008                         ap[j]->n_op = ICON; /* for tfree() */
 20092009                         continue;
 20102010                 }
 20112011                 /* Convert arrays to pointers */
 20122012                 if (ISARY(ap[j]->n_type)) {
 20132013                         ap[j]->n_type += (PTR-ARY);
 20142014                         ap[j]->n_df++;
 20152015                 }
 20162016                 /* Convert (silently) functions to pointers */
 20172017                 if (ISFTN(ap[j]->n_type))
 20182018                         ap[j]->n_type = INCREF(ap[j]->n_type);
 20192019                 ty = ap[j]->n_type;
 20202020 #ifdef GCC_COMPAT
 20212021                 if (ty == UNIONTY &&
 20222022                     attr_find(ap[j]->n_ap, GCC_ATYP_TRANSP_UNION)){
 20232023                         /* transparent unions must have compatible types
 20242024                          * shortcut here: if pointers, set void *,
 20252025                          * otherwise btype.
 20262026                          */
 20272027                         struct symtab *sp = strmemb(ap[j]->n_ap);
 20282028                         ty = ISPTR(sp->stype) ? PTR|VOID : sp->stype;
 20292029                 }
 20302030 #endif
 20312031                 al[k++].type = ty;
 20322032                 if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
 20332033                         al[k++].sap = ap[j]->n_ap;
 20342034                 while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
 20352035                         ty = DECREF(ty);
 20362036                 if (ty > BTMASK)
 20372037                         al[k++].df = ap[j]->n_df;
 20382038         }
 20392039         al[k++].type = TNULL;
 20402040         if (k > num)
 20412041                 cerror("arglist: k%d > num%d", k, num);
 20422042         tfree(n);
 20432043 #ifdef PCC_DEBUG
 20442044         if (pdebug)
 20452045                 alprint(al, 0);
 20462046 #endif
 20472047         return al;
 20482048 }
 20492049 
 20502050 static void
 20512051 tylkadd(union dimfun dim, struct tylnk **tylkp, int *ntdim)
 20522052 {
 20532053         (*tylkp)->next = tmpalloc(sizeof(struct tylnk));
 20542054         *tylkp = (*tylkp)->next;
 20552055         (*tylkp)->next = NULL;
 20562056         (*tylkp)->df = dim;
 20572057         (*ntdim)++;
 20582058 }
 20592059 
 20602060 /*
 20612061  * build a type, and stash away dimensions,
 20622062  * from a parse tree of the declaration
 20632063  * the type is build top down, the dimensions bottom up
 20642064  */
 20652065 static void
 20662066 tyreduce(NODE *p, struct tylnk **tylkp, int *ntdim)
 20672067 {
 20682068         union dimfun dim;
 20692069         NODE *r = NULL;
 20702070         int o;
 20712071         TWORD t, q;
 20722072 
 20732073         o = p->n_op;
 20742074         if (o == NAME) {
 20752075                 p->n_qual = DECQAL(p->n_qual);
 20762076                 return;
 20772077         }
 20782078 
 20792079         t = INCREF(p->n_type);
 20802080         q = p->n_qual;
 20812081         switch (o) {
 20822082         case CALL:
 20832083                 t += (FTN-PTR);
 20842084                 dim.dfun = arglist(p->n_right);
 20852085                 break;
 20862086         case UCALL:
 20872087                 t += (FTN-PTR);
 20882088                 dim.dfun = NULL;
 20892089                 break;
 20902090         case LB:
 20912091                 t += (ARY-PTR);
 20922092                 if (p->n_right->n_op != ICON) {
 20932093                         r = p->n_right;
 20942094                         o = RB;
 20952095                 } else {
 20962096                         dim.ddim = (int)p->n_right->n_lval;
 20972097                         nfree(p->n_right);
 20982098 #ifdef notdef
 20992099         /* XXX - check dimensions at usage time */
 21002100                         if (dim.ddim == NOOFFSET && p->n_left->n_op == LB)
 21012101                                 uerror("null dimension");
 21022102 #endif
 21032103                 }
 21042104                 break;
 21052105         }
 21062106 
 21072107         p->n_left->n_type = t;
 21082108         p->n_left->n_qual = INCQAL(q) | p->n_left->n_qual;
 21092109         tyreduce(p->n_left, tylkp, ntdim);
 21102110 
 21112111         if (o == LB || o == UCALL || o == CALL)
 21122112                 tylkadd(dim, tylkp, ntdim);
 21132113         if (o == RB) {
 21142114                 dim.ddim = -1;
 21152115                 tylkadd(dim, tylkp, ntdim);
 21162116                 arrstk[arrstkp++] = r;
 21172117         }
 21182118 
 21192119         p->n_sp = p->n_left->n_sp;
 21202120         p->n_type = p->n_left->n_type;
 21212121         p->n_qual = p->n_left->n_qual;
 21222122 }
 21232123 
 21242124 /*
 21252125  * merge type typ with identifier idp.
 21262126  * idp is returned as a NAME node with correct types,
 21272127  * typ is untouched since multiple declarations uses it.
 21282128  * typ has type attributes, idp can never carry such attributes
 21292129  * so on return just a pointer to the typ attributes is returned.
 21302130  */
 21312131 NODE *
 21322132 tymerge(NODE *typ, NODE *idp)
 21332133 {
 21342134         TWORD t;
 21352135         NODE *p;
 21362136         union dimfun *j;
 21372137         struct tylnk *base, tylnk, *tylkp;
 21382138         struct attr *bap;
 21392139         int ntdim, i;
 21402140 
 21412141 #ifdef PCC_DEBUG
 21422142         if (ddebug > 2) {
 21432143                 printf("tymerge(%p,%p)\n", typ, idp);
 21442144                 fwalk(typ, eprint, 0);
 21452145                 fwalk(idp, eprint, 0);
 21462146         }
 21472147 #endif
 21482148 
 21492149         if (typ->n_op != TYPE)
 21502150                 cerror("tymerge: arg 1");
 21512151 
 21522152         bap = typ->n_ap;
 21532153 
 21542154         idp->n_type = typ->n_type;
 21552155         idp->n_qual |= typ->n_qual;
 21562156 
 21572157         tylkp = &tylnk;
 21582158         tylkp->next = NULL;
 21592159         ntdim = 0;
 21602160 
 21612161         tyreduce(idp, &tylkp, &ntdim);
 21622162 
 21632163         for (t = typ->n_type, j = typ->n_df; t&TMASK; t = DECREF(t))
 21642164                 if (ISARY(t) || ISFTN(t))
 21652165                         tylkadd(*j++, &tylkp, &ntdim);
 21662166 
 21672167         if (ntdim) {
 21682168                 union dimfun *a = permalloc(sizeof(union dimfun) * ntdim);
 21692169                 dimfuncnt += ntdim;
 21702170                 for (i = 0, base = tylnk.next; base; base = base->next, i++)
 21712171                         a[i] = base->df;
 21722172                 idp->n_df = a;
 21732173         } else
 21742174                 idp->n_df = NULL;
 21752175 
 21762176         /* now idp is a single node: fix up type */
 21772177         if ((t = ctype(idp->n_type)) != idp->n_type)
 21782178                 idp->n_type = t;
 21792179         
 21802180         if (idp->n_op != NAME) {
 21812181                 for (p = idp->n_left; p->n_op != NAME; p = p->n_left)
 21822182                         nfree(p);
 21832183                 nfree(p);
 21842184                 idp->n_op = NAME;
 21852185         }
 21862186         /* carefully not destroy any type attributes */
 21872187         if (idp->n_ap != NULL) {
 21882188                 struct attr *ap = idp->n_ap;
 21892189                 while (ap->next)
 21902190                         ap = ap->next;
 21912191                 ap->next = bap;
 21922192         } else
 21932193                 idp->n_ap = bap;
 21942194 
 21952195         return(idp);
 21962196 }
 21972197 
 21982198 static NODE *
 21992199 argcast(NODE *p, TWORD t, union dimfun *d, struct attr *ap)
 22002200 {
 22012201         NODE *u, *r = talloc();
 22022202 
 22032203         r->n_op = NAME;
 22042204         r->n_type = t;
 22052205         r->n_qual = 0; /* XXX */
 22062206         r->n_df = d;
 22072207         r->n_ap = ap;
 22082208 
 22092209         u = buildtree(CAST, r, p);
 22102210         nfree(u->n_left);
 22112211         r = u->n_right;
 22122212         nfree(u);
 22132213         return r;
 22142214 }
 22152215 
 22162216 #ifdef PCC_DEBUG
 22172217 /*
 22182218  * Print a prototype.
 22192219  */
 22202220 static void
 22212221 alprint(union arglist *al, int in)
 22222222 {
 22232223         TWORD t;
 22242224         int i = 0, j;
 22252225 
 22262226         for (; al->type != TNULL; al++) {
 22272227                 for (j = in; j > 0; j--)
 22282228                         printf("  ");
 22292229                 printf("arg %d: ", i++);
 22302230                 t = al->type;
 22312231                 tprint(t, 0);
 22322232                 while (t > BTMASK) {
 22332233                         if (ISARY(t)) {
 22342234                                 al++;
 22352235                                 printf(" dim %d ", al->df->ddim);
 22362236                         } else if (ISFTN(t)) {
 22372237                                 al++;
 22382238                                 if (al->df->dfun) {
 22392239                                         printf("\n");
 22402240                                         alprint(al->df->dfun, in+1);
 22412241                                 }
 22422242                         }
 22432243                         t = DECREF(t);
 22442244                 }
 22452245                 if (ISSOU(t)) {
 22462246                         al++;
 22472247                         printf(" (size %d align %d)", (int)tsize(t, 0, al->sap),
 22482248                             (int)talign(t, al->sap));
 22492249                 }
 22502250                 printf("\n");
 22512251         }
 22522252         if (in == 0)
 22532253                 printf("end arglist\n");
 22542254 }
 22552255 #endif
 22562256 
 22572257 int
 22582258 suemeq(struct attr *s1, struct attr *s2)
 22592259 {
 22602260 
 22612261         return (strmemb(s1) == strmemb(s2));
 22622262 }
 22632263 
 22642264 /*
 22652265  * Sanity-check old-style args.
 22662266  */
 22672267 static NODE *
 22682268 oldarg(NODE *p)
 22692269 {
 22702270         if (p->n_op == TYPE)
 22712271                 uerror("type is not an argument");
 22722272         if (p->n_type == FLOAT)
 22732273                 return cast(p, DOUBLE, p->n_qual);
 22742274         return p;
 22752275 }
 22762276 
 22772277 /*
 22782278  * Do prototype checking and add conversions before calling a function.
 22792279  * Argument f is function and a is a CM-separated list of arguments.
 22802280  * Returns a merged node (via buildtree() of function and arguments.
 22812281  */
 22822282 NODE *
 22832283 doacall(struct symtab *sp, NODE *f, NODE *a)
 22842284 {
 22852285         NODE *w, *r;
 22862286         union arglist *al;
 22872287         struct ap {
 22882288                 struct ap *next;
 22892289                 NODE *node;
 22902290         } *at, *apole = NULL;
 22912291         int argidx/* , hasarray = 0*/;
 22922292         TWORD type, arrt;
 22932293 
 22942294 #ifdef PCC_DEBUG
 22952295         if (ddebug) {
 22962296                 printf("doacall.\n");
 22972297                 fwalk(f, eprint, 0);
 22982298                 if (a)
 22992299                         fwalk(a, eprint, 0);
 23002300         }
 23012301 #endif
 23022302 
 23032303         /* First let MD code do something */
 23042304         calldec(f, a);
 23052305 /* XXX XXX hack */
 23062306         if ((f->n_op == CALL) &&
 23072307             f->n_left->n_op == ADDROF &&
 23082308             f->n_left->n_left->n_op == NAME &&
 23092309             (f->n_left->n_left->n_type & 0x7e0) == 0x4c0)
 23102310                 goto build;
 23112311 /* XXX XXX hack */
 23122312 
 23132313         /* Check for undefined or late defined enums */
 23142314         if (BTYPE(f->n_type) == ENUMTY) {
 23152315                 /* not-yet check if declared enum */
 23162316                 struct symtab *sq = strmemb(f->n_ap);
 23172317                 if (sq->stype != ENUMTY)
 23182318                         MODTYPE(f->n_type, sq->stype);
 23192319                 if (BTYPE(f->n_type) == ENUMTY)
 23202320                         uerror("enum %s not declared", sq->sname);
 23212321         }
 23222322 
 23232323         /*
 23242324          * Do some basic checks.
 23252325          */
 23262326         if (f->n_df == NULL || (al = f->n_df[0].dfun) == NULL) {
 23272327                 /*
 23282328                  * Handle non-prototype declarations.
 23292329                  */
 23302330                 if (f->n_op == NAME && f->n_sp != NULL) {
 23312331                         if (strncmp(f->n_sp->sname, "__builtin", 9) != 0 &&
 23322332                             (f->n_sp->sflags & SINSYS) == 0)
 23332333                                 warner(Wmissing_prototypes, f->n_sp->sname);
 23342334                 } else
 23352335                         warner(Wmissing_prototypes, "<pointer>");
 23362336 
 23372337                 /* floats must be cast to double */
 23382338                 if (a == NULL)
 23392339                         goto build;
 23402340                 if (a->n_op != CM) {
 23412341                         a = oldarg(a);
 23422342                 } else {
 23432343                         for (w = a; w->n_left->n_op == CM; w = w->n_left)
 23442344                                 w->n_right = oldarg(w->n_right);
 23452345                         w->n_left = oldarg(w->n_left);
 23462346                         w->n_right = oldarg(w->n_right);
 23472347                 }
 23482348                 goto build;
 23492349         }
 23502350         if (al->type == VOID) {
 23512351                 if (a != NULL)
 23522352                         uerror("function takes no arguments");
 23532353                 goto build; /* void function */
 23542354         } else {
 23552355                 if (a == NULL) {
 23562356                         uerror("function needs arguments");
 23572357                         goto build;
 23582358                 }
 23592359         }
 23602360 #ifdef PCC_DEBUG
 23612361         if (pdebug) {
 23622362                 printf("arglist for %s\n",
 23632363                     f->n_sp != NULL ? f->n_sp->sname : "function pointer");
 23642364                 alprint(al, 0);
 23652365         }
 23662366 #endif
 23672367 
 23682368         /*
 23692369          * Create a list of pointers to the nodes given as arg.
 23702370          */
 23712371         for (w = a; w->n_op == CM; w = w->n_left) {
 23722372                 at = tmpalloc(sizeof(struct ap));
 23732373                 at->node = w->n_right;
 23742374                 at->next = apole;
 23752375                 apole = at;
 23762376         }
 23772377         at = tmpalloc(sizeof(struct ap));
 23782378         at->node = w;
 23792379         at->next = apole;
 23802380         apole = at;
 23812381 
 23822382         /*
 23832383          * Do the typechecking by walking up the list.
 23842384          */
 23852385         argidx = 1;
 23862386         while (al->type != TNULL) {
 23872387                 if (al->type == TELLIPSIS) {
 23882388                         /* convert the rest of float to double */
 23892389                         for (; apole; apole = apole->next) {
 23902390                                 if (apole->node->n_type != FLOAT)
 23912391                                         continue;
 23922392                                 MKTY(apole->node, DOUBLE, 0, 0);
 23932393                         }
 23942394                         goto build;
 23952395                 }
 23962396                 if (apole == NULL) {
 23972397                         uerror("too few arguments to function");
 23982398                         goto build;
 23992399                 }
 24002400 /* al = prototyp, apole = argument till ftn */
 24012401 /* type = argumentets typ, arrt = prototypens typ */
 24022402                 type = apole->node->n_type;
 24032403                 arrt = al->type;
 24042404 #if 0
 24052405                 if ((hasarray = ISARY(arrt)))
 24062406                         arrt += (PTR-ARY);
 24072407 #endif
 24082408                 /* Taking addresses of arrays are meaningless in expressions */
 24092409                 /* but people tend to do that and also use in prototypes */
 24102410                 /* this is mostly a problem with typedefs */
 24112411                 if (ISARY(type)) {
 24122412                         if (ISPTR(arrt) && ISARY(DECREF(arrt)))
 24132413                                 type = INCREF(type);
 24142414                         else
 24152415                                 type += (PTR-ARY);
 24162416                 } else if (ISPTR(type) && !ISARY(DECREF(type)) &&
 24172417                     ISPTR(arrt) && ISARY(DECREF(arrt))) {
 24182418                         type += (ARY-PTR);
 24192419                         type = INCREF(type);
 24202420                 }
 24212421 
 24222422                 /* Check structs */
 24232423                 if (type <= BTMASK && arrt <= BTMASK) {
 24242424                         if (type != arrt) {
 24252425                                 if (ISSOU(BTYPE(type)) || ISSOU(BTYPE(arrt))) {
 24262426 incomp:                                 uerror("incompatible types for arg %d",
 24272427                                             argidx);
 24282428                                 } else {
 24292429                                         MKTY(apole->node, arrt, 0, 0)
 24302430                                 }
 24312431 #ifndef NO_COMPLEX
 24322432                         } else if (type == STRTY &&
 24332433                             attr_find(apole->node->n_ap, ATTR_COMPLEX) &&
 24342434                             attr_find(al[1].sap, ATTR_COMPLEX)) {
 24352435                                 /* Both are complex */
 24362436                                 if (strmemb(apole->node->n_ap)->stype !=
 24372437                                     strmemb(al[1].sap)->stype) {
 24382438                                         /* must convert to correct type */
 24392439                                         w = talloc();
 24402440                                         *w = *apole->node;
 24412441                                         w = mkcmplx(w,
 24422442                                             strmemb(al[1].sap)->stype);
 24432443                                         *apole->node = *w;
 24442444                                         nfree(w);
 24452445                                 }
 24462446                                 goto out;
 24472447 #endif
 24482448                         } else if (ISSOU(BTYPE(type))) {
 24492449                                 if (!suemeq(apole->node->n_ap, al[1].sap))
 24502450                                         goto incomp;
 24512451                         }
 24522452                         goto out;
 24532453                 }
 24542454 
 24552455                 /* XXX should (recusively) check return type and arg list of
 24562456                    func ptr arg XXX */
 24572457                 if (ISFTN(DECREF(arrt)) && ISFTN(type))
 24582458                         type = INCREF(type);
 24592459 
 24602460                 /* Hereafter its only pointers (or arrays) left */
 24612461                 /* Check for struct/union intermixing with other types */
 24622462                 if (((type <= BTMASK) && ISSOU(BTYPE(type))) ||
 24632463                     ((arrt <= BTMASK) && ISSOU(BTYPE(arrt))))
 24642464                         goto incomp;
 24652465 
 24662466                 /* Check for struct/union compatibility */
 24672467                 if (type == arrt) {
 24682468                         if (ISSOU(BTYPE(type))) {
 24692469                                 if (suemeq(apole->node->n_ap, al[1].sap))
 24702470                                         goto out;
 24712471                         } else
 24722472                                 goto out;
 24732473                 }
 24742474                 if (BTYPE(arrt) == VOID && type > BTMASK)
 24752475                         goto skip; /* void *f = some pointer */
 24762476                 if (arrt > BTMASK && BTYPE(type) == VOID)
 24772477                         goto skip; /* some *f = void pointer */
 24782478                 if (apole->node->n_op == ICON && apole->node->n_lval == 0)
 24792479                         goto skip; /* Anything assigned a zero */
 24802480 
 24812481                 if ((type & ~BTMASK) == (arrt & ~BTMASK)) {
 24822482                         /* do not complain for pointers with signedness */
 24832483                         if ((DEUNSIGN(BTYPE(type)) == DEUNSIGN(BTYPE(arrt))) &&
 24842484                             (BTYPE(type) != BTYPE(arrt))) {
 24852485                                 warner(Wpointer_sign, NULL);
 24862486                                 goto skip;
 24872487                         }
 24882488                 }
 24892489 
 24902490                 werror("implicit conversion of argument %d due to prototype",
 24912491                     argidx);
 24922492 
 24932493 skip:           if (ISSOU(BTYPE(arrt))) {
 24942494                         MKTY(apole->node, arrt, 0, al[1].sap)
 24952495                 } else {
 24962496                         MKTY(apole->node, arrt, 0, 0)
 24972497                 }
 24982498 
 24992499 out:            al++;
 25002500                 if (ISSOU(BTYPE(arrt)))
 25012501                         al++;
 25022502 #if 0
 25032503                 while (arrt > BTMASK && !ISFTN(arrt))
 25042504                         arrt = DECREF(arrt);
 25052505                 if (ISFTN(arrt) || hasarray)
 25062506                         al++;
 25072507 #else
 25082508                 while (arrt > BTMASK) {
 25092509                         if (ISARY(arrt) || ISFTN(arrt)) {
 25102510                                 al++;
 25112511                                 break;
 25122512                         }
 25132513                         arrt = DECREF(arrt);
 25142514                 }
 25152515 #endif
 25162516                 apole = apole->next;
 25172517                 argidx++;
 25182518         }
 25192519         if (apole != NULL)
 25202520                 uerror("too many arguments to function");
 25212521 
 25222522 build:  if (sp != NULL && (sp->sflags & SINLINE) && (w = inlinetree(sp, f, a)))
 25232523                 return w;
 25242524         return buildtree(a == NIL ? UCALL : CALL, f, a);
 25252525 }
 25262526 
 25272527 static int
 25282528 chk2(TWORD type, union dimfun *dsym, union dimfun *ddef)
 25292529 {
 25302530         while (type > BTMASK) {
 25312531                 switch (type & TMASK) {
 25322532                 case ARY:
 25332533                         /* may be declared without dimension */
 25342534                         if (dsym->ddim == NOOFFSET)
 25352535                                 dsym->ddim = ddef->ddim;
 25362536                         if (dsym->ddim < 0 && ddef->ddim < 0)
 25372537                                 ; /* dynamic arrays as arguments */
 25382538                         else if (ddef->ddim > 0 && dsym->ddim != ddef->ddim)
 25392539                                 return 1;
 25402540                         dsym++, ddef++;
 25412541                         break;
 25422542                 case FTN:
 25432543                         /* old-style function headers with function pointers
 25442544                          * will most likely not have a prototype.
 25452545                          * This is not considered an error.  */
 25462546                         if (ddef->dfun == NULL) {
 25472547 #ifdef notyet
 25482548                                 werror("declaration not a prototype");
 25492549 #endif
 25502550                         } else if (chkftn(dsym->dfun, ddef->dfun))
 25512551                                 return 1;
 25522552                         dsym++, ddef++;
 25532553                         break;
 25542554                 }
 25552555                 type = DECREF(type);
 25562556         }
 25572557         return 0;
 25582558 }
 25592559 
 25602560 /*
 25612561  * Compare two function argument lists to see if they match.
 25622562  */
 25632563 int
 25642564 chkftn(union arglist *usym, union arglist *udef)
 25652565 {
 25662566         TWORD t2;
 25672567         int ty, tyn;
 25682568 
 25692569         if (usym == NULL)
 25702570                 return 0;
 25712571         if (cftnsp != NULL && udef == NULL && usym->type == VOID)
 25722572                 return 0; /* foo() { function with foo(void); prototype */
 25732573         if (udef == NULL && usym->type != TNULL)
 25742574                 return 1;
 25752575         while (usym->type != TNULL) {
 25762576                 if (usym->type == udef->type)
 25772577                         goto done;
 25782578                 /*
 25792579                  * If an old-style declaration, then all types smaller than
 25802580                  * int are given as int parameters.
 25812581                  */
 25822582                 if (intcompare) {
 25832583                         ty = BTYPE(usym->type);
 25842584                         tyn = BTYPE(udef->type);
 25852585                         if (ty == tyn || ty != INT)