1: // Copyright (C) 1984-1998 by Symantec
   2: // Copyright (C) 2000-2011 by Digital Mars
   3: // All Rights Reserved
   4: // http://www.digitalmars.com
   5: // Written by Walter Bright
   6: /*
   7:  * This source file is made available for personal use
   8:  * only. The license is in /dmd/src/dmd/backendlicense.txt
   9:  * or /dm/src/dmd/backendlicense.txt
  10:  * For any other uses, please contact Digital Mars.
  11:  */
  12: 
  13: #if !SPP
  14: 
  15: #include        <stdio.h>
  16: #include        <string.h>
  17: #include        <stdlib.h>
  18: #include        <time.h>
  19: 
  20: #include        "cc.h"
  21: #include        "global.h"
  22: #include        "type.h"
  23: #include        "dt.h"
  24: #if TX86
  25: #include        "cgcv.h"
  26: #endif
  27: 
  28: #include        "el.h"
  29: #include        "oper.h"                /* for OPMAX            */
  30: #include        "token.h"
  31: 
  32: #if SCPP
  33: #include        "parser.h"
  34: #include        "cpp.h"
  35: #endif
  36: 
  37: static char __file__[] = __FILE__;      /* for tassert.h                */
  38: #include        "tassert.h"
  39: 
  40: //STATIC void symbol_undef(symbol *s);
  41: STATIC void symbol_freemember(symbol *s);
  42: STATIC void mptr_hydrate(mptr_t **);
  43: STATIC void mptr_dehydrate(mptr_t **);
  44: STATIC void baseclass_hydrate(baseclass_t **);
  45: STATIC void baseclass_dehydrate(baseclass_t **);
  46: 
  47: /*********************************
  48:  * Allocate/free symbol table.
  49:  */
  50: 
  51: symbol **symtab_realloc(symbol **tab, size_t symmax)
  52: {   symbol **newtab;
  53: 
  54:     if (config.flags2 & (CFG2phgen | CFG2phuse | CFG2phauto | CFG2phautoy))
  55:     {
  56:         newtab = (symbol **) MEM_PH_REALLOC(tab, symmax * sizeof(symbol *));
  57:     }
  58:     else
  59:     {
  60:         newtab = (symbol **) realloc(tab, symmax * sizeof(symbol *));
  61:         if (!newtab)
  62:             err_nomem();
  63:     }
  64:     return newtab;
  65: }
  66: 
  67: symbol **symtab_malloc(size_t symmax)
  68: {   symbol **newtab;
  69: 
  70:     if (config.flags2 & (CFG2phgen | CFG2phuse | CFG2phauto | CFG2phautoy))
  71:     {
  72:         newtab = (symbol **) MEM_PH_MALLOC(symmax * sizeof(symbol *));
  73:     }
  74:     else
  75:     {
  76:         newtab = (symbol **) malloc(symmax * sizeof(symbol *));
  77:         if (!newtab)
  78:             err_nomem();
  79:     }
  80:     return newtab;
  81: }
  82: 
  83: symbol **symtab_calloc(size_t symmax)
  84: {   symbol **newtab;
  85: 
  86:     if (config.flags2 & (CFG2phgen | CFG2phuse | CFG2phauto | CFG2phautoy))
  87:     {
  88:         newtab = (symbol **) MEM_PH_CALLOC(symmax * sizeof(symbol *));
  89:     }
  90:     else
  91:     {
  92:         newtab = (symbol **) calloc(symmax, sizeof(symbol *));
  93:         if (!newtab)
  94:             err_nomem();
  95:     }
  96:     return newtab;
  97: }
  98: 
  99: void symtab_free(symbol **tab)
 100: {
 101:     if (config.flags2 & (CFG2phgen | CFG2phuse | CFG2phauto | CFG2phautoy))
 102:         MEM_PH_FREE(tab);
 103:     else if (tab)
 104:         free(tab);
 105: }
 106: 
 107: /*******************************
 108:  * Type out symbol information.
 109:  */
 110: 
 111: #ifdef DEBUG
 112: 
 113: void symbol_print(symbol *s)
 114: {
 115: #if !SPP
 116:     if (!s) return;
 117:     dbg_printf("symbol %p '%s'\n ",s,s->Sident);
 118:     dbg_printf(" Sclass = "); WRclass((enum SC) s->Sclass);
 119:     dbg_printf(" Ssymnum = %d",s->Ssymnum);
 120:     dbg_printf(" Sfl = "); WRFL((enum FL) s->Sfl);
 121:     dbg_printf(" Sseg = %d\n",s->Sseg);
 122: //  dbg_printf(" Ssize   = x%02x\n",s->Ssize);
 123:     dbg_printf(" Soffset = x%04lx",s->Soffset);
 124:     dbg_printf(" Sweight = %d",s->Sweight);
 125:     dbg_printf(" Sflags = x%04lx",s->Sflags);
 126:     dbg_printf(" Sxtrnnum = %d\n",s->Sxtrnnum);
 127:     dbg_printf("  Stype   = %p",s->Stype);
 128: #if SCPP
 129:     dbg_printf(" Ssequence = %x", s->Ssequence);
 130:     dbg_printf(" Scover  = %p", s->Scover);
 131: #endif
 132:     dbg_printf(" Sl      = %p",s->Sl);
 133:     dbg_printf(" Sr      = %p\n",s->Sr);
 134: #if SCPP
 135:     if (s->Sscope)
 136:         dbg_printf(" Sscope = '%s'\n",s->Sscope->Sident);
 137: #endif
 138:     if (s->Stype)
 139:         type_print(s->Stype);
 140:     if (s->Sclass == SCmember || s->Sclass == SCfield)
 141:     {
 142:         dbg_printf("  Smemoff =%5ld",s->Smemoff);
 143:         dbg_printf("  Sbit    =%3d",s->Sbit);
 144:         dbg_printf("  Swidth  =%3d\n",s->Swidth);
 145:     }
 146: #if SCPP
 147:     if (s->Sclass == SCstruct)
 148:     {
 149: #if VBTABLES
 150:         dbg_printf("  Svbptr = %p, Svptr = %p\n",s->Sstruct->Svbptr,s->Sstruct->Svptr);
 151: #endif
 152:     }
 153: #endif
 154: #endif
 155: }
 156: 
 157: #endif
 158: 
 159: /*********************************
 160:  * Terminate use of symbol table.
 161:  */
 162: 
 163: static symbol *keep;
 164: 
 165: void symbol_term()
 166: {
 167:     symbol_free(keep);
 168: }
 169: 
 170: /****************************************
 171:  * Keep symbol around until symbol_term().
 172:  */
 173: 
 174: #if TERMCODE
 175: 
 176: void symbol_keep(symbol *s)
 177: {
 178:     symbol_debug(s);
 179:     s->Sr = keep;       // use Sr so symbol_free() doesn't nest
 180:     keep = s;
 181: }
 182: 
 183: #endif
 184: 
 185: /***********************************
 186:  * Get user name of symbol.
 187:  */
 188: 
 189: char *symbol_ident(symbol *s)
 190: {
 191: #if SCPP
 192:     static char noname[] = "__unnamed";
 193:     switch (s->Sclass)
 194:     {   case SCstruct:
 195:             if (s->Sstruct->Salias)
 196:                 s = s->Sstruct->Salias;
 197:             else if (s->Sstruct->Sflags & STRnotagname)
 198:                 return noname;
 199:             break;
 200:         case SCenum:
 201:             if (CPP)
 202:             {   if (s->Senum->SEalias)
 203:                     s = s->Senum->SEalias;
 204:                 else if (s->Senum->SEflags & SENnotagname)
 205:                     return noname;
 206:             }
 207:             break;
 208: 
 209:         case SCnamespace:
 210:             if (s->Sident[0] == '?' && s->Sident[1] == '%')
 211:                 return "unique";        // an unnamed namespace
 212:             break;
 213:     }
 214: #endif
 215:     return s->Sident;
 216: }
 217: 
 218: /****************************************
 219:  * Create a new symbol.
 220:  */
 221: 
 222: symbol * symbol_calloc(const char *id)
 223: {   symbol *s;
 224:     int len;
 225: 
 226:     len = strlen(id);
 227:     //printf("sizeof(symbol)=%d, sizeof(s->Sident)=%d, len=%d\n",sizeof(symbol),sizeof(s->Sident),len);
 228:     s = (symbol *) mem_fmalloc(sizeof(symbol) - sizeof(s->Sident) + len + 1 + 5);
 229:     memset(s,0,sizeof(symbol) - sizeof(s->Sident));
 230: #if SCPP
 231:     s->Ssequence = pstate.STsequence;
 232:     pstate.STsequence += 1;
 233:     //if (s->Ssequence == 0x21) *(char*)0=0;
 234: #endif
 235: #ifdef DEBUG
 236:     if (debugy)
 237:         dbg_printf("symbol_calloc('%s') = %p\n",id,s);
 238:     s->id = IDsymbol;
 239: #endif
 240:     memcpy(s->Sident,id,len + 1);
 241:     s->Ssymnum = -1;
 242:     return s;
 243: }
 244: 
 245: /****************************************
 246:  * Create a symbol, given a name and type.
 247:  */
 248: 
 249: symbol * symbol_name(const char *name,int sclass,type *t)
 250: {
 251:     type_debug(t);
 252:     symbol *s = symbol_calloc(name);
 253:     s->Sclass = (enum SC) sclass;
 254:     s->Stype = t;
 255:     s->Stype->Tcount++;
 256: #if ELFOBJ || MACHOBJ // Burton
 257:     s->Sseg = CDATA;
 258: #endif
 259: 
 260:     if (tyfunc(t->Tty))
 261:         symbol_func(s);
 262:     return s;
 263: }
 264: 
 265: /****************************************
 266:  * Create a symbol that is an alias to another function symbol.
 267:  */
 268: 
 269: Funcsym *symbol_funcalias(Funcsym *sf)
 270: {
 271:     Funcsym *s;
 272: 
 273:     symbol_debug(sf);
 274:     assert(tyfunc(sf->Stype->Tty));
 275:     if (sf->Sclass == SCfuncalias)
 276:         sf = sf->Sfunc->Falias;
 277:     s = (Funcsym *)symbol_name(sf->Sident,SCfuncalias,sf->Stype);
 278:     s->Sfunc->Falias = sf;
 279: #if SCPP
 280:     s->Scover = sf->Scover;
 281: #endif
 282:     return s;
 283: }
 284: 
 285: /****************************************
 286:  * Create a symbol, give it a name, storage class and type.
 287:  */
 288: 
 289: symbol * symbol_generate(int sclass,type *t)
 290: {   char name[10];
 291:     static int tmpnum;
 292: 
 293:     sprintf(name,"_TMP%d",tmpnum++);
warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(371) : see declaration of 'sprintf'
294: #ifdef DEBUG 295: symbol *s = symbol_name(name,sclass,t); 296: //symbol_print(s); 297: return s; 298: #else 299: return symbol_name(name,sclass,t); 300: #endif 301: } 302: 303: /**************************************** 304: * Generate an auto symbol, and add it to the symbol table. 305: */ 306: 307: symbol * symbol_genauto(type *t) 308: { symbol *s; 309: 310: s = symbol_generate(SCauto,t); 311: #if SCPP 312: //printf("symbol_genauto(t) '%s'\n", s->Sident); 313: if (pstate.STdefertemps) 314: { symbol_keep(s); 315: s->Ssymnum = -1; 316: } 317: else 318: { s->Sflags |= SFLfree; 319: if (init_staticctor) 320: { // variable goes into _STI_xxxx 321: s->Ssymnum = -1; // deferred allocation 322: //printf("test2\n"); 323: //if (s->Sident[4] == '2') *(char*)0=0; 324: } 325: else 326: { 327: symbol_add(s); 328: } 329: } 330: #else 331: s->Sflags |= SFLfree; 332: symbol_add(s); 333: #endif 334: return s; 335: } 336: 337: /****************************************** 338: * Generate symbol into which we can copy the contents of expression e. 339: */ 340: 341: Symbol *symbol_genauto(elem *e) 342: { 343: return symbol_genauto(type_fake(e->Ety)); 344: } 345: 346: /****************************************** 347: * Generate symbol into which we can copy the contents of expression e. 348: */ 349: 350: Symbol *symbol_genauto(tym_t ty) 351: { 352: return symbol_genauto(type_fake(ty)); 353: } 354: 355: /**************************************** 356: * Add in the variants for a function symbol. 357: */ 358: 359: void symbol_func(symbol *s) 360: { 361: //printf("symbol_func(%s, x%x)\n", s->Sident, fregsaved); 362: symbol_debug(s); 363: s->Sfl = FLfunc; 364: // Interrupt functions modify all registers 365: #if TX86 366: // BUG: do interrupt functions really save BP? 367: #define mBP 0x20 368: // Note that fregsaved may not be set yet 369: s->Sregsaved = (s->Stype && tybasic(s->Stype->Tty) == TYifunc) ? mBP : fregsaved; 370: s->Sseg = UNKNOWN; // don't know what segment it is in 371: #endif 372: if (!s->Sfunc) 373: s->Sfunc = func_calloc(); 374: } 375: 376: /******************************** 377: * Define symbol in specified symbol table. 378: * Returns: 379: * pointer to symbol 380: */ 381: 382: #if SCPP 383: 384: symbol * defsy(const char *p,symbol **parent) 385: { 386: symbol *s = symbol_calloc(p); 387: symbol_addtotree(parent,s); 388: return s; 389: } 390: 391: #endif 392: 393: /******************************** 394: * Check integrity of symbol data structure. 395: */ 396: 397: #ifdef DEBUG 398: 399: void symbol_check(symbol *s) 400: { 401: //dbg_printf("symbol_check('%s',%p)\n",s->Sident,s); 402: symbol_debug(s); 403: if (s->Stype) type_debug(s->Stype); 404: assert((unsigned)s->Sclass < (unsigned)SCMAX); 405: #if SCPP 406: if (s->Sscope) 407: symbol_check(s->Sscope); 408: if (s->Scover) 409: symbol_check(s->Scover); 410: #endif 411: } 412: 413: void symbol_tree_check(symbol *s) 414: { 415: while (s) 416: { symbol_check(s); 417: symbol_tree_check(s->Sl); 418: s = s->Sr; 419: } 420: } 421: 422: #endif 423: 424: /******************************** 425: * Insert symbol in specified symbol table. 426: */ 427: 428: #if SCPP 429: 430: void symbol_addtotree(symbol **parent,symbol *s) 431: { symbol *rover; 432: signed char cmp; 433: size_t len; 434: const char *p; 435: char c; 436: 437: //dbg_printf("symbol_addtotree('%s',%p)\n",s->Sident,*parent); 438: #ifdef DEBUG 439: symbol_tree_check(*parent); 440: assert(!s->Sl && !s->Sr); 441: #endif 442: symbol_debug(s); 443: p = s->Sident; 444: c = *p; 445: len = strlen(p); 446: p++; 447: rover = *parent; 448: while (rover != NULL) // while we haven't run out of tree 449: { symbol_debug(rover); 450: if ((cmp = c - rover->Sident[0]) == 0) 451: { cmp = memcmp(p,rover->Sident + 1,len); // compare identifier strings 452: if (cmp == 0) // found it if strings match 453: { 454: if (CPP) 455: { symbol *s2; 456: 457: switch (rover->Sclass) 458: { case SCstruct: 459: s2 = rover; 460: goto case_struct; 461: 462: case_struct: 463: if (s2->Sstruct->Sctor && 464: !(s2->Sstruct->Sctor->Sfunc->Fflags & Fgen)) 465: cpperr(EM_ctor_disallowed,p); // no ctor allowed for class rover 466: s2->Sstruct->Sflags |= STRnoctor; 467: goto case_cover; 468: 469: case_cover: 470: // Replace rover with the new symbol s, and 471: // have s 'cover' the tag symbol s2. 472: // BUG: memory leak on rover if s2!=rover 473: assert(!s2->Scover); 474: s->Sl = rover->Sl; 475: s->Sr = rover->Sr; 476: s->Scover = s2; 477: *parent = s; 478: rover->Sl = rover->Sr = NULL; 479: return; 480: 481: case SCenum: 482: s2 = rover; 483: goto case_cover; 484: 485: case SCtemplate: 486: s2 = rover; 487: s2->Stemplate->TMflags |= STRnoctor; 488: goto case_cover; 489: 490: case SCalias: 491: s2 = rover->Smemalias; 492: if (s2->Sclass == SCstruct) 493: goto case_struct; 494: if (s2->Sclass == SCenum) 495: goto case_cover; 496: break; 497: } 498: } 499: synerr(EM_multiple_def,p - 1); // symbol is already defined 500: //symbol_undef(s); // undefine the symbol 501: return; 502: } 503: } 504: parent = (cmp < 0) ? /* if we go down left side */ 505: &(rover->Sl) : /* then get left child */ 506: &(rover->Sr); /* else get right child */ 507: rover = *parent; /* get child */ 508: } 509: /* not in table, so insert into table */ 510: *parent = s; /* link new symbol into tree */ 511: L1: 512: ; 513: } 514: 515: #endif 516: 517: /************************************* 518: * Search for symbol in multiple symbol tables, 519: * starting with most recently nested one. 520: * Input: 521: * p -> identifier string 522: * Returns: 523: * pointer to symbol 524: * NULL if couldn't find it 525: */ 526: 527: #if 0 528: symbol * lookupsym(const char *p) 529: { 530: return scope_search(p,SCTglobal | SCTlocal); 531: } 532: #endif 533: 534: /************************************* 535: * Search for symbol in symbol table. 536: * Input: 537: * p -> identifier string 538: * rover -> where to start looking 539: * Returns: 540: * pointer to symbol (NULL if not found) 541: */ 542: 543: #if SCPP 544: 545: symbol * findsy(const char *p,symbol *rover) 546: { 547: #if __INTSIZE == 2 && TX86 && !defined(_MSC_VER) 548: volatile int len; 549: __asm 550: { 551: push DS 552: mov DS,word ptr p+2 553: les DI,p 554: mov DX,word ptr p 555: mov BX,ES:[DI] 556: xor AL,AL 557: mov CX,0FFFFh 558: repne scasb 559: not CX 560: sub CX,2 561: mov len,CX 562: add DX,2 563: mov AX,BX 564: les BX,rover 565: jmp short L1 566: 567: L38C: les BX,ES:symbol.Sl[BX] 568: L1: test BX,BX 569: je L3A5 570: cmp AL,ES:symbol.Sident[BX] 571: js L38C 572: je L2 573: les BX,ES:symbol.Sr[BX] 574: jmp L1 575: 576: L2: cmp AH,ES:symbol.Sident+1[BX] 577: js L38C 578: je L3 579: les BX,ES:symbol.Sr[BX] 580: jmp L1 581: 582: L3: mov SI,DX 583: lea DI,symbol.Sident+2[BX] 584: mov CX,len 585: rep cmpsb 586: js L38C 587: je L3A5 588: les BX,ES:symbol.Sr[BX] 589: jmp L1 590: 591: L3A5: mov DX,ES 592: mov AX,BX 593: pop DS 594: } 595: #elif __INTSIZE == 4 && TX86 && !defined(_MSC_VER) && !M_UNIX 596: volatile int len; 597: __asm 598: { 599: #if !_WIN32 600: push DS 601: pop ES 602: #endif 603: mov EDI,p 604: xor AL,AL 605: 606: mov BL,[EDI] 607: mov ECX,-1 608: 609: repne scasb 610: 611: not ECX 612: mov EDX,p 613: 614: dec ECX 615: inc EDX 616: 617: mov len,ECX 618: mov AL,BL 619: 620: mov EBX,rover 621: mov ESI,EDX 622: 623: test EBX,EBX 624: je L6 625: 626: cmp AL,symbol.Sident[EBX] 627: js L2 628: 629: lea EDI,symbol.Sident+1[EBX] 630: je L5 631: 632: mov EBX,symbol.Sr[EBX] 633: jmp L3 634: 635: L1: mov ECX,len 636: L2: mov EBX,symbol.Sl[EBX] 637: 638: L3: test EBX,EBX 639: je L6 640: 641: L4: cmp AL,symbol.Sident[EBX] 642: js L2 643: 644: lea EDI,symbol.Sident+1[EBX] 645: je L5 646: 647: mov EBX,symbol.Sr[EBX] 648: jmp L3 649: 650: L5: rep cmpsb 651: 652: mov ESI,EDX 653: js L1 654: 655: je L6 656: 657: mov EBX,symbol.Sr[EBX] 658: mov ECX,len 659: 660: test EBX,EBX 661: jne L4 662: 663: L6: mov EAX,EBX 664: } 665: #else 666: size_t len; 667: signed char cmp; /* set to value of strcmp */ 668: char c = *p; 669: 670: len = strlen(p); 671: p++; // will pick up 0 on memcmp 672: while (rover != NULL) // while we haven't run out of tree 673: { symbol_debug(rover); 674: if ((cmp = c - rover->Sident[0]) == 0) 675: { cmp = memcmp(p,rover->Sident + 1,len); /* compare identifier strings */ 676: if (cmp == 0) 677: return rover; /* found it if strings match */ 678: } 679: rover = (cmp < 0) ? rover->Sl : rover->Sr; 680: } 681: return rover; // failed to find it 682: #endif 683: } 684: 685: #endif 686: 687: /*********************************** 688: * Create a new symbol table. 689: */ 690: 691: #if SCPP 692: 693: void createglobalsymtab() 694: { 695: assert(!scope_end); 696: if (CPP) 697: scope_push(NULL,(scope_fp)findsy, SCTcglobal); 698: else 699: scope_push(NULL,(scope_fp)findsy, SCTglobaltag); 700: scope_push(NULL,(scope_fp)findsy, SCTglobal); 701: } 702: 703: 704: void createlocalsymtab() 705: { 706: assert(scope_end); 707: if (!CPP) 708: scope_push(NULL,(scope_fp)findsy, SCTtag); 709: scope_push(NULL,(scope_fp)findsy, SCTlocal); 710: } 711: 712: 713: /*********************************** 714: * Delete current symbol table and back up one. 715: */ 716: 717: void deletesymtab() 718: { symbol *root; 719: 720: root = (symbol *)scope_pop(); 721: if (root) 722: { 723: if (funcsym_p) 724: list_prepend(&funcsym_p->Sfunc->Fsymtree,root); 725: else 726: symbol_free(root); // free symbol table 727: } 728: 729: if (!CPP) 730: { 731: root = (symbol *)scope_pop(); 732: if (root) 733: { 734: if (funcsym_p) 735: list_prepend(&funcsym_p->Sfunc->Fsymtree,root); 736: else 737: symbol_free(root); // free symbol table 738: } 739: } 740: } 741: 742: #endif 743: 744: /********************************* 745: * Delete symbol from symbol table, taking care to delete 746: * all children of a symbol. 747: * Make sure there are no more forward references (labels, tags). 748: * Input: 749: * pointer to a symbol 750: */ 751: 752: void meminit_free(meminit_t *m) /* helper for symbol_free() */ 753: { 754: list_free(&m->MIelemlist,(list_free_fp)el_free); 755: MEM_PARF_FREE(m); 756: } 757: 758: void symbol_free(symbol *s) 759: { 760: while (s) /* if symbol exists */ 761: { symbol *sr; 762: 763: #ifdef DEBUG 764: if (debugy) 765: dbg_printf("symbol_free('%s',%p)\n",s->Sident,s); 766: symbol_debug(s); 767: assert(/*s->Sclass != SCunde &&*/ (int) s->Sclass < (int) SCMAX); 768: #endif 769: { type *t = s->Stype; 770: 771: if (t) 772: type_debug(t); 773: if (t && tyfunc(t->Tty) && s->Sfunc)
warning C4390: ';' : empty controlled statement found; is this the intent?
774: { 775: func_t *f = s->Sfunc; 776: 777: debug(assert(f)); 778: blocklist_free(&f->Fstartblock); 779: freesymtab(f->Flocsym.tab,0,f->Flocsym.top); 780: 781: symtab_free(f->Flocsym.tab); 782: if (CPP) 783: { 784: if (f->Fflags & Fnotparent) 785: { debug(debugy && dbg_printf("not parent, returning\n")); 786: return; 787: } 788: 789: /* We could be freeing the symbol before it's class is */ 790: /* freed, so remove it from the class's field list */ 791: #if 1 792: if (f->Fclass) 793: { list_t tl; 794: 795: symbol_debug(f->Fclass); 796: tl = list_inlist(f->Fclass->Sstruct->Sfldlst,s); 797: if (tl) 798: list_setsymbol(tl,0); 799: } 800: #endif 801: if (f->Foversym && f->Foversym->Sfunc) 802: { f->Foversym->Sfunc->Fflags &= ~Fnotparent; 803: f->Foversym->Sfunc->Fclass = NULL; 804: symbol_free(f->Foversym); 805: } 806: 807: if (f->Fexplicitspec) 808: symbol_free(f->Fexplicitspec); 809: 810: /* If operator function, remove from list of such functions */ 811: if (f->Fflags & Foperator) 812: { assert(f->Foper && f->Foper < OPMAX); 813: //if (list_inlist(cpp_operfuncs[f->Foper],s)) 814: // list_subtract(&cpp_operfuncs[f->Foper],s); 815: } 816: 817: list_free(&f->Fclassfriends,FPNULL); 818: list_free(&f->Ffwdrefinstances,FPNULL); 819: param_free(&f->Farglist); 820: param_free(&f->Fptal); 821: list_free(&f->Fexcspec,(list_free_fp)type_free); 822: #if SCPP 823: token_free(f->Fbody); 824: #endif 825: el_free(f->Fbaseinit); 826: if (f->Fthunk && !(f->Fflags & Finstance)) 827: MEM_PH_FREE(f->Fthunk); 828: list_free(&f->Fthunks,(list_free_fp)symbol_free); 829: } 830: list_free(&f->Fsymtree,(list_free_fp)symbol_free); 831: func_free(f); 832: } 833: switch (s->Sclass) 834: { 835: #if SCPP 836: case SClabel: 837: if (!s->Slabel) 838: synerr(EM_unknown_label,s->Sident); 839: break; 840: #endif 841: case SCstruct: 842: #if SCPP 843: if (CPP) 844: { 845: struct_t *st = s->Sstruct; 846: assert(st); 847: list_free(&st->Sclassfriends,FPNULL); 848: list_free(&st->Sfriendclass,FPNULL); 849: list_free(&st->Sfriendfuncs,FPNULL); 850: list_free(&st->Scastoverload,FPNULL); 851: list_free(&st->Sopoverload,FPNULL); 852: list_free(&st->Svirtual,MEM_PH_FREEFP); 853: list_free(&st->Sfldlst,FPNULL); 854: symbol_free(st->Sroot); 855: baseclass_t *b,*bn; 856: 857: for (b = st->Sbase; b; b = bn) 858: { bn = b->BCnext; 859: list_free(&b->BCpublics,FPNULL); 860: baseclass_free(b); 861: } 862: for (b = st->Svirtbase; b; b = bn) 863: { bn = b->BCnext; 864: baseclass_free(b); 865: } 866: for (b = st->Smptrbase; b; b = bn) 867: { bn = b->BCnext; 868: list_free(&b->BCmptrlist,MEM_PH_FREEFP); 869: baseclass_free(b); 870: } 871: #if VBTABLES 872: for (b = st->Svbptrbase; b; b = bn) 873: { bn = b->BCnext; 874: baseclass_free(b); 875: } 876: #endif 877: param_free(&st->Sarglist); 878: param_free(&st->Spr_arglist); 879: struct_free(st); 880: } 881: else 882: #endif 883: { 884: #ifdef DEBUG 885: if (debugy) 886: dbg_printf("freeing members %p\n",s->Sstruct->Sfldlst); 887: #endif 888: list_free(&s->Sstruct->Sfldlst,FPNULL); 889: symbol_free(s->Sstruct->Sroot); 890: struct_free(s->Sstruct); 891: } 892: #if 0 /* Don't complain anymore about these, ANSI C says */ 893: /* it's ok */ 894: if (t && t->Tflags & TFsizeunknown) 895: synerr(EM_unknown_tag,s->Sident); 896: #endif 897: break; 898: case SCenum: 899: /* The actual member symbols are either in a local */ 900: /* table or on the member list of a class, so we */ 901: /* don't free them here. */ 902: assert(s->Senum); 903: list_free(&s->Senumlist,FPNULL); 904: MEM_PH_FREE(s->Senum); 905: s->Senum = NULL; 906: break; 907: 908: #if SCPP 909: case SCtemplate: 910: { template_t *tm = s->Stemplate; 911: 912: list_free(&tm->TMinstances,FPNULL); 913: list_free(&tm->TMmemberfuncs,(list_free_fp)tmf_free); 914: list_free(&tm->TMexplicit,(list_free_fp)tme_free); 915: list_free(&tm->TMnestedexplicit,(list_free_fp)tmne_free); 916: list_free(&tm->TMnestedfriends,(list_free_fp)tmnf_free); 917: param_free(&tm->TMptpl); 918: param_free(&tm->TMptal); 919: token_free(tm->TMbody); 920: symbol_free(tm->TMpartial); 921: list_free(&tm->TMfriends,FPNULL); 922: MEM_PH_FREE(tm); 923: break; 924: } 925: case SCnamespace: 926: symbol_free(s->Snameroot); 927: list_free(&s->Susing,FPNULL); 928: break; 929: 930: case SCmemalias: 931: case SCfuncalias: 932: case SCadl: 933: list_free(&s->Spath,FPNULL); 934: break; 935: #endif 936: case SCparameter: 937: case SCregpar: 938: case SCfastpar: 939: case SCregister: 940: case SCtmp: 941: case SCauto: 942: vec_free(s->Srange); 943: /* FALL-THROUGH */ 944: #if 0 945: case SCconst: 946: if (s->Sflags & (SFLvalue | SFLdtorexp)) 947: el_free(s->Svalue); 948: #endif 949: break; 950: default: 951: break; 952: } 953: if (s->Sflags & (SFLvalue | SFLdtorexp)) 954: el_free(s->Svalue); 955: if (s->Sdt) 956: dt_free(s->Sdt); 957: type_free(t); 958: symbol_free(s->Sl); 959: #if SCPP 960: if (s->Scover) 961: symbol_free(s->Scover); 962: #endif 963: sr = s->Sr; 964: #ifdef DEBUG 965: s->id = 0; 966: #endif 967: mem_ffree(s); 968: } 969: s = sr; 970: } 971: } 972: 973: /******************************** 974: * Undefine a symbol. 975: * Assume error msg was already printed. 976: */ 977: 978: #if 0 979: STATIC void symbol_undef(symbol *s) 980: { 981: s->Sclass = SCunde; 982: s->Ssymnum = -1; 983: type_free(s->Stype); /* free type data */ 984: s->Stype = NULL; 985: } 986: #endif 987: 988: /***************************** 989: * Add symbol to current symbol array. 990: */ 991: 992: SYMIDX symbol_add(symbol *s) 993: { SYMIDX sitop; 994: 995: //printf("symbol_add('%s')\n", s->Sident); 996: #ifdef DEBUG 997: if (!s || !s->Sident[0]) 998: { dbg_printf("bad symbol\n"); 999: assert(0); 1000: } 1001: #endif 1002: symbol_debug(s); 1003: if (pstate.STinsizeof) 1004: { symbol_keep(s); 1005: return -1; 1006: } 1007: debug(assert(cstate.CSpsymtab)); 1008: sitop = cstate.CSpsymtab->top; 1009: assert(sitop <= cstate.CSpsymtab->symmax); 1010: if (sitop == cstate.CSpsymtab->symmax) 1011: { 1012: #ifdef DEBUG 1013: #define SYMINC 1 /* flush out reallocation bugs */ 1014: #else 1015: #define SYMINC 99 1016: #endif 1017: cstate.CSpsymtab->symmax += (cstate.CSpsymtab == &globsym) ? SYMINC : 1; 1018: //assert(cstate.CSpsymtab->symmax * sizeof(symbol *) < 4096 * 4); 1019: cstate.CSpsymtab->tab = symtab_realloc(cstate.CSpsymtab->tab, cstate.CSpsymtab->symmax); 1020: } 1021: cstate.CSpsymtab->tab[sitop] = s; 1022: #if AUTONEST 1023: if (pushcount) 1024: { s->Spush = pushcount; 1025: pushcount = 0; 1026: } 1027: #endif 1028: #ifdef DEBUG 1029: if (debugy) 1030: dbg_printf("symbol_add(%p '%s') = %d\n",s,s->Sident,cstate.CSpsymtab->top); 1031: #endif 1032: assert(s->Ssymnum == -1); 1033: return s->Ssymnum = cstate.CSpsymtab->top++; 1034: } 1035: 1036: /**************************** 1037: * Free up the symbol table, from symbols n1 through n2, not 1038: * including n2. 1039: */ 1040: 1041: void freesymtab(symbol **stab,SYMIDX n1,SYMIDX n2) 1042: { SYMIDX si; 1043: 1044: if (!stab) 1045: return; 1046: #ifdef DEBUG 1047: if (debugy) 1048: dbg_printf("freesymtab(from %d to %d)\n",n1,n2); 1049: #endif 1050: assert(stab != globsym.tab || (n1 <= n2 && n2 <= globsym.top)); 1051: for (si = n1; si < n2; si++) 1052: { symbol *s; 1053: 1054: s = stab[si]; 1055: if (s && s->Sflags & SFLfree) 1056: { stab[si] = NULL; 1057: #ifdef DEBUG 1058: if (debugy) 1059: dbg_printf("Freeing %p '%s' (%d)\n",s,s->Sident,si); 1060: symbol_debug(s); 1061: #endif 1062: s->Sl = s->Sr = NULL; 1063: s->Ssymnum = -1; 1064: symbol_free(s); 1065: } 1066: } 1067: } 1068: 1069: /**************************** 1070: * Create a copy of a symbol. 1071: */ 1072: 1073: symbol * symbol_copy(symbol *s) 1074: { symbol *scopy; 1075: type *t; 1076: 1077: symbol_debug(s); 1078: /*dbg_printf("symbol_copy(%s)\n",s->Sident);*/ 1079: scopy = symbol_calloc(s->Sident); 1080: memcpy(scopy,s,sizeof(symbol) - sizeof(s->Sident)); 1081: scopy->Sl = scopy->Sr = scopy->Snext = NULL; 1082: scopy->Ssymnum = -1; 1083: if (scopy->Sdt) 1084: dtsymsize(scopy); 1085: if (scopy->Sflags & (SFLvalue | SFLdtorexp)) 1086: scopy->Svalue = el_copytree(s->Svalue); 1087: t = scopy->Stype; 1088: if (t) 1089: { t->Tcount++; /* one more parent of the type */ 1090: type_debug(t); 1091: } 1092: return scopy; 1093: } 1094: 1095: /******************************* 1096: * Search list for a symbol with an identifier that matches. 1097: * Returns: 1098: * pointer to matching symbol 1099: * NULL if not found 1100: */ 1101: 1102: #if SCPP 1103: 1104: symbol * symbol_searchlist(symlist_t sl,const char *vident) 1105: { symbol *s; 1106: #ifdef DEBUG 1107: int count = 0; 1108: #endif 1109: 1110: //dbg_printf("searchlist(%s)\n",vident); 1111: for (; sl; sl = list_next(sl)) 1112: { s = list_symbol(sl); 1113: symbol_debug(s); 1114: /*dbg_printf("\tcomparing with %s\n",s->Sident);*/ 1115: if (strcmp(vident,s->Sident) == 0) 1116: return s; 1117: #ifdef DEBUG 1118: assert(++count < 300); /* prevent infinite loops */ 1119: #endif 1120: } 1121: return NULL; 1122: } 1123: 1124: /*************************************** 1125: * Search for symbol in sequence of symbol tables. 1126: * Input: 1127: * glbl !=0 if global symbol table only 1128: */ 1129: 1130: symbol *symbol_search(const char *id) 1131: { 1132: Scope *sc; 1133: if (CPP) 1134: { unsigned sct; 1135: 1136: sct = pstate.STclasssym ? SCTclass : 0; 1137: sct |= SCTmfunc | SCTlocal | SCTwith | SCTglobal | SCTnspace | SCTtemparg | SCTtempsym; 1138: return scope_searchx(id,sct,&sc); 1139: } 1140: else 1141: return scope_searchx(id,SCTglobal | SCTlocal,&sc); 1142: } 1143: 1144: #endif 1145: 1146: /******************************************* 1147: * Hydrate a symbol tree. 1148: */ 1149: 1150: #if HYDRATE 1151: void symbol_tree_hydrate(symbol **ps) 1152: { symbol *s; 1153: 1154: while (isdehydrated(*ps)) /* if symbol is dehydrated */ 1155: { 1156: s = symbol_hydrate(ps); 1157: symbol_debug(s); 1158: if (s->Scover) 1159: symbol_hydrate(&s->Scover); 1160: symbol_tree_hydrate(&s->Sl); 1161: ps = &s->Sr; 1162: } 1163: 1164: } 1165: #endif 1166: 1167: /******************************************* 1168: * Dehydrate a symbol tree. 1169: */ 1170: 1171: #if DEHYDRATE 1172: void symbol_tree_dehydrate(symbol **ps) 1173: { symbol *s; 1174: 1175: while ((s = *ps) != NULL && !isdehydrated(s)) /* if symbol exists */ 1176: { 1177: symbol_debug(s); 1178: symbol_dehydrate(ps); 1179: #if DEBUG_XSYMGEN 1180: if (xsym_gen && ph_in_head(s)) 1181: return; 1182: #endif 1183: symbol_dehydrate(&s->Scover); 1184: symbol_tree_dehydrate(&s->Sl); 1185: ps = &s->Sr; 1186: } 1187: } 1188: #endif 1189: 1190: /******************************************* 1191: * Hydrate a symbol. 1192: */ 1193: 1194: #if HYDRATE 1195: symbol *symbol_hydrate(symbol **ps) 1196: { symbol *s; 1197: 1198: s = *ps; 1199: if (isdehydrated(s)) /* if symbol is dehydrated */ 1200: { type *t; 1201: struct_t *st; 1202: 1203: s = (symbol *) ph_hydrate(ps); 1204: #ifdef DEBUG 1205: debugy && dbg_printf("symbol_hydrate('%s')\n",s->Sident); 1206: #endif 1207: symbol_debug(s); 1208: if (!isdehydrated(s->Stype)) // if this symbol is already dehydrated 1209: return s; // no need to do it again 1210: #if SOURCE_4SYMS 1211: s->Ssrcpos.Sfilnum += File_Hydrate_Num; /* file number relative header build */ 1212: #endif 1213: if (pstate.SThflag != FLAG_INPLACE && s->Sfl != FLreg) 1214: s->Sxtrnnum = 0; // not written to .OBJ file yet 1215: type_hydrate(&s->Stype); 1216: //dbg_printf("symbol_hydrate(%p, '%s', t = %p)\n",s,s->Sident,s->Stype); 1217: t = s->Stype; 1218: if (t) 1219: type_debug(t); 1220: 1221: if (t && tyfunc(t->Tty) && ph_hydrate(&s->Sfunc)) 1222: { 1223: func_t *f = s->Sfunc; 1224: SYMIDX si; 1225: 1226: debug(assert(f)); 1227: 1228: list_hydrate(&f->Fsymtree,(list_free_fp)symbol_tree_hydrate); 1229: blocklist_hydrate(&f->Fstartblock); 1230: 1231: ph_hydrate(&f->Flocsym.tab); 1232: for (si = 0; si < f->Flocsym.top; si++) 1233: symbol_hydrate(&f->Flocsym.tab[si]); 1234: 1235: srcpos_hydrate(&f->Fstartline); 1236: srcpos_hydrate(&f->Fendline); 1237: 1238: symbol_hydrate(&f->F__func__); 1239: 1240: if (CPP) 1241: { 1242: symbol_hydrate(&f->Fparsescope); 1243: Classsym_hydrate(&f->Fclass); 1244: symbol_hydrate(&f->Foversym); 1245: symbol_hydrate(&f->Fexplicitspec); 1246: symbol_hydrate(&f->Fsurrogatesym); 1247: 1248: list_hydrate(&f->Fclassfriends,(list_free_fp)symbol_hydrate); 1249: el_hydrate(&f->Fbaseinit); 1250: token_hydrate(&f->Fbody); 1251: symbol_hydrate(&f->Falias); 1252: list_hydrate(&f->Fthunks,(list_free_fp)symbol_hydrate); 1253: if (f->Fflags & Finstance) 1254: symbol_hydrate(&f->Ftempl); 1255: else 1256: thunk_hydrate(&f->Fthunk); 1257: param_hydrate(&f->Farglist); 1258: param_hydrate(&f->Fptal); 1259: list_hydrate(&f->Ffwdrefinstances,(list_free_fp)symbol_hydrate); 1260: list_hydrate(&f->Fexcspec,(list_free_fp)type_hydrate); 1261: } 1262: } 1263: if (CPP) 1264: symbol_hydrate(&s->Sscope); 1265: switch (s->Sclass) 1266: { 1267: case SCstruct: 1268: if (CPP) 1269: { 1270: st = (struct_t *) ph_hydrate(&s->Sstruct); 1271: assert(st); 1272: symbol_tree_hydrate(&st->Sroot); 1273: ph_hydrate(&st->Spvirtder); 1274: list_hydrate(&st->Sfldlst,(list_free_fp)symbol_hydrate); 1275: list_hydrate(&st->Svirtual,(list_free_fp)mptr_hydrate); 1276: list_hydrate(&st->Sopoverload,(list_free_fp)symbol_hydrate); 1277: list_hydrate(&st->Scastoverload,(list_free_fp)symbol_hydrate); 1278: list_hydrate(&st->Sclassfriends,(list_free_fp)symbol_hydrate); 1279: list_hydrate(&st->Sfriendclass,(list_free_fp)symbol_hydrate); 1280: list_hydrate(&st->Sfriendfuncs,(list_free_fp)symbol_hydrate); 1281: assert(!st->Sinlinefuncs); 1282: 1283: baseclass_hydrate(&st->Sbase); 1284: baseclass_hydrate(&st->Svirtbase); 1285: baseclass_hydrate(&st->Smptrbase); 1286: baseclass_hydrate(&st->Sprimary); 1287: #if VBTABLES 1288: baseclass_hydrate(&st->Svbptrbase); 1289: #endif 1290: 1291: ph_hydrate(&st->Svecctor); 1292: ph_hydrate(&st->Sctor); 1293: ph_hydrate(&st->Sdtor); 1294: #if VBTABLES 1295: ph_hydrate(&st->Sprimdtor); 1296: ph_hydrate(&st->Spriminv); 1297: ph_hydrate(&st->Sscaldeldtor); 1298: #endif 1299: ph_hydrate(&st->Sinvariant); 1300: ph_hydrate(&st->Svptr); 1301: ph_hydrate(&st->Svtbl); 1302: ph_hydrate(&st->Sopeq); 1303: ph_hydrate(&st->Sopeq2); 1304: ph_hydrate(&st->Scpct); 1305: ph_hydrate(&st->Sveccpct); 1306: ph_hydrate(&st->Salias); 1307: ph_hydrate(&st->Stempsym); 1308: param_hydrate(&st->Sarglist); 1309: param_hydrate(&st->Spr_arglist); 1310: #if VBTABLES 1311: ph_hydrate(&st->Svbptr); 1312: ph_hydrate(&st->Svbptr_parent); 1313: ph_hydrate(&st->Svbtbl); 1314: #endif 1315: } 1316: else 1317: { 1318: ph_hydrate(&s->Sstruct); 1319: symbol_tree_hydrate(&s->Sstruct->Sroot); 1320: list_hydrate(&s->Sstruct->Sfldlst,(list_free_fp)symbol_hydrate); 1321: } 1322: break; 1323: 1324: case SCenum: 1325: assert(s->Senum); 1326: ph_hydrate(&s->Senum); 1327: if (CPP) 1328: { ph_hydrate(&s->Senum->SEalias); 1329: list_hydrate(&s->Senumlist,(list_free_fp)symbol_hydrate); 1330: } 1331: break; 1332: 1333: case SCtemplate: 1334: { template_t *tm; 1335: 1336: tm = (template_t *) ph_hydrate(&s->Stemplate); 1337: list_hydrate(&tm->TMinstances,(list_free_fp)symbol_hydrate); 1338: list_hydrate(&tm->TMfriends,(list_free_fp)symbol_hydrate); 1339: param_hydrate(&tm->TMptpl); 1340: param_hydrate(&tm->TMptal); 1341: token_hydrate(&tm->TMbody); 1342: list_hydrate(&tm->TMmemberfuncs,(list_free_fp)tmf_hydrate); 1343: list_hydrate(&tm->TMexplicit,(list_free_fp)tme_hydrate); 1344: list_hydrate(&tm->TMnestedexplicit,(list_free_fp)tmne_hydrate); 1345: list_hydrate(&tm->TMnestedfriends,(list_free_fp)tmnf_hydrate); 1346: ph_hydrate(&tm->TMnext); 1347: symbol_hydrate(&tm->TMpartial); 1348: symbol_hydrate(&tm->TMprimary); 1349: break; 1350: } 1351: 1352: case SCnamespace: 1353: symbol_tree_hydrate(&s->Snameroot); 1354: list_hydrate(&s->Susing,(list_free_fp)symbol_hydrate); 1355: break; 1356: 1357: case SCmemalias: 1358: case SCfuncalias: 1359: case SCadl: 1360: list_hydrate(&s->Spath,(list_free_fp)symbol_hydrate); 1361: case SCalias: 1362: ph_hydrate(&s->Smemalias); 1363: break; 1364: 1365: default: 1366: if (s->Sflags & (SFLvalue | SFLdtorexp)) 1367: el_hydrate(&s->Svalue); 1368: break; 1369: } 1370: { dt_t **pdt,*dt; 1371: 1372: for (pdt = &s->Sdt; isdehydrated(*pdt); pdt = &dt->DTnext) 1373: { 1374: dt = (dt_t *) ph_hydrate(pdt); 1375: switch (dt->dt) 1376: { case DT_abytes: 1377: case DT_nbytes: 1378: ph_hydrate(&dt->DTpbytes); 1379: break; 1380: case DT_xoff: 1381: symbol_hydrate(&dt->DTsym); 1382: break; 1383: } 1384: } 1385: } 1386: if (s->Scover) 1387: symbol_hydrate(&s->Scover); 1388: } 1389: return s; 1390: } 1391: #endif 1392: 1393: /******************************************* 1394: * Dehydrate a symbol. 1395: */ 1396: 1397: #if DEHYDRATE 1398: void symbol_dehydrate(symbol **ps) 1399: { 1400: symbol *s; 1401: 1402: if ((s = *ps) != NULL && !isdehydrated(s)) /* if symbol exists */ 1403: { type *t; 1404: struct_t *st; 1405: 1406: #ifdef DEBUG 1407: if (debugy) 1408: dbg_printf("symbol_dehydrate('%s')\n",s->Sident); 1409: #endif 1410: ph_dehydrate(ps); 1411: #if DEBUG_XSYMGEN 1412: if (xsym_gen && ph_in_head(s)) 1413: return; 1414: #endif 1415: symbol_debug(s); 1416: t = s->Stype; 1417: if (isdehydrated(t)) 1418: return; 1419: type_dehydrate(&s->Stype); 1420: 1421: if (tyfunc(t->Tty) && !isdehydrated(s->Sfunc)) 1422: { 1423: func_t *f = s->Sfunc; 1424: SYMIDX si; 1425: 1426: debug(assert(f)); 1427: ph_dehydrate(&s->Sfunc); 1428: 1429: list_dehydrate(&f->Fsymtree,(list_free_fp)symbol_tree_dehydrate); 1430: blocklist_dehydrate(&f->Fstartblock); 1431: assert(!isdehydrated(&f->Flocsym.tab)); 1432: 1433: #if DEBUG_XSYMGEN 1434: if (!xsym_gen || !ph_in_head(f->Flocsym.tab)) 1435: 1436: #endif 1437: for (si = 0; si < f->Flocsym.top; si++) 1438: symbol_dehydrate(&f->Flocsym.tab[si]); 1439: ph_dehydrate(&f->Flocsym.tab); 1440: 1441: srcpos_dehydrate(&f->Fstartline); 1442: srcpos_dehydrate(&f->Fendline); 1443: symbol_dehydrate(&f->F__func__); 1444: if (CPP) 1445: { 1446: symbol_dehydrate(&f->Fparsescope); 1447: ph_dehydrate(&f->Fclass); 1448: symbol_dehydrate(&f->Foversym); 1449: symbol_dehydrate(&f->Fexplicitspec); 1450: symbol_dehydrate(&f->Fsurrogatesym); 1451: 1452: list_dehydrate(&f->Fclassfriends,FPNULL); 1453: el_dehydrate(&f->Fbaseinit); 1454: #if DEBUG_XSYMGEN 1455: if (xsym_gen && s->Sclass == SCfunctempl) 1456: ph_dehydrate(&f->Fbody); 1457: else 1458: #endif 1459: token_dehydrate(&f->Fbody); 1460: symbol_dehydrate(&f->Falias); 1461: list_dehydrate(&f->Fthunks,(list_free_fp)symbol_dehydrate); 1462: if (f->Fflags & Finstance) 1463: symbol_dehydrate(&f->Ftempl); 1464: else 1465: thunk_dehydrate(&f->Fthunk); 1466: #if !TX86 && DEBUG_XSYMGEN 1467: if (xsym_gen && s->Sclass == SCfunctempl) 1468: ph_dehydrate(&f->Farglist); 1469: else 1470: #endif 1471: param_dehydrate(&f->Farglist); 1472: param_dehydrate(&f->Fptal); 1473: list_dehydrate(&f->Ffwdrefinstances,(list_free_fp)symbol_dehydrate); 1474: list_dehydrate(&f->Fexcspec,(list_free_fp)type_dehydrate); 1475: } 1476: } 1477: if (CPP) 1478: ph_dehydrate(&s->Sscope); 1479: switch (s->Sclass) 1480: { 1481: case SCstruct: 1482: if (CPP) 1483: { 1484: st = s->Sstruct; 1485: if (isdehydrated(st)) 1486: break; 1487: ph_dehydrate(&s->Sstruct); 1488: assert(st); 1489: symbol_tree_dehydrate(&st->Sroot); 1490: ph_dehydrate(&st->Spvirtder); 1491: list_dehydrate(&st->Sfldlst,(list_free_fp)symbol_dehydrate); 1492: list_dehydrate(&st->Svirtual,(list_free_fp)mptr_dehydrate); 1493: list_dehydrate(&st->Sopoverload,(list_free_fp)symbol_dehydrate); 1494: list_dehydrate(&st->Scastoverload,(list_free_fp)symbol_dehydrate); 1495: list_dehydrate(&st->Sclassfriends,(list_free_fp)symbol_dehydrate); 1496: list_dehydrate(&st->Sfriendclass,(list_free_fp)ph_dehydrate); 1497: list_dehydrate(&st->Sfriendfuncs,(list_free_fp)ph_dehydrate); 1498: assert(!st->Sinlinefuncs); 1499: 1500: baseclass_dehydrate(&st->Sbase); 1501: baseclass_dehydrate(&st->Svirtbase); 1502: baseclass_dehydrate(&st->Smptrbase); 1503: baseclass_dehydrate(&st->Sprimary); 1504: #if VBTABLES 1505: baseclass_dehydrate(&st->Svbptrbase); 1506: #endif 1507: 1508: ph_dehydrate(&st->Svecctor); 1509: ph_dehydrate(&st->Sctor); 1510: ph_dehydrate(&st->Sdtor); 1511: #if VBTABLES 1512: ph_dehydrate(&st->Sprimdtor); 1513: ph_dehydrate(&st->Spriminv); 1514: ph_dehydrate(&st->Sscaldeldtor); 1515: #endif 1516: ph_dehydrate(&st->Sinvariant); 1517: ph_dehydrate(&st->Svptr); 1518: ph_dehydrate(&st->Svtbl); 1519: ph_dehydrate(&st->Sopeq); 1520: ph_dehydrate(&st->Sopeq2); 1521: ph_dehydrate(&st->Scpct); 1522: ph_dehydrate(&st->Sveccpct); 1523: ph_dehydrate(&st->Salias); 1524: ph_dehydrate(&st->Stempsym); 1525: param_dehydrate(&st->Sarglist); 1526: param_dehydrate(&st->Spr_arglist); 1527: #if VBTABLES 1528: ph_dehydrate(&st->Svbptr); 1529: ph_dehydrate(&st->Svbptr_parent); 1530: ph_dehydrate(&st->Svbtbl); 1531: #endif 1532: } 1533: else 1534: { 1535: symbol_tree_dehydrate(&s->Sstruct->Sroot); 1536: list_dehydrate(&s->Sstruct->Sfldlst,(list_free_fp)symbol_dehydrate); 1537: ph_dehydrate(&s->Sstruct); 1538: } 1539: break; 1540: 1541: case SCenum: 1542: assert(s->Senum); 1543: if (!isdehydrated(s->Senum)) 1544: { 1545: if (CPP) 1546: { ph_dehydrate(&s->Senum->SEalias); 1547: list_dehydrate(&s->Senumlist,(list_free_fp)ph_dehydrate); 1548: } 1549: ph_dehydrate(&s->Senum); 1550: } 1551: break; 1552: 1553: case SCtemplate: 1554: { template_t *tm; 1555: 1556: tm = s->Stemplate; 1557: if (!isdehydrated(tm)) 1558: { 1559: ph_dehydrate(&s->Stemplate); 1560: list_dehydrate(&tm->TMinstances,(list_free_fp)symbol_dehydrate); 1561: list_dehydrate(&tm->TMfriends,(list_free_fp)symbol_dehydrate); 1562: list_dehydrate(&tm->TMnestedfriends,(list_free_fp)tmnf_dehydrate); 1563: param_dehydrate(&tm->TMptpl); 1564: param_dehydrate(&tm->TMptal); 1565: token_dehydrate(&tm->TMbody); 1566: list_dehydrate(&tm->TMmemberfuncs,(list_free_fp)tmf_dehydrate); 1567: list_dehydrate(&tm->TMexplicit,(list_free_fp)tme_dehydrate); 1568: list_dehydrate(&tm->TMnestedexplicit,(list_free_fp)tmne_dehydrate); 1569: ph_dehydrate(&tm->TMnext); 1570: symbol_dehydrate(&tm->TMpartial); 1571: symbol_dehydrate(&tm->TMprimary); 1572: } 1573: break; 1574: } 1575: 1576: case SCnamespace: 1577: symbol_tree_dehydrate(&s->Snameroot); 1578: list_dehydrate(&s->Susing,(list_free_fp)symbol_dehydrate); 1579: break; 1580: 1581: case SCmemalias: 1582: case SCfuncalias: 1583: case SCadl: 1584: list_dehydrate(&s->Spath,(list_free_fp)symbol_dehydrate); 1585: case SCalias: 1586: ph_dehydrate(&s->Smemalias); 1587: break; 1588: 1589: default: 1590: if (s->Sflags & (SFLvalue | SFLdtorexp)) 1591: el_dehydrate(&s->Svalue); 1592: break; 1593: } 1594: { dt_t **pdt,*dt; 1595: 1596: for (pdt = &s->Sdt; 1597: (dt = *pdt) != NULL && !isdehydrated(dt); 1598: pdt = &dt->DTnext) 1599: { 1600: ph_dehydrate(pdt); 1601: switch (dt->dt) 1602: { case DT_abytes: 1603: case DT_nbytes: 1604: ph_dehydrate(&dt->DTpbytes); 1605: break; 1606: case DT_xoff: 1607: symbol_dehydrate(&dt->DTsym); 1608: break; 1609: } 1610: } 1611: } 1612: if (s->Scover) 1613: symbol_dehydrate(&s->Scover); 1614: } 1615: } 1616: #endif 1617: 1618: /*************************** 1619: * Dehydrate threaded list of symbols. 1620: */ 1621: 1622: #if DEHYDRATE 1623: void symbol_symdefs_dehydrate(symbol **ps) 1624: { 1625: symbol *s; 1626: 1627: for (; *ps; ps = &s->Snext) 1628: { 1629: s = *ps; 1630: symbol_debug(s); 1631: //dbg_printf("symbol_symdefs_dehydrate(%p, '%s')\n",s,s->Sident); 1632: symbol_dehydrate(ps); 1633: } 1634: } 1635: #endif 1636: 1637: /*************************** 1638: * Hydrate threaded list of symbols. 1639: * Input: 1640: * *ps start of threaded list 1641: * *parent root of symbol table to add symbol into 1642: * flag !=0 means add onto existing stuff 1643: * 0 means hydrate in place 1644: */ 1645: 1646: #if SCPP 1647: 1648: void symbol_symdefs_hydrate(symbol **ps,symbol **parent,int flag) 1649: { symbol *s; 1650: 1651: //printf("symbol_symdefs_hydrate(flag = %d)\n",flag); 1652: #ifdef DEBUG 1653: int count = 0; 1654: 1655: if (flag) symbol_tree_check(*parent); 1656: #endif 1657: for (; *ps; ps = &s->Snext) 1658: { 1659: //dbg_printf("%p ",*ps); 1660: #ifdef DEBUG 1661: count++; 1662: #endif 1663: s = dohydrate ? symbol_hydrate(ps) : *ps; 1664: 1665: //if (s->Sclass == SCstruct) 1666: //dbg_printf("symbol_symdefs_hydrate(%p, '%s')\n",s,s->Sident); 1667: symbol_debug(s); 1668: #if 0 1669: if (tyfunc(s->Stype->Tty)) 1670: { Outbuffer buf; 1671: char *p1; 1672: 1673: p1 = param_tostring(&buf,s->Stype); 1674: dbg_printf("'%s%s'\n",cpp_prettyident(s),p1); 1675: } 1676: #endif 1677: type_debug(s->Stype); 1678: if (flag) 1679: { char *p; 1680: symbol **ps; 1681: symbol *rover; 1682: char c; 1683: size_t len; 1684: 1685: p = s->Sident; 1686: c = *p; 1687: 1688: // Put symbol s into symbol table 1689: 1690: #if MMFIO 1691: if (s->Sl || s->Sr) // avoid writing to page if possible 1692: #endif 1693: s->Sl = s->Sr = NULL; 1694: len = strlen(p); 1695: p++; 1696: ps = parent; 1697: while ((rover = *ps) != NULL) 1698: { signed char cmp; 1699: 1700: if ((cmp = c - rover->Sident[0]) == 0) 1701: { cmp = memcmp(p,rover->Sident + 1,len); // compare identifier strings 1702: if (cmp == 0) 1703: { 1704: if (CPP && tyfunc(s->Stype->Tty) && tyfunc(rover->Stype->Tty)) 1705: { symbol **ps; 1706: symbol *sn; 1707: symbol *so; 1708: 1709: so = s; 1710: do 1711: { 1712: // Tack onto end of overloaded function list 1713: for (ps = &rover; *ps; ps = &(*ps)->Sfunc->Foversym) 1714: { if (cpp_funccmp(so, *ps)) 1715: { //printf("function '%s' already in list\n",so->Sident); 1716: goto L2; 1717: } 1718: } 1719: //printf("appending '%s' to rover\n",so->Sident); 1720: *ps = so; 1721: L2: 1722: sn = so->Sfunc->Foversym; 1723: so->Sfunc->Foversym = NULL; 1724: so = sn; 1725: } while (so); 1726: //printf("overloading...\n"); 1727: } 1728: else if (s->Sclass == SCstruct) 1729: { 1730: if (CPP && rover->Scover) 1731: { ps = &rover->Scover; 1732: rover = *ps; 1733: } 1734: else 1735: if (rover->Sclass == SCstruct) 1736: { 1737: if (!(s->Stype->Tflags & TFforward)) 1738: { // Replace rover with s in symbol table 1739: //printf("Replacing '%s'\n",s->Sident); 1740: *ps = s; 1741: s->Sl = rover->Sl; 1742: s->Sr = rover->Sr; 1743: rover->Sl = rover->Sr = NULL; 1744: rover->Stype->Ttag = (Classsym *)s; 1745: symbol_keep(rover); 1746: } 1747: else 1748: s->Stype->Ttag = (Classsym *)rover; 1749: } 1750: } 1751: goto L1; 1752: } 1753: } 1754: ps = (cmp < 0) ? /* if we go down left side */ 1755: &rover->Sl : 1756: &rover->Sr; 1757: } 1758: *ps = s; 1759: if (s->Sclass == SCcomdef) 1760: { s->Sclass = SCglobal; 1761: outcommon(s,type_size(s->Stype)); 1762: } 1763: } 1764: L1: ; 1765: } // for 1766: #ifdef DEBUG 1767: if (flag) symbol_tree_check(*parent); 1768: printf("%d symbols hydrated\n",count); 1769: #endif 1770: } 1771: 1772: #endif 1773: 1774: #if 0 1775: 1776: /************************************* 1777: * Put symbol table s into parent symbol table. 1778: */ 1779: 1780: void symboltable_hydrate(symbol *s,symbol **parent) 1781: { 1782: while (s) 1783: { symbol *sl,*sr; 1784: char *p; 1785: 1786: symbol_debug(s); 1787: 1788: sl = s->Sl; 1789: sr = s->Sr; 1790: p = s->Sident; 1791: 1792: //dbg_printf("symboltable_hydrate('%s')\n",p); 1793: 1794: /* Put symbol s into symbol table */ 1795: { symbol **ps; 1796: symbol *rover; 1797: int c = *p; 1798: 1799: ps = parent; 1800: while ((rover = *ps) != NULL) 1801: { int cmp; 1802: 1803: if ((cmp = c - rover->Sident[0]) == 0) 1804: { cmp = strcmp(p,rover->Sident); /* compare identifier strings */ 1805: if (cmp == 0) 1806: { 1807: if (CPP && tyfunc(s->Stype->Tty) && tyfunc(rover->Stype->Tty)) 1808: { symbol **ps; 1809: symbol *sn; 1810: 1811: do 1812: { 1813: // Tack onto end of overloaded function list 1814: for (ps = &rover; *ps; ps = &(*ps)->Sfunc->Foversym) 1815: { if (cpp_funccmp(s, *ps)) 1816: goto L2; 1817: } 1818: s->Sl = s->Sr = NULL; 1819: *ps = s; 1820: L2: 1821: sn = s->Sfunc->Foversym; 1822: s->Sfunc->Foversym = NULL; 1823: s = sn; 1824: } while (s); 1825: } 1826: else 1827: { 1828: if (!typematch(s->Stype,rover->Stype,0)) 1829: { 1830: // cpp_predefine() will define this again 1831: if (type_struct(rover->Stype) && 1832: rover->Sstruct->Sflags & STRpredef) 1833: { s->Sl = s->Sr = NULL; 1834: symbol_keep(s); 1835: } 1836: else 1837: synerr(EM_multiple_def,p); // already defined 1838: } 1839: } 1840: goto L1; 1841: } 1842: } 1843: ps = (cmp < 0) ? /* if we go down left side */ 1844: &rover->Sl : 1845: &rover->Sr; 1846: } 1847: { 1848: s->Sl = s->Sr = NULL; 1849: *ps = s; 1850: } 1851: } 1852: L1: 1853: symboltable_hydrate(sl,parent); 1854: s = sr; 1855: } 1856: } 1857: 1858: #endif 1859: 1860: 1861: /************************************ 1862: * Hydrate/dehydrate an mptr_t. 1863: */ 1864: 1865: #if HYDRATE 1866: STATIC void mptr_hydrate(mptr_t **pm) 1867: { mptr_t *m; 1868: 1869: m = (mptr_t *) ph_hydrate(pm); 1870: symbol_hydrate(&m->MPf); 1871: symbol_hydrate(&m->MPparent); 1872: } 1873: #endif 1874: 1875: #if DEHYDRATE 1876: STATIC void mptr_dehydrate(mptr_t **pm) 1877: { mptr_t *m; 1878: 1879: m = *pm; 1880: if (m && !isdehydrated(m)) 1881: { 1882: ph_dehydrate(pm); 1883: #if DEBUG_XSYMGEN 1884: if (xsym_gen && ph_in_head(m->MPf)) 1885: ph_dehydrate(&m->MPf); 1886: else 1887: #endif 1888: symbol_dehydrate(&m->MPf); 1889: symbol_dehydrate(&m->MPparent); 1890: } 1891: } 1892: #endif 1893: 1894: /************************************ 1895: * Hydrate/dehydrate a baseclass_t. 1896: */ 1897: 1898: #if HYDRATE 1899: STATIC void baseclass_hydrate(baseclass_t **pb) 1900: { baseclass_t *b; 1901: 1902: assert(pb); 1903: while (isdehydrated(*pb)) 1904: { 1905: b = (baseclass_t *) ph_hydrate(pb); 1906: 1907: ph_hydrate(&b->BCbase); 1908: ph_hydrate(&b->BCpbase); 1909: list_hydrate(&b->BCpublics,(list_free_fp)symbol_hydrate); 1910: #if VBTABLES 1911: #else 1912: symbol_hydrate(&b->param); 1913: #endif 1914: list_hydrate(&b->BCmptrlist,(list_free_fp)mptr_hydrate); 1915: symbol_hydrate(&b->BCvtbl); 1916: Classsym_hydrate(&b->BCparent); 1917: 1918: pb = &b->BCnext; 1919: } 1920: } 1921: #endif 1922: 1923: /********************************** 1924: * Dehydrate a baseclass_t. 1925: */ 1926: 1927: #if DEHYDRATE 1928: STATIC void baseclass_dehydrate(baseclass_t **pb) 1929: { baseclass_t *b; 1930: 1931: while ((b = *pb) != NULL && !isdehydrated(b)) 1932: { 1933: ph_dehydrate(pb); 1934: 1935: #if DEBUG_XSYMGEN 1936: if (xsym_gen && ph_in_head(b)) 1937: return; 1938: #endif 1939: 1940: ph_dehydrate(&b->BCbase); 1941: ph_dehydrate(&b->BCpbase); 1942: list_dehydrate(&b->BCpublics,(list_free_fp)symbol_dehydrate); 1943: #if VBTABLES 1944: #else 1945: symbol_dehydrate(&b->param); 1946: #endif 1947: list_dehydrate(&b->BCmptrlist,(list_free_fp)mptr_dehydrate); 1948: symbol_dehydrate(&b->BCvtbl); 1949: Classsym_dehydrate(&b->BCparent); 1950: 1951: pb = &b->BCnext; 1952: } 1953: } 1954: #endif 1955: 1956: /*************************** 1957: * Look down baseclass list to find sbase. 1958: * Returns: 1959: * NULL not found 1960: * pointer to baseclass 1961: */ 1962: 1963: baseclass_t *baseclass_find(baseclass_t *bm,Classsym *sbase) 1964: { 1965: symbol_debug(sbase); 1966: for (; bm; bm = bm->BCnext) 1967: if (bm->BCbase == sbase) 1968: break; 1969: return bm; 1970: } 1971: 1972: baseclass_t *baseclass_find_nest(baseclass_t *bm,Classsym *sbase) 1973: { 1974: symbol_debug(sbase); 1975: for (; bm; bm = bm->BCnext) 1976: { 1977: if (bm->BCbase == sbase || 1978: baseclass_find_nest(bm->BCbase->Sstruct->Sbase, sbase)) 1979: break; 1980: } 1981: return bm; 1982: } 1983: 1984: /****************************** 1985: * Calculate number of baseclasses in list. 1986: */ 1987: 1988: #if VBTABLES 1989: 1990: int baseclass_nitems(baseclass_t *b) 1991: { int i; 1992: 1993: for (i = 0; b; b = b->BCnext) 1994: i++; 1995: return i; 1996: } 1997: 1998: #endif 1999: 2000: 2001: /***************************** 2002: * Go through symbol table preparing it to be written to a precompiled 2003: * header. That means removing references to things in the .OBJ file. 2004: */ 2005: 2006: #if SCPP 2007: 2008: void symboltable_clean(symbol *s) 2009: { 2010: while (s) 2011: { 2012: struct_t *st; 2013: 2014: //printf("clean('%s')\n",s->Sident); 2015: if (config.fulltypes != CVTDB && s->Sxtrnnum && s->Sfl != FLreg) 2016: s->Sxtrnnum = 0; // eliminate debug info type index 2017: switch (s->Sclass) 2018: { 2019: case SCstruct: 2020: s->Stypidx = 0; 2021: st = s->Sstruct; 2022: assert(st); 2023: symboltable_clean(st->Sroot); 2024: //list_apply(&st->Sfldlst,(list_free_fp)symboltable_clean); 2025: break; 2026: 2027: case SCtypedef: 2028: case SCenum: 2029: s->Stypidx = 0; 2030: break; 2031: #if 1 2032: case SCtemplate: 2033: { template_t *tm = s->Stemplate; 2034: 2035: list_apply(&tm->TMinstances,(list_free_fp)symboltable_clean); 2036: break; 2037: } 2038: #endif 2039: case SCnamespace: 2040: symboltable_clean(s->Snameroot); 2041: break; 2042: 2043: default: 2044: if (s->Sxtrnnum && s->Sfl != FLreg) 2045: s->Sxtrnnum = 0; // eliminate external symbol index 2046: if (tyfunc(s->Stype->Tty)) 2047: { 2048: func_t *f = s->Sfunc; 2049: SYMIDX si; 2050: 2051: debug(assert(f)); 2052: 2053: list_apply(&f->Fsymtree,(list_free_fp)symboltable_clean); 2054: for (si = 0; si < f->Flocsym.top; si++) 2055: symboltable_clean(f->Flocsym.tab[si]); 2056: if (f->Foversym) 2057: symboltable_clean(f->Foversym); 2058: if (f->Fexplicitspec) 2059: symboltable_clean(f->Fexplicitspec); 2060: } 2061: break; 2062: } 2063: if (s->Sl) 2064: symboltable_clean(s->Sl); 2065: if (s->Scover) 2066: symboltable_clean(s->Scover); 2067: s = s->Sr; 2068: } 2069: } 2070: 2071: #endif 2072: 2073: #if SCPP 2074: 2075: /* 2076: * Balance our symbol tree in place. This is nice for precompiled headers, since they 2077: * will typically be written out once, but read in many times. We balance the tree in 2078: * place by traversing the tree inorder and writing the pointers out to an ordered 2079: * list. Once we have a list of symbol pointers, we can create a tree by recursively 2080: * dividing the list, using the midpoint of each division as the new root for that 2081: * subtree. 2082: */ 2083: 2084: struct Balance 2085: { 2086: unsigned nsyms; 2087: symbol **array; 2088: unsigned index; 2089: }; 2090: 2091: static Balance balance; 2092: 2093: STATIC void count_symbols(symbol *s) 2094: { 2095: while (s) 2096: { 2097: balance.nsyms++; 2098: switch (s->Sclass) 2099: { 2100: case SCnamespace: 2101: symboltable_balance(&s->Snameroot); 2102: break; 2103: 2104: case SCstruct: 2105: symboltable_balance(&s->Sstruct->Sroot); 2106: break; 2107: } 2108: count_symbols(s->Sl); 2109: s = s->Sr; 2110: } 2111: } 2112: 2113: STATIC void place_in_array(symbol *s) 2114: { 2115: while (s) 2116: { 2117: place_in_array(s->Sl); 2118: balance.array[balance.index++] = s; 2119: s = s->Sr; 2120: } 2121: } 2122: 2123: /* 2124: * Create a tree in place by subdividing between lo and hi inclusive, using i 2125: * as the root for the tree. When the lo-hi interval is one, we've either 2126: * reached a leaf or an empty node. We subdivide below i by halving the interval 2127: * between i and lo, and using i-1 as our new hi point. A similar subdivision 2128: * is created above i. 2129: */ 2130: STATIC symbol * create_tree(int i, int lo, int hi) 2131: { 2132: symbol *s = balance.array[i]; 2133: 2134: if (i < lo || i > hi) /* empty node ? */ 2135: return NULL; 2136: 2137: assert((unsigned) i < balance.nsyms); 2138: if (i == lo && i == hi) { /* leaf node ? */ 2139: s->Sl = NULL; 2140: s->Sr = NULL; 2141: return s; 2142: } 2143: 2144: s->Sl = create_tree((i + lo) / 2, lo, i - 1); 2145: s->Sr = create_tree((i + hi + 1) / 2, i + 1, hi); 2146: 2147: return s; 2148: } 2149: 2150: #define METRICS 0 2151: 2152: #if METRICS 2153: void symbol_table_metrics(void); 2154: #endif 2155: 2156: void symboltable_balance(symbol **ps) 2157: { 2158: Balance balancesave; 2159: #if METRICS 2160: long ticks; 2161: 2162: dbg_printf("symbol table before balance:\n"); 2163: symbol_table_metrics(); 2164: ticks = clock(); 2165: #endif 2166: balancesave = balance; // so we can nest 2167: balance.nsyms = 0; 2168: count_symbols(*ps); 2169: //dbg_printf("Number of global symbols = %d\n",balance.nsyms); 2170: 2171: #if __INTSIZE == 2 2172: // Don't balance tree if we get 16 bit overflow 2173: if (balance.nsyms >= (unsigned)(0x10000 / sizeof(symbol *))) 2174: goto Lret; 2175: #endif 2176: 2177: // Use malloc instead of mem because of pagesize limits 2178: balance.array = (symbol **) malloc(balance.nsyms * sizeof(symbol *)); 2179: if (!balance.array) 2180: goto Lret; // no error, just don't balance 2181: 2182: balance.index = 0; 2183: place_in_array(*ps); 2184: 2185: *ps = create_tree(balance.nsyms / 2, 0, balance.nsyms - 1); 2186: 2187: free(balance.array); 2188: #if METRICS 2189: dbg_printf("time to balance: %ld\n", clock() - ticks); 2190: dbg_printf("symbol table after balance:\n"); 2191: symbol_table_metrics(); 2192: #endif 2193: Lret: 2194: balance = balancesave; 2195: } 2196: 2197: #endif 2198: 2199: /***************************************** 2200: * Symbol table search routine for members of structs, given that 2201: * we don't know which struct it is in. 2202: * Give error message if it appears more than once. 2203: * Returns: 2204: * NULL member not found 2205: * symbol* symbol matching member 2206: */ 2207: 2208: #if SCPP 2209: 2210: struct Paramblock // to minimize stack usage in helper function 2211: { const char *id; // identifier we are looking for 2212: symbol *sm; // where to put result 2213: symbol *s; 2214: }; 2215: 2216: STATIC void membersearchx(struct Paramblock *p,symbol *s) 2217: { symbol *sm; 2218: list_t sl; 2219: 2220: while (s) 2221: { symbol_debug(s); 2222: 2223: switch (s->Sclass) 2224: { case SCstruct: 2225: for (sl = s->Sstruct->Sfldlst; sl; sl = list_next(sl)) 2226: { sm = list_symbol(sl); 2227: symbol_debug(sm); 2228: if ((sm->Sclass == SCmember || sm->Sclass == SCfield) && 2229: strcmp(p->id,sm->Sident) == 0) 2230: { 2231: if (p->sm && p->sm->Smemoff != sm->Smemoff) 2232: synerr(EM_ambig_member,p->id,s->Sident,p->s->Sident); // ambiguous reference to id 2233: p->s = s; 2234: p->sm = sm; 2235: break; 2236: } 2237: } 2238: break; 2239: } 2240: 2241: if (s->Sl) 2242: membersearchx(p,s->Sl); 2243: s = s->Sr; 2244: } 2245: } 2246: 2247: symbol *symbol_membersearch(const char *id) 2248: { 2249: list_t sl; 2250: struct Paramblock pb; 2251: Scope *sc; 2252: 2253: pb.id = id; 2254: pb.sm = NULL; 2255: for (sc = scope_end; sc; sc = sc->next) 2256: { 2257: if (sc->sctype & (CPP ? (SCTglobal | SCTlocal) : (SCTglobaltag | SCTtag))) 2258: membersearchx((struct Paramblock *)&pb,(symbol *)sc->root); 2259: } 2260: return pb.sm; 2261: } 2262: 2263: /******************************************* 2264: * Generate debug info for global struct tag symbols. 2265: */ 2266: 2267: STATIC void symbol_gendebuginfox(symbol *s) 2268: { 2269: for (; s; s = s->Sr) 2270: { 2271: if (s->Sl) 2272: symbol_gendebuginfox(s->Sl); 2273: if (s->Scover) 2274: symbol_gendebuginfox(s->Scover); 2275: switch (s->Sclass) 2276: { 2277: case SCenum: 2278: if (CPP && s->Senum->SEflags & SENnotagname) 2279: break; 2280: goto Lout; 2281: case SCstruct: 2282: if (s->Sstruct->Sflags & STRanonymous) 2283: break; 2284: goto Lout; 2285: case SCtypedef: 2286: Lout: 2287: if (!s->Stypidx) 2288: cv_outsym(s); 2289: break; 2290: } 2291: } 2292: } 2293: 2294: void symbol_gendebuginfo() 2295: { Scope *sc; 2296: 2297: for (sc = scope_end; sc; sc = sc->next) 2298: { 2299: if (sc->sctype & (SCTglobaltag | SCTglobal)) 2300: symbol_gendebuginfox((symbol *)sc->root); 2301: } 2302: } 2303: 2304: #endif 2305: 2306: #endif /* !SPP */ 2307: 2308: