Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 591

Show
Ignore:
Timestamp:
08/02/10 08:28:28 (14 years ago)
Author:
walter
Message:

harmonize

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/declaration.h

    r453 r591  
    8181#define STCsafe         0x200000000LL 
    8282#define STCtrusted      0x400000000LL 
    8383#define STCsystem       0x800000000LL 
    8484#define STCctfe         0x1000000000LL  // can be used in CTFE, even if it is static 
    8585 
    8686struct Match 
    8787{ 
    8888    int count;                  // number of matches found 
    8989    MATCH last;                 // match level of lastf 
    9090    FuncDeclaration *lastf;     // last matching function we found 
    9191    FuncDeclaration *nextf;     // current matching function 
    9292    FuncDeclaration *anyf;      // pick a func, any func, to use for error recovery 
    9393}; 
    9494 
    9595void overloadResolveX(Match *m, FuncDeclaration *f, 
    9696        Expression *ethis, Expressions *arguments); 
    9797int overloadApply(FuncDeclaration *fstart, 
    9898        int (*fp)(void *, FuncDeclaration *), 
    9999        void *param); 
    100100 
     101enum Semantic 
     102{ 
     103    SemanticStart,      // semantic has not been run 
     104    SemanticIn,         // semantic() is in progress 
     105    SemanticDone,       // semantic() has been run 
     106    Semantic2Done,      // semantic2() has been run 
     107}; 
     108 
    101109/**************************************************************/ 
    102110 
    103111struct Declaration : Dsymbol 
    104112{ 
    105113    Type *type; 
    106114    Type *originalType;         // before semantic analysis 
    107115    StorageClass storage_class; 
    108116    enum PROT protection; 
    109117    enum LINK linkage; 
    110118    int inuse;                  // used to detect cycles 
    111119 
    112120    Declaration(Identifier *id); 
    113121    void semantic(Scope *sc); 
    114122    const char *kind(); 
    115123    unsigned size(Loc loc); 
    116124    void checkModify(Loc loc, Scope *sc, Type *t); 
    117125 
    118126    void emitComment(Scope *sc); 
    119127    void toJsonBuffer(OutBuffer *buf); 
    120128    void toDocBuffer(OutBuffer *buf); 
     
    436444}; 
    437445 
    438446#if DMDV2 
    439447struct TypeInfoConstDeclaration : TypeInfoDeclaration 
    440448{ 
    441449    TypeInfoConstDeclaration(Type *tinfo); 
    442450 
    443451    void toDt(dt_t **pdt); 
    444452}; 
    445453 
    446454struct TypeInfoInvariantDeclaration : TypeInfoDeclaration 
    447455{ 
    448456    TypeInfoInvariantDeclaration(Type *tinfo); 
    449457 
    450458    void toDt(dt_t **pdt); 
    451459}; 
    452460 
    453461struct TypeInfoSharedDeclaration : TypeInfoDeclaration 
    454462{ 
    455463    TypeInfoSharedDeclaration(Type *tinfo); 
     464 
     465    void toDt(dt_t **pdt); 
     466}; 
     467 
     468struct TypeInfoWildDeclaration : TypeInfoDeclaration 
     469{ 
     470    TypeInfoWildDeclaration(Type *tinfo); 
    456471 
    457472    void toDt(dt_t **pdt); 
    458473}; 
    459474#endif 
    460475 
    461476/**************************************************************/ 
    462477 
    463478struct ThisDeclaration : VarDeclaration 
    464479{ 
    465480    ThisDeclaration(Loc loc, Type *t); 
    466481    Dsymbol *syntaxCopy(Dsymbol *); 
    467482    ThisDeclaration *isThisDeclaration() { return this; } 
    468483}; 
    469484 
    470485enum ILS 
    471486{ 
    472487    ILSuninitialized,   // not computed yet 
    473488    ILSno,              // cannot inline 
    474489    ILSyes,             // can inline 
    475490}; 
     
    581596    FuncDeclaration *overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags = 0); 
    582597    MATCH leastAsSpecialized(FuncDeclaration *g); 
    583598    LabelDsymbol *searchLabel(Identifier *ident); 
    584599    AggregateDeclaration *isThis(); 
    585600    AggregateDeclaration *isMember2(); 
    586601    int getLevel(Loc loc, FuncDeclaration *fd); // lexical nesting level difference 
    587602    void appendExp(Expression *e); 
    588603    void appendState(Statement *s); 
    589604    char *mangle(); 
    590605    const char *toPrettyChars(); 
    591606    int isMain(); 
    592607    int isWinMain(); 
    593608    int isDllMain(); 
    594609    enum BUILTIN isBuiltin(); 
    595610    int isExport(); 
    596611    int isImportedSymbol(); 
    597612    int isAbstract(); 
    598613    int isCodeseg(); 
    599614    int isOverloadable(); 
    600615    int isPure(); 
     616    int isSafe(); 
     617    int isTrusted(); 
    601618    virtual int isNested(); 
    602619    int needThis(); 
    603620    virtual int isVirtual(); 
    604621    virtual int isFinal(); 
    605622    virtual int addPreInvariant(); 
    606623    virtual int addPostInvariant(); 
    607624    Expression *interpret(InterState *istate, Expressions *arguments, Expression *thisexp = NULL); 
    608625    void inlineScan(); 
    609626    int canInline(int hasthis, int hdrscan = 0); 
    610627    Expression *doInline(InlineScanState *iss, Expression *ethis, Array *arguments); 
    611628    const char *kind(); 
    612629    void toDocBuffer(OutBuffer *buf); 
    613630    FuncDeclaration *isUnique(); 
    614631    int needsClosure(); 
    615632    Statement *mergeFrequire(Statement *); 
    616633    Statement *mergeFensure(Statement *); 
    617634    Parameters *getParameters(int *pvarargs); 
    618635 
    619636    static FuncDeclaration *genCfunc(Type *treturn, const char *name); 
    620637    static FuncDeclaration *genCfunc(Type *treturn, Identifier *id); 
     
    718735    DtorDeclaration *isDtorDeclaration() { return this; } 
    719736}; 
    720737 
    721738struct StaticCtorDeclaration : FuncDeclaration 
    722739{ 
    723740    StaticCtorDeclaration(Loc loc, Loc endloc); 
    724741    Dsymbol *syntaxCopy(Dsymbol *); 
    725742    void semantic(Scope *sc); 
    726743    AggregateDeclaration *isThis(); 
    727744    int isStaticConstructor(); 
    728745    int isVirtual(); 
    729746    int addPreInvariant(); 
    730747    int addPostInvariant(); 
    731748    void emitComment(Scope *sc); 
    732749    void toJsonBuffer(OutBuffer *buf); 
    733750    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    734751 
    735752    StaticCtorDeclaration *isStaticCtorDeclaration() { return this; } 
    736753}; 
    737754 
     755#if DMDV2 
     756struct SharedStaticCtorDeclaration : StaticCtorDeclaration 
     757{ 
     758    SharedStaticCtorDeclaration(Loc loc, Loc endloc); 
     759    Dsymbol *syntaxCopy(Dsymbol *); 
     760    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     761 
     762    SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; } 
     763}; 
     764#endif 
     765 
    738766struct StaticDtorDeclaration : FuncDeclaration 
    739767{   VarDeclaration *vgate;      // 'gate' variable 
    740768 
    741769    StaticDtorDeclaration(Loc loc, Loc endloc); 
    742770    Dsymbol *syntaxCopy(Dsymbol *); 
    743771    void semantic(Scope *sc); 
    744772    AggregateDeclaration *isThis(); 
    745773    int isStaticDestructor(); 
    746774    int isVirtual(); 
    747775    int addPreInvariant(); 
    748776    int addPostInvariant(); 
    749777    void emitComment(Scope *sc); 
    750778    void toJsonBuffer(OutBuffer *buf); 
    751779    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    752780 
    753781    StaticDtorDeclaration *isStaticDtorDeclaration() { return this; } 
    754782}; 
    755783 
     784#if DMDV2 
     785struct SharedStaticDtorDeclaration : StaticDtorDeclaration 
     786{ 
     787    SharedStaticDtorDeclaration(Loc loc, Loc endloc); 
     788    Dsymbol *syntaxCopy(Dsymbol *); 
     789    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     790 
     791    SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; } 
     792}; 
     793#endif 
     794 
    756795struct InvariantDeclaration : FuncDeclaration 
    757796{ 
    758797    InvariantDeclaration(Loc loc, Loc endloc); 
    759798    Dsymbol *syntaxCopy(Dsymbol *); 
    760799    void semantic(Scope *sc); 
    761800    int isVirtual(); 
    762801    int addPreInvariant(); 
    763802    int addPostInvariant(); 
    764803    void emitComment(Scope *sc); 
    765804    void toJsonBuffer(OutBuffer *buf); 
    766805    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    767806 
    768807    InvariantDeclaration *isInvariantDeclaration() { return this; } 
    769808}; 
    770809 
    771810 
    772811struct UnitTestDeclaration : FuncDeclaration 
    773812{ 
    774813    UnitTestDeclaration(Loc loc, Loc endloc); 
    775814    Dsymbol *syntaxCopy(Dsymbol *); 
  • branches/dmd-1.x/src/glue.c

    r428 r591  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2009 by Digital Mars 
     3// Copyright (c) 1999-2010 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77 
    88#include <stdio.h> 
    99#include <stddef.h> 
    1010#include <time.h> 
    1111#include <assert.h> 
    1212 
    1313#if __sun&&__SVR4 
    1414#include <alloca.h> 
    1515#endif 
    1616 
    1717#include "mars.h" 
    1818#include "module.h" 
    1919#include "mtype.h" 
    2020#include "declaration.h" 
    2121#include "statement.h" 
    2222#include "enum.h" 
    2323#include "aggregate.h" 
     
    3636#include "type.h" 
    3737#include "dt.h" 
    3838#include "cgcv.h" 
    3939#include "outbuf.h" 
    4040#include "irstate.h" 
    4141 
    4242struct Environment; 
    4343 
    4444Environment *benv; 
    4545 
    4646void out_config_init(); 
    4747void slist_add(Symbol *s); 
    4848void slist_reset(); 
    4949void clearStringTab(); 
    5050 
    5151#define STATICCTOR      0 
    5252 
    5353elem *eictor; 
    5454symbol *ictorlocalgot; 
    5555elem *ector; 
     56Array ectorgates; 
    5657elem *edtor; 
    5758elem *etest; 
    5859 
     60elem *esharedctor; 
     61Array esharedctorgates; 
     62elem *eshareddtor; 
     63 
    5964int dtorcount; 
     65int shareddtorcount; 
    6066 
    6167char *lastmname; 
    6268 
    6369/************************************** 
    6470 * Append s to list of object files to generate later. 
    6571 */ 
    6672 
    6773Array obj_symbols_towrite; 
    6874 
    6975void obj_append(Dsymbol *s) 
    7076{ 
    7177    obj_symbols_towrite.push(s); 
    7278} 
    7379 
    7480void obj_write_deferred(Library *library) 
    7581{ 
    7682    for (int i = 0; i < obj_symbols_towrite.dim; i++) 
    7783    {   Dsymbol *s = (Dsymbol *)obj_symbols_towrite.data[i]; 
    7884        Module *m = s->getModule(); 
    7985 
     
    8793            //mname = s->ident->toChars(); 
    8894            mname = lastmname; 
    8995            assert(mname); 
    9096        } 
    9197 
    9298        obj_start(mname); 
    9399 
    94100        static int count; 
    95101        count++;                // sequence for generating names 
    96102 
    97103        /* Create a module that's a doppelganger of m, with just 
    98104         * enough to be able to create the moduleinfo. 
    99105         */ 
    100106        OutBuffer idbuf; 
    101107        idbuf.printf("%s.%d", m ? m->ident->toChars() : mname, count); 
    102108        char *idstr = idbuf.toChars(); 
    103109        idbuf.data = NULL; 
    104110        Identifier *id = new Identifier(idstr, TOKidentifier); 
    105111 
    106112        Module *md = new Module(mname, id, 0, 0); 
    107         md->members = new Array(); 
     113        md->members = new Dsymbols(); 
    108114        md->members->push(s);   // its only 'member' is s 
    109115        if (m) 
    110116        { 
    111117            md->doppelganger = 1;       // identify this module as doppelganger 
    112118            md->md = m->md; 
    113119            md->aimports.push(m);       // it only 'imports' m 
    114120            md->massert = m->massert; 
     121            md->munittest = m->munittest; 
    115122            md->marray = m->marray; 
    116123        } 
    117124 
    118125        md->genobjfile(0); 
    119126 
    120127        /* Set object file name to be source name with sequence number, 
    121128         * as mangled symbol names get way too long. 
    122129         */ 
    123130        char *fname = FileName::removeExt(mname); 
    124131        OutBuffer namebuf; 
    125132        unsigned hash = 0; 
    126133        for (char *p = s->toChars(); *p; p++) 
    127134            hash += *p; 
    128135        namebuf.printf("%s_%x_%x.%s", fname, count, hash, global.obj_ext); 
    129136        namebuf.writeByte(0); 
    130137        mem.free(fname); 
    131138        fname = (char *)namebuf.extractData(); 
    132139 
    133140        //printf("writing '%s'\n", fname); 
    134141        File *objfile = new File(fname); 
     
    189196    objbuf.inc = 0; 
    190197} 
    191198 
    192199/************************************** 
    193200 * Generate .obj file for Module. 
    194201 */ 
    195202 
    196203void Module::genobjfile(int multiobj) 
    197204{ 
    198205    //EEcontext *ee = env->getEEcontext(); 
    199206 
    200207    //printf("Module::genobjfile(multiobj = %d) %s\n", multiobj, toChars()); 
    201208 
    202209    lastmname = srcfile->toChars(); 
    203210 
    204211    obj_initfile(lastmname, NULL, toPrettyChars()); 
    205212 
    206213    eictor = NULL; 
    207214    ictorlocalgot = NULL; 
    208215    ector = NULL; 
     216    ectorgates.setDim(0); 
    209217    edtor = NULL; 
     218    esharedctor = NULL; 
     219    esharedctorgates.setDim(0); 
     220    eshareddtor = NULL; 
    210221    etest = NULL; 
    211222    dtorcount = 0; 
     223    shareddtorcount = 0; 
    212224 
    213225    if (doppelganger) 
    214226    { 
    215227        /* Generate a reference to the moduleinfo, so the module constructors 
    216228         * and destructors get linked in. 
    217229         */ 
    218230        Module *m = (Module *)aimports.data[0]; 
    219231        assert(m); 
    220232        if (m->sictor || m->sctor || m->sdtor) 
    221233        { 
    222234            Symbol *s = m->toSymbol(); 
    223235            //objextern(s); 
    224236            //if (!s->Sxtrnnum) objextdef(s->Sident); 
    225237            if (!s->Sxtrnnum) 
    226238            { 
    227239                //printf("%s\n", s->Sident); 
    228240#if 0 /* This should work, but causes optlink to fail in common/newlib.asm */ 
    229241                objextdef(s->Sident); 
    230242#else 
    231243#if ELFOBJ || MACHOBJ 
     
    326338        t->Tnext = tsvoid; 
    327339        tsvoid->Tcount++; 
    328340 
    329341        static char moddeco[] = "FZv"; 
    330342 
    331343        if (eictor) 
    332344        { 
    333345            localgot = ictorlocalgot; 
    334346 
    335347            block *b = block_calloc(); 
    336348            b->BC = BCret; 
    337349            b->Belem = eictor; 
    338350            sictor->Sfunc->Fstartblock = b; 
    339351            writefunc(sictor); 
    340352        } 
    341353 
    342354        if (ector) 
    343355        { 
    344356            localgot = NULL; 
    345357            sctor = toSymbolX("__modctor", SCglobal, t, moddeco); 
     358#if DMDV2 
     359            cstate.CSpsymtab = &sctor->Sfunc->Flocsym; 
     360 
     361            for (int i = 0; i < ectorgates.dim; i++) 
     362            {   StaticDtorDeclaration *f = (StaticDtorDeclaration *)ectorgates.data[i]; 
     363 
     364                Symbol *s = f->vgate->toSymbol(); 
     365                elem *e = el_var(s); 
     366                e = el_bin(OPaddass, TYint, e, el_long(TYint, 1)); 
     367                ector = el_combine(ector, e); 
     368            } 
     369#endif 
    346370 
    347371            block *b = block_calloc(); 
    348372            b->BC = BCret; 
    349373            b->Belem = ector; 
    350374            sctor->Sfunc->Fstartblock = b; 
    351375            writefunc(sctor); 
    352376#if STATICCTOR 
    353377            obj_staticctor(sctor, dtorcount, 1); 
    354378#endif 
    355379        } 
    356380 
    357381        if (edtor) 
    358382        { 
    359383            localgot = NULL; 
    360384            sdtor = toSymbolX("__moddtor", SCglobal, t, moddeco); 
    361385 
    362386            block *b = block_calloc(); 
    363387            b->BC = BCret; 
    364388            b->Belem = edtor; 
    365389            sdtor->Sfunc->Fstartblock = b; 
    366390            writefunc(sdtor); 
    367391        } 
    368392 
     393#if DMDV2 
     394        if (esharedctor || esharedctorgates.dim) 
     395        { 
     396            localgot = NULL; 
     397            ssharedctor = toSymbolX("__modsharedctor", SCglobal, t, moddeco); 
     398            cstate.CSpsymtab = &ssharedctor->Sfunc->Flocsym; 
     399 
     400            for (int i = 0; i < esharedctorgates.dim; i++) 
     401            {   SharedStaticDtorDeclaration *f = (SharedStaticDtorDeclaration *)esharedctorgates.data[i]; 
     402 
     403                Symbol *s = f->vgate->toSymbol(); 
     404                elem *e = el_var(s); 
     405                e = el_bin(OPaddass, TYint, e, el_long(TYint, 1)); 
     406                esharedctor = el_combine(esharedctor, e); 
     407            } 
     408 
     409            block *b = block_calloc(); 
     410            b->BC = BCret; 
     411            b->Belem = esharedctor; 
     412            ssharedctor->Sfunc->Fstartblock = b; 
     413            writefunc(ssharedctor); 
     414#if STATICCTOR 
     415            obj_staticctor(ssharedctor, shareddtorcount, 1); 
     416#endif 
     417        } 
     418 
     419        if (eshareddtor) 
     420        { 
     421            localgot = NULL; 
     422            sshareddtor = toSymbolX("__modshareddtor", SCglobal, t, moddeco); 
     423 
     424            block *b = block_calloc(); 
     425            b->BC = BCret; 
     426            b->Belem = eshareddtor; 
     427            sshareddtor->Sfunc->Fstartblock = b; 
     428            writefunc(sshareddtor); 
     429        } 
     430#endif 
     431 
    369432        if (etest) 
    370433        { 
    371434            localgot = NULL; 
    372435            stest = toSymbolX("__modtest", SCglobal, t, moddeco); 
    373436 
    374437            block *b = block_calloc(); 
    375438            b->BC = BCret; 
    376439            b->Belem = etest; 
    377440            stest->Sfunc->Fstartblock = b; 
    378441            writefunc(stest); 
    379442        } 
    380443 
    381444        if (doppelganger) 
    382445            genmoduleinfo(); 
    383446    } 
    384447 
    385448    if (doppelganger) 
    386449    { 
    387450        obj_termfile(); 
    388451        return; 
    389452    } 
    390453 
    391454    if (global.params.multiobj) 
    392455    {   /* This is necessary because the main .obj for this module is written 
    393          * first, but determining whether marray or massert are needed is done 
     456         * first, but determining whether marray or massert or munittest are needed is done 
    394457         * possibly later in the doppelganger modules. 
    395458         * Another way to fix it is do the main one last. 
    396459         */ 
    397460        toModuleAssert(); 
    398461        toModuleArray(); 
    399462    } 
    400463 
    401464#if 1 
    402465    // If module assert 
    403466    for (int i = 0; i < 2; i++) 
    404467    { 
    405         Symbol *ma = i ? marray : massert; 
     468        Symbol *ma; 
     469        unsigned rt; 
     470        switch (i) 
     471        { 
     472            case 0:     ma = marray;    rt = RTLSYM_DARRAY;     break; 
     473            case 1:     ma = massert;   rt = RTLSYM_DASSERT;   break; 
     474            case 2:     ma = munittest; rt = RTLSYM_DUNITTESTM; break; 
     475            default:    assert(0); 
     476        } 
    406477 
    407478        if (ma) 
    408479        { 
    409480            elem *elinnum; 
    410             elem *efilename; 
    411481 
    412482            localgot = NULL; 
    413483 
    414484            // Call dassert(filename, line) 
    415485            // Get sole parameter, linnum 
    416486            { 
    417                 Symbol *sp; 
    418  
    419                 sp = symbol_calloc("linnum"); 
     487                Symbol *sp = symbol_calloc("linnum"); 
    420488                sp->Stype = type_fake(TYint); 
    421489                sp->Stype->Tcount++; 
    422490                sp->Sclass = SCfastpar; 
    423491                sp->Spreg = AX; 
    424492                sp->Sflags &= ~SFLspill; 
    425493                sp->Sfl = FLpara;       // FLauto? 
    426494                cstate.CSpsymtab = &ma->Sfunc->Flocsym; 
    427495                symbol_add(sp); 
    428496 
    429497                elinnum = el_var(sp); 
    430498            } 
    431499 
    432             efilename = toEmodulename(); 
    433  
    434             elem *e = el_var(rtlsym[i ? RTLSYM_DARRAY : RTLSYM_DASSERT]); 
     500            elem *efilename = toEmodulename(); 
     501 
     502            elem *e = el_var(rtlsym[rt]); 
    435503            e = el_bin(OPcall, TYvoid, e, el_param(elinnum, efilename)); 
    436504 
    437505            block *b = block_calloc(); 
    438506            b->BC = BCret; 
    439507            b->Belem = e; 
    440508            ma->Sfunc->Fstartblock = b; 
    441509            ma->Sclass = SCglobal; 
    442510            ma->Sfl = 0; 
    443511            writefunc(ma); 
    444512        } 
    445513    } 
    446514#endif 
    447515 
    448516#if 1 
    449517    // Always generate module info, because of templates and -cov 
    450518    if (1 || needModuleInfo()) 
    451519        genmoduleinfo(); 
    452520#endif 
    453521 
    454522    obj_termfile(); 
    455523} 
    456524 
    457525 
    458526/* ================================================================== */ 
    459527 
    460528void FuncDeclaration::toObjFile(int multiobj) 
    461529{ 
    462     Symbol *s; 
    463     func_t *f; 
    464530    Symbol *senter; 
    465531    Symbol *sexit; 
    466532    FuncDeclaration *func = this; 
    467533    ClassDeclaration *cd = func->parent->isClassDeclaration(); 
    468534    int reverse; 
    469535    int i; 
    470536    int has_arguments; 
    471537 
    472     //printf("FuncDeclaration::toObjFile(%p, %s)\n", func, func->toChars()); 
     538    //printf("FuncDeclaration::toObjFile(%p, %s.%s)\n", func, parent->toChars(), func->toChars()); 
    473539#if 0 
    474540    //printf("line = %d\n",func->getWhere() / LINEINC); 
    475541    EEcontext *ee = env->getEEcontext(); 
    476542    if (ee->EEcompile == 2) 
    477543    { 
    478544        if (ee->EElinnum < (func->getWhere() / LINEINC) || 
    479545            ee->EElinnum > (func->endwhere / LINEINC) 
    480546           ) 
    481547            return;             // don't compile this function 
    482548        ee->EEfunc = func->toSymbol(); 
    483549    } 
    484550#endif 
    485551 
    486552    if (multiobj && !isStaticDtorDeclaration() && !isStaticCtorDeclaration()) 
    487553    {   obj_append(this); 
    488554        return; 
    489555    } 
    490556 
    491557    if (semanticRun >= PASSobj) // if toObjFile() already run 
    492558        return; 
    493559    semanticRun = PASSobj; 
    494560 
    495561    if (!func->fbody) 
    496562    { 
    497563        return; 
    498564    } 
    499565    if (func->isUnitTestDeclaration() && !global.params.useUnitTests) 
    500566        return; 
    501567 
    502568    if (global.params.verbose) 
    503569        printf("function  %s\n",func->toChars()); 
    504570 
    505     s = func->toSymbol(); 
    506     f = s->Sfunc; 
     571    Symbol *s = func->toSymbol(); 
     572    func_t *f = s->Sfunc; 
    507573 
    508574#if TARGET_WINDOS 
    509575    /* This is done so that the 'this' pointer on the stack is the same 
    510576     * distance away from the function parameters, so that an overriding 
    511577     * function can call the nested fdensure or fdrequire of its overridden function 
    512578     * and the stack offsets are the same. 
    513579     */ 
    514580    if (isVirtual() && (fensure || frequire)) 
    515581        f->Fflags3 |= Ffakeeh; 
    516582#endif 
    517583 
    518584#if TARGET_OSX 
    519585    s->Sclass = SCcomdat; 
    520586#else 
    521587    s->Sclass = SCglobal; 
    522588#endif 
    523589    for (Dsymbol *p = parent; p; p = p->parent) 
    524590    { 
    525591        if (p->isTemplateInstance()) 
    526592        { 
     
    736802        } 
    737803    } 
    738804 
    739805    if (func->fbody) 
    740806    {   block *b; 
    741807        Blockx bx; 
    742808        Statement *sbody; 
    743809 
    744810        localgot = NULL; 
    745811 
    746812        sbody = func->fbody; 
    747813        memset(&bx,0,sizeof(bx)); 
    748814        bx.startblock = block_calloc(); 
    749815        bx.curblock = bx.startblock; 
    750816        bx.funcsym = s; 
    751817        bx.scope_index = -1; 
    752818        bx.classdec = cd; 
    753819        bx.member = func; 
    754820        bx.module = getModule(); 
    755821        irs.blx = &bx; 
     822#if DMDV2 
     823        buildClosure(&irs); 
     824#endif 
    756825 
    757826#if 0 
    758827        if (func->isSynchronized()) 
    759828        { 
    760829            if (cd) 
    761830            {   elem *esync; 
    762831                if (func->isStatic()) 
    763832                {   // monitor is in ClassInfo 
    764833                    esync = el_ptr(cd->toSymbol()); 
    765834                } 
    766835                else 
    767836                {   // 'this' is the monitor 
    768837                    esync = el_var(sthis); 
    769838                } 
    770839 
    771840                if (func->isStatic() || sbody->usesEH() || 
    772841                    !(config.flags2 & CFG2seh)) 
    773842                {   // BUG: what if frequire or fensure uses EH? 
    774843 
    775844                    sbody = new SynchronizedStatement(func->loc, esync, sbody); 
     
    809878        bx.curblock->BC = BCret; 
    810879 
    811880        f->Fstartblock = bx.startblock; 
    812881//      einit = el_combine(einit,bx.init); 
    813882 
    814883        if (isCtorDeclaration()) 
    815884        { 
    816885            assert(sthis); 
    817886            for (b = f->Fstartblock; b; b = b->Bnext) 
    818887            { 
    819888                if (b->BC == BCret) 
    820889                { 
    821890                    b->BC = BCretexp; 
    822891                    b->Belem = el_combine(b->Belem, el_var(sthis)); 
    823892                } 
    824893            } 
    825894        } 
    826895    } 
    827896 
    828897    // If static constructor 
    829     if (isStaticConstructor()) 
     898#if DMDV2 
     899    if (isSharedStaticCtorDeclaration())        // must come first because it derives from StaticCtorDeclaration 
     900    { 
     901        elem *e = el_una(OPucall, TYvoid, el_var(s)); 
     902        esharedctor = el_combine(esharedctor, e); 
     903    } 
     904    else 
     905#endif 
     906    if (isStaticCtorDeclaration()) 
    830907    { 
    831908        elem *e = el_una(OPucall, TYvoid, el_var(s)); 
    832909        ector = el_combine(ector, e); 
    833910    } 
    834911 
    835912    // If static destructor 
    836     if (isStaticDestructor()) 
     913#if DMDV2 
     914    if (isSharedStaticDtorDeclaration())        // must come first because it derives from StaticDtorDeclaration 
     915    { 
     916        elem *e; 
     917 
     918#if STATICCTOR 
     919        e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_FATEXIT]), el_ptr(s)); 
     920        esharedctor = el_combine(esharedctor, e); 
     921        shareddtorcount++; 
     922#else 
     923        SharedStaticDtorDeclaration *f = isSharedStaticDtorDeclaration(); 
     924        assert(f); 
     925        if (f->vgate) 
     926        {   /* Increment destructor's vgate at construction time 
     927             */ 
     928            esharedctorgates.push(f); 
     929        } 
     930 
     931        e = el_una(OPucall, TYvoid, el_var(s)); 
     932        eshareddtor = el_combine(e, eshareddtor); 
     933#endif 
     934    } 
     935    else 
     936#endif 
     937    if (isStaticDtorDeclaration()) 
    837938    { 
    838939        elem *e; 
    839940 
    840941#if STATICCTOR 
    841942        e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_FATEXIT]), el_ptr(s)); 
    842943        ector = el_combine(ector, e); 
    843944        dtorcount++; 
    844945#else 
    845946        StaticDtorDeclaration *f = isStaticDtorDeclaration(); 
    846947        assert(f); 
    847948        if (f->vgate) 
    848         {   /* Increment vgate at construction time 
     949        {   /* Increment destructor's vgate at construction time 
    849950             */ 
    850951            Symbol *s = f->vgate->toSymbol(); 
    851952            e = el_var(s); 
    852953            e = el_bin(OPaddass, TYint, e, el_long(TYint, 1)); 
    853954            ector = el_combine(ector, e); 
    854955        } 
    855956 
    856957        e = el_una(OPucall, TYvoid, el_var(s)); 
    857958        edtor = el_combine(e, edtor); 
    858959#endif 
    859960    } 
    860961 
    861962    // If unit test 
    862963    if (isUnitTestDeclaration()) 
    863964    { 
    864965        elem *e = el_una(OPucall, TYvoid, el_var(s)); 
    865966        etest = el_combine(etest, e); 
    866967    } 
    867968 
    868969    if (global.errors) 
     
    9231024        case Tcomplex80: t = TYcldouble; break; 
    9241025        //case Tbit:    t = TYuchar;    break; 
    9251026        case Tbool:     t = TYbool;     break; 
    9261027        case Tchar:     t = TYchar;     break; 
    9271028#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    9281029        case Twchar:    t = TYwchar_t;  break; 
    9291030        case Tdchar:    t = TYdchar;    break; 
    9301031#else 
    9311032        case Twchar:    t = TYwchar_t;  break; 
    9321033        case Tdchar: 
    9331034                t = (global.params.symdebug == 1) ? TYdchar : TYulong; 
    9341035                break; 
    9351036#endif 
    9361037 
    9371038        case Taarray:   t = TYaarray;   break; 
    9381039        case Tclass: 
    9391040        case Treference: 
    9401041        case Tpointer:  t = TYnptr;     break; 
    9411042        case Tdelegate: t = TYdelegate; break; 
    9421043        case Tarray:    t = TYdarray;   break; 
     1044#if SARRAYVALUE 
     1045        case Tsarray:   t = TYstruct;   break; 
     1046#else 
    9431047        case Tsarray:   t = TYarray;    break; 
     1048#endif 
    9441049        case Tstruct:   t = TYstruct;   break; 
    9451050 
    9461051        case Tenum: 
    9471052        case Ttypedef: 
    9481053             t = toBasetype()->totym(); 
    9491054             break; 
    9501055 
    9511056        case Tident: 
    9521057        case Ttypeof: 
    9531058#ifdef DEBUG 
    9541059            printf("ty = %d, '%s'\n", ty, toChars()); 
    9551060#endif 
    9561061            error(0, "forward reference of %s", toChars()); 
    9571062            t = TYint; 
    9581063            break; 
    9591064 
    9601065        default: 
    9611066#ifdef DEBUG 
    9621067            printf("ty = %d, '%s'\n", ty, toChars()); 
    9631068            halt(); 
    9641069#endif 
    9651070            assert(0); 
    9661071    } 
    9671072 
    9681073#if DMDV2 
    9691074    // Add modifiers 
    9701075    switch (mod) 
    9711076    { 
    9721077        case 0: 
    9731078            break; 
    9741079        case MODconst: 
     1080        case MODwild: 
    9751081            t |= mTYconst; 
    9761082            break; 
    9771083        case MODimmutable: 
    9781084            t |= mTYimmutable; 
    9791085            break; 
    9801086        case MODshared: 
    9811087            t |= mTYshared; 
    9821088            break; 
     1089        case MODshared | MODwild: 
    9831090        case MODshared | MODconst: 
    9841091            t |= mTYshared | mTYconst; 
    9851092            break; 
    9861093        default: 
    9871094            assert(0); 
    9881095    } 
    9891096#endif 
    9901097 
    9911098    return t; 
    9921099} 
    9931100 
    9941101unsigned TypeFunction::totym() 
    9951102{ 
    9961103    tym_t tyf; 
    9971104 
    9981105    //printf("TypeFunction::totym(), linkage = %d\n", linkage); 
    9991106    switch (linkage) 
    10001107    { 
    10011108        case LINKwindows: 
    10021109            tyf = (varargs == 1) ? TYnfunc : TYnsfunc; 
  • branches/dmd-1.x/src/module.c

    r583 r591  
    7272    md = NULL; 
    7373    errors = 0; 
    7474    numlines = 0; 
    7575    members = NULL; 
    7676    isHtml = 0; 
    7777    isDocFile = 0; 
    7878    needmoduleinfo = 0; 
    7979#ifdef IN_GCC 
    8080    strictlyneedmoduleinfo = 0; 
    8181#endif 
    8282    selfimports = 0; 
    8383    insearch = 0; 
    8484    searchCacheIdent = NULL; 
    8585    searchCacheSymbol = NULL; 
    8686    searchCacheFlags = 0; 
    8787    semanticstarted = 0; 
    8888    semanticRun = 0; 
    8989    decldefs = NULL; 
    9090    vmoduleinfo = NULL; 
    9191    massert = NULL; 
     92    munittest = NULL; 
    9293    marray = NULL; 
    9394    sictor = NULL; 
    9495    sctor = NULL; 
    9596    sdtor = NULL; 
    9697    stest = NULL; 
    9798    sfilename = NULL; 
    9899    root = 0; 
    99100    importedFrom = NULL; 
    100101    srcfile = NULL; 
    101102    docfile = NULL; 
    102103 
    103104    debuglevel = 0; 
    104105    debugids = NULL; 
    105106    debugidsNot = NULL; 
    106107    versionlevel = 0; 
    107108    versionids = NULL; 
    108109    versionidsNot = NULL; 
    109110 
    110111    macrotable = NULL; 
    111112    escapetable = NULL; 
  • branches/dmd-1.x/src/module.h

    r428 r591  
    143143    static void runDeferredSemantic(); 
    144144    static void clearCache(); 
    145145    int imports(Module *m); 
    146146 
    147147    // Back end 
    148148 
    149149    int doppelganger;           // sub-module 
    150150    Symbol *cov;                // private uint[] __coverage; 
    151151    unsigned *covb;             // bit array of valid code line numbers 
    152152 
    153153    Symbol *sictor;             // module order independent constructor 
    154154    Symbol *sctor;              // module constructor 
    155155    Symbol *sdtor;              // module destructor 
    156156    Symbol *stest;              // module unit test 
    157157 
    158158    Symbol *sfilename;          // symbol for filename 
    159159 
    160160    Symbol *massert;            // module assert function 
    161161    Symbol *toModuleAssert();   // get module assert function 
    162162 
     163    Symbol *munittest;          // module unittest failure function 
     164    Symbol *toModuleUnittest(); // get module unittest failure function 
     165 
    163166    Symbol *marray;             // module array bounds function 
    164167    Symbol *toModuleArray();    // get module array bounds function 
    165168 
    166169 
    167170    static Symbol *gencritsec(); 
    168171    elem *toEfilename(); 
    169172    elem *toEmodulename(); 
    170173 
    171174    Symbol *toSymbol(); 
    172175    void genmoduleinfo(); 
    173176 
    174177    Module *isModule() { return this; } 
    175178}; 
    176179 
    177180 
    178181struct ModuleDeclaration 
    179182{ 
    180183    Identifier *id; 
    181184    Array *packages;            // array of Identifier's representing packages 
    182185    bool safe; 
  • trunk/src/declaration.h

    r521 r591  
    728728    DtorDeclaration *isDtorDeclaration() { return this; } 
    729729}; 
    730730 
    731731struct StaticCtorDeclaration : FuncDeclaration 
    732732{ 
    733733    StaticCtorDeclaration(Loc loc, Loc endloc); 
    734734    StaticCtorDeclaration(Loc loc, Loc endloc, const char *name); 
    735735    Dsymbol *syntaxCopy(Dsymbol *); 
    736736    void semantic(Scope *sc); 
    737737    AggregateDeclaration *isThis(); 
    738738    int isVirtual(); 
    739739    int addPreInvariant(); 
    740740    int addPostInvariant(); 
    741741    void emitComment(Scope *sc); 
    742742    void toJsonBuffer(OutBuffer *buf); 
    743743    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    744744 
    745745    StaticCtorDeclaration *isStaticCtorDeclaration() { return this; } 
    746746}; 
    747747 
     748#if DMDV2 
    748749struct SharedStaticCtorDeclaration : StaticCtorDeclaration 
    749750{ 
    750751    SharedStaticCtorDeclaration(Loc loc, Loc endloc); 
    751752    Dsymbol *syntaxCopy(Dsymbol *); 
    752753    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    753754 
    754755    SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; } 
    755756}; 
     757#endif 
    756758 
    757759struct StaticDtorDeclaration : FuncDeclaration 
    758760{   VarDeclaration *vgate;      // 'gate' variable 
    759761 
    760762    StaticDtorDeclaration(Loc loc, Loc endloc); 
    761763    StaticDtorDeclaration(Loc loc, Loc endloc, const char *name); 
    762764    Dsymbol *syntaxCopy(Dsymbol *); 
    763765    void semantic(Scope *sc); 
    764766    AggregateDeclaration *isThis(); 
    765767    int isVirtual(); 
    766768    int addPreInvariant(); 
    767769    int addPostInvariant(); 
    768770    void emitComment(Scope *sc); 
    769771    void toJsonBuffer(OutBuffer *buf); 
    770772    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    771773 
    772774    StaticDtorDeclaration *isStaticDtorDeclaration() { return this; } 
    773775}; 
    774776 
     777#if DMDV2 
    775778struct SharedStaticDtorDeclaration : StaticDtorDeclaration 
    776779{ 
    777780    SharedStaticDtorDeclaration(Loc loc, Loc endloc); 
    778781    Dsymbol *syntaxCopy(Dsymbol *); 
    779782    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    780783 
    781784    SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; } 
    782785}; 
     786#endif 
    783787 
    784788struct InvariantDeclaration : FuncDeclaration 
    785789{ 
    786790    InvariantDeclaration(Loc loc, Loc endloc); 
    787791    Dsymbol *syntaxCopy(Dsymbol *); 
    788792    void semantic(Scope *sc); 
    789793    int isVirtual(); 
    790794    int addPreInvariant(); 
    791795    int addPostInvariant(); 
    792796    void emitComment(Scope *sc); 
    793797    void toJsonBuffer(OutBuffer *buf); 
    794798    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    795799 
    796800    InvariantDeclaration *isInvariantDeclaration() { return this; } 
    797801}; 
    798802 
    799803struct UnitTestDeclaration : FuncDeclaration 
    800804{ 
    801805    UnitTestDeclaration(Loc loc, Loc endloc); 
    802806    Dsymbol *syntaxCopy(Dsymbol *); 
  • trunk/src/glue.c

    r455 r591  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2009 by Digital Mars 
     3// Copyright (c) 1999-2010 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77 
    88#include <stdio.h> 
    99#include <stddef.h> 
    1010#include <time.h> 
    1111#include <assert.h> 
    1212 
    1313#if __sun&&__SVR4 
    1414#include <alloca.h> 
    1515#endif 
    1616 
    1717#include "mars.h" 
    1818#include "module.h" 
    1919#include "mtype.h" 
    2020#include "declaration.h" 
    2121#include "statement.h" 
    2222#include "enum.h" 
    2323#include "aggregate.h" 
     
    339339        t->Tnext = tsvoid; 
    340340        tsvoid->Tcount++; 
    341341 
    342342        static char moddeco[] = "FZv"; 
    343343 
    344344        if (eictor) 
    345345        { 
    346346            localgot = ictorlocalgot; 
    347347 
    348348            block *b = block_calloc(); 
    349349            b->BC = BCret; 
    350350            b->Belem = eictor; 
    351351            sictor->Sfunc->Fstartblock = b; 
    352352            writefunc(sictor); 
    353353        } 
    354354 
    355355        if (ector || ectorgates.dim) 
    356356        { 
    357357            localgot = NULL; 
    358358            sctor = toSymbolX("__modctor", SCglobal, t, moddeco); 
     359#if DMDV2 
    359360            cstate.CSpsymtab = &sctor->Sfunc->Flocsym; 
    360361 
    361362            for (int i = 0; i < ectorgates.dim; i++) 
    362363            {   StaticDtorDeclaration *f = (StaticDtorDeclaration *)ectorgates.data[i]; 
    363364 
    364365                Symbol *s = f->vgate->toSymbol(); 
    365366                elem *e = el_var(s); 
    366367                e = el_bin(OPaddass, TYint, e, el_long(TYint, 1)); 
    367368                ector = el_combine(ector, e); 
    368369            } 
     370#endif 
    369371 
    370372            block *b = block_calloc(); 
    371373            b->BC = BCret; 
    372374            b->Belem = ector; 
    373375            sctor->Sfunc->Fstartblock = b; 
    374376            writefunc(sctor); 
    375377#if STATICCTOR 
    376378            obj_staticctor(sctor, dtorcount, 1); 
    377379#endif 
    378380        } 
    379381 
    380382        if (edtor) 
    381383        { 
    382384            localgot = NULL; 
    383385            sdtor = toSymbolX("__moddtor", SCglobal, t, moddeco); 
    384386 
    385387            block *b = block_calloc(); 
    386388            b->BC = BCret; 
    387389            b->Belem = edtor; 
    388390            sdtor->Sfunc->Fstartblock = b; 
    389391            writefunc(sdtor); 
    390392        } 
    391393 
     394#if DMDV2 
    392395        if (esharedctor || esharedctorgates.dim) 
    393396        { 
    394397            localgot = NULL; 
    395398            ssharedctor = toSymbolX("__modsharedctor", SCglobal, t, moddeco); 
    396399            cstate.CSpsymtab = &ssharedctor->Sfunc->Flocsym; 
    397400 
    398401            for (int i = 0; i < esharedctorgates.dim; i++) 
    399402            {   SharedStaticDtorDeclaration *f = (SharedStaticDtorDeclaration *)esharedctorgates.data[i]; 
    400403 
    401404                Symbol *s = f->vgate->toSymbol(); 
    402405                elem *e = el_var(s); 
    403406                e = el_bin(OPaddass, TYint, e, el_long(TYint, 1)); 
    404407                esharedctor = el_combine(esharedctor, e); 
    405408            } 
    406409 
    407410            block *b = block_calloc(); 
    408411            b->BC = BCret; 
    409412            b->Belem = esharedctor; 
    410413            ssharedctor->Sfunc->Fstartblock = b; 
    411414            writefunc(ssharedctor); 
    412415#if STATICCTOR 
    413416            obj_staticctor(ssharedctor, shareddtorcount, 1); 
    414417#endif 
    415418        } 
    416419 
    417420        if (eshareddtor) 
    418421        { 
    419422            localgot = NULL; 
    420423            sshareddtor = toSymbolX("__modshareddtor", SCglobal, t, moddeco); 
    421424 
    422425            block *b = block_calloc(); 
    423426            b->BC = BCret; 
    424427            b->Belem = eshareddtor; 
    425428            sshareddtor->Sfunc->Fstartblock = b; 
    426429            writefunc(sshareddtor); 
    427430        } 
     431#endif 
    428432 
    429433        if (etest) 
    430434        { 
    431435            localgot = NULL; 
    432436            stest = toSymbolX("__modtest", SCglobal, t, moddeco); 
    433437 
    434438            block *b = block_calloc(); 
    435439            b->BC = BCret; 
    436440            b->Belem = etest; 
    437441            stest->Sfunc->Fstartblock = b; 
    438442            writefunc(stest); 
    439443        } 
    440444 
    441445        if (doppelganger) 
    442446            genmoduleinfo(); 
    443447    } 
    444448 
    445449    if (doppelganger) 
    446450    { 
    447451        obj_termfile(); 
     
    798802        } 
    799803    } 
    800804 
    801805    if (func->fbody) 
    802806    {   block *b; 
    803807        Blockx bx; 
    804808        Statement *sbody; 
    805809 
    806810        localgot = NULL; 
    807811 
    808812        sbody = func->fbody; 
    809813        memset(&bx,0,sizeof(bx)); 
    810814        bx.startblock = block_calloc(); 
    811815        bx.curblock = bx.startblock; 
    812816        bx.funcsym = s; 
    813817        bx.scope_index = -1; 
    814818        bx.classdec = cd; 
    815819        bx.member = func; 
    816820        bx.module = getModule(); 
    817821        irs.blx = &bx; 
    818  
     822#if DMDV2 
    819823        buildClosure(&irs); 
     824#endif 
    820825 
    821826#if 0 
    822827        if (func->isSynchronized()) 
    823828        { 
    824829            if (cd) 
    825830            {   elem *esync; 
    826831                if (func->isStatic()) 
    827832                {   // monitor is in ClassInfo 
    828833                    esync = el_ptr(cd->toSymbol()); 
    829834                } 
    830835                else 
    831836                {   // 'this' is the monitor 
    832837                    esync = el_var(sthis); 
    833838                } 
    834839 
    835840                if (func->isStatic() || sbody->usesEH() || 
    836841                    !(config.flags2 & CFG2seh)) 
    837842                {   // BUG: what if frequire or fensure uses EH? 
    838843 
    839844                    sbody = new SynchronizedStatement(func->loc, esync, sbody); 
     
    873878        bx.curblock->BC = BCret; 
    874879 
    875880        f->Fstartblock = bx.startblock; 
    876881//      einit = el_combine(einit,bx.init); 
    877882 
    878883        if (isCtorDeclaration()) 
    879884        { 
    880885            assert(sthis); 
    881886            for (b = f->Fstartblock; b; b = b->Bnext) 
    882887            { 
    883888                if (b->BC == BCret) 
    884889                { 
    885890                    b->BC = BCretexp; 
    886891                    b->Belem = el_combine(b->Belem, el_var(sthis)); 
    887892                } 
    888893            } 
    889894        } 
    890895    } 
    891896 
    892897    // If static constructor 
     898#if DMDV2 
    893899    if (isSharedStaticCtorDeclaration())        // must come first because it derives from StaticCtorDeclaration 
    894900    { 
    895901        elem *e = el_una(OPucall, TYvoid, el_var(s)); 
    896902        esharedctor = el_combine(esharedctor, e); 
    897903    } 
    898     else if (isStaticCtorDeclaration()) 
     904    else 
     905#endif 
     906    if (isStaticCtorDeclaration()) 
    899907    { 
    900908        elem *e = el_una(OPucall, TYvoid, el_var(s)); 
    901909        ector = el_combine(ector, e); 
    902910    } 
    903911 
    904912    // If static destructor 
     913#if DMDV2 
    905914    if (isSharedStaticDtorDeclaration())        // must come first because it derives from StaticDtorDeclaration 
    906915    { 
    907916        elem *e; 
    908917 
    909918#if STATICCTOR 
    910919        e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_FATEXIT]), el_ptr(s)); 
    911920        esharedctor = el_combine(esharedctor, e); 
    912921        shareddtorcount++; 
    913922#else 
    914923        SharedStaticDtorDeclaration *f = isSharedStaticDtorDeclaration(); 
    915924        assert(f); 
    916925        if (f->vgate) 
    917926        {   /* Increment destructor's vgate at construction time 
    918927             */ 
    919928            esharedctorgates.push(f); 
    920929        } 
    921930 
    922931        e = el_una(OPucall, TYvoid, el_var(s)); 
    923932        eshareddtor = el_combine(e, eshareddtor); 
    924933#endif 
    925934    } 
    926     else if (isStaticDtorDeclaration()) 
     935    else 
     936#endif 
     937    if (isStaticDtorDeclaration()) 
    927938    { 
    928939        elem *e; 
    929940 
    930941#if STATICCTOR 
    931942        e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_FATEXIT]), el_ptr(s)); 
    932943        ector = el_combine(ector, e); 
    933944        dtorcount++; 
    934945#else 
    935946        StaticDtorDeclaration *f = isStaticDtorDeclaration(); 
    936947        assert(f); 
    937948        if (f->vgate) 
    938949        {   /* Increment destructor's vgate at construction time 
    939950             */ 
    940951            ectorgates.push(f); 
    941952        } 
    942953 
    943954        e = el_una(OPucall, TYvoid, el_var(s)); 
    944955        edtor = el_combine(e, edtor); 
    945956#endif 
    946957    }