Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.360
 
1.361
 
MAIN:plunky:20121022091009
 
pftn.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
 44  * All rights reserved.
 55  *
 66  * Redistribution and use in source and binary forms, with or without
 77  * modification, are permitted provided that the following conditions
 88  * are met:
 99  * 1. Redistributions of source code must retain the above copyright
 1010  *    notice, this list of conditions and the following disclaimer.
 1111  * 2. Redistributions in binary form must reproduce the above copyright
 1212  *    notice, this list of conditions and the following disclaimer in the
 1313  *    documentation and/or other materials provided with the distribution.
 1414  *
 1515  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1616  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1717  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 1818  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 1919  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2020  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2121  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2222  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2323  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2424  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2525  */
 2626 /*
 2727  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 2828  *
 2929  * Redistribution and use in source and binary forms, with or without
 3030  * modification, are permitted provided that the following conditions
 3131  * are met:
 3232  *
 3333  * Redistributions of source code and documentation must retain the above
 3434  * copyright notice, this list of conditions and the following disclaimer.
 3535  * Redistributions in binary form must reproduce the above copyright
 3636  * notice, this list of conditionsand the following disclaimer in the
 3737  * documentation and/or other materials provided with the distribution.
 3838  * All advertising materials mentioning features or use of this software
 3939  * must display the following acknowledgement:
 4040  *      This product includes software developed or owned by Caldera
 4141  *      International, Inc.
 4242  * Neither the name of Caldera International, Inc. nor the names of other
 4343  * contributors may be used to endorse or promote products derived from
 4444  * this software without specific prior written permission.
 4545  *
 4646  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 4747  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 4848  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 4949  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 5050  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 5151  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 5252  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 5353  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 5454  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 5555  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 5656  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 5757  * POSSIBILITY OF SUCH DAMAGE.
 5858  */
 5959 
 6060 /*
 6161  * Many changes from the 32V sources, among them:
 6262  * - New symbol table manager (moved to another file).
 6363  * - Prototype saving/checks.
 6464  */
 6565 
 6666 # include "pass1.h"
 6767 
 6868 #include "cgram.h"
 6969 
 7070 struct symtab *cftnsp;
 7171 int arglistcnt, dimfuncnt;      /* statistics */
 7272 int symtabcnt, suedefcnt;       /* statistics */
 7373 int autooff,            /* the next unused automatic offset */
 7474     maxautooff,         /* highest used automatic offset in function */
 7575     argoff;             /* the next unused argument offset */
 7676 int retlab = NOLAB;     /* return label for subroutine */
 7777 int brklab;
 7878 int contlab;
 7979 int flostat;
 8080 int blevel;
 8181 int reached, prolab;
 8282 
 8383 struct params;
 8484 
 8585 #define MKTY(p, t, d, s) r = talloc(); *r = *p; \
 8686         r = argcast(r, t, d, s); *p = *r; nfree(r);
 8787 
 8888 /*
 8989  * Linked list stack while reading in structs.
 9090  */
 9191 struct rstack {
 9292         struct  rstack *rnext;
 9393         int     rsou;
 9494         int     rstr;
 9595         struct  symtab *rsym;
 9696         struct  symtab *rb;
 9797         struct  attr *ap;
 9898         int     flags;
 9999 #define LASTELM 1
 100100 } *rpole;
 101101 
 102102 /*
 103103  * Linked list for parameter (and struct elements) declaration.
 104104  */
 105105 static struct params {
 106106         struct params *next, *prev;
 107107         struct symtab *sym;
 108108 } *lpole, *lparam;
 109109 static int nparams;
 110110 
 111111 /* defines used for getting things off of the initialization stack */
 112112 
 113113 NODE *arrstk[10];
 114114 int arrstkp;
 115115 static int intcompare;
 116116 NODE *parlink;
 117117 
 118118 void fixtype(NODE *p, int class);
 119119 int fixclass(int class, TWORD type);
 120120 static void dynalloc(struct symtab *p, int *poff);
 121121 static void evalidx(struct symtab *p);
 122122 int isdyn(struct symtab *p);
 123123 void inforce(OFFSZ n);
 124124 void vfdalign(int n);
 125125 static void ssave(struct symtab *);
 126126 #ifdef PCC_DEBUG
 127127 static void alprint(union arglist *al, int in);
 128128 #endif
 129129 static void lcommadd(struct symtab *sp);
 130130 static NODE *mkcmplx(NODE *p, TWORD dt);
 131131 extern int fun_inline;
 132132 
 133133 void
 134134 defid(NODE *q, int class)
 135135 {
 136136         defid2(q, class, 0);
 137137 }
 138138 
 139139 /*
 140140  * Declaration of an identifier.  Handles redeclarations, hiding,
 141141  * incomplete types and forward declarations.
 142142  *
 143143  * q is a TYPE node setup after parsing with n_type, n_df and n_ap.
 144144  * n_sp is a pointer to the not-yet initalized symbol table entry
 145145  * unless it's a redeclaration or supposed to hide a variable.
 146146  */
 147147 
 148148 void
 149149 defid2(NODE *q, int class, char *astr)
 150150 {
 151151         struct attr *ap;
 152152         struct symtab *p;
 153153         TWORD type, qual;
 154154         TWORD stp, stq;
 155155         int scl;
 156156         union dimfun *dsym, *ddef;
 157157         int slev, temp, changed;
 158158 
 159159         if (q == NIL)
 160160                 return/* an error was detected */
 161161 
 162162 #ifdef GCC_COMPAT
 163163         gcc_modefix(q);
 164164 #endif
 165165         p = q->n_sp;
 166166 
 167167         if (p->sname == NULL)
 168168                 cerror("defining null identifier");
 169169 
 170170 #ifdef PCC_DEBUG
 171171         if (ddebug) {
 172172                 printf("defid(%s '%s'(%p), ", p->sname, p->soname , p);
 173173                 tprint(q->n_type, q->n_qual);
 174174                 printf(", %s, (%p)), level %d\n\t", scnames(class),
 175175                     q->n_df, blevel);
 176176                 dump_attr(q->n_ap);
 177177         }
 178178 #endif
 179179 
 180180         fixtype(q, class);
 181181 
 182182         type = q->n_type;
 183183         qual = q->n_qual;
 184184         class = fixclass(class, type);
 185185 
 186186         stp = p->stype;
 187187         stq = p->squal;
 188188         slev = p->slevel;
 189189 
 190190 #ifdef PCC_DEBUG
 191191         if (ddebug) {
 192192                 printf("        modified to ");
 193193                 tprint(type, qual);
 194194                 printf(", %s\n", scnames(class));
 195195                 printf("        previous def'n: ");
 196196                 tprint(stp, stq);
 197197                 printf(", %s, (%p,%p)), level %d\n",
 198198                     scnames(p->sclass), p->sdf, p->sap, slev);
 199199         }
 200200 #endif
 201201 
 202202         if (blevel == 1) {
 203203                 switch (class) {
 204204                 default:
 205205                         if (!(class&FIELD) && !ISFTN(type))
 206206                                 uerror("declared argument %s missing",
 207207                                     p->sname );
<> 208+                        break;
208209                 case MOS:
 209210                 case MOU:
 210211                         cerror("field5");
 211212                 case TYPEDEF:
 212213                 case PARAM:
<>213 -                        ;
  214+                        break;
<_214215                 }
 215216         }
 216217 
 217218         if (stp == UNDEF)
 218219                 goto enter; /* New symbol */
 219220 
 220221         if (type != stp)
 221222                 goto mismatch;
 222223 
 223224         if (blevel > slev && (class == AUTO || class == REGISTER))
 224225                 /* new scope */
 225226                 goto mismatch;
 226227 
 227228         /*
 228229          * test (and possibly adjust) dimensions.
 229230          * also check that prototypes are correct.
 230231          */
 231232         dsym = p->sdf;
 232233         ddef = q->n_df;
 233234         changed = 0;
 234235         for (temp = type; temp & TMASK; temp = DECREF(temp)) {
 235236                 if (ISARY(temp)) {
 236237                         if (dsym->ddim == NOOFFSET) {
 237238                                 dsym->ddim = ddef->ddim;
 238239                                 changed = 1;
 239240                         } else if (ddef->ddim != NOOFFSET &&
 240241                             dsym->ddim!=ddef->ddim) {
 241242                                 goto mismatch;
 242243                         }
 243244                         ++dsym;
 244245                         ++ddef;
 245246                 } else if (ISFTN(temp)) {
 246247                         /* add a late-defined prototype here */
 247248                         if (cftnsp == NULL && dsym->dfun == NULL)
 248249                                 dsym->dfun = ddef->dfun;
 249250                         if (!oldstyle && ddef->dfun != NULL &&
 250251                             chkftn(dsym->dfun, ddef->dfun))
 251252                                 uerror("declaration doesn't match prototype");
 252253                         dsym++, ddef++;
 253254                 }
 254255         }
 255256 #ifdef STABS
 256257         if (changed && gflag)
 257258                 stabs_chgsym(p); /* symbol changed */
 258259 #endif
 259260 
 260261         /* check that redeclarations are to the same structure */
 261262         if (temp == STRTY || temp == UNIONTY) {
 262263                 if (strmemb(p->sap) != strmemb(q->n_ap))
 263264                         goto mismatch;
 264265         }
 265266 
 266267         scl = p->sclass;
 267268 
 268269 #ifdef PCC_DEBUG
 269270         if (ddebug)
 270271                 printf("        previous class: %s\n", scnames(scl));
 271272 #endif
 272273 
 273274         /*
 274275          * Its allowed to add attributes to existing declarations.
 275276          * Be careful though not to trash existing attributes.
 276277          * XXX - code below is probably not correct.
 277278          */
 278279         if (p->sap && p->sap->atype <= ATTR_MAX) {
 279280                 /* nothing special, just overwrite */
 280281                 p->sap = q->n_ap;
 281282         } else {
 282283                 if (p->slevel == blevel) {
 283284                         for (ap = q->n_ap; ap; ap = ap->next) {
 284285                                 if (ap->atype > ATTR_MAX)
 285286                                         p->sap = attr_add(p->sap, attr_dup(ap, 3));
 286287                         }
 287288                 } else
 288289                         p->sap = q->n_ap;
 289290         }
 290291 
 291292         if (class & FIELD)
 292293                 cerror("field1");
 293294         switch(class) {
 294295 
 295296         case EXTERN:
 296297                 if (astr)
 297298                         p->soname = astr;
 298299                 switch( scl ){
 299300                 case STATIC:
 300301                 case USTATIC:
 301302                         if( slev==0 )
 302303                                 goto done;
 303304                         break;
 304305                 case EXTDEF:
 305306                 case EXTERN:
 306307                         goto done;
 307308                 case SNULL:
 308309                         if (p->sflags & SINLINE) {
 309310                                 p->sclass = EXTDEF;
 310311                                 inline_ref(p);
 311312                                 goto done;
 312313                         }
 313314                         break;
 314315                 }
 315316                 break;
 316317 
 317318         case STATIC:
 318319                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
 319320                         p->sclass = STATIC;
 320321                         goto done;
 321322                 }
 322323                 if (changed || (scl == STATIC && blevel == slev))
 323324                         goto done; /* identical redeclaration */
 324325                 break;
 325326 
 326327         case USTATIC:
 327328                 if (scl==STATIC || scl==USTATIC)
 328329                         goto done;
 329330                 break;
 330331 
 331332         case TYPEDEF:
 332333                 if (scl == class)
 333334                         goto done;
 334335                 break;
 335336 
 336337         case MOU:
 337338         case MOS:
 338339                 cerror("field6");
 339340 
 340341         case EXTDEF:
 341342                 switch (scl) {
 342343                 case EXTERN:
 343344                         p->sclass = EXTDEF;
 344345                         goto done;
 345346                 case USTATIC:
 346347                         p->sclass = STATIC;
 347348                         goto done;
 348349                 case SNULL:
 349350                         /*
 350351                          * Handle redeclarations of inlined functions.
 351352                          * This is allowed if the previous declaration is of
 352353                          * type gnu_inline.
 353354                          */
 354355                         if (attr_find(p->sap, GCC_ATYP_GNU_INLINE))
 355356                                 goto done;
 356357                         break;
 357358                 }
 358359                 break;
 359360 
 360361         case AUTO:
 361362         case REGISTER:
 362363                 break/* mismatch.. */
 363364         case SNULL:
 364365                 if (fun_inline && ISFTN(type)) {
 365366                         if (scl == EXTERN) {
 366367                                 p->sclass = EXTDEF;
 367368                                 inline_ref(p);
 368369                         }
 369370                         goto done;
 370371                 }
 371372                 break;
 372373         }
 373374 
 374375         mismatch:
 375376 
 376377         /*
 377378          * Only allowed for automatic variables.
 378379          */
 379380         if ((blevel == 2 && slev == 1) || blevel <= slev || class == EXTERN) {
 380381                 uerror("redeclaration of %s", p->sname);
 381382                 return;
 382383         }
 383384         q->n_sp = p = hide(p);
 384385 
 385386         enter/* make a new entry */
 386387 
 387388 #ifdef PCC_DEBUG
 388389         if(ddebug)
 389390                 printf("        new entry made\n");
 390391 #endif
 391392         p->stype = type;
 392393         p->squal = qual;
 393394         p->sclass = (char)class;
 394395         p->slevel = (char)blevel;
 395396         p->soffset = NOOFFSET;
 396397         if (q->n_ap)
 397398                 p->sap = attr_add(q->n_ap, p->sap);
 398399 
 399400         /* copy dimensions */
 400401         p->sdf = q->n_df;
 401402         /* Do not save param info for old-style functions */
 402403         if (ISFTN(type) && oldstyle)
 403404                 p->sdf->dfun = NULL;
 404405 
 405406         if (arrstkp)
 406407                 evalidx(p);
 407408 
 408409         /* allocate offsets */
 409410         if (class&FIELD) {
 410411                 cerror("field2");  /* new entry */
 411412         } else switch (class) {
 412413 
 413414         case REGISTER:
 414415                 if (astr != NULL)
 415416                         werror("no register assignment (yet)");
 416417                 p->sclass = class = AUTO;
 417418                 /* FALLTHROUGH */
 418419         case AUTO:
 419420                 if (isdyn(p)) {
 420421                         p->sflags |= SDYNARRAY;
 421422                         dynalloc(p, &autooff);
 422423                 } else
 423424                         oalloc(p, &autooff);
 424425                 break;
 425426 
 426427         case PARAM:
 427428                 if (q->n_type != FARG)
 428429                         oalloc(p, &argoff);
 429430                 break;
 430431                 
 431432         case STATIC:
 432433         case EXTDEF:
 433434         case EXTERN:
 434435                 p->soffset = getlab();
 435436                 if (astr)
 436437                         p->soname = astr;
 437438                 break;
 438439 
 439440         case MOU:
 440441         case MOS:
 441442                 cerror("field7");
 442443         case SNULL:
 443444 #ifdef notdef
 444445                 if (fun_inline) {
 445446                         p->slevel = 1;
 446447                         p->soffset = getlab();
 447448                 }
 448449 #endif
 449450                 break;
 450451         }
 451452 
 452453 #ifdef STABS
 453454         if (gflag && p->stype != FARG)
 454455                 stabs_newsym(p);
 455456 #endif
 456457 
 457458 done:
 458459         fixdef(p);      /* Leave last word to target */
 459460 #ifndef HAVE_WEAKREF
 460461         {
 461462                 struct attr *at;
 462463 
 463464                 /* Refer renamed function */
 464465                 if ((at = attr_find(p->sap, GCC_ATYP_WEAKREF)))
 465466                         p->soname = at->sarg(0);
 466467         }
 467468 #endif
 468469 #ifdef PCC_DEBUG
 469470         if (ddebug) {
 470471                 printf( "       sdf, offset: %p, %d\n\t",
 471472                     p->sdf, p->soffset);
 472473                 dump_attr(p->sap);
 473474         }
 474475 #endif
 475476 }
 476477 
 477478 void
 478479 ssave(struct symtab *sym)
 479480 {
 480481         struct params *p;
 481482 
 482483         p = tmpalloc(sizeof(struct params));
 483484         p->next = NULL;
 484485         p->sym = sym;
 485486 
 486487         if ((p->prev = lparam) == NULL)
 487488                 lpole = p;
 488489         else
 489490                 lparam->next = p;
 490491         lparam = p;
 491492 }
 492493 
 493494 /*
 494495  * end of function
 495496  */
 496497 void
 497498 ftnend(void)
 498499 {
 499500         struct attr *gc, *gd;
 500501         extern int *mkclabs(void);
 501502         extern NODE *cftnod;
 502503         extern struct savbc *savbc;
 503504         extern struct swdef *swpole;
 504505         extern int tvaloff;
 505506         char *c;
 506507 
 507508         if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
 508509                 plabel(retlab);
 509510                 if (cftnod)
 510511                         ecomp(buildtree(FORCE, cftnod, NIL));
 511512                 efcode(); /* struct return handled here */
 512513                 if ((c = cftnsp->soname) == NULL)
 513514                         c = addname(exname(cftnsp->sname));
 514515                 SETOFF(maxautooff, ALCHAR);
 515516                 send_passt(IP_EPILOG, maxautooff/SZCHAR, c,
 516517                     cftnsp->stype, cftnsp->sclass == EXTDEF,
 517518                     retlab, tvaloff, mkclabs());
 518519         }
 519520 
 520521         cftnod = NIL;
 521522         tcheck();
 522523         brklab = contlab = retlab = NOLAB;
 523524         flostat = 0;
 524525         if (nerrors == 0) {
 525526                 if (savbc != NULL)
 526527                         cerror("bcsave error");
 527528                 if (lparam != NULL)
 528529                         cerror("parameter reset error");
 529530                 if (swpole != NULL)
 530531                         cerror("switch error");
 531532         }
 532533         if (cftnsp) {
 533534                 gc = attr_find(cftnsp->sap, GCC_ATYP_CONSTRUCTOR);
 534535                 gd = attr_find(cftnsp->sap, GCC_ATYP_DESTRUCTOR);
 535536                 if (gc || gd) {
 536537                         struct symtab sts = *cftnsp;
 537538                         NODE *p;
 538539                         sts.stype = INCREF(sts.stype);
 539540                         p = nametree(&sts);
 540541                         p->n_op = ICON;
 541542                         if (gc) {
 542543                                 locctr(CTORS, &sts);
 543544                                 inval(0, SZPOINT(0), p);
 544545                         }
 545546                         if (gd) {
 546547                                 locctr(DTORS, &sts);
 547548                                 inval(0, SZPOINT(0), p);
 548549                         }
 549550                         tfree(p);
 550551                 }
 551552         }
 552553         savbc = NULL;
 553554         lparam = NULL;
 554555         cftnsp = NULL;
 555556         maxautooff = autooff = AUTOINIT;
 556557         reached = 1;
 557558 
 558559         if (isinlining)
 559560                 inline_end();
 560561         inline_prtout();
 561562 
 562563         tmpfree(); /* Release memory resources */
 563564 }
 564565 
 565566 static struct symtab nulsym = {
 566567         NULL, 0, 0, 0, 0, "null", "null", INT, 0, NULL, NULL
 567568 };
 568569 
 569570 void
 570571 dclargs(void)
 571572 {
 572573         union dimfun *df;
 573574         union arglist *al, *al2, *alb;
 574575         struct params *a;
 575576         struct symtab *p, **parr = NULL; /* XXX gcc */
 576577         int i;
 577578 
 578579         /*
 579580          * Deal with fun(void) properly.
 580581          */
 581582         if (nparams == 1 && lparam->sym && lparam->sym->stype == VOID)
 582583                 goto done;
 583584 
 584585         /*
 585586          * Generate a list for bfcode().
 586587          * Parameters were pushed in reverse order.
 587588          */
 588589         if (nparams != 0)
 589590                 parr = tmpalloc(sizeof(struct symtab *) * nparams);
 590591 
 591592         if (nparams)
 592593             for (a = lparam, i = 0; a != NULL; a = a->prev) {
 593594                 p = a->sym;
 594595                 parr[i++] = p;
 595596                 if (p == NULL) {
 596597                         uerror("parameter %d name missing", i);
 597598                         p = &nulsym; /* empty symtab */
 598599                 }
 599600                 if (p->stype == FARG)
 600601                         p->stype = INT;
 601602                 if (ISARY(p->stype)) {
 602603                         p->stype += (PTR-ARY);
 603604                         p->sdf++;
 604605                 } else if (ISFTN(p->stype)) {
 605606                         werror("function declared as argument");
 606607                         p->stype = INCREF(p->stype);
 607608                 }
 608609 #ifdef STABS
 609610                 if (gflag)
 610611                         stabs_newsym(p);
 611612 #endif
 612613         }
 613614         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
 614615                 /*
 615616                  * Check against prototype of oldstyle function.
 616617                  */
 617618                 alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
 618619                 for (i = 0; i < nparams; i++) {
 619620                         TWORD type = parr[i]->stype;
 620621                         (al2++)->type = type;
 621622                         if (ISSOU(BTYPE(type)))
 622623                                 (al2++)->sap = parr[i]->sap;
 623624                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
 624625                                 type = DECREF(type);
 625626                         if (type > BTMASK)
 626627                                 (al2++)->df = parr[i]->sdf;
 627628                 }
 628629                 al2->type = TNULL;
 629630                 intcompare = 1;
 630631                 if (chkftn(al, alb))
 631632                         uerror("function doesn't match prototype");
 632633                 intcompare = 0;
 633634 
 634635         }
 635636 
 636637         if (oldstyle && nparams) {
 637638                 /* Must recalculate offset for oldstyle args here */
 638639                 argoff = ARGINIT;
 639640                 for (i = 0; i < nparams; i++) {
 640641                         parr[i]->soffset = NOOFFSET;
 641642                         oalloc(parr[i], &argoff);
 642643                 }
 643644         }
 644645 
 645646 done:   autooff = AUTOINIT;
 646647 
 647648         plabel(prolab); /* after prolog, used in optimization */
 648649         retlab = getlab();
 649650         bfcode(parr, nparams);
 650651         if (fun_inline &&
 651652             (xinline || attr_find(cftnsp->sap, GCC_ATYP_ALW_INL)))
 652653                 inline_args(parr, nparams);
 653654         plabel(getlab()); /* used when spilling */
 654655         if (parlink)
 655656                 ecomp(parlink);
 656657         parlink = NIL;
 657658         lparam = NULL;
 658659         nparams = 0;
 659660         symclear(1);    /* In case of function pointer args */
 660661 }
 661662 
 662663 /*
 663664  * basic attributes for structs and enums
 664665  */
 665666 static struct attr *
 666667 seattr(void)
 667668 {
 668669         return attr_add(attr_new(GCC_ATYP_ALIGNED, 4), attr_new(ATTR_STRUCT, 2));
 669670 }
 670671 
 671672 /*
 672673  * Struct/union/enum symtab construction.
 673674  */
 674675 static void
 675676 defstr(struct symtab *sp, int class)
 676677 {
 677678         sp->sclass = (char)class;
 678679         if (class == STNAME)
 679680                 sp->stype = STRTY;
 680681         else if (class == UNAME)
 681682                 sp->stype = UNIONTY;
 682683         else if (class == ENAME)
 683684                 sp->stype = ENUMTY;
 684685 }
 685686 
 686687 /*
 687688  * Declare a struct/union/enum tag.
 688689  * If not found, create a new tag with UNDEF type.
 689690  */
 690691 static struct symtab *
 691692 deftag(char *name, int class)
 692693 {
 693694         struct symtab *sp;
 694695 
 695696         if ((sp = lookup(name, STAGNAME))->sap == NULL) {
 696697                 /* New tag */
 697698                 defstr(sp, class);
 698699         } else if (sp->sclass != class)
 699700                 uerror("tag %s redeclared", name);
 700701         return sp;
 701702 }
 702703 
 703704 /*
 704705  * reference to a structure or union, with no definition
 705706  */
 706707 NODE *
 707708 rstruct(char *tag, int soru)
 708709 {
 709710         struct symtab *sp;
 710711 
 711712         sp = deftag(tag, soru);
 712713         if (sp->sap == NULL)
 713714                 sp->sap = seattr();
 714715         return mkty(sp->stype, 0, sp->sap);
 715716 }
 716717 
 717718 static int enumlow, enumhigh;
 718719 int enummer;
 719720 
 720721 /*
 721722  * Declare a member of enum.
 722723  */
 723724 void
 724725 moedef(char *name)
 725726 {
 726727         struct symtab *sp;
 727728 
 728729         sp = lookup(name, SNORMAL);
 729730         if (sp->stype == UNDEF || (sp->slevel < blevel)) {
 730731                 if (sp->stype != UNDEF)
 731732                         sp = hide(sp);
 732733                 sp->stype = INT; /* always */
 733734                 sp->sclass = MOE;
 734735                 sp->soffset = enummer;
 735736         } else
 736737                 uerror("%s redeclared", name);
 737738         if (enummer < enumlow)
 738739                 enumlow = enummer;
 739740         if (enummer > enumhigh)
 740741                 enumhigh = enummer;
 741742         enummer++;
 742743 }
 743744 
 744745 /*
 745746  * Declare an enum tag.  Complain if already defined.
 746747  */
 747748 struct symtab *
 748749 enumhd(char *name)
 749750 {
 750751         struct attr *ap;
 751752         struct symtab *sp;
 752753 
 753754         enummer = enumlow = enumhigh = 0;
 754755         if (name == NULL)
 755756                 return NULL;
 756757 
 757758         sp = deftag(name, ENAME);
 758759         if (sp->stype != ENUMTY) {
 759760                 if (sp->slevel == blevel)
 760761                         uerror("%s redeclared", name);
 761762                 sp = hide(sp);
 762763                 defstr(sp, ENAME);
 763764         }
 764765         if (sp->sap == NULL)
 765766                 ap = sp->sap = attr_new(ATTR_STRUCT, 4);
 766767         else
 767768                 ap = attr_find(sp->sap, ATTR_STRUCT);
 768769         ap->amlist = sp;
 769770         return sp;
 770771 }
 771772 
 772773 /*
 773774  * finish declaration of an enum
 774775  */
 775776 NODE *
 776777 enumdcl(struct symtab *sp)
 777778 {
 778779         NODE *p;
 779780         TWORD t;
 780781 
 781782 #ifdef ENUMSIZE
 782783         t = ENUMSIZE(enumhigh, enumlow);
 783784 #else
 784785         t = ctype(enumlow < 0 ? INT : UNSIGNED);
 785786 #ifdef notdef
 786787         if (enumhigh <= MAX_CHAR && enumlow >= MIN_CHAR)
 787788                 t = ctype(CHAR);
 788789         else if (enumhigh <= MAX_SHORT && enumlow >= MIN_SHORT)
 789790                 t = ctype(SHORT);
 790791         else
 791792                 t = ctype(INT);
 792793 #endif
 793794 #endif
 794795         
 795796         if (sp)
 796797                 sp->stype = t;
 797798         p = mkty(t, 0, 0);
 798799         p->n_sp = sp;
 799800         return p;
 800801 }
 801802 
 802803 /*
 803804  * Handle reference to an enum
 804805  */
 805806 NODE *
 806807 enumref(char *name)
 807808 {
 808809         struct symtab *sp;
 809810         NODE *p;
 810811 
 811812         sp = lookup(name, STAGNAME);
 812813 
 813814 #ifdef notdef
 814815         /*
 815816          * 6.7.2.3 Clause 2:
 816817          * "A type specifier of the form 'enum identifier' without an
 817818          *  enumerator list shall only appear after the type it specifies
 818819          *  is complete."
 819820          */
 820821         if (sp->sclass != ENAME)
 821822                 uerror("enum %s undeclared", name);
 822823 #endif
 823824         if (sp->sclass == SNULL) {
 824825                 /* declare existence of enum */
 825826                 sp = enumhd(name);
 826827                 sp->stype = ENUMTY;
 827828         }
 828829 
 829830         p = mkty(sp->stype, 0, sp->sap);
 830831         p->n_sp = sp;
 831832         return p;
 832833 }
 833834 
 834835 /*
 835836  * begining of structure or union declaration
 836837  * It's an error if this routine is called twice with the same struct.
 837838  */
 838839 struct rstack *
 839840 bstruct(char *name, int soru, NODE *gp)
 840841 {
 841842         struct rstack *r;
 842843         struct symtab *sp;
 843844         struct attr *ap, *gap;
 844845 
 845846         gap = gp ? gcc_attr_parse(gp) : NULL;
 846847 
 847848         if (name != NULL) {
 848849                 sp = deftag(name, soru);
 849850                 if (sp->sap == NULL)
 850851                         sp->sap = seattr();
 851852                 ap = attr_find(sp->sap, GCC_ATYP_ALIGNED);
 852853                 if (ap->iarg(0) != 0) {
 853854                         if (sp->slevel < blevel) {
 854855                                 sp = hide(sp);
 855856                                 defstr(sp, soru);
 856857                                 sp->sap = seattr();
 857858                         } else
 858859                                 uerror("%s redeclared", name);
 859860                 }
 860861                 gap = sp->sap = attr_add(sp->sap, gap);
 861862         } else {
 862863                 gap = attr_add(seattr(), gap);
 863864                 sp = NULL;
 864865         }
 865866 
 866867         r = tmpcalloc(sizeof(struct rstack));
 867868         r->rsou = soru;
 868869         r->rsym = sp;
 869870         r->rb = NULL;
 870871         r->ap = gap;
 871872         r->rnext = rpole;
 872873         rpole = r;
 873874 
 874875         return r;
 875876 }
 876877 
 877878 /*
 878879  * Called after a struct is declared to restore the environment.
 879880  * - If ALSTRUCT is defined, this will be the struct alignment and the
 880881  *   struct size will be a multiple of ALSTRUCT, otherwise it will use
 881882  *   the alignment of the largest struct member.
 882883  */
 883884 NODE *
 884885 dclstruct(struct rstack *r)
 885886 {
 886887         NODE *n;
 887888         struct attr *aps, *apb;
 888889         struct symtab *sp;
 889890         int al, sa, sz;
 890891 
 891892         apb = attr_find(r->ap, GCC_ATYP_ALIGNED);
 892893         aps = attr_find(r->ap, ATTR_STRUCT);
 893894         aps->amlist = r->rb;
 894895 
 895896 #ifdef ALSTRUCT
 896897         al = ALSTRUCT;
 897898 #else
 898899         al = ALCHAR;
 899900 #endif
 900901 
 901902         /*
 902903          * extract size and alignment, calculate offsets
 903904          */
 904905         for (sp = r->rb; sp; sp = sp->snext) {
 905906                 sa = talign(sp->stype, sp->sap);
 906907                 if (sp->sclass & FIELD)
 907908                         sz = sp->sclass&FLDSIZ;
 908909                 else
 909910                         sz = (int)tsize(sp->stype, sp->sdf, sp->sap);
 910911                 if (sz > rpole->rstr)
 911912                         rpole->rstr = sz/* for use with unions */
 912913                 /*
 913914                  * set al, the alignment, to the lcm of the alignments
 914915                  * of the members.
 915916                  */
 916917                 SETOFF(al, sa);
 917918         }
 918919 
 919920         SETOFF(rpole->rstr, al);
 920921 
 921922         aps->amsize = rpole->rstr;
 922923         apb->iarg(0) = al;
 923924 
 924925 #ifdef PCC_DEBUG
 925926         if (ddebug) {
 926927                 printf("dclstruct(%s): size=%d, align=%d\n",
 927928                     r->rsym ? r->rsym->sname : "??",
 928929                     aps->amsize, apb->iarg(0));
 929930         }
 930931         if (ddebug>1) {
 931932                 printf("\tsize %d align %d link %p\n",
 932933                     aps->amsize, apb->iarg(0), aps->amlist);
 933934                 for (sp = aps->amlist; sp != NULL; sp = sp->snext) {
 934935                         printf("\tmember %s(%p)\n", sp->sname, sp);
 935936                 }
 936937         }
 937938 #endif
 938939 
 939940 #ifdef STABS
 940941         if (gflag)
 941942                 stabs_struct(r->rsym, r->ap);
 942943 #endif
 943944 
 944945         rpole = r->rnext;
 945946         n = mkty(r->rsou == STNAME ? STRTY : UNIONTY, 0, r->ap);
 946947         n->n_sp = r->rsym;
 947948 
 948949         n->n_qual |= 1; /* definition place XXX used by attributes */
 949950         return n;
 950951 }
 951952 
 952953 /*
 953954  * Add a new member to the current struct or union being declared.
 954955  */
 955956 void
 956957 soumemb(NODE *n, char *name, int class)
 957958 {
 958959         struct symtab *sp, *lsp;
 959960         int incomp, tsz, al;
 960961         TWORD t;
 961962  
 962963         if (rpole == NULL)
 963964                 cerror("soumemb");
 964965  
 965966         /* check if tag name exists */
 966967         lsp = NULL;
 967968         for (sp = rpole->rb; sp != NULL; lsp = sp, sp = sp->snext)
 968969                 if (*name != '*' && sp->sname == name)
 969970                         uerror("redeclaration of %s", name);
 970971 
 971972         sp = getsymtab(name, SMOSNAME);
 972973         if (rpole->rb == NULL)
 973974                 rpole->rb = sp;
 974975         else
 975976                 lsp->snext = sp;
 976977 
 977978         n->n_sp = sp;
 978979         sp->stype = n->n_type;
 979980         sp->squal = n->n_qual;
 980981         sp->slevel = blevel;
 981982         sp->sap = n->n_ap;
 982983         sp->sdf = n->n_df;
 983984 
 984985         if (class & FIELD) {
 985986                 sp->sclass = (char)class;
 986987                 falloc(sp, class&FLDSIZ, NIL);
 987988         } else if (rpole->rsou == STNAME || rpole->rsou == UNAME) {
 988989                 sp->sclass = rpole->rsou == STNAME ? MOS : MOU;
 989990                 if (sp->sclass == MOU)
 990991                         rpole->rstr = 0;
 991992                 al = talign(sp->stype, sp->sap);
 992993                 tsz = (int)tsize(sp->stype, sp->sdf, sp->sap);
 993994                 sp->soffset = upoff(tsz, al, &rpole->rstr);
 994995         }
 995996 
 996997         /*
 997998          * 6.7.2.1 clause 16:
 998999          * "...the last member of a structure with more than one
 9991000          *  named member may have incomplete array type;"
 10001001          */
 10011002         if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
 10021003                 incomp = 1;
 10031004         else
 10041005                 incomp = 0;
 10051006         if ((rpole->flags & LASTELM) || (rpole->rb == sp && incomp == 1))
 10061007                 uerror("incomplete array in struct");
 10071008         if (incomp == 1)
 10081009                 rpole->flags |= LASTELM;
 10091010 
 10101011         /*
 10111012          * 6.7.2.1 clause 2:
 10121013          * "...such a structure shall not be a member of a structure
 10131014          *  or an element of an array."
 10141015          */
 10151016         t = sp->stype;
 10161017         if (rpole->rsou != STNAME || BTYPE(t) != STRTY)
 10171018                 return; /* not for unions */
 10181019         while (ISARY(t))
 10191020                 t = DECREF(t);
 10201021         if (ISPTR(t))
 10211022                 return;
 10221023 
 10231024         if ((lsp = strmemb(sp->sap)) != NULL) {
 10241025                 for (; lsp->snext; lsp = lsp->snext)
 10251026                         ;
 10261027                 if (ISARY(lsp->stype) && lsp->snext &&
 10271028                     lsp->sdf->ddim == NOOFFSET)
 10281029                         uerror("incomplete struct in struct");
 10291030         }
 10301031 }
 10311032 
 10321033 /*
 10331034  * error printing routine in parser
 10341035  */
 10351036 void
 10361037 yyerror(char *s)
 10371038 {
 10381039         uerror(s);
 10391040 }
 10401041 
 10411042 void yyaccpt(void);
 10421043 void
 10431044 yyaccpt(void)
 10441045 {
 10451046         ftnend();
 10461047 }
 10471048 
 10481049 /*
 10491050  * p is top of type list given to tymerge later.
 10501051  * Find correct CALL node and declare parameters from there.
 10511052  */
 10521053 void
 10531054 ftnarg(NODE *p)
 10541055 {
 10551056         NODE *q;
 10561057 
 10571058 #ifdef PCC_DEBUG
 10581059         if (ddebug > 2)
 10591060                 printf("ftnarg(%p)\n", p);
 10601061 #endif
 10611062         /*
 10621063          * Push argument symtab entries onto param stack in reverse order,
 10631064          * due to the nature of the stack it will be reclaimed correct.
 10641065          */
 10651066         for (; p->n_op != NAME; p = p->n_left) {
 10661067                 if (p->n_op == UCALL && p->n_left->n_op == NAME)
 10671068                         return/* Nothing to enter */
 10681069                 if (p->n_op == CALL && p->n_left->n_op == NAME)
 10691070                         break;
 10701071         }
 10711072 
 10721073         p = p->n_right;
 10731074         while (p->n_op == CM) {
 10741075                 q = p->n_right;
 10751076                 if (q->n_op != ELLIPSIS) {
 10761077                         ssave(q->n_sp);
 10771078                         nparams++;
 10781079 #ifdef PCC_DEBUG
 10791080                         if (ddebug > 2)
 10801081                                 printf("        saving sym %s (%p) from (%p)\n",
 10811082                                     q->n_sp->sname, q->n_sp, q);
 10821083 #endif
 10831084                 }
 10841085                 p = p->n_left;
 10851086         }
 10861087         ssave(p->n_sp);
 10871088         if (p->n_type != VOID)
 10881089                 nparams++;
 10891090 
 10901091 #ifdef PCC_DEBUG
 10911092         if (ddebug > 2)
 10921093                 printf("        saving sym %s (%p) from (%p)\n",
 10931094                     nparams ? p->n_sp->sname : "<noname>", p->n_sp, p);
 10941095 #endif
 10951096 }
 10961097 
 10971098 /*
 10981099  * compute the alignment of an object with type ty, sizeoff index s
 10991100  */
 11001101 int
 11011102 talign(unsigned int ty, struct attr *apl)
 11021103 {
 11031104         struct attr *al;
 11041105         int a;
 11051106 
 11061107         for (; ty > BTMASK; ty = DECREF(ty)) {
 11071108                 switch (ty & TMASK) {
 11081109                 case PTR:
 11091110                         return(ALPOINT);
 11101111                 case ARY:
 11111112                         continue;
 11121113                 case FTN:
 11131114                         cerror("compiler takes alignment of function");
 11141115                 }
 11151116         }
 11161117 
 11171118         /* check for alignment attribute */
 11181119         if ((al = attr_find(apl, GCC_ATYP_ALIGNED))) {
 11191120                 if ((a = al->iarg(0)) == 0) {
 11201121                         uerror("no alignment");
 11211122                         a = ALINT;
 11221123                 }
 11231124                 return a;
 11241125         }
 11251126 
 11261127         ty = BTYPE(ty);
 11271128         if (ty >= CHAR && ty <= ULONGLONG && ISUNSIGNED(ty))
 11281129                 ty = DEUNSIGN(ty);
 11291130 
 11301131         switch (ty) {
 11311132         case BOOL: a = ALBOOL; break;
 11321133         case CHAR: a = ALCHAR; break;
 11331134         case SHORT: a = ALSHORT; break;
 11341135         case INT: a = ALINT; break;
 11351136         case LONG: a = ALLONG; break;
 11361137         case LONGLONG: a = ALLONGLONG; break;
 11371138         case FLOAT: a = ALFLOAT; break;
 11381139         case DOUBLE: a = ALDOUBLE; break;
 11391140         case LDOUBLE: a = ALLDOUBLE; break;
 11401141         default:
 11411142                 uerror("no alignment");
 11421143                 a = ALINT;
 11431144         }
 11441145         return a;
 11451146 }
 11461147 
 11471148 short sztable[] = { 0, SZBOOL, SZCHAR, SZCHAR, SZSHORT, SZSHORT, SZINT, SZINT,
 11481149         SZLONG, SZLONG, SZLONGLONG, SZLONGLONG, SZFLOAT, SZDOUBLE, SZLDOUBLE };
 11491150 
 11501151 /* compute the size associated with type ty,
 11511152  *  dimoff d, and sizoff s */
 11521153 /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
 11531154 OFFSZ
 11541155 tsize(TWORD ty, union dimfun *d, struct attr *apl)
 11551156 {
 11561157         struct attr *ap, *ap2;
 11571158         OFFSZ mult, sz;
 11581159 
 11591160         mult = 1;
 11601161 
 11611162         for (; ty > BTMASK; ty = DECREF(ty)) {
 11621163                 switch (ty & TMASK) {
 11631164 
 11641165                 case FTN:
 11651166                         uerror( "cannot take size of function");
 11661167                 case PTR:
 11671168                         return( SZPOINT(ty) * mult );
 11681169                 case ARY:
 11691170                         if (d->ddim == NOOFFSET)
 11701171                                 return 0;
 11711172                         if (d->ddim < 0)
 11721173                                 cerror("tsize: dynarray");
 11731174                         mult *= d->ddim;
 11741175                         d++;
 11751176                 }
 11761177         }
 11771178 
 11781179         if (ty == VOID)
 11791180                 ty = CHAR;
 11801181         if (ty <= LDOUBLE)
 11811182                 sz = sztable[ty];
 11821183         else if (ISSOU(ty)) {
 11831184                 if ((ap = strattr(apl)) == NULL ||
 11841185                     (ap2 = attr_find(apl, GCC_ATYP_ALIGNED)) == NULL ||
 11851186                     (ap2->iarg(0) == 0)) {
 11861187                         uerror("unknown structure/union/enum");
 11871188                         sz = SZINT;
 11881189                 } else
 11891190                         sz = ap->amsize;
 11901191         } else {
 11911192                 uerror("unknown type");
 11921193                 sz = SZINT;
 11931194         }
 11941195 
 11951196         return((unsigned int)sz * mult);
 11961197 }
 11971198 
 11981199 /*
 11991200  * Save string (and print it out).  If wide then wide string.
 12001201  */
 12011202 NODE *
 12021203 strend(int wide, char *str)
 12031204 {
 12041205         struct symtab *sp;
 12051206         NODE *p;
 12061207 
 12071208         /* If an identical string is already emitted, just forget this one */
 12081209         if (wide) {
 12091210                 /* Do not save wide strings, at least not now */
 12101211                 sp = getsymtab(str, SSTRING|STEMP);
 12111212         } else {
 12121213                 str = addstring(str);   /* enter string in string table */
 12131214                 sp = lookup(str, SSTRING);      /* check for existance */
 12141215         }
 12151216 
 12161217         if (sp->soffset == 0) { /* No string */
 12171218                 char *wr;
 12181219                 int i;
 12191220 
 12201221                 sp->sclass = STATIC;
 12211222                 sp->slevel = 1;
 12221223                 sp->soffset = getlab();
 12231224                 sp->squal = (CON >> TSHIFT);
 12241225                 sp->sdf = permalloc(sizeof(union dimfun));
 12251226                 if (wide) {
 12261227                         sp->stype = WCHAR_TYPE+ARY;
 12271228                 } else {
 12281229                         if (xuchar) {
 12291230                                 sp->stype = UCHAR+ARY;
 12301231                         } else {
 12311232                                 sp->stype = CHAR+ARY;
 12321233                         }
 12331234                 }
 12341235                 for (wr = sp->sname, i = 1; *wr; i++)
 12351236                         if (*wr++ == '\\')
 12361237                                 (void)esccon(&wr);
 12371238 
 12381239                 sp->sdf->ddim = i;
 12391240                 if (wide)
 12401241                         inwstring(sp);
 12411242                 else
 12421243                         instring(sp);
 12431244         }
 12441245 
 12451246         p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
 12461247         p->n_sp = sp;
 12471248         return(clocal(p));
 12481249 }
 12491250 
 12501251 /*
 12511252  * Print out a wide string by calling ninval().
 12521253  */
 12531254 void
 12541255 inwstring(struct symtab *sp)
 12551256 {
 12561257         char *s = sp->sname;
 12571258         NODE *p;
 12581259 
 12591260         locctr(STRNG, sp);
 12601261         defloc(sp);
 12611262         p = xbcon(0, NULL, WCHAR_TYPE);
 12621263         do {
 12631264                 if (*s++ == '\\')
 12641265                         p->n_lval = esccon(&s);
 12651266                 else
 12661267                         p->n_lval = (unsigned char)s[-1];
 12671268                 inval(0, tsize(WCHAR_TYPE, NULL, NULL), p);
 12681269         } while (s[-1] != 0);
 12691270         nfree(p);
 12701271 }
 12711272 
 12721273 #ifndef MYINSTRING
 12731274 /*
 12741275  * Print out a string of characters.
 12751276  * Assume that the assembler understands C-style escape
 12761277  * sequences.
 12771278  */
 12781279 void
 12791280 instring(struct symtab *sp)
 12801281 {
 12811282         char *s, *str;
 12821283 
 12831284         locctr(STRNG, sp);
 12841285         defloc(sp);
 12851286         str = sp->sname;
 12861287 
 12871288         /* be kind to assemblers and avoid long strings */
 12881289         printf("\t.ascii \"");
 12891290         for (s = str; *s != 0; ) {
 12901291                 if (*s++ == '\\') {
 12911292                         (void)esccon(&s);
 12921293                 }
 12931294                 if (s - str > 60) {
 12941295                         fwrite(str, 1, s - str, stdout);
 12951296                         printf("\"\n\t.ascii \"");
 12961297                         str = s;
 12971298                 }
 12981299         }
 12991300         fwrite(str, 1, s - str, stdout);
 13001301         printf("\\0\"\n");
 13011302 }
 13021303 #endif
 13031304 
 13041305 /*
 13051306  * update the offset pointed to by poff; return the
 13061307  * offset of a value of size `size', alignment `alignment',
 13071308  * given that off is increasing
 13081309  */
 13091310 int
 13101311 upoff(int size, int alignment, int *poff)
 13111312 {
 13121313         int off;
 13131314 
 13141315         off = *poff;
 13151316         SETOFF(off, alignment);
 13161317         if (off < 0)
 13171318                 cerror("structure or stack overgrown"); /* wrapped */
 13181319         *poff = off+size;
 13191320         return (off);
 13201321 }
 13211322 
 13221323 /*
 13231324  * allocate p with offset *poff, and update *poff
 13241325  */
 13251326 int
 13261327 oalloc(struct symtab *p, int *poff )
 13271328 {
 13281329         int al, off, tsz;
 13291330         int noff;
 13301331 
 13311332         /*
 13321333          * Only generate tempnodes if we are optimizing,
 13331334          * and only for integers, floats or pointers,
 13341335          * and not if the type on this level is volatile.
 13351336          */
 13361337         if (xtemps && ((p->sclass == AUTO) || (p->sclass == REGISTER)) &&
 13371338             (p->stype < STRTY || ISPTR(p->stype)) &&
 13381339             !(cqual(p->stype, p->squal) & VOL) && cisreg(p->stype)) {
 13391340                 NODE *tn = tempnode(0, p->stype, p->sdf, p->sap);
 13401341                 p->soffset = regno(tn);
 13411342                 p->sflags |= STNODE;
 13421343                 nfree(tn);
 13431344                 return 0;
 13441345         }
 13451346 
 13461347         al = talign(p->stype, p->sap);
 13471348         noff = off = *poff;
 13481349         tsz = (int)tsize(p->stype, p->sdf, p->sap);
 13491350 #ifdef BACKAUTO
 13501351         if (p->sclass == AUTO) {
 13511352                 noff = off + tsz;
 13521353                 if (noff < 0)
 13531354                         cerror("stack overflow");
 13541355                 SETOFF(noff, al);
 13551356                 off = -noff;
 13561357         } else
 13571358 #endif
 13581359         if (p->sclass == PARAM && (p->stype == CHAR || p->stype == UCHAR ||
 13591360             p->stype == SHORT || p->stype == USHORT || p->stype == BOOL)) {
 13601361                 off = upoff(SZINT, ALINT, &noff);
 13611362 #if TARGET_ENDIAN == TARGET_BE
 13621363                 off = noff - tsz;
 13631364 #endif
 13641365         } else {
 13651366                 off = upoff(tsz, al, &noff);
 13661367         }
 13671368 
 13681369         if (p->sclass != REGISTER) {
 13691370         /* in case we are allocating stack space for register arguments */
 13701371                 if (p->soffset == NOOFFSET)
 13711372                         p->soffset = off;
 13721373                 else if(off != p->soffset)
 13731374                         return(1);
 13741375         }
 13751376 
 13761377         *poff = noff;
 13771378         return(0);
 13781379 }
 13791380 
 13801381 /*
 13811382  * Delay emission of code generated in argument headers.
 13821383  */
 13831384 static void
 13841385 edelay(NODE *p)
 13851386 {
 13861387         if (blevel == 1) {
 13871388                 /* Delay until after declarations */
 13881389                 if (parlink == NULL)
 13891390                         parlink = p;
 13901391                 else
 13911392                         parlink = block(COMOP, parlink, p, 0, 0, 0);
 13921393         } else
 13931394                 ecomp(p);
 13941395 }
 13951396 
 13961397 /*
 13971398  * Traverse through the array args, evaluate them and put the
 13981399  * resulting temp numbers in the dim fields.
 13991400  */
 14001401 static void
 14011402 evalidx(struct symtab *sp)
 14021403 {
 14031404         union dimfun *df;
 14041405         NODE *p;
 14051406         TWORD t;
 14061407         int astkp = 0;
 14071408 
 14081409         if (arrstk[0] == NIL)
 14091410                 astkp++; /* for parameter arrays */
 14101411 
 14111412         if (isdyn(sp))
 14121413                 sp->sflags |= SDYNARRAY;
 14131414 
 14141415         df = sp->sdf;
 14151416         for (t = sp->stype; t > BTMASK; t = DECREF(t)) {
 14161417                 if (!ISARY(t))
 14171418                         continue;
 14181419                 if (df->ddim == -1) {
 14191420                         p = tempnode(0, INT, 0, 0);
 14201421                         df->ddim = -regno(p);
 14211422                         edelay(buildtree(ASSIGN, p, arrstk[astkp++]));
 14221423                 }
 14231424                 df++;
 14241425         }
 14251426         arrstkp = 0;
 14261427 }
 14271428 
 14281429 /*
 14291430  * Return 1 if dynamic array, 0 otherwise.
 14301431  */
 14311432 int
 14321433 isdyn(struct symtab *sp)
 14331434 {
 14341435         union dimfun *df = sp->sdf;
 14351436         TWORD t;
 14361437 
 14371438         for (t = sp->stype; t > BTMASK; t = DECREF(t)) {
 14381439                 if (!ISARY(t))
 14391440                         return 0;
 14401441                 if (df->ddim < 0 && df->ddim != NOOFFSET)
 14411442                         return 1;
 14421443                 df++;
 14431444         }
 14441445         return 0;
 14451446 }
 14461447 
 14471448 /*
 14481449  * Allocate space on the stack for dynamic arrays (or at least keep track
 14491450  * of the index).
 14501451  * Strategy is as follows:
 14511452  * - first entry is a pointer to the dynamic datatype.
 14521453  * - if it's a one-dimensional array this will be the only entry used.
 14531454  * - if it's a multi-dimensional array the following (numdim-1) integers
 14541455  *   will contain the sizes to multiply the indexes with.
 14551456  * - code to write the dimension sizes this will be generated here.
 14561457  * - code to allocate space on the stack will be generated here.
 14571458  */
 14581459 static void
 14591460 dynalloc(struct symtab *p, int *poff)
 14601461 {
 14611462         union dimfun *df;
 14621463         NODE *n, *tn, *pol;
 14631464         TWORD t;
 14641465 
 14651466         /*
 14661467          * The pointer to the array is not necessarily stored in a
 14671468          * TEMP node, but if it is, its number is in the soffset field;
 14681469          */
 14691470         t = p->stype;
 14701471         p->sflags |= STNODE;
 14711472         p->stype = INCREF(p->stype); /* Make this an indirect pointer */
 14721473         tn = tempnode(0, p->stype, p->sdf, p->sap);
 14731474         p->soffset = regno(tn);
 14741475 
 14751476         df = p->sdf;
 14761477 
 14771478         pol = bcon(1);
 14781479         for (; t > BTMASK; t = DECREF(t)) {
 14791480                 if (!ISARY(t))
 14801481                         break;
 14811482                 if (df->ddim < 0)
 14821483                         n = tempnode(-df->ddim, INT, 0, 0);
 14831484                 else
 14841485                         n = bcon(df->ddim);
 14851486 
 14861487                 pol = buildtree(MUL, pol, n);
 14871488                 df++;
 14881489         }
 14891490         /* Create stack gap */
 14901491         spalloc(tn, pol, tsize(t, 0, p->sap));
 14911492 }
 14921493 
 14931494 /*
 14941495  * allocate a field of width w
 14951496  * new is 0 if new entry, 1 if redefinition, -1 if alignment
 14961497  */
 14971498 int
 14981499 falloc(struct symtab *p, int w, NODE *pty)
 14991500 {
 15001501         TWORD otype, type;
 15011502         int al,sz;
 15021503 
 15031504         otype = type = p ? p->stype : pty->n_type;
 15041505 
 15051506         if (type == BOOL)
 15061507                 type = BOOL_TYPE;
 15071508         if (!ISINTEGER(type)) {
 15081509                 uerror("illegal field type");
 15091510                 type = INT;
 15101511         }
 15111512 
 15121513         al = talign(type, NULL);
 15131514         sz = tsize(type, NULL, NULL);
 15141515 
 15151516         if (w > sz) {
 15161517                 uerror("field too big");
 15171518                 w = sz;
 15181519         }
 15191520 
 15201521         if (w == 0) { /* align only */
 15211522                 SETOFF(rpole->rstr, al);
 15221523                 if (p != NULL)
 15231524                         uerror("zero size field");
 15241525                 return(0);
 15251526         }
 15261527 
 15271528         if (rpole->rstr%al + w > sz)
 15281529                 SETOFF(rpole->rstr, al);
 15291530         if (p == NULL) {
 15301531                 rpole->rstr += w/* we know it will fit */
 15311532                 return(0);
 15321533         }
 15331534 
 15341535         /* establish the field */
 15351536 
 15361537         p->soffset = rpole->rstr;
 15371538         rpole->rstr += w;
 15381539         p->stype = otype;
 15391540         fldty(p);
 15401541         return(0);
 15411542 }
 15421543 
 15431544 /*
 15441545  * Check if this symbol should be a common or must be handled in data seg.
 15451546  */
 15461547 static void
 15471548 commchk(struct symtab *sp)
 15481549 {
 15491550         if ((sp->sflags & STLS) || attr_find(sp->sap, GCC_ATYP_SECTION)) {
 15501551                 /* TLS handled in data segment */
 15511552                 if (sp->sclass == EXTERN)
 15521553                         sp->sclass = EXTDEF;
 15531554                 beginit(sp);
 15541555                 endinit(1);
 15551556         } else {
 15561557                 symdirec(sp);
 15571558                 defzero(sp);
 15581559         }
 15591560 }
 15601561 
 15611562 void
 15621563 nidcl(NODE *p, int class)
 15631564 {
 15641565         nidcl2(p, class, 0);
 15651566 }
 15661567 
 15671568 /*
 15681569  * handle unitialized declarations assumed to be not functions:
 15691570  * int a;
 15701571  * extern int a;
 15711572  * static int a;
 15721573  */
 15731574 void
 15741575 nidcl2(NODE *p, int class, char *astr)
 15751576 {
 15761577         struct symtab *sp;
 15771578         int commflag = 0;
 15781579 
 15791580         /* compute class */
 15801581         if (class == SNULL) {
 15811582                 if (blevel > 1)
 15821583                         class = AUTO;
 15831584                 else if (blevel != 0 || rpole)
 15841585                         cerror( "nidcl error" );
 15851586                 else /* blevel = 0 */
 15861587                         commflag = 1, class = EXTERN;
 15871588         }
 15881589 
 15891590         defid2(p, class, astr);
 15901591 
 15911592         sp = p->n_sp;
 15921593         /* check if forward decl */
 15931594         if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
 15941595                 return;
 15951596 
 15961597         if (sp->sflags & SASG)
 15971598                 return; /* already initialized */
 15981599 
 15991600         switch (class) {
 16001601         case EXTDEF:
 16011602                 /* simulate initialization by 0 */
 16021603                 simpleinit(p->n_sp, bcon(0));
 16031604                 break;
 16041605         case EXTERN:
 16051606                 if (commflag)
 16061607                         lcommadd(p->n_sp);
 16071608                 else
 16081609                         extdec(p->n_sp);
 16091610                 break;
 16101611         case STATIC:
 16111612                 if (blevel == 0)
 16121613                         lcommadd(p->n_sp);
 16131614                 else
 16141615                         commchk(p->n_sp);
 16151616                 break;
 16161617         }
 16171618 }
 16181619 
 16191620 struct lcd {
 16201621         SLIST_ENTRY(lcd) next;
 16211622         struct symtab *sp;
 16221623 };
 16231624 
 16241625 static SLIST_HEAD(, lcd) lhead = { NULL, &lhead.q_forw};
 16251626 
 16261627 /*
 16271628  * Add a local common statement to the printout list.
 16281629  */
 16291630 void
 16301631 lcommadd(struct symtab *sp)
 16311632 {
 16321633         struct lcd *lc, *lcp;
 16331634 
 16341635         lcp = NULL;
 16351636         SLIST_FOREACH(lc, &lhead, next) {
 16361637                 if (lc->sp == sp)
 16371638                         return; /* already exists */
 16381639                 if (lc->sp == NULL && lcp == NULL)
 16391640                         lcp = lc;
 16401641         }
 16411642         if (lcp == NULL) {
 16421643                 lc = permalloc(sizeof(struct lcd));
 16431644                 lc->sp = sp;
 16441645                 SLIST_INSERT_LAST(&lhead, lc, next);
 16451646         } else
 16461647                 lcp->sp = sp;
 16471648 }
 16481649 
 16491650 /*
 16501651  * Delete a local common statement.
 16511652  */
 16521653 void
 16531654 lcommdel(struct symtab *sp)
 16541655 {
 16551656         struct lcd *lc;
 16561657 
 16571658         SLIST_FOREACH(lc, &lhead, next) {
 16581659                 if (lc->sp == sp) {
 16591660                         lc->sp = NULL;
 16601661                         return;
 16611662                 }
 16621663         }
 16631664 }
 16641665 
 16651666 /*
 16661667  * Print out the remaining common statements.
 16671668  */
 16681669 void
 16691670 lcommprint(void)
 16701671 {
 16711672         struct lcd *lc;
 16721673 
 16731674         SLIST_FOREACH(lc, &lhead, next) {
 16741675                 if (lc->sp != NULL)
 16751676                         commchk(lc->sp);
 16761677         }
 16771678 }
 16781679 
 16791680 /*
 16801681  * Merge given types to a single node.
 16811682  * Any type can end up here.
 16821683  * p is the old node, q is the old (if any).
 16831684  * CLASS is AUTO, EXTERN, REGISTER, STATIC or TYPEDEF.
 16841685  * QUALIFIER is VOL or CON
 16851686  * TYPE is CHAR, SHORT, INT, LONG, SIGNED, UNSIGNED, VOID, BOOL, FLOAT,
 16861687  *      DOUBLE, STRTY, UNIONTY.
 16871688  */
 16881689 struct typctx {
 16891690         int class, qual, sig, uns, cmplx, imag, err;
 16901691         TWORD type;
 16911692         NODE *saved;
 16921693         struct attr *pre, *post;
 16931694 };
 16941695 
 16951696 static void
 16961697 typwalk(NODE *p, void *arg)
 16971698 {
 16981699         struct typctx *tc = arg;
 16991700 
 17001701 #define cmop(x,y) block(CM, x, y, INT, 0, 0)
 17011702         switch (p->n_op) {
 17021703         case ATTRIB:
 17031704                 if (tc->saved && (tc->saved->n_qual & 1)) {
 17041705                         tc->post = attr_add(tc->post,gcc_attr_parse(p->n_left));
 17051706                 } else {
 17061707                         tc->pre = attr_add(tc->pre, gcc_attr_parse(p->n_left));
 17071708                 }
 17081709                 p->n_left = bcon(0); /* For tfree() */
 17091710                 break;
 17101711         case CLASS:
 17111712                 if (tc->class)
 17121713                         tc->err = 1; /* max 1 class */
 17131714                 tc->class = p->n_type;
 17141715                 break;
 17151716 
 17161717         case QUALIFIER:
 17171718 #if 0
 17181719                 if (p->n_qual == 0)
 17191720                         uerror("invalid use of 'restrict'");
 17201721 #endif
 17211722                 tc->qual |= p->n_qual >> TSHIFT;
 17221723                 break;
 17231724 
 17241725         case TYPE:
 17251726                 if (p->n_sp != NULL || ISSOU(p->n_type)) {
 17261727                         /* typedef, enum or struct/union */
 17271728                         if (tc->saved || tc->type)
 17281729                                 tc->err = 1;
 17291730 #ifdef GCC_COMPAT
 17301731                         if (ISSOU(p->n_type) && p->n_left) {
 17311732                                 if (tc->post)
 17321733                                         cerror("typwalk");
 17331734                                 tc->post = gcc_attr_parse(p->n_left);
 17341735                         }
 17351736 #endif
 17361737                         tc->saved = ccopy(p);
 17371738                         break;
 17381739                 }
 17391740 
 17401741                 switch (p->n_type) {
 17411742                 case BOOL:
 17421743                 case CHAR:
 17431744                 case FLOAT:
 17441745                 case VOID:
 17451746                         if (tc->type)
 17461747                                 tc->err = 1;
 17471748                         tc->type = p->n_type;
 17481749                         break;
 17491750                 case DOUBLE:
 17501751                         if (tc->type == 0)
 17511752                                 tc->type = DOUBLE;
 17521753                         else if (tc->type == LONG)
 17531754                                 tc->type = LDOUBLE;
 17541755                         else
 17551756                                 tc->err = 1;
 17561757                         break;
 17571758                 case SHORT:
 17581759                         if (tc->type == 0 || tc->type == INT)
 17591760                                 tc->type = SHORT;
 17601761                         else
 17611762                                 tc->err = 1;
 17621763                         break;
 17631764                 case INT:
 17641765                         if (tc->type == SHORT || tc->type == LONG ||
 17651766                             tc->type == LONGLONG)
 17661767                                 break;
 17671768                         else if (tc->type == 0)
 17681769                                 tc->type = INT;
 17691770                         else
 17701771                                 tc->err = 1;
 17711772                         break;
 17721773                 case LONG:
 17731774                         if (tc->type == 0)
 17741775                                 tc->type = LONG;
 17751776                         else if (tc->type == INT)
 17761777                                 break;
 17771778                         else if (tc->type == LONG)
 17781779                                 tc->type = LONGLONG;
 17791780                         else if (tc->type == DOUBLE)
 17801781                                 tc->type = LDOUBLE;
 17811782                         else
 17821783                                 tc->err = 1;
 17831784                         break;
 17841785                 case SIGNED:
 17851786                         if (tc->sig || tc->uns)
 17861787                                 tc->err = 1;
 17871788                         tc->sig = 1;
 17881789                         break;
 17891790                 case UNSIGNED:
 17901791                         if (tc->sig || tc->uns)
 17911792                                 tc->err = 1;
 17921793                         tc->uns = 1;
 17931794                         break;
 17941795                 case COMPLEX:
 17951796                         tc->cmplx = 1;
 17961797                         break;
 17971798                 case IMAG:
 17981799                         tc->imag = 1;
 17991800                         break;
 18001801                 default:
 18011802                         cerror("typwalk");
 18021803                 }
 18031804         }
 18041805 
 18051806 }
 18061807 
 18071808 NODE *
 18081809 typenode(NODE *p)
 18091810 {
 18101811         struct symtab *sp;
 18111812         struct typctx tc;
 18121813         NODE *q;
 18131814         char *c;
 18141815 
 18151816         memset(&tc, 0, sizeof(struct typctx));
 18161817 
 18171818         flist(p, typwalk, &tc);
 18181819         tfree(p);
 18191820 
 18201821         if (tc.err)
 18211822                 goto bad;
 18221823 
 18231824         if (tc.cmplx || tc.imag) {
 18241825                 if (tc.type == 0)
 18251826                         tc.type = DOUBLE;
 18261827                 if ((tc.cmplx && tc.imag) || tc.sig || tc.uns ||
 18271828                     !ISFTY(tc.type))
 18281829                         goto bad;
 18291830                 if (tc.cmplx) {
 18301831                         c = tc.type == DOUBLE ? "0d" :
 18311832                             tc.type == FLOAT ? "0f" : "0l";
 18321833                         sp = lookup(addname(c), 0);
 18331834                         tc.type = STRTY;
 18341835                         tc.saved = mkty(tc.type, sp->sdf, sp->sap);
 18351836                         tc.saved->n_sp = sp;
 18361837                         tc.type = 0;
 18371838                 } else
 18381839                         tc.type += (FIMAG-FLOAT);
 18391840         }
 18401841 
 18411842         if (tc.saved && tc.type)
 18421843                 goto bad;
 18431844         if (tc.sig || tc.uns) {
 18441845                 if (tc.type == 0)
 18451846                         tc.type = tc.sig ? INT : UNSIGNED;
 18461847                 if (tc.type > ULONGLONG)
 18471848                         goto bad;
 18481849                 if (tc.uns)
 18491850                         tc.type = ENUNSIGN(tc.type);
 18501851         }
 18511852 
 18521853         if (xuchar && tc.type == CHAR && tc.sig == 0)
 18531854                 tc.type = UCHAR;
 18541855 
 18551856 #ifdef GCC_COMPAT
 18561857         if (pragma_packed) {
 18571858                 q = bdty(CALL, bdty(NAME, "packed"), bcon(pragma_packed));
 18581859                 tc.post = attr_add(tc.post, gcc_attr_parse(q));
 18591860         }
 18601861         if (pragma_aligned) {
 18611862                 /* Deal with relevant pragmas */
 18621863                 q = bdty(CALL, bdty(NAME, "aligned"), bcon(pragma_aligned));
 18631864                 tc.post = attr_add(tc.post, gcc_attr_parse(q));
 18641865         }
 18651866         pragma_aligned = pragma_packed = 0;
 18661867 #endif
 18671868         if ((q = tc.saved) == NULL) {
 18681869                 TWORD t;
 18691870                 if ((t = BTYPE(tc.type)) > LDOUBLE && t != VOID &&
 18701871                     t != BOOL && !(t >= FIMAG && t <= LIMAG))
 18711872                         cerror("typenode2 t %x", tc.type);
 18721873                 if (t == UNDEF) {
 18731874                         t = INT;
 18741875                         MODTYPE(tc.type, INT);
 18751876                 }
 18761877                 qmkty(tc.type, 0, 0);
 18771878         }
 18781879         q->n_ap = attr_add(q->n_ap, tc.post);
 18791880         q->n_qual = tc.qual;
 18801881         q->n_lval = tc.class;
 18811882 #ifdef GCC_COMPAT
 18821883         if (tc.post) {
 18831884                 /* Can only occur for TYPEDEF, STRUCT or UNION */
 18841885                 if (tc.saved == NULL)
 18851886                         cerror("typenode");
 18861887                 if (tc.saved->n_sp) /* trailer attributes for structs */
 18871888                         tc.saved->n_sp->sap = q->n_ap;
 18881889         }
 18891890         if (tc.pre)
 18901891                 q->n_ap = attr_add(q->n_ap, tc.pre);
 18911892         gcc_tcattrfix(q);
 18921893 #endif
 18931894         return q;
 18941895 
 18951896 bad:    uerror("illegal type combination");
 18961897         return mkty(INT, 0, 0);
 18971898 }
 18981899 
 18991900 struct tylnk {
 19001901         struct tylnk *next;
 19011902         union dimfun df;
 19021903 };
 19031904 
 19041905 /*
 19051906  * Retrieve all CM-separated argument types, sizes and dimensions and
 19061907  * put them in an array.
 19071908  * XXX - can only check first type level, side effects?
 19081909  */
 19091910 static union arglist *
 19101911 arglist(NODE *n)
 19111912 {
 19121913         union arglist *al;
 19131914         NODE *w = n, **ap;
 19141915         int num, cnt, i, j, k;
 19151916         TWORD ty;
 19161917 
 19171918 #ifdef PCC_DEBUG
 19181919         if (pdebug) {
 19191920                 printf("arglist %p\n", n);
 19201921                 fwalk(n, eprint, 0);
 19211922         }
 19221923 #endif
 19231924         /* First: how much to allocate */
 19241925         for (num = cnt = 0, w = n; w->n_op == CM; w = w->n_left) {
 19251926                 cnt++;  /* Number of levels */
 19261927                 num++;  /* At least one per step */
 19271928                 if (w->n_right->n_op == ELLIPSIS)
 19281929                         continue;
 19291930                 ty = w->n_right->n_type;
 19301931                 if (ty == ENUMTY) {
 19311932                         uerror("arg %d enum undeclared", cnt);
 19321933                         ty = w->n_right->n_type = INT;
 19331934                 }
 19341935                 if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
 19351936                         num++;
 19361937                 while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
 19371938                         ty = DECREF(ty);
 19381939                 if (ty > BTMASK)
 19391940                         num++;
 19401941         }
 19411942         cnt++;
 19421943         ty = w->n_type;
 19431944         if (ty == ENUMTY) {
 19441945                 uerror("arg %d enum undeclared", cnt);
 19451946                 ty = w->n_type = INT;
 19461947         }
 19471948         if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
 19481949                 num++;
 19491950         while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
 19501951                 ty = DECREF(ty);
 19511952         if (ty > BTMASK)
 19521953                 num++;
 19531954         num += 2; /* TEND + last arg type */
 19541955 
 19551956         /* Second: Create list to work on */
 19561957         ap = tmpalloc(sizeof(NODE *) * cnt);
 19571958         al = permalloc(sizeof(union arglist) * num);
 19581959         arglistcnt += num;
 19591960 
 19601961         for (w = n, i = 0; w->n_op == CM; w = w->n_left)
 19611962                 ap[i++] = w->n_right;
 19621963         ap[i] = w;
 19631964 
 19641965         /* Third: Create actual arg list */
 19651966         for (k = 0, j = i; j >= 0; j--) {
 19661967                 if (ap[j]->n_op == ELLIPSIS) {
 19671968                         al[k++].type = TELLIPSIS;
 19681969                         ap[j]->n_op = ICON; /* for tfree() */
 19691970                         continue;
 19701971                 }
 19711972                 /* Convert arrays to pointers */
 19721973                 if (ISARY(ap[j]->n_type)) {
 19731974                         ap[j]->n_type += (PTR-ARY);
 19741975                         ap[j]->n_df++;
 19751976                 }
 19761977                 /* Convert (silently) functions to pointers */
 19771978                 if (ISFTN(ap[j]->n_type))
 19781979                         ap[j]->n_type = INCREF(ap[j]->n_type);
 19791980                 ty = ap[j]->n_type;
 19801981 #ifdef GCC_COMPAT
 19811982                 if (ty == UNIONTY &&
 19821983                     attr_find(ap[j]->n_ap, GCC_ATYP_TRANSP_UNION)){
 19831984                         /* transparent unions must have compatible types
 19841985                          * shortcut here: if pointers, set void *,
 19851986                          * otherwise btype.
 19861987                          */
 19871988                         struct symtab *sp = strmemb(ap[j]->n_ap);
 19881989                         ty = ISPTR(sp->stype) ? PTR|VOID : sp->stype;
 19891990                 }
 19901991 #endif
 19911992                 al[k++].type = ty;
 19921993                 if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
 19931994                         al[k++].sap = ap[j]->n_ap;
 19941995                 while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
 19951996                         ty = DECREF(ty);
 19961997                 if (ty > BTMASK)
 19971998                         al[k++].df = ap[j]->n_df;
 19981999         }
 19992000         al[k++].type = TNULL;
 20002001         if (k > num)
 20012002                 cerror("arglist: k%d > num%d", k, num);
 20022003         tfree(n);
 20032004 #ifdef PCC_DEBUG
 20042005         if (pdebug)
 20052006                 alprint(al, 0);
 20062007 #endif
 20072008         return al;
 20082009 }
 20092010 
 20102011 static void
 20112012 tylkadd(union dimfun dim, struct tylnk **tylkp, int *ntdim)
 20122013 {
 20132014         (*tylkp)->next = tmpalloc(sizeof(struct tylnk));
 20142015         *tylkp = (*tylkp)->next;
 20152016         (*tylkp)->next = NULL;
 20162017         (*tylkp)->df = dim;
 20172018         (*ntdim)++;
 20182019 }
 20192020 
 20202021 /*
 20212022  * build a type, and stash away dimensions,
 20222023  * from a parse tree of the declaration
 20232024  * the type is build top down, the dimensions bottom up
 20242025  */
 20252026 static void
 20262027 tyreduce(NODE *p, struct tylnk **tylkp, int *ntdim)
 20272028 {
 20282029         union dimfun dim;
 20292030         NODE *r = NULL;
 20302031         int o;
 20312032         TWORD t, q;
 20322033 
 20332034         o = p->n_op;
 20342035         if (o == NAME) {
 20352036                 p->n_qual = DECQAL(p->n_qual);
 20362037                 return;
 20372038         }
 20382039 
 20392040         t = INCREF(p->n_type);
 20402041         q = p->n_qual;
 20412042         switch (o) {
 20422043         case CALL:
 20432044                 t += (FTN-PTR);
 20442045                 dim.dfun = arglist(p->n_right);
 20452046                 break;
 20462047         case UCALL:
 20472048                 t += (FTN-PTR);
 20482049                 dim.dfun = NULL;
 20492050                 break;
 20502051         case LB:
 20512052                 t += (ARY-PTR);
 20522053                 if (p->n_right->n_op != ICON) {
 20532054                         r = p->n_right;
 20542055                         o = RB;
 20552056                 } else {
 20562057                         dim.ddim = (int)p->n_right->n_lval;
 20572058                         nfree(p->n_right);
 20582059 #ifdef notdef
 20592060         /* XXX - check dimensions at usage time */
 20602061                         if (dim.ddim == NOOFFSET && p->n_left->n_op == LB)
 20612062                                 uerror("null dimension");
 20622063 #endif
 20632064                 }
 20642065                 break;
 20652066         }
 20662067 
 20672068         p->n_left->n_type = t;
 20682069         p->n_left->n_qual = INCQAL(q) | p->n_left->n_qual;
 20692070         tyreduce(p->n_left, tylkp, ntdim);
 20702071 
 20712072         if (o == LB || o == UCALL || o == CALL)
 20722073                 tylkadd(dim, tylkp, ntdim);
 20732074         if (o == RB) {
 20742075                 dim.ddim = -1;
 20752076                 tylkadd(dim, tylkp, ntdim);
 20762077                 arrstk[arrstkp++] = r;
 20772078         }
 20782079 
 20792080         p->n_sp = p->n_left->n_sp;
 20802081         p->n_type = p->n_left->n_type;
 20812082         p->n_qual = p->n_left->n_qual;
 20822083 }
 20832084 
 20842085 /*
 20852086  * merge type typ with identifier idp.
 20862087  * idp is returned as a NAME node with correct types,
 20872088  * typ is untouched since multiple declarations uses it.
 20882089  * typ has type attributes, idp can never carry such attributes
 20892090  * so on return just a pointer to the typ attributes is returned.
 20902091  */
 20912092 NODE *
 20922093 tymerge(NODE *typ, NODE *idp)
 20932094 {
 20942095         TWORD t;
 20952096         NODE *p;
 20962097         union dimfun *j;
 20972098         struct tylnk *base, tylnk, *tylkp;
 20982099         struct attr *bap;
 20992100         int ntdim, i;
 21002101 
 21012102 #ifdef PCC_DEBUG
 21022103         if (ddebug > 2) {
 21032104                 printf("tymerge(%p,%p)\n", typ, idp);
 21042105                 fwalk(typ, eprint, 0);
 21052106                 fwalk(idp, eprint, 0);
 21062107         }
 21072108 #endif
 21082109 
 21092110         if (typ->n_op != TYPE)
 21102111                 cerror("tymerge: arg 1");
 21112112 
 21122113         bap = typ->n_ap;
 21132114 
 21142115         idp->n_type = typ->n_type;
 21152116         idp->n_qual |= typ->n_qual;
 21162117 
 21172118         tylkp = &tylnk;
 21182119         tylkp->next = NULL;
 21192120         ntdim = 0;
 21202121 
 21212122         tyreduce(idp, &tylkp, &ntdim);
 21222123 
 21232124         for (t = typ->n_type, j = typ->n_df; t&TMASK; t = DECREF(t))
 21242125                 if (ISARY(t) || ISFTN(t))
 21252126                         tylkadd(*j++, &tylkp, &ntdim);
 21262127 
 21272128         if (ntdim) {
 21282129                 union dimfun *a = permalloc(sizeof(union dimfun) * ntdim);
 21292130                 dimfuncnt += ntdim;
 21302131                 for (i = 0, base = tylnk.next; base; base = base->next, i++)
 21312132                         a[i] = base->df;
 21322133                 idp->n_df = a;
 21332134         } else
 21342135                 idp->n_df = NULL;
 21352136 
 21362137         /* now idp is a single node: fix up type */
 21372138         if ((t = ctype(idp->n_type)) != idp->n_type)
 21382139                 idp->n_type = t;
 21392140         
 21402141         if (idp->n_op != NAME) {
 21412142                 for (p = idp->n_left; p->n_op != NAME; p = p->n_left)
 21422143                         nfree(p);
 21432144                 nfree(p);
 21442145                 idp->n_op = NAME;
 21452146         }
 21462147         idp->n_ap = bap;
 21472148 
 21482149         return(idp);
 21492150 }
 21502151 
 21512152 static NODE *
 21522153 argcast(NODE *p, TWORD t, union dimfun *d, struct attr *ap)
 21532154 {
 21542155         NODE *u, *r = talloc();
 21552156 
 21562157         r->n_op = NAME;
 21572158         r->n_type = t;
 21582159         r->n_qual = 0; /* XXX */
 21592160         r->n_df = d;
 21602161         r->n_ap = ap;
 21612162 
 21622163         u = buildtree(CAST, r, p);
 21632164         nfree(u->n_left);
 21642165         r = u->n_right;
 21652166         nfree(u);
 21662167         return r;
 21672168 }
 21682169 
 21692170 #ifdef PCC_DEBUG
 21702171 /*
 21712172  * Print a prototype.
 21722173  */
 21732174 static void
 21742175 alprint(union arglist *al, int in)
 21752176 {
 21762177         TWORD t;
 21772178         int i = 0, j;
 21782179 
 21792180         for (; al->type != TNULL; al++) {
 21802181                 for (j = in; j > 0; j--)
 21812182                         printf("  ");
 21822183                 printf("arg %d: ", i++);
 21832184                 t = al->type;
 21842185                 tprint(t, 0);
 21852186                 while (t > BTMASK) {
 21862187                         if (ISARY(t)) {
 21872188                                 al++;
 21882189                                 printf(" dim %d ", al->df->ddim);
 21892190                         } else if (ISFTN(t)) {
 21902191                                 al++;
 21912192                                 if (al->df->dfun) {
 21922193                                         printf("\n");
 21932194                                         alprint(al->df->dfun, in+1);
 21942195                                 }
 21952196                         }
 21962197                         t = DECREF(t);
 21972198                 }
 21982199                 if (ISSOU(t)) {
 21992200                         al++;
 22002201                         printf(" (size %d align %d)", (int)tsize(t, 0, al->sap),
 22012202                             (int)talign(t, al->sap));
 22022203                 }
 22032204                 printf("\n");
 22042205         }
 22052206         if (in == 0)
 22062207                 printf("end arglist\n");
 22072208 }
 22082209 #endif
 22092210 
 22102211 int
 22112212 suemeq(struct attr *s1, struct attr *s2)
 22122213 {
 22132214 
 22142215         return (strmemb(s1) == strmemb(s2));
 22152216 }
 22162217 
 22172218 /*
 22182219  * Sanity-check old-style args.
 22192220  */
 22202221 static NODE *
 22212222 oldarg(NODE *p)
 22222223 {
 22232224         if (p->n_op == TYPE)
 22242225                 uerror("type is not an argument");
 22252226         if (p->n_type == FLOAT)
 22262227                 return cast(p, DOUBLE, p->n_qual);
 22272228         return p;
 22282229 }
 22292230 
 22302231 /*
 22312232  * Do prototype checking and add conversions before calling a function.
 22322233  * Argument f is function and a is a CM-separated list of arguments.
 22332234  * Returns a merged node (via buildtree() of function and arguments.
 22342235  */
 22352236 NODE *
 22362237 doacall(struct symtab *sp, NODE *f, NODE *a)
 22372238 {
 22382239         NODE *w, *r;
 22392240         union arglist *al;
 22402241         struct ap {
 22412242                 struct ap *next;
 22422243                 NODE *node;
 22432244         } *at, *apole = NULL;
 22442245         int argidx/* , hasarray = 0*/;
 22452246         TWORD type, arrt;
 22462247 
 22472248 #ifdef PCC_DEBUG
 22482249         if (ddebug) {
 22492250                 printf("doacall.\n");
 22502251                 fwalk(f, eprint, 0);
 22512252                 if (a)
 22522253                         fwalk(a, eprint, 0);
 22532254         }
 22542255 #endif
 22552256 
 22562257         /* First let MD code do something */
 22572258         calldec(f, a);
 22582259 /* XXX XXX hack */
 22592260         if ((f->n_op == CALL) &&
 22602261             f->n_left->n_op == ADDROF &&
 22612262             f->n_left->n_left->n_op == NAME &&
 22622263             (f->n_left->n_left->n_type & 0x7e0) == 0x4c0)
 22632264                 goto build;
 22642265 /* XXX XXX hack */
 22652266 
 22662267         /* Check for undefined or late defined enums */
 22672268         if (BTYPE(f->n_type) == ENUMTY) {
 22682269                 /* not-yet check if declared enum */
 22692270                 struct symtab *sq = strmemb(f->n_ap);
 22702271                 if (sq->stype != ENUMTY)
 22712272                         MODTYPE(f->n_type, sq->stype);
 22722273                 if (BTYPE(f->n_type) == ENUMTY)
 22732274                         uerror("enum %s not declared", sq->sname);
 22742275         }
 22752276 
 22762277         /*
 22772278          * Do some basic checks.
 22782279          */
 22792280         if (f->n_df == NULL || (al = f->n_df[0].dfun) == NULL) {
 22802281                 /*
 22812282                  * Handle non-prototype declarations.
 22822283                  */
 22832284                 if (f->n_op == NAME && f->n_sp != NULL) {
 22842285                         if (strncmp(f->n_sp->sname, "__builtin", 9) != 0 &&
 22852286                             (f->n_sp->sflags & SINSYS) == 0)
 22862287                                 warner(Wmissing_prototypes, f->n_sp->sname);
 22872288                 } else
 22882289                         warner(Wmissing_prototypes, "<pointer>");
 22892290 
 22902291                 /* floats must be cast to double */
 22912292                 if (a == NULL)
 22922293                         goto build;
 22932294                 if (a->n_op != CM) {
 22942295                         a = oldarg(a);
 22952296                 } else {
 22962297                         for (w = a; w->n_left->n_op == CM; w = w->n_left)
 22972298                                 w->n_right = oldarg(w->n_right);
 22982299                         w->n_left = oldarg(w->n_left);
 22992300                         w->n_right = oldarg(w->n_right);
 23002301                 }
 23012302                 goto build;
 23022303         }
 23032304         if (al->type == VOID) {
 23042305                 if (a != NULL)
 23052306                         uerror("function takes no arguments");
 23062307                 goto build; /* void function */
 23072308         } else {
 23082309                 if (a == NULL) {
 23092310                         uerror("function needs arguments");
 23102311                         goto build;
 23112312                 }
 23122313         }
 23132314 #ifdef PCC_DEBUG
 23142315         if (pdebug) {
 23152316                 printf("arglist for %s\n",
 23162317                     f->n_sp != NULL ? f->n_sp->sname : "function pointer");
 23172318                 alprint(al, 0);
 23182319         }
 23192320 #endif
 23202321 
 23212322         /*
 23222323          * Create a list of pointers to the nodes given as arg.
 23232324          */
 23242325         for (w = a; w->n_op == CM; w = w->n_left) {
 23252326                 at = tmpalloc(sizeof(struct ap));
 23262327                 at->node = w->n_right;
 23272328                 at->next = apole;
 23282329                 apole = at;
 23292330         }
 23302331         at = tmpalloc(sizeof(struct ap));
 23312332         at->node = w;
 23322333         at->next = apole;
 23332334         apole = at;
 23342335 
 23352336         /*
 23362337          * Do the typechecking by walking up the list.
 23372338          */
 23382339         argidx = 1;
 23392340         while (al->type != TNULL) {
 23402341                 if (al->type == TELLIPSIS) {
 23412342                         /* convert the rest of float to double */
 23422343                         for (; apole; apole = apole->next) {
 23432344                                 if (apole->node->n_type != FLOAT)
 23442345                                         continue;
 23452346                                 MKTY(apole->node, DOUBLE, 0, 0);
 23462347                         }
 23472348                         goto build;
 23482349                 }
 23492350                 if (apole == NULL) {
 23502351                         uerror("too few arguments to function");
 23512352                         goto build;
 23522353                 }
 23532354 /* al = prototyp, apole = argument till ftn */
 23542355 /* type = argumentets typ, arrt = prototypens typ */
 23552356                 type = apole->node->n_type;
 23562357                 arrt = al->type;
 23572358 #if 0
 23582359                 if ((hasarray = ISARY(arrt)))
 23592360                         arrt += (PTR-ARY);
 23602361 #endif
 23612362                 /* Taking addresses of arrays are meaningless in expressions */
 23622363                 /* but people tend to do that and also use in prototypes */
 23632364                 /* this is mostly a problem with typedefs */
 23642365                 if (ISARY(type)) {
 23652366                         if (ISPTR(arrt) && ISARY(DECREF(arrt)))
 23662367                                 type = INCREF(type);
 23672368                         else
 23682369                                 type += (PTR-ARY);
 23692370                 } else if (ISPTR(type) && !ISARY(DECREF(type)) &&
 23702371                     ISPTR(arrt) && ISARY(DECREF(arrt))) {
 23712372                         type += (ARY-PTR);
 23722373                         type = INCREF(type);
 23732374                 }
 23742375 
 23752376                 /* Check structs */
 23762377                 if (type <= BTMASK && arrt <= BTMASK) {
 23772378                         if (type != arrt) {
 23782379                                 if (ISSOU(BTYPE(type)) || ISSOU(BTYPE(arrt))) {
 23792380 incomp:                                 uerror("incompatible types for arg %d",
 23802381                                             argidx);
 23812382                                 } else {
 23822383                                         MKTY(apole->node, arrt, 0, 0)
 23832384                                 }
 23842385 #ifndef NO_COMPLEX
 23852386                         } else if (type == STRTY &&
 23862387                             attr_find(apole->node->n_ap, ATTR_COMPLEX) &&
 23872388                             attr_find(al[1].sap, ATTR_COMPLEX)) {
 23882389                                 /* Both are complex */
 23892390                                 if (strmemb(apole->node->n_ap)->stype !=
 23902391                                     strmemb(al[1].sap)->stype) {
 23912392                                         /* must convert to correct type */
 23922393                                         w = talloc();
 23932394                                         *w = *apole->node;
 23942395                                         w = mkcmplx(w,
 23952396                                             strmemb(al[1].sap)->stype);
 23962397                                         *apole->node = *w;
 23972398                                         nfree(w);
 23982399                                 }
 23992400                                 goto out;
 24002401 #endif
 24012402                         } else if (ISSOU(BTYPE(type))) {
 24022403                                 if (!suemeq(apole->node->n_ap, al[1].sap))
 24032404                                         goto incomp;
 24042405                         }
 24052406                         goto out;
 24062407                 }
 24072408 
 24082409                 /* XXX should (recusively) check return type and arg list of
 24092410                    func ptr arg XXX */
 24102411                 if (ISFTN(DECREF(arrt)) && ISFTN(type))
 24112412                         type = INCREF(type);
 24122413 
 24132414                 /* Hereafter its only pointers (or arrays) left */
 24142415                 /* Check for struct/union intermixing with other types */
 24152416                 if (((type <= BTMASK) && ISSOU(BTYPE(type))) ||
 24162417                     ((arrt <= BTMASK) && ISSOU(BTYPE(arrt))))
 24172418                         goto incomp;
 24182419 
 24192420                 /* Check for struct/union compatibility */
 24202421                 if (type == arrt) {
 24212422                         if (ISSOU(BTYPE(type))) {
 24222423                                 if (suemeq(apole->node->n_ap, al[1].sap))
 24232424                                         goto out;
 24242425                         } else
 24252426                                 goto out;
 24262427                 }
 24272428                 if (BTYPE(arrt) == VOID && type > BTMASK)
 24282429                         goto skip; /* void *f = some pointer */
 24292430                 if (arrt > BTMASK && BTYPE(type) == VOID)
 24302431                         goto skip; /* some *f = void pointer */
 24312432                 if (apole->node->n_op == ICON && apole->node->n_lval == 0)
 24322433                         goto skip; /* Anything assigned a zero */
 24332434 
 24342435                 if ((type & ~BTMASK) == (arrt & ~BTMASK)) {
 24352436                         /* do not complain for pointers with signedness */
 24362437                         if ((DEUNSIGN(BTYPE(type)) == DEUNSIGN(BTYPE(arrt))) &&
 24372438                             (BTYPE(type) != BTYPE(arrt))) {
 24382439                                 warner(Wpointer_sign, NULL);
 24392440                                 goto skip;
 24402441                         }
 24412442                 }
 24422443 
 24432444                 werror("implicit conversion of argument %d due to prototype",
 24442445                     argidx);
 24452446 
 24462447 skip:           if (ISSOU(BTYPE(arrt))) {
 24472448                         MKTY(apole->node, arrt, 0, al[1].sap)
 24482449                 } else {
 24492450                         MKTY(apole->node, arrt, 0, 0)
 24502451                 }
 24512452 
 24522453 out:            al++;
 24532454                 if (ISSOU(BTYPE(arrt)))
 24542455                         al++;
 24552456 #if 0
 24562457                 while (arrt > BTMASK && !ISFTN(arrt))
 24572458                         arrt = DECREF(arrt);
 24582459                 if (ISFTN(arrt) || hasarray)
 24592460                         al++;
 24602461 #else
 24612462                 while (arrt > BTMASK) {
 24622463                         if (ISARY(arrt) || ISFTN(arrt)) {
 24632464                                 al++;
 24642465                                 break;
 24652466                         }
 24662467                         arrt = DECREF(arrt);
 24672468                 }
 24682469 #endif
 24692470                 apole = apole->next;
 24702471                 argidx++;
 24712472         }
 24722473         if (apole != NULL)
 24732474                 uerror("too many arguments to function");
 24742475 
 24752476 build:  if (sp != NULL && (sp->sflags & SINLINE) && (w = inlinetree(sp, f, a)))
 24762477                 return w;
 24772478         return buildtree(a == NIL ? UCALL : CALL, f, a);
 24782479 }
 24792480 
 24802481 static int
 24812482 chk2(TWORD type, union dimfun *dsym, union dimfun *ddef)
 24822483 {
 24832484         while (type > BTMASK) {
 24842485                 switch (type & TMASK) {
 24852486                 case ARY:
 24862487                         /* may be declared without dimension */
 24872488                         if (dsym->ddim == NOOFFSET)
 24882489                                 dsym->ddim = ddef->ddim;
 24892490                         if (dsym->ddim < 0 && ddef->ddim < 0)
 24902491                                 ; /* dynamic arrays as arguments */
 24912492                         else if (ddef->ddim > 0 && dsym->ddim != ddef->ddim)
 24922493                                 return 1;
 24932494                         dsym++, ddef++;
 24942495                         break;
 24952496                 case FTN:
 24962497                         /* old-style function headers with function pointers
 24972498                          * will most likely not have a prototype.
 24982499                          * This is not considered an error.  */
 24992500                         if (ddef->dfun == NULL) {
 25002501 #ifdef notyet
 25012502                                 werror("declaration not a prototype");
 25022503 #endif
 25032504                         } else if (chkftn(dsym->dfun, ddef->dfun))
 25042505                                 return 1;
 25052506                         dsym++, ddef++;
 25062507                         break;
 25072508                 }
 25082509                 type = DECREF(type);
 25092510         }
 25102511         return 0;
 25112512 }
 25122513 
 25132514 /*
 25142515  * Compare two function argument lists to see if they match.
 25152516  */
 25162517 int
 25172518 chkftn(union arglist *usym, union arglist *udef)
 25182519 {
 25192520         TWORD t2;
 25202521         int ty, tyn;
 25212522 
 25222523         if (usym == NULL)
 25232524                 return 0;
 25242525         if (cftnsp != NULL && udef == NULL && usym->type == VOID)
 25252526                 return 0; /* foo() { function with foo(void); prototype */
 25262527         if (udef == NULL && usym->type != TNULL)
 25272528                 return 1;
 25282529         while (usym->type != TNULL) {
 25292530                 if (usym->type == udef->type)
 25302531                         goto done;
 25312532                 /*
 25322533                  * If an old-style declaration, then all types smaller than
 25332534                  * int are given as int parameters.
 25342535                  */
 25352536                 if (intcompare) {
 25362537                         ty = BTYPE(usym->type);
 25372538                         tyn = BTYPE(udef->type);
 25382539                         if (ty == tyn || ty != INT)
 25392540                                 return 1;
 25402541                         if (tyn == CHAR || tyn == UCHAR ||
 25412542                             tyn == SHORT || tyn == USHORT)
 25422543                                 goto done;
 25432544                         return 1;
 25442545                 } else
 25452546                         return 1;
 25462547 
 25472548 done:           ty = BTYPE(usym->type);
 25482549                 t2 = usym->type;
 25492550                 if (ISSOU(ty)) {
 25502551                         usym++, udef++;
 25512552                         if (suemeq(usym->sap, udef->sap) == 0)
 25522553                                 return 1;
 25532554                 }
 25542555 
 25552556                 while (!ISFTN(t2) && !ISARY(t2) && t2 > BTMASK)
 25562557                         t2 = DECREF(t2);
 25572558                 if (t2 > BTMASK) {
 25582559                         usym++, udef++;
 25592560                         if (chk2(t2, usym->df, udef->df))
 25602561                                 return 1;
 25612562                 }
 25622563                 usym++, udef++;
 25632564         }
 25642565         if (usym->type != udef->type)
 25652566                 return 1;
 25662567         return 0;
 25672568 }
 25682569 
 25692570 void
 25702571 fixtype(NODE *p, int class)
 25712572 {
 25722573         unsigned int t, type;
 25732574         int mod1, mod2;
 25742575         /* fix up the types, and check for legality */
 25752576 
 25762577         /* forward declared enums */
 25772578         if (BTYPE(p->n_sp->stype) == ENUMTY) {
 25782579                 MODTYPE(p->n_sp->stype, strmemb(p->n_sp->sap)->stype);
 25792580         }
 25802581 
 25812582         if( (