1: // Copyright (C) 1985-1998 by Symantec
   2: // Copyright (C) 2000-2009 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 __SC__
  14: #pragma once
  15: #endif
  16: 
  17: #ifndef CC_H
  18: #define CC_H    1
  19: 
  20: #ifdef SCPP
  21: #define CPP     (config.flags3 & CFG3cpp)       // if compiling for C++
  22: #else
  23: #if !SPP
  24: #define SCPP            0
  25: #endif
  26: #endif
  27: 
  28: #ifndef CPP
  29: #define CPP             0
  30: #endif
  31: 
  32: #ifndef SPP
  33: #define SPP             0
  34: #endif
  35: 
  36: #ifndef MARS
  37: #define MARS            0       // not compiling MARS code
  38: #endif
  39: 
  40: #ifndef HTOD
  41: #define HTOD            0
  42: #endif
  43: 
  44: #define GENOBJ          1       // generating .obj file
  45: 
  46: #define mskl(i)         (1L << (i))     /* convert int to mask          */
  47: 
  48: #ifndef STATIC
  49: #define STATIC  static
  50: #endif
  51: 
  52: #ifndef CEXTERN
  53: #define CEXTERN extern
  54: #endif
  55: 
  56: // Warnings
  57: enum WM
  58: {
  59:         WM_no_inline    = 1,    //function '%s' is too complicated to inline
  60:         WM_assignment   = 2,    //possible unintended assignment
  61:         WM_nestcomment  = 3,    //comments do not nest
  62:         WM_assignthis   = 4,    //assignment to 'this' is obsolete, use X::operator new/delete
  63:         WM_notagname    = 5,    //no tag name for struct or enum
  64:         WM_valuenotused = 6,    //value of expression is not used
  65:         WM_extra_semi   = 7,    //possible extraneous ';'
  66:         WM_large_auto   = 8,    //very large automatic
  67:         WM_obsolete_del = 9,    //use delete[] rather than delete[expr], expr ignored
  68:         WM_obsolete_inc = 10,   //using operator++() (or --) instead of missing operator++(int)
  69:         WM_init2tmp     = 11,   //non-const reference initialized to temporary
  70:         WM_used_b4_set  = 12,   //variable '%s' used before set
  71:         WM_bad_op       = 13,   //Illegal type/size of operands for the %s instruction
  72:         WM_386_op       = 14,   //Reference to '%s' caused a 386 instruction to be generated
  73:         WM_ret_auto     = 15,   //returning address of automatic '%s'
  74:         WM_ds_ne_dgroup = 16,   //DS is not equal to DGROUP
  75:         WM_unknown_pragma = 17, //unrecognized pragma
  76:         WM_implied_ret  = 18,   //implied return at closing '}' does not return value
  77:         WM_num_args     = 19,   //%d actual arguments expected for %s, had %d
  78:         WM_before_pch   = 20,   //symbols or macros defined before #include of precompiled header
  79:         WM_pch_first    = 21,   //precompiled header must be first #include when -H is used
  80:         WM_pch_config   = 22,
  81:         WM_divby0       = 23,
  82:         WM_badnumber    = 24,
  83:         WM_ccast        = 25,
  84:         WM_obsolete     = 26,
  85: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
  86:         WM_skip_attribute   = 27, // skip GNUC attribute specification
  87:         WM_warning_message  = 28, // preprocessor warning message
  88:         WM_bad_vastart      = 29, // args for builtin va_start bad
  89:         WM_undefined_inline = 30, // static inline not expanded or defined
  90: #endif
  91: };
  92: 
  93: // Language for error messages
  94: enum LANG
  95: {       LANGenglish,
  96:         LANGgerman,
  97:         LANGfrench,
  98:         LANGjapanese,
  99: };
 100: 
 101: #include        "cdef.h"        // host and target compiler definition
 102: 
 103: #define INITIALIZED_STATIC_DEF  static
 104: 
 105: #if MEMMODELS == 1
 106: #define LARGEDATA 0     /* don't want 48 bit pointers */
 107: #define LARGECODE 0
 108: #endif
 109: 
 110: #ifndef __INTSIZE
 111: #define __INTSIZE       4       // host ints are 4 bytes
 112: #endif
 113: 
 114: #if SPP || SCPP
 115: #include        "msgs2.h"
 116: #endif
 117: #include        "ty.h"
 118: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
 119: #include        "../tk/mem.h"
 120: #else
 121: #include        "mem.h"
 122: #endif
 123: #include        "list.h"
 124: #include        "vec.h"
 125: 
 126: #if SPP
 127: #define COMPILER "Preprocessor"
 128: #define ACTIVITY "preprocessing..."
 129: #elif HTOD
 130: #define COMPILER ".h to D Migration Tool"
 131: #define ACTIVITY "migrating..."
 132: #else
 133: #define COMPILER "C/C++ Compiler"
 134: #define ACTIVITY "compiling..."
 135: #endif
 136: 
 137: #ifdef DEBUG
 138: #   define debug(a)     (a)
 139: #   define debugx(a)    (a)
 140: #   define debug_assert assert
 141: #else
 142: #   define debug(a)
 143: #   define debugx(a)
 144: #   define debug_assert(e)
 145: #endif
 146: 
 147: 
 148: /***************************
 149:  * Print out debugging information.
 150:  */
 151: 
 152: #ifdef DEBUG
 153: #define debugmes(s)     (debugw && dbg_printf(s))
 154: #define cmes(s)         (debugc && dbg_printf(s))
 155: #define cmes2(s,b)      (debugc && dbg_printf((s),(b)))
 156: #define cmes3(s,b,c)    (debugc && dbg_printf((s),(b),(c)))
 157: #else
 158: #define debugmes(s)
 159: #define cmes(s)
 160: #define cmes2(s,b)
 161: #define cmes3(s,b,c)
 162: #endif
 163: 
 164: #define TRUE            1
 165: #define FALSE           0
 166: 
 167: #ifndef ARG_TRUE
 168: #define ARG_TRUE        ,TRUE
 169: #define ARG_FALSE       ,FALSE
 170: #endif
 171: 
 172: #define arraysize(array)        (sizeof(array) / sizeof(array[0]))
 173: 
 174: #define IDMAX   900 //467 //254 // identifier max (excluding terminating 0)
 175: #define IDOHD   (4+1+sizeof(int)*3)     // max amount of overhead to ID added by
 176: #define STRMAX  65000           // max length of string (determined by
 177:                                 // max ph size)
 178: 
 179: enum SC;
 180: struct Thunk;
 181: struct token_t;
 182: struct PARAM;
 183: typedef struct PARAM param_t;
 184: struct block;
 185: struct Classsym;
 186: struct Nspacesym;
 187: struct Outbuffer;
 188: struct Aliassym;
 189: struct dt_t;
 190: typedef struct TYPE type;
 191: typedef struct Symbol symbol;
 192: typedef Symbol Funcsym;
 193: //typedef Symbol Classsym;      // a Symbol that is an SCclass, SCstruct or SCunion
 194: struct elem;
 195: typedef struct MACRO macro_t;
 196: typedef struct BLKLST blklst;
 197: typedef list_t symlist_t;       /* list of pointers to Symbols          */
 198: typedef struct SYMTAB_S symtab_t;
 199: struct code;
 200: 
 201: extern Config config;
 202: 
 203: /////////// Position in source file
 204: 
 205: typedef struct Srcpos
 206: {
 207:     unsigned Slinnum;           // 0 means no info available
 208: #if SPP || SCPP
 209:     struct Sfile **Sfilptr;     // file
 210:     #define srcpos_sfile(p)     (**(p).Sfilptr)
 211:     #define srcpos_name(p)      (srcpos_sfile(p).SFname)
 212: #endif
 213: #if MARS
 214:     const char *Sfilename;
 215:     #define srcpos_name(p)      ((p).SFname)
 216: #endif
 217: #if M_UNIX
 218:     short Sfilnum;              // file number
 219: #endif
 220: #if SOURCE_OFFSETS
 221:     unsigned long Sfiloff;      // byte offset
 222: #endif
 223: 
 224:     void print(const char *func);
 225: } Srcpos;
 226: 
 227: #ifndef TOKEN_H
 228: #include "token.h"
 229: #endif
 230: 
 231: /**********************************
 232:  * Current 'state' of the compiler.
 233:  * Used to gather together most global variables.
 234:  * This struct is saved/restored during function body parsing.
 235:  */
 236: 
 237: typedef struct Pstate
 238: {
 239:     char STinopeq;              // if in n2_createopeq()
 240:     char STinarglist;           // if !=0, then '>' is the end of a template
 241:                                 // argument list, not an operator
 242:     char STinsizeof;            // !=0 if in a sizeof expression. Useful to
 243:                                 // prevent <array of> being converted to
 244:                                 // <pointer to>.
 245:     char STintemplate;          // if !=0, then expanding a function template
 246:                                 // (do not expand template Symbols)
 247:     char STdeferDefaultArg;     // defer parsing of default arg for parameter
 248:     char STnoexpand;            // if !=0, don't expand template symbols
 249:     char STignoretal;           // if !=0 ignore template argument list
 250:     char STexplicitInstantiation;       // if !=0, then template explicit instantiation
 251:     char STexplicitSpecialization;      // if !=0, then template explicit specialization
 252:     char STinconstexp;          // if !=0, then parsing a constant expression
 253:     char STisaddr;              // is this a possible pointer to member expression?
 254:     unsigned STinexp;           // if !=0, then in an expression
 255: #if NTEXCEPTIONS
 256:     char STinfilter;            // if !=0 then in exception filter
 257:     char STinexcept;            // if !=0 then in exception handler
 258:     block *STbfilter;           // current exception filter
 259: #endif
 260: #if !MARS
 261:     int STinitseg;              // segment for static constructor function pointer
 262: #endif
 263:     Funcsym *STfuncsym_p;       // if inside a function, then this is the
 264:                                 // function Symbol.
 265: 
 266: #   define funcsym_p (pstate.STfuncsym_p)
 267: 
 268:     unsigned STflags;
 269: #       define PFLpreprocessor  1       // in preprocessor
 270: #       define preprocessor     (pstate.STflags & PFLpreprocessor)
 271: #       define PFLmasm          2       // in Microsoft-style inline assembler
 272: #       define PFLbasm          4       // in Borland-style inline assembler
 273: #       define inline_asm       (pstate.STflags & (PFLmasm | PFLbasm))
 274: #       define PFLsemi          8       // ';' means start of comment
 275: //#     define PFLautogen       0x10    // automatically generate HX ph file
 276: #       define PFLmftemp        0x20    // if expanding member function template
 277: #       define PFLextdef        0x40    // we had an external def
 278: #       define PFLhxwrote       0x80    // already generated HX ph file
 279: #       define PFLhxdone        0x100   // done with HX ph file
 280: #if TX86
 281: #       define PFLhxread        0x200   // have read in an HX ph file
 282: #       define PFLhxgen         0x400   // need to generate HX ph file
 283: #       define PFLphread        0x800   // read a ph file
 284: #       define PFLcomdef        0x1000  // had a common block
 285: #       define PFLmacdef        0x2000  // defined a macro in the source code
 286: #       define PFLsymdef        0x4000  // declared a global Symbol in the source
 287: #       define PFLinclude       0x8000  // read a .h file
 288: #       define PFLmfc           0x10000 // something will affect MFC compatibility
 289: #endif
 290: #if !MARS
 291:     int STinparamlist;          // if != 0, then parser is in
 292:                                 // function parameter list
 293:     int STingargs;              // in template argument list
 294:     list_t STincalias;          // list of include aliases
 295:     list_t STsysincalias;       // list of system include aliases
 296: #endif
 297: 
 298: #if TX86
 299:     // should probably be inside #if HYDRATE, but unclear for the dmc source
 300:     char SThflag;               // FLAG_XXXX: hydration flag
 301: #define FLAG_INPLACE    0       // in place hydration
 302: #define FLAG_HX         1       // HX file hydration
 303: #define FLAG_SYM        2       // .SYM file hydration
 304: #endif
 305: 
 306:     Classsym *STclasssym;       // if in the scope of this class
 307:     symlist_t STclasslist;      // list of classes that have deferred inline
 308:                                 // functions to parse
 309:     Classsym *STstag;           // returned by struct_searchmember() and with_search()
 310:     SYMIDX STmarksi;            // to determine if temporaries are created
 311:     char STnoparse;             // add to classlist instead of parsing
 312:     char STdeferparse;          // defer member func parse
 313:     enum SC STgclass;           // default function storage class
 314:     int STdefertemps;           // defer allocation of temps
 315:     int STdeferaccesscheck;     // defer access check for members (BUG: it
 316:                                 // never does get done later)
 317:     int STnewtypeid;            // parsing new-type-id
 318:     int STdefaultargumentexpression;    // parsing default argument expression
 319:     block *STbtry;              // current try block
 320:     block *STgotolist;          // threaded goto scoping list
 321:     long STtdbtimestamp;        // timestamp of tdb file
 322:     Symbol *STlastfunc;         // last function symbol parsed by ext_def()
 323: 
 324:     // For "point of definition" vs "point of instantiation" template name lookup
 325:     unsigned STsequence;        // sequence number (Ssequence) of next Symbol
 326:     unsigned STmaxsequence;     // won't find Symbols with STsequence larger
 327:                                 // than STmaxsequence
 328: } Pstate;
 329: 
 330: extern Pstate pstate;
 331: 
 332: /****************************
 333:  * Global variables.
 334:  */
 335: 
 336: typedef struct Cstate
 337: {
 338:     struct BLKLST *CSfilblk;    // current source file we are parsing
 339:     Symbol *CSlinkage;          // table of forward referenced linkage pragmas
 340:     list_t CSlist_freelist;     // free list for list package
 341:     symtab_t *CSpsymtab;        // pointer to current Symbol table
 342: #if MEMORYHX
 343:     void **CSphx;               // pointer to HX data block
 344: #endif
 345:     char *modname;              // module unique identifier
 346: } Cstate;
 347: 
 348: extern Cstate cstate;
 349: 
 350: /* Bits for sytab[] that give characteristics of storage classes        */
 351: #define SCEXP   1       // valid inside expressions
 352: #define SCKEP   2       // Symbol should be kept even when function is done
 353: #define SCSCT   4       // storage class is valid for use in static ctor
 354: #define SCSS    8       // storage class is on the stack
 355: #define SCRD    0x10    // we can do reaching definitions on these
 356: 
 357: // Determine if Symbol has a Ssymnum associated with it.
 358: // (That is, it is allocated on the stack or has live variable analysis
 359: //  done on it, so it is stack and register variables.)
 360: #define symbol_isintab(s)       (sytab[(s)->Sclass] & SCSS)
 361: 
 362: #if defined(__SC__) || defined(_MSC_VER)
 363: typedef char enum_SC;
 364: #else
 365: typedef enum SC enum_SC;
 366: #endif
 367: 
 368: /******************************************
 369:  * Basic blocks:
 370:  *      Basic blocks are a linked list of all the basic blocks
 371:  *      in a function. startblock heads the list.
 372:  */
 373: 
 374: #if MARS
 375: struct ClassDeclaration;
 376: struct Declaration;
 377: struct Module;
 378: #endif
 379: 
 380: struct Blockx
 381: {
 382: #if MARS
 383:     block *startblock;
 384:     block *curblock;
 385:     Funcsym *funcsym;
 386:     Symbol *context;            // eh frame context variable
 387:     int scope_index;            // current scope index
 388:     int next_index;             // value for next scope index
 389:     unsigned flags;             // value to OR into Bflags
 390:     block *tryblock;            // current enclosing try block
 391:     elem *init;                 // static initializer
 392:     ClassDeclaration *classdec;
 393:     Declaration *member;        // member we're compiling for
 394:     Module *module;             // module we're in
 395: #endif
 396: };
 397: 
 398: typedef struct block
 399: {
 400:     union
 401:     {
 402:         elem *Belem;            // pointer to elem tree
 403:         list_t  Blist;          // list of expressions
 404:     };
 405: 
 406:     block *Bnext;               // pointer to next block in list
 407:     list_t        Bsucc;        // linked list of pointers to successors
 408:                                 //     of this block
 409:     list_t        Bpred;        // and the predecessor list
 410:     int Bindex;                 // into created object stack
 411:     int Bendindex;              // index at end of block
 412:     block *Btry;                // BCtry,BC_try: enclosing try block, if any
 413:                                 // BC???: if in try-block, points to BCtry or BC_try
 414:                                 // note that can't have a BCtry and BC_try in
 415:                                 // the same function.
 416:     union
 417:     {   targ_llong      *Bswitch;       // BCswitch: pointer to switch data
 418:         struct {
 419:             regm_t usIasmregs;          // Registers modified
 420:             unsigned char  bIasmrefparam;   // References parameters?
 421:             #define usIasmregs          BS.BIASM.usIasmregs
 422:             #define bIasmrefparam       BS.BIASM.bIasmrefparam
 423:         } BIASM;                        // BCasm
 424: 
 425:         struct
 426:         {   Symbol *catchvar;           // __throw() fills in this
 427:             #define catchvar BS.BITRY.catchvar
 428:         } BITRY;                        // BCtry
 429: 
 430: #if SCPP
 431:         struct
 432:         {   type *catchtype;            // one type for each catch block
 433:             #define Bcatchtype BS.BICATCH.catchtype
 434:         } BICATCH;                      // BCcatch
 435: #endif
 436: #if MARS
 437:         struct
 438:         {   Symbol *catchtype;          // one type for each catch block
 439:             #define Bcatchtype BS.BIJCATCH.catchtype
 440:         } BIJCATCH;                     // BCjcatch
 441: #endif
 442: #if NTEXCEPTIONS || MARS
 443:         struct
 444:         {
 445: #if MARS
 446:             Symbol *jcatchvar;          // __j_throw() fills in this
 447:             #define jcatchvar BS.BI_TRY.jcatchvar
 448: #endif
 449:             int Bscope_index;           // index into scope table
 450:             #define Bscope_index BS.BI_TRY.Bscope_index
 451:             int Blast_index;            // enclosing index into scope table
 452:             #define Blast_index BS.BI_TRY.Blast_index
 453:         } BI_TRY;                       // BC_try
 454: #endif
 455: 
 456:     } BS;
 457:     Srcpos      Bsrcpos;        // line number (0 if not known)
 458:     unsigned char BC;           // exit condition (enum BC)
 459: // NEW
 460:     unsigned char Balign;       // alignment
 461: 
 462:     unsigned short Bflags;              // flags (BFLxxxx)
 463:         #define BFLvisited    1         // set if block is visited
 464:         #define BFLmark       2         // set if block is visited
 465:         #define BFLjmpoptdone 4         // set when no more jump optimizations
 466:                                         //  are possible for this block
 467:         #define BFLnostackopt 8         // set when stack elimination should not
 468:                                         // be done
 469: #if NTEXCEPTIONS
 470:         #define BFLehcode     0x10      // set when we need to load exception code
 471:         #define BFLunwind     0x1000    // do local_unwind following block
 472: #endif
 473:         #define BFLnomerg      0x20     // do not merge with other blocks
 474:         #define BFLprolog      0x80     // generate function prolog
 475:         #define BFLepilog      0x100    // generate function epilog
 476:         #define BFLrefparam    0x200    // referenced parameter
 477:         #define BFLreflocal    0x400    // referenced local
 478:         #define BFLoutsideprolog 0x800  // outside function prolog/epilog
 479:         #define BFLlabel        0x2000  // block preceded by label
 480:         #define BFLvolatile     0x4000  // block is volatile
 481:     code        *Bcode;         // code generated for this block
 482: 
 483:     unsigned Bweight;           // relative number of times this block
 484:                                 // is executed (optimizer and codegen)
 485: 
 486:     unsigned    Bdfoidx;        // index of this block in dfo[]
 487:     union
 488:     {
 489:         // CPP
 490:         struct
 491:         {
 492:             SYMIDX      symstart;       // (symstart <= symnum < symend) Symbols
 493:             SYMIDX      symend;         // are declared in this block
 494:             block       *endscope;      // block that forms the end of the
 495:                                         // scope for the declared Symbols
 496:             unsigned blknum;            // position of block from startblock
 497:             Symbol      *Binitvar;      // !=NULL points to an auto variable with
 498:                                         // an explicit or implicit initializer
 499:             block       *gotolist;      // BCtry, BCcatch: backward list of try scopes
 500:             block       *gotothread;    // BCgoto: threaded list of goto's to
 501:                                         // unknown labels
 502: 
 503:             #define Bsymstart   _BLU._UP.symstart
 504:             #define Bsymend     _BLU._UP.symend
 505:             #define Bendscope   _BLU._UP.endscope
 506:             #define Bblknum     _BLU._UP.blknum
 507:             #define Binitvar    _BLU._UP.Binitvar
 508:             #define Bgotolist   _BLU._UP.gotolist
 509:             #define Bgotothread _BLU._UP.gotothread
 510:         }_UP;
 511: 
 512:         // OPTIMIZER
 513:         struct
 514:         {
 515:             vec_t       Bdom;           // mask of dominators for this block
 516:             vec_t       Binrd;
 517:             vec_t       Boutrd;         // IN and OUT for reaching definitions
 518:             vec_t       Binlv;
 519:             vec_t       Boutlv;         // IN and OUT for live variables
 520:             vec_t       Bin;
 521:             vec_t       Bout;           // IN and OUT for other flow analyses
 522:             vec_t       Bgen;
 523:             vec_t       Bkill;          // pointers to bit vectors used by data
 524:                                         // flow analysis
 525: 
 526:             // BCiftrue can have different vectors for the 2nd successor:
 527:             vec_t       Bout2;
 528:             vec_t       Bgen2;
 529:             vec_t       Bkill2;
 530: 
 531:             #define Bdom        _BLU._UO.Bdom
 532:             #define Binrd       _BLU._UO.Binrd
 533:             #define Boutrd      _BLU._UO.Boutrd
 534:             #define Binlv       _BLU._UO.Binlv
 535:             #define Boutlv      _BLU._UO.Boutlv
 536:             #define Bin         _BLU._UO.Bin
 537:             #define Bout        _BLU._UO.Bout
 538:             #define Bgen        _BLU._UO.Bgen
 539:             #define Bkill       _BLU._UO.Bkill
 540:             #define Bout2       _BLU._UO.Bout2
 541:             #define Bgen2       _BLU._UO.Bgen2
 542:             #define Bkill2      _BLU._UO.Bkill2
 543:         }_UO;
 544: 
 545:         // CODGEN
 546:         struct
 547:         {
 548:             targ_size_t Btablesize;     // BCswitch, BCjmptab
 549:             targ_size_t Btableoffset;   // BCswitch, BCjmptab
 550:             targ_size_t Boffset;        // code offset of start of this block
 551:             targ_size_t Bsize;          // code size of this block
 552:             con_t       Bregcon;        // register state at block exit
 553:             targ_size_t Btryoff;        // BCtry: offset of try block data
 554: 
 555:             #define Btablesize          _BLU._UD.Btablesize
 556:             #define Btableoffset        _BLU._UD.Btableoffset
 557:             #define Boffset             _BLU._UD.Boffset
 558:             #define Bsize               _BLU._UD.Bsize
 559: //          #define Bcode               _BLU._UD.Bcode
 560:             #define Bregcon             _BLU._UD.Bregcon
 561:             #define Btryoff             _BLU._UD.Btryoff
 562:         } _UD;
 563:     } _BLU;
 564: } block;
 565: 
 566: #define list_block(l)   ((block *) list_ptr(l))
 567: 
 568: /** Basic block control flow operators. **/
 569: 
 570: enum BC {
 571:     BCgoto      = 1,    // goto Bsucc block
 572:     BCiftrue    = 2,    // if (Belem) goto Bsucc[0] else Bsucc[1]
 573:     BCret       = 3,    // return (no return value)
 574:     BCretexp    = 4,    // return with return value
 575:     BCexit      = 5,    // never reaches end of block (like exit() was called)
 576:     BCasm       = 6,    // inline assembler block (Belem is NULL, Bcode
 577:                         // contains code generated).
 578:                         // These blocks have one or more successors in Bsucc,
 579:                         // never 0
 580:     BCswitch    = 7,    // switch statement
 581:                         // Bswitch points to switch data
 582:                         // Default is Bsucc
 583:                         // Cases follow in linked list
 584:     BCifthen    = 8,    // a BCswitch is converted to if-then
 585:                         // statements
 586:     BCjmptab    = 9,    // a BCswitch is converted to a jump
 587:                         // table (switch value is index into
 588:                         // the table)
 589:     BCtry       = 10,   // C++ try block
 590:                         // first block in a try-block. The first block in
 591:                         // Bsucc is the next one to go to, subsequent
 592:                         // blocks are the catch blocks
 593:     BCcatch     = 11,   // C++ catch block
 594:     BCjump      = 12,   // Belem specifies (near) address to jump to
 595:     BC_try      = 13,   // SEH: first block of try-except or try-finally
 596:                         // Jupiter, Mars: try-catch or try-finally
 597:     BC_filter   = 14,   // SEH exception-filter (always exactly one block)
 598:     BC_finally  = 15,   // first block of SEH termination-handler,
 599:                         // or finally block
 600:     BC_ret      = 16,   // last block of SEH termination-handler or finally block
 601:     BC_except   = 17,   // first block of SEH exception-handler
 602:     BCjcatch    = 18,   // first block of Jupiter or Mars catch-block
 603:     BCjplace    = 19,   // Jupiter: placeholder
 604:     BCMAX
 605: };
 606: 
 607: /**********************************
 608:  * Functions
 609:  */
 610: 
 611: typedef struct SYMTAB_S
 612: {
 613:     SYMIDX top;                 // 1 past end
 614:     SYMIDX symmax;              // max # of entries in tab[] possible
 615:     Symbol **tab;               // local Symbol table
 616: } symtab_t;
 617: 
 618: typedef struct FUNC_S
 619: {
 620:     symlist_t Fsymtree;         // local Symbol table
 621:     block *Fstartblock;         // list of blocks comprising function
 622:     symtab_t Flocsym;           // local Symbol table
 623:     Srcpos Fstartline;          // starting line # of function
 624:     Srcpos Fendline;            // line # of closing brace of function
 625:     Symbol *F__func__;          // symbol for __func__[] string
 626:     unsigned Fflags;
 627: #       define Fpending  1      // if function has been queued for being written
 628: #       define Foutput   2      /* if function has been written out     */
 629: #       define Finline   0x10   /* if SCinline, and function really is inline */
 630: #       define Foverload 0x20   /* if function can be overloaded        */
 631: #       define Ftypesafe 0x40   /* if function name needs type appended */
 632: #       define Fmustoutput 0x80 /* set for forward ref'd functions that */
 633:                                 /* must be output                       */
 634: #       define Finlinenest 0x1000 /* used as a marker to prevent nested */
 635:                                 /* inlines from expanding               */
 636: #       define Flinkage 0x2000  /* linkage is already specified         */
 637: #       define Fstatic  0x4000  /* static member function (no this)     */
 638: #       define Foperator 4      /* if operator overload                 */
 639: #       define Fcast     8      /* if cast overload                     */
 640: #       define Fvirtual 0x100   /* if function is a virtual function    */
 641: #       define Fctor    0x200   /* if function is a constructor         */
 642: #       define Fdtor    0x400   /* if function is a destructor          */
 643: #       define Fnotparent 0x800 /* if function is down Foversym chain   */
 644: #       define Fbitcopy 0x8000  /* it's a simple bitcopy (op=() or X(X&)) */
 645: #       define Fpure     0x10000        // pure function
 646: #       define Finstance 0x20000        // function is an instance of a template
 647: #       define Ffixed    0x40000        // ctor has had cpp_fixconstructor() run on it,
 648:                                         // dtor has had cpp_fixdestructor()
 649: #       define Fintro    0x80000        // function doesn't hide a previous virtual function
 650: //#     define unused    0x100000       // unused bit
 651: #       define Fkeeplink 0x200000       // don't change linkage to default
 652: #       define Fnodebug  0x400000       // do not generate debug info for this function
 653: #       define Fgen      0x800000       // compiler generated function
 654: #       define Finvariant 0x1000000     // __invariant function
 655: #       define Fexplicit  0x2000000     // explicit constructor
 656: #       define Fsurrogate 0x4000000     // surrogate call function
 657:     unsigned Fflags3;
 658:         #define Fvtblgen        0x01    // generate vtbl[] when this function is defined
 659:         #define Femptyexc       0x02    // empty exception specification (obsolete, use Tflags & TFemptyexc)
 660:         #define Fcppeh          0x04    // uses C++ EH
 661:         #define Fdeclared       0x10    // already declared function Symbol
 662:         #define Fmark           0x20    // has unbalanced OPctor's
 663:         #define Fnteh           0x08    // uses NT Structured EH
 664:         #define Fdoinline       0x40    // do inline walk
 665:         #define Foverridden     0x80    // ignore for overriding purposes
 666: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
 667:         #define Fnowrite        0x100   // SCinline should never output definition
 668: #else
 669:         #define Fjmonitor       0x100   // Jupiter synchronized function
 670: #endif
 671:         #define Fnosideeff      0x200   // function has no side effects
 672:         #define F3badoparrow    0x400   // bad operator->()
 673:         #define Fmain           0x800   // function is main() or wmain()
 674:         #define Fnested         0x1000  // D nested function with 'this'
 675:         #define Fmember         0x2000  // D member function with 'this'
 676:         #define Fnotailrecursion 0x4000 // no tail recursion optimizations
 677:         #define Ffakeeh         0x8000  // allocate space for NT EH context sym anyway
 678:     unsigned char Foper;        // operator number (OPxxxx) if Foperator
 679: 
 680:     Symbol *Fparsescope;        // use this scope to parse friend functions
 681:                                 // which are defined within a class, so the
 682:                                 // class is in scope, but are not members
 683:                                 // of the class
 684: 
 685:     Classsym *Fclass;           // if member of a class, this is the class
 686:                                 // (I think this is redundant with Sscope)
 687:     Funcsym *Foversym;          // overloaded function at same scope
 688:     symlist_t Fclassfriends;    /* Symbol list of classes of which this */
 689:                                 /* function is a friend                 */
 690:     block *Fbaseblock;          // block where base initializers get attached
 691:     block *Fbaseendblock;       // block where member destructors get attached
 692:     elem *Fbaseinit;            /* list of member initializers (meminit_t) */
 693:                                 /* this field has meaning only for      */
 694:                                 /* functions which are constructors     */
 695:     struct token_t *Fbody;      /* if deferred parse, this is the list  */
 696:                                 /* of tokens that make up the function  */
 697:                                 /* body                                 */
 698:                                 // also used if SCfunctempl, SCftexpspec
 699:     unsigned Fsequence;         // sequence number at point of definition
 700:     union
 701:     {
 702:         Symbol *Ftempl;         // if Finstance this is the template that generated it
 703:         struct Thunk *Fthunk;   // !=NULL if this function is actually a thunk
 704:     };
 705:     Funcsym *Falias;            // SCfuncalias: function Symbol referenced
 706:                                 // by using-declaration
 707:     symlist_t Fthunks;          // list of thunks off of this function
 708:     param_t *Farglist;          // SCfunctempl: the template-parameter-list
 709:     param_t *Fptal;             // Finstance: this is the template-argument-list
 710:                                 // SCftexpspec: for explicit specialization, this
 711:                                 // is the template-argument-list
 712:     list_t Ffwdrefinstances;    // SCfunctempl: list of forward referenced instances
 713:     list_t Fexcspec;            // List of types in the exception-specification
 714:                                 // (NULL if none or empty)
 715:     Funcsym *Fexplicitspec;     // SCfunctempl, SCftexpspec: threaded list
 716:                                 // of SCftexpspec explicit specializations
 717:     Funcsym *Fsurrogatesym;     // Fsurrogate: surrogate cast function
 718: 
 719: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
 720:     char *Fredirect;            // redirect function name to this name in object
 721: #endif
 722: } func_t;
 723: 
 724: #define func_calloc()   ((func_t *) mem_fcalloc(sizeof(func_t)))
 725: #define func_free(f)    mem_ffree(f)
 726: 
 727: /**************************
 728:  * Item in list for member initializer.
 729:  */
 730: 
 731: typedef struct MEMINIT
 732: {
 733:     list_t  MIelemlist;         /* arg list for initializer             */
 734:     Symbol *MIsym;              /* if NULL, then this initializer is    */
 735:                                 /* for the base class. Otherwise, this  */
 736:                                 /* is the member that needs the ctor    */
 737:                                 /* called for it                        */
 738: } meminit_t;
 739: 
 740: 
 741: /************************************
 742:  * Base classes are a list of these.
 743:  */
 744: 
 745: typedef struct BASECLASS
 746: {
 747:     Classsym         *BCbase;           // base class Symbol
 748:     struct BASECLASS *BCnext;           // next base class
 749:     targ_size_t       BCoffset;         // offset from start of derived class to this
 750: #if VBTABLES
 751:     unsigned short    BCvbtbloff;       // for BCFvirtual, offset from start of
 752:                                         //     vbtbl[] to entry for this virtual base.
 753:                                         //     Valid in Sbase list
 754: #else
 755:     targ_size_t memoffset;      /* for BCFvirtual, offset from this to
 756:                                    pointer to virtual base class.
 757:                                    Valid in Sbase list
 758:                                  */
 759:     Symbol *param;              /* parameter for this Symbol (in        */
 760:                                 /* Svirtbase list only)                 */
 761: #endif
 762:     symlist_t         BCpublics;        // public members of base class (list is freeable)
 763:     list_t            BCmptrlist;       // (in Smptrbase only) this is the vtbl
 764:                                         // (NULL if not different from base class's vtbl
 765:     Symbol           *BCvtbl;           // Symbol for vtbl[] array (in Smptrbase list)
 766:                                         // Symbol for vbtbl[] array (in Svbptrbase list)
 767:     unsigned          BCflags;          // base class flags
 768: #define BCFpublic       1                   // base class is public
 769: #define BCFprotected    2                   // base class is protected
 770: #define BCFprivate      4                   // base class is private
 771: #define BCFpmask        (BCFpublic | BCFprotected | BCFprivate)
 772: 
 773: #define BCFvirtual      8                   // base class is virtual
 774: #define BCFvfirst       0x10                // virtual base class, and this is the
 775:                                             // first virtual appearance of it
 776: #define BCFnewvtbl      0x20                // new vtbl generated for this base class
 777: #define BCFvirtprim     0x40                // Primary base class of a virtual base class
 778: #define BCFdependent    0x80                // base class is a dependent type
 779:     Classsym         *BCparent;         // immediate parent of this base class
 780:                                         //     in Smptrbase
 781: #if TX86
 782:     struct BASECLASS *BCpbase;          // parent base, NULL if did not come from a parent
 783: #endif
 784: } baseclass_t;
 785: 
 786: #define baseclass_malloc()      ((baseclass_t *)mem_fmalloc(sizeof(baseclass_t)))
 787: #define baseclass_free(b)       ((void)(b))
 788: 
 789: /*************************
 790:  * For virtual tables.
 791:  */
 792: 
 793: typedef struct MPTR
 794: {   targ_short     MPd;
 795:     targ_short     MPi;
 796:     Symbol        *MPf;
 797:     Symbol        *MPparent;    // immediate parent of this base class
 798:                                 //   in Smptrbase
 799:     unsigned char  MPflags;
 800: #define MPTRvirtual     1       // it's an offset to a virtual base
 801: #define MPTRcovariant   2       // need covariant return pointer adjustment
 802: } mptr_t;
 803: 
 804: #define list_mptr(l)    ((mptr_t *) list_ptr(l))
 805: 
 806: 
 807: /***********************************
 808:  * Information gathered about externally defined template member functions,
 809:  * member data, and member classes.
 810:  */
 811: 
 812: struct TMF
 813: {
 814:     Classsym *stag;             // if !=NULL, this is the enclosing class
 815:     token_t *tbody;             // tokens making it up
 816:     token_t *to;                // pointer within tbody where we left off in
 817:                                 // template_function_decl()
 818:     param_t *temp_arglist;      // template parameter list
 819:     int member_class;           // 1: it's a member class
 820: 
 821:     // These are for member templates
 822:     int castoverload;           // 1: it's a user defined cast
 823:     char *name;                 // name of template (NULL if castoverload)
 824:     int member_template;        // 0: regular template
 825:                                 // 1: member template
 826:     param_t *temp_arglist2;     // if member template,
 827:                                 // then member's template parameter list
 828: 
 829:     param_t *ptal;              // if explicit specialization, this is the
 830:                                 // explicit template-argument-list
 831:     Symbol *sclassfriend;       // if member function is a friend of class X,
 832:                                 // this is class X
 833:     unsigned access_specifier;
 834: };
 835: 
 836: /***********************************
 837:  * Information gathered about primary member template explicit specialization.
 838:  */
 839: 
 840: struct TME
 841: {
 842:     /* Given:
 843:      *  template<> template<class T2> struct A<short>::B { };
 844:      *  temp_arglist2 = <class T2>
 845:      *  name = "B"
 846:      *  ptal = <short>
 847:      */
 848:     param_t *ptal;              // explicit template-argument-list for enclosing
 849:                                 // template A
 850:     symbol *stempl;             // template symbol for B
 851: };
 852: 
 853: /***********************************
 854:  * Information gathered about nested explicit specializations.
 855:  */
 856: 
 857: struct TMNE
 858: {
 859:     /* For:
 860:      *  template<> template<> struct A<short>::B<double> { };
 861:      */
 862: 
 863:     enum_TK tk;                 // TKstruct / TKclass / TKunion
 864:     char *name;                 // name of template, i.e. "B"
 865:     param_t *ptal;              // explicit template-argument-list for enclosing
 866:                                 // template A, i.e. "short"
 867:     token_t *tdecl;             // the tokens "<double> { }"
 868: };
 869: 
 870: /***********************************
 871:  * Information gathered about nested class friends.
 872:  */
 873: 
 874: struct TMNF
 875: {
 876:     /* Given:
 877:      *  template<class T> struct A { struct B { }; };
 878:      *  class C { template<class T> friend struct A<T>::B;
 879:      */
 880:     token_t *tdecl;             // the tokens "A<T>::B;"
 881:     param_t *temp_arglist;      // <class T>
 882:     Classsym *stag;             // the class symbol C
 883:     symbol *stempl;             // the template symbol A
 884: };
 885: 
 886: /***********************************
 887:  * Special information for class templates.
 888:  */
 889: 
 890: typedef struct TEMPLATE
 891: {
 892:     symlist_t     TMinstances;  // list of Symbols that are instances
 893:     param_t      *TMptpl;       // template-parameter-list
 894:     struct token_t *TMbody;     // tokens making up class body
 895:     unsigned TMsequence;        // sequence number at point of definition
 896:     list_t TMmemberfuncs;       // templates for member functions (list of TMF's)
 897:     list_t TMexplicit;          // list of TME's: primary member template explicit specializations
 898:     list_t TMnestedexplicit;    // list of TMNE's: primary member template nested explicit specializations
 899:     Symbol *TMnext;             // threaded list of template classes headed
 900:                                 // up by template_class_list
 901:     enum_TK        TMtk;        // TKstruct, TKclass or TKunion
 902:     int            TMflags;     // STRxxx flags
 903: 
 904:     symbol *TMprimary;          // primary class template
 905:     symbol *TMpartial;          // next class template partial specialization
 906:     param_t *TMptal;            // template-argument-list for partial specialization
 907:                                 // (NULL for primary class template)
 908:     list_t TMfriends;           // list of Classsym's for which any instantiated
 909:                                 // classes of this template will be friends of
 910:     list_t TMnestedfriends;     // list of TMNF's
 911:     int TMflags2;               // !=0 means dummy template created by template_createargtab()
 912: } template_t;
 913: 
 914: /***********************************
 915:  * Special information for enums.
 916:  */
 917: 
 918: typedef struct ENUM
 919: {
 920:     unsigned SEflags;
 921: #define SENnotagname    1       // no tag name for enum
 922: #define SENforward      2       // forward referenced enum
 923: 
 924:     Symbol *SEalias;            // pointer to identifier E to use if
 925:                                 /* enum was defined as:                 */
 926:                                 /*      typedef enum { ... } E;         */
 927:     symlist_t SEenumlist;       // all members of enum
 928: } enum_t;
 929: 
 930: /***********************************
 931:  * Special information for structs.
 932:  */
 933: 
 934: typedef struct STRUCT
 935: {
 936:     targ_size_t Sstructsize;    // size of struct
 937:     symlist_t Sfldlst;          // all members of struct (list freeable)
 938:     Symbol *Sroot;              // root of binary tree Symbol table
 939:     unsigned Salignsize;        // size of struct for alignment purposes
 940:     unsigned char Sstructalign; // struct member alignment in effect
 941:     unsigned long Sflags;
 942: #define STRanonymous    0x01    // set for unions with no tag names
 943: #define STRglobal       0x02    // defined at file scope
 944: #define STRnotagname    0x04    // struct/class with no tag name
 945: #define STRoutdef       0x08    // we've output the debug definition
 946: #define STRbitfields    0x10    // set if struct contains bit fields
 947: #define STRpredef       0x1000 // a predefined struct
 948: #define STRunion        0x4000  // actually, it's a union
 949: 
 950: #define STRabstract     0x20    // abstract class
 951: #define STRbitcopy      0x40    // set if operator=() is merely a bit copy
 952: #define STRanyctor      0x80    // set if any constructors were defined
 953:                                 // by the user
 954: #define STRnoctor       0x100   // no constructors allowed
 955: #define STRgen          0x200   // if struct is an instantiation of a
 956:                                 // template class, and was generated by
 957:                                 // that template
 958: #define STRvtblext      0x400   // generate vtbl[] only when first member function
 959:                                 // definition is encountered (see Fvtblgen)
 960: #define STRexport       0x800   // all member functions are to be _export
 961: #define STRclass        0x8000  // it's a class, not a struct
 962: #if TX86
 963: #define STRimport       0x40000 // imported class
 964: #define STRstaticmems   0x80000 // class has static members
 965: #endif
 966: #define STR0size        0x100000        // zero sized struct
 967: #define STRinstantiating 0x200000       // if currently being instantiated
 968: #define STRexplicit     0x400000        // if explicit template instantiation
 969: #define STRgenctor0     0x800000        // need to gen X::X()
 970:     tym_t ptrtype;              // type of pointer to refer to classes by
 971:     unsigned short access;      // current access privilege, here so
 972:                                 // enum declarations can get at it
 973:     targ_size_t Snonvirtsize;   // size of struct excluding virtual classes
 974:     list_t Svirtual;            // freeable list of mptrs
 975:                                 // that go into vtbl[]
 976: #if TX86
 977:     list_t *Spvirtder;          // pointer into Svirtual that points to start
 978:                                 // of virtual functions for this (derived) class
 979:     symlist_t Sopoverload;      // overloaded operator funcs (list freeable)
 980: #endif
 981:     symlist_t Scastoverload;    // overloaded cast funcs (list freeable)
 982:     symlist_t Sclassfriends;    // list of classes of which this is a friend
 983:                                 // (list is freeable)
 984:     symlist_t Sfriendclass;     // classes which are a friend to this class
 985:                                 // (list is freeable)
 986:     symlist_t Sfriendfuncs;     // functions which are a friend to this class
 987:                                 // (list is freeable)
 988:     symlist_t Sinlinefuncs;     // list of tokenized functions
 989:     baseclass_t *Sbase;         // list of direct base classes
 990:     baseclass_t *Svirtbase;     // list of all virtual base classes
 991:     baseclass_t *Smptrbase;     // list of all base classes that have
 992:                                 // their own vtbl[]
 993:     baseclass_t *Sprimary;      // if not NULL, then points to primary
 994:                                 // base class
 995:     Funcsym *Svecctor;          // constructor for use by vec_new()
 996:     Funcsym *Sctor;             // constructor function
 997: 
 998:     Funcsym *Sdtor;             // basic destructor
 999: #if VBTABLES
1000:     Funcsym *Sprimdtor;         // primary destructor
1001:     Funcsym *Spriminv;          // primary invariant
1002:     Funcsym *Sscaldeldtor;      // scalar deleting destructor
1003: #endif
1004: 
1005:     Funcsym *Sinvariant;        // basic invariant function
1006: 
1007:     Symbol *Svptr;              // Symbol of vptr
1008:     Symbol *Svtbl;              // Symbol of vtbl[]
1009: #if VBTABLES
1010:     Symbol *Svbptr;             // Symbol of pointer to vbtbl[]
1011:     Symbol *Svbptr_parent;      // base class for which Svbptr is a member.
1012:                                 // NULL if Svbptr is a member of this class
1013:     targ_size_t Svbptr_off;     // offset of Svbptr member
1014:     Symbol *Svbtbl;             // virtual base offset table
1015:     baseclass_t *Svbptrbase;    // list of all base classes in canonical
1016:                                 // order that have their own vbtbl[]
1017: #endif
1018:     Funcsym *Sopeq;             // X& X::operator =(X&)
1019:     Funcsym *Sopeq2;            // Sopeq, but no copy of virtual bases
1020:     Funcsym *Scpct;             // copy constructor
1021:     Funcsym *Sveccpct;          // vector copy constructor
1022:     Symbol *Salias;             // pointer to identifier S to use if
1023:                                 // struct was defined as:
1024:                                 //      typedef struct { ... } S;
1025: 
1026:     Symbol *Stempsym;           // if this struct is an instantiation
1027:                                 // of a template class, this is the
1028:                                 // template class Symbol
1029: 
1030:     /* For:
1031:      *  template<class T> struct A { };
1032:      *  template<class T> struct A<T *> { };
1033:      *
1034:      *  A<int> a;               // primary
1035:      * Gives:
1036:      *  Sarglist = <int>
1037:      *  Spr_arglist = NULL;
1038:      *
1039:      *  A<int*> a;              // specialization
1040:      * Gives:
1041:      *  Sarglist = <int>
1042:      *  Spr_arglist = <int*>;
1043:      */
1044: 
1045:     param_t *Sarglist;          // if this struct is an instantiation
1046:                                 // of a template class, this is the
1047:                                 // actual arg list used
1048:     param_t *Spr_arglist;       // if this struct is an instantiation
1049:                                 // of a specialized template class, this is the
1050:                                 // actual primary arg list used.
1051:                                 // It is NULL for the
1052:                                 // primary template class (since it would be
1053:                                 // identical to Sarglist).
1054: } struct_t;
1055: 
1056: #define struct_calloc() ((struct_t *) mem_fcalloc(sizeof(struct_t)))
1057: #define struct_free(st) ((void)(st))
1058: 
1059: /**********************************
1060:  * Symbol Table
1061:  */
1062: 
1063: #define list_symbol(l)          ((Symbol *) list_ptr(l))
1064: #define list_setsymbol(l,s)     list_ptr(l) = (s)
1065: #define list_Classsym(l)        ((Classsym *) list_ptr(l))
1066: 
1067: struct Symbol
1068: {
1069: #ifdef DEBUG
1070:     unsigned short      id;
1071: #define IDsymbol 0x5678
1072: #define symbol_debug(s) assert((s)->id == IDsymbol)
1073: #define class_debug(s) assert((s)->id == IDsymbol)
1074: #else
1075: #define symbol_debug(s)
1076: #define class_debug(s)
1077: #endif
1078: 
1079:     Symbol *Sl,*Sr;             // left, right child
1080:     Symbol *Snext;              // next in threaded list
1081:     dt_t *Sdt;                  // variables: initializer
1082:     type *Stype;                // type of Symbol
1083:     #define ty() Stype->Tty
1084: 
1085:     union                       // variants for different Symbol types
1086:     {
1087:         enum_t *Senum_;         // SCenum
1088:         #define Senum _SU.Senum_
1089:         struct
1090:         {    func_t *Sfunc_;    // tyfunc
1091:              #define Sfunc _SU._SF.Sfunc_
1092:              list_t Spath1_;    // SCfuncalias member functions: same as Spath
1093:              #define Spath1 _SU._SF.Spath1_
1094:                                 // and in same position
1095:                                 // SCadl: list of associated functions for ADL lookup
1096:         }_SF;
1097:         struct                  // SClabel
1098:         {   int Slabel_;                // TRUE if label was defined
1099:              #define Slabel _SU._SL.Slabel_
1100:             block *Slabelblk_;  // label block
1101:              #define Slabelblk _SU._SL.Slabelblk_
1102:         }_SL;
1103:         #define Senumlist Senum->SEenumlist
1104: 
1105: #if !MARS
1106:         struct                  // SClinkage
1107:         {
1108:             long Slinkage_;     // tym linkage bits
1109:              #define Slinkage _SU._SLK.Slinkage_
1110:             unsigned Smangle_;
1111:              #define Smangle _SU._SLK.Smangle_
1112:         }_SLK;
1113: #else
1114:         long Slinkage;          // SClinkage, tym linkage bits
1115: #endif
1116: 
1117:         struct
1118:         {
1119:             char Sbit_;         // SCfield: bit position of start of bit field
1120:              #define Sbit _SU._SB.Sbit_
1121:             char Swidth_;       // SCfield: width in bits of bit field
1122:              #define Swidth _SU._SB.Swidth_
1123:             targ_size_t Smemoff_; // SCmember,SCfield: offset from start of struct
1124:              #define Smemoff _SU._SB.Smemoff_
1125:         }_SB;
1126: 
1127:         elem *Svalue_;          /* SFLvalue: value of const
1128:                                    SFLdtorexp: for objects with destructor,
1129:                                    conditional expression to precede dtor call
1130:                                  */
1131:         #define Svalue _SU.Svalue_
1132: 
1133:         struct_t *Sstruct_;     // SCstruct
1134:         #define Sstruct _SU.Sstruct_
1135:         template_t *Stemplate_; // SCtemplate
1136:         #define Stemplate _SU.Stemplate_
1137: #if SCPP
1138:         struct                  // SCnamespace
1139:         {   Symbol *Snameroot_; // the Symbol table for the namespace
1140:              #define Snameroot _SU._SN.Snameroot_
1141:             list_t Susing_;     // other namespaces from using-directives
1142:              #define Susing _SU._SN.Susing_
1143:         }_SN;
1144:         struct
1145:         {   Symbol *Smemalias_; // SCalias: pointer to Symbol to use instead
1146:                                 // (generated by using-declarations and
1147:                                 // namespace-alias-definitions)
1148:                                 // SCmemalias: pointer to member of base class
1149:                                 // to use instead (using-declarations)
1150:              #define Smemalias _SU._SA.Smemalias_
1151:             symlist_t Spath_;   // SCmemalias: path of classes to get to base
1152:                                 // class of which Salias is a member
1153:              #define Spath _SU._SA.Spath_
1154:         }_SA;
1155: #endif
1156: #if !MARS
1157:         Symbol *Simport_;       // SCextern: if dllimport Symbol, this is the
1158:         #define Simport _SU.Simport_
1159:                                 // Symbol it was imported from
1160: #endif
1161:         unsigned char Spreg_;   // SCfastpar: register parameter is passed in
1162:         #define Spreg _SU.Spreg_
1163:     }_SU;
1164: 
1165: #if SCPP || MARS
1166:     Symbol *Sscope;             // enclosing scope (could be struct tag,
1167:                                 // enclosing inline function for statics,
1168:                                 // or namespace)
1169: #define isclassmember(s)        ((s)->Sscope && (s)->Sscope->Sclass == SCstruct)
1170: #endif
1171: 
1172: #if SCPP
1173:     Symbol *Scover;             // if there is a tag name and a regular name
1174:                                 // of the same identifier, Scover is the tag
1175:                                 // Scover can be SCstruct, SCenum, SCtemplate
1176:                                 // or an SCalias to them.
1177: #define isscover(s)             ((s)->Sclass == SCstruct || (s)->Sclass == SCenum || (s)->Sclass == SCtemplate)
1178:     unsigned Ssequence;         // sequence number (used for 2 level lookup)
1179:                                 // also used as 'parameter number' for SCTtemparg
1180: #elif MARS
1181:     const char *prettyIdent;    // the symbol identifer as the user sees it
1182: #elif AUTONEST
1183:     unsigned char Spush;        // # of pushes followed by # of
1184:     unsigned char Spop;         // pops of scope level
1185: #endif
1186: 
1187: #if ELFOBJ || MACHOBJ
1188:     long          obj_si;       // Symbol index of coff or elf symbol
1189:     unsigned long dwarf_off;    // offset into .debug section
1190:     targ_size_t   code_off;     // rel. offset from start of block where var is initialized
1191:     targ_size_t   last_off;     // last offset using var
1192: #endif
1193: #if TARGET_OSX
1194:     targ_size_t Slocalgotoffset;
1195: #endif
1196: 
1197:     enum_SC Sclass;             // storage class (SCxxxx)
1198:     char Sfl;                   // flavor (FLxxxx)
1199:     SYMFLGS Sflags;             // flag bits (SFLxxxx)
1200:         #define SFLmark         0x08    // temporary marker
1201:         #define SFLvalue        0x01    // Svalue contains const expression
1202:         #define SFLimplem       0x02    // if seen implementation of Symbol
1203:                                         // (function body for functions,
1204:                                         // initializer for variables)
1205:         #define SFLdouble       0x02    // SCregpar or SCparameter, where float
1206:                                         // is really passed as a double
1207:         #define SFLfree         0x04    // if we can symbol_free() a Symbol in
1208:                                         // a Symbol table[]
1209:         #define SFLexit         0x10    // tyfunc: function does not return
1210:                                         // (ex: exit,abort,_assert,longjmp)
1211:         #define SFLtrue         0x200   // value of Symbol != 0
1212:         #define SFLreplace      SFLmark // variable gets replaced in inline expansion
1213:         #define SFLskipinit     0x10000 // SCfield, SCmember: initializer is skipped
1214:         #define SFLnodebug      0x20000 // don't generate debug info
1215:         #define SFLwasstatic    0x800000 // was an uninitialized static
1216:         #define SFLweak         0x1000000 // resolve to NULL if not found
1217: 
1218:         // CPP
1219:         #define SFLnodtor       0x10    // set if destructor for Symbol is already called
1220:         #define SFLdtorexp      0x80    // Svalue has expression to tack onto dtor
1221:         #define SFLmutable      0x100000        // SCmember or SCfield is mutable
1222:         #define SFLdyninit      0x200000        // symbol has dynamic initializer
1223:         #define SFLtmp          0x400000        // symbol is a generated temporary
1224: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
1225:         #define SFLthunk        0x40000 // symbol is temporary for thunk
1226: #endif
1227: 
1228:         // Possible values for protection bits
1229:         #define SFLprivate      0x60
1230:         #define SFLprotected    0x40
1231:         #define SFLpublic       0x20
1232:         #define SFLnone         0x00
1233:         #define SFLpmask        0x60    // mask for the protection bits
1234: #if VEC_VTBL_LIST
1235:         #define SFLvtbl         0x2000  // Symbol is a vtable or vbtable
1236: #endif
1237: 
1238:         // OPTIMIZER and CODGEN
1239:         #define GTregcand       0x100   // if Symbol is a register candidate
1240:         #define SFLdead         0x800   // this variable is dead
1241:         #define GTunregister    0x2000000       // 'unregister' a previous register assignment
1242: 
1243:         // OPTIMIZER only
1244:         #define SFLunambig      0x400   // only accessible by unambiguous reference,
1245:                                         // i.e. cannot be addressed via pointer
1246:                                         // (GTregcand is a subset of this)
1247:                                         // P.S. code generator turns off this
1248:                                         // flag if any reads are done from it.
1249:                                         // This is to eliminate stores to it
1250:                                         // that are never read.
1251:         #define SFLlivexit      0x1000  // live on exit from function
1252:         #define SFLnotbasiciv   0x4000  // not a basic induction variable
1253:         #define SFLnord         SFLdouble // SCauto,SCregister,SCtmp: disallow redundant warnings
1254: 
1255:         // CODGEN only
1256:         #define GTtried         SFLmark // tried to place in register
1257:         #define GTbyte          0x8000  // variable is sometimes accessed as
1258:         #define SFLread         0x40000 // variable is actually read from
1259:                                         // (to eliminate dead stores)
1260:         #define SFLspill        0x80000 // only in register part of the time
1261: 
1262:     vec_t       Srange;         // live range, if any
1263:     vec_t       Slvreg;         // when symbol is in register
1264:     targ_size_t Ssize;          // tyfunc: size of function
1265:     targ_size_t Soffset;        // variables: offset of Symbol in its storage class
1266: 
1267:     // CPP || OPTIMIZER
1268:     SYMIDX Ssymnum;             // Symbol number (index into globsym.tab[])
1269:                                 // SCauto,SCparameter,SCtmp,SCregpar,SCregister
1270:     // CODGEN
1271:     int Sseg;                   // segment index
1272:     int Sweight;                // usage count, the higher the number,
1273:                                 // the more worthwhile it is to put in
1274:                                 // a register
1275:     union
1276:     {
1277:         unsigned Sxtrnnum_;     // SCcomdef,SCextern,SCcomdat: external symbol # (starting from 1)
1278:         #define Sxtrnnum _SXR.Sxtrnnum_
1279:         unsigned long Stypidx_; // SCstruct,SCunion,SCclass,SCenum,SCtypedef: debug info type index
1280:         #define Stypidx _SXR.Stypidx_
1281:         struct
1282:         { unsigned char Sreglsw_;
1283:           #define Sreglsw _SXR._SR.Sreglsw_
1284:           unsigned char Sregmsw_;
1285:           #define Sregmsw _SXR._SR.Sregmsw_
1286:           regm_t Sregm_;        // mask of registers
1287:           #define Sregm _SXR._SR.Sregm_
1288:         }_SR;                   // SCregister,SCregpar,SCpseudo: register number
1289:     }_SXR;
1290:     regm_t      Sregsaved;      // mask of registers not affected by this func
1291: 
1292: #if SOURCE_4SYMS
1293:     Srcpos Ssrcpos;             // file position for definition
1294: #endif
1295: 
1296:     char Sident[SYM_PREDEF_SZ]; // identifier string (dynamic array)
1297:                                 // (the size is for static Symbols)
1298: 
1299:     int needThis();     // !=0 if symbol needs a 'this' pointer
1300: };
1301: #pragma SC align
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
warning C4068: unknown pragma
1302: 1303: // Class, struct or union 1304: 1305: struct Classsym : Symbol { }; 1306: 1307: // Namespace Symbol 1308: struct Nspacesym : Symbol { }; 1309: 1310: // Alias for another Symbol 1311: struct Aliassym : Symbol { }; 1312: 1313: // Function symbol 1314: //struct Funcsym : Symbol { }; 1315: 1316: // Determine if this Symbol is stored in a COMDAT 1317: #if MARS 1318: #define symbol_iscomdat(s) ((s)->Sclass == SCcomdat || \ 1319: config.flags2 & CFG2comdat && (s)->Sclass == SCinline || \ 1320: config.flags4 & CFG4allcomdat && ((s)->Sclass == SCglobal)) 1321: #else 1322: #define symbol_iscomdat(s) ((s)->Sclass == SCcomdat || \ 1323: config.flags2 & CFG2comdat && (s)->Sclass == SCinline || \ 1324: config.flags4 & CFG4allcomdat && ((s)->Sclass == SCglobal || (s)->Sclass == SCstatic)) 1325: #endif 1326: 1327: /* Format the identifier for presentation to the user */ 1328: char *cpp_prettyident (Symbol *s); 1329: 1330: #if defined(CPP) && !CPP 1331: inline char *prettyident(Symbol *s) { return s->Sident; } 1332: #else 1333: inline char *prettyident(Symbol *s) { return CPP ? cpp_prettyident(s) : s->Sident; } 1334: #endif 1335: 1336: /********************************** 1337: * Function parameters: 1338: * Pident identifier of parameter 1339: * Ptype type of argument 1340: * Pelem default value for argument 1341: * Psym symbol corresponding to Pident when using the 1342: * parameter list as a symbol table 1343: * For template-parameter-list: 1344: * Pident identifier of parameter 1345: * Ptype if NULL, this is a type-parameter 1346: * else the type for a parameter-declaration value argument 1347: * Pelem default value for value argument 1348: * Pdeftype default value for type-parameter 1349: * Pptpl template-parameter-list for template-template-parameter 1350: * Psym default value for template-template-parameter 1351: * For template-arg-list: (actual arguments) 1352: * Pident NULL 1353: * Ptype type-name 1354: * Pelem expression (either Ptype or Pelem is NULL) 1355: * Psym SCtemplate for template-template-argument 1356: */ 1357: 1358: struct PARAM 1359: { 1360: #ifdef DEBUG 1361: unsigned short id; 1362: #define IDparam 0x7050 1363: #define param_debug(s) assert((s)->id == IDparam) 1364: #else 1365: #define param_debug(s) 1366: #endif 1367: 1368: char *Pident; // identifier 1369: type *Ptype; // type of parameter (NULL if not known yet) 1370: elem *Pelem; // default value 1371: token_t *PelemToken; // tokens making up default elem 1372: type *Pdeftype; // Ptype==NULL: default type for type-argument 1373: param_t *Pptpl; // template-parameter-list for template-template-parameter 1374: Symbol *Psym; 1375: PARAM *Pnext; // next in list 1376: unsigned Pflags; 1377: #define PFexplicit 1 // this template argument was explicit, i.e. in < > 1378: #if SOURCE_4PARAMS 1379: Srcpos Psrcpos; // parameter source definition 1380: #endif 1381: 1382: PARAM *createTal(PARAM *); // create template-argument-list blank from 1383: // template-parameter-list 1384: PARAM *search(char *id); // look for Pident matching id 1385: int searchn(char *id); // look for Pident matching id, return index 1386: unsigned length(); // number of parameters in list 1387: void print(); // print this param_t 1388: void print_list(); // print this list of param_t's 1389: }; 1390: 1391: /************************************** 1392: * Element types. 1393: * These should be combined with storage classes. 1394: */ 1395: 1396: enum FL 1397: { 1398: FLunde, 1399: FLconst, // numerical constant 1400: FLoper, // operator node 1401: FLfunc, // function symbol 1402: FLdata, // ref to data segment variable 1403: FLreg, // ref to register variable 1404: FLpseudo, // pseuodo register variable 1405: FLauto, // ref to automatic variable 1406: FLpara, // ref to function parameter variable 1407: FLextern, // ref to external variable 1408: FLtmp, // ref to a stack temporary, int contains temp number 1409: FLcode, // offset to code 1410: FLblock, // offset to block 1411: FLudata, // ref to udata segment variable 1412: FLcs, // ref to common subexpression number 1413: FLswitch, // ref to offset of switch data block 1414: FLfltreg, // ref to floating reg on stack, int contains offset 1415: FLoffset, // offset (a variation on constant, needed so we 1416: // can add offsets (different meaning for FLconst)) 1417: FLdatseg, // ref to data segment offset 1418: FLctor, // constructed object 1419: FLdtor, // destructed object 1420: FLregsave, // ref to saved register on stack, int contains offset 1421: FLasm, // (code) an ASM code 1422: #if TX86 1423: FLndp, // saved 8087 register 1424: FLfardata, // ref to far data segment 1425: FLlocalsize, // replaced with # of locals in the stack frame 1426: FLcsdata, // ref to code segment variable 1427: FLtlsdata, // thread local storage 1428: FLbprel, // ref to variable at fixed offset from frame pointer 1429: FLframehandler, // ref to C++ frame handler for NT EH 1430: FLblockoff, // address of block 1431: FLallocatmp, // temp for built-in alloca() 1432: FLstack, // offset from ESP rather than EBP 1433: FLdsymbol, // it's a Dsymbol 1434: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS 1435: // Change this, update debug.c too 1436: FLgot, // global offset table entry outside this object file 1437: FLgotoff, // global offset table entry inside this object file 1438: //FLoncedata, // link once data 1439: //FLoncecode, // link once code 1440: #endif 1441: #endif 1442: FLMAX 1443: }; 1444: 1445: ////////// Srcfiles 1446: 1447: #if !MARS 1448: // Collect information about a source file. 1449: typedef struct Sfile 1450: { 1451: #ifdef DEBUG 1452: unsigned short id; 1453: #define IDsfile (('f' << 8) | 's') 1454: #define sfile_debug(sf) assert((sf)->id == IDsfile) 1455: #else 1456: #define sfile_debug(sf) 1457: #endif 1458: 1459: char *SFname; // name of file 1460: unsigned SFflags; 1461: #define SFonce 0x01 // file is to be #include'd only once 1462: #define SFhx 0x02 // file is in an HX file and has not been loaded 1463: #define SFtop 0x04 // file is a top level source file 1464: #define SFloaded 0x08 // read from PH file 1465: list_t SFfillist; // file pointers of Sfile's that this Sfile is 1466: // dependent on (i.e. they were #include'd). 1467: // Does not include nested #include's 1468: macro_t *SFmacdefs; // threaded list of macros #defined by this file 1469: macro_t **SFpmacdefs; // end of macdefs list 1470: Symbol *SFsymdefs; // threaded list of global symbols declared by this file 1471: symlist_t SFcomdefs; // comdefs defined in PH 1472: symlist_t SFtemp_ft; // template_ftlist 1473: symlist_t SFtemp_class; // template_class_list 1474: Symbol *SFtagsymdefs; // list of tag names (C only) 1475: unsigned SFhashval; // hash of file name 1476: } Sfile; 1477: 1478: // Source files are referred to by a pointer into pfiles[]. This is so that 1479: // when PH files are hydrated, only pfiles[] needs updating. Of course, this 1480: // means that pfiles[] cannot be reallocated to larger numbers, its size is 1481: // fixed at SRCFILES_MAX. 1482: 1483: typedef struct Srcfiles 1484: { 1485: // Sfile *arr; // array of Sfiles 1486: Sfile **pfiles; // parallel array of pointers into arr[] 1487: #define SRCFILES_MAX (2*512) 1488: unsigned dim; // dimension of array 1489: unsigned idx; // # used in array 1490: } Srcfiles; 1491: 1492: #define sfile(fi) (*srcfiles.pfiles[fi]) 1493: #define srcfiles_name(fi) (sfile(fi).SFname) 1494: #endif 1495: 1496: /************************************************** 1497: * This is to support compiling expressions within the context of a function. 1498: */ 1499: 1500: struct EEcontext 1501: { 1502: unsigned EElinnum; // line number to insert expression 1503: char *EEexpr; // expression 1504: char *EEtypedef; // typedef identifier 1505: char EEpending; // !=0 means we haven't compiled it yet 1506: char EEimminent; // we've installed it in the source text 1507: char EEcompile; // we're compiling for the EE expression 1508: char EEin; // we are parsing an EE expression 1509: elem *EEelem; // compiled version of EEexpr 1510: Symbol *EEfunc; // function expression is in 1511: code *EEcode; // generated code 1512: }; 1513: 1514: extern EEcontext eecontext; 1515: 1516: #include "rtlsym.h" 1517: 1518: #undef SYMBOL_Z 1519: #define SYMBOL_Z(e,fl,saved,n,flags,ty) RTLSYM_##e, 1520: 1521: enum 1522: { 1523: RTLSYMS 1524: 1525: RTLSYM_MAX 1526: }; 1527: 1528: extern Symbol *rtlsym[RTLSYM_MAX]; 1529: 1530: // Different goals for el_optimize() 1531: #define GOALnone 0 // evaluate for side effects only 1532: #define GOALvalue 1 // evaluate for value 1533: #define GOALflags 2 // evaluate for flags 1534: #define GOALagain 4 1535: #define GOALstruct 8 1536: #define GOALhandle 0x10 // don't replace handle'd objects 1537: 1538: /* Globals returned by declar() */ 1539: struct Declar 1540: { 1541: Classsym *class_sym; 1542: Nspacesym *namespace_sym; 1543: int oper; 1544: bool constructor; 1545: bool destructor; 1546: bool invariant; 1547: param_t *ptal; 1548: bool explicitSpecialization; 1549: int hasExcSpec; // has exception specification 1550: }; 1551: 1552: extern Declar gdeclar; 1553: 1554: #endif 1555: