Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

Changeset 1587:def7a1d494fd

Show
Ignore:
Timestamp:
11/06/09 17:58:01 (2 years ago)
Author:
Christian Kamm <kamm incasoftware de>
branch:
default
Message:

Merge DMD 1.051

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • dmd/aggregate.h

    r1530 r1587  
    6363                // 2: cannot determine size; fwd referenced 
    6464    int isdeprecated;       // !=0 if deprecated 
    65     Scope *scope;       // !=NULL means context to use 
    6665 
    6766    // Special member functions 
     
    6968    NewDeclaration *aggNew;     // allocator 
    7069    DeleteDeclaration *aggDelete;   // deallocator 
     70 
     71#if DMDV2 
     72    //CtorDeclaration *ctor; 
     73    Dsymbol *ctor;          // CtorDeclaration or TemplateDeclaration 
     74    CtorDeclaration *defaultCtor;   // default constructor 
     75    Dsymbol *aliasthis;         // forward unresolved lookups to aliasthis 
     76#endif 
    7177 
    7278    FuncDeclarations dtors; // Array of destructors 
     
    8995 
    9096    void emitComment(Scope *sc); 
     97    void toJsonBuffer(OutBuffer *buf); 
    9198    void toDocBuffer(OutBuffer *buf); 
    9299 
  • dmd/arrayop.c

    r1408 r1587  
    11 
    2 // Copyright (c) 1999-2008 by Digital Mars 
     2// Copyright (c) 1999-2009 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
     
    3232Expression *BinExp::arrayOp(Scope *sc) 
    3333{ 
     34    //printf("BinExp::arrayOp() %s\n", toChars()); 
     35 
     36    if (type->toBasetype()->nextOf()->toBasetype()->ty == Tvoid) 
     37    { 
     38        error("Cannot perform array operations on void[] arrays"); 
     39        return new ErrorExp(); 
     40    } 
     41 
    3442    Expressions *arguments = new Expressions(); 
    3543 
     
    289297        sc->linkage = LINKd; 
    290298        fd->semantic(sc); 
     299        fd->semantic2(sc); 
     300        fd->semantic3(sc); 
    291301        sc->pop(); 
    292302//     } 
     
    319329} 
    320330 
     331void CastExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 
     332{ 
     333    Type *tb = type->toBasetype(); 
     334    if (tb->ty == Tarray || tb->ty == Tsarray) 
     335    { 
     336    e1->buildArrayIdent(buf, arguments); 
     337    } 
     338    else 
     339    Expression::buildArrayIdent(buf, arguments); 
     340} 
     341 
    321342void SliceExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 
    322343{ 
     
    403424} 
    404425 
     426Expression *CastExp::buildArrayLoop(Arguments *fparams) 
     427{ 
     428    Type *tb = type->toBasetype(); 
     429    if (tb->ty == Tarray || tb->ty == Tsarray) 
     430    { 
     431    return e1->buildArrayLoop(fparams); 
     432    } 
     433    else 
     434    return Expression::buildArrayLoop(fparams); 
     435} 
     436 
    405437Expression *SliceExp::buildArrayLoop(Arguments *fparams) 
    406438{ 
     
    421453     */ 
    422454    Expression *ex2 = e2->buildArrayLoop(fparams); 
     455#if DMDV2 
     456    /* Need the cast because: 
     457     *   b = c + p[i]; 
     458     * where b is a byte fails because (c + p[i]) is an int 
     459     * which cannot be implicitly cast to byte. 
     460     */ 
     461    ex2 = new CastExp(0, ex2, e1->type->nextOf()); 
     462#endif 
    423463    Expression *ex1 = e1->buildArrayLoop(fparams); 
    424464    Argument *param = (Argument *)fparams->data[0]; 
     
    489529 
    490530 
     531/*********************************************** 
     532 * Test if operand is a valid array op operand. 
     533 */ 
     534 
     535int Expression::isArrayOperand() 
     536{ 
     537    //printf("Expression::isArrayOperand() %s\n", toChars()); 
     538    if (op == TOKslice) 
     539    return 1; 
     540    if (type->toBasetype()->ty == Tarray) 
     541    { 
     542    switch (op) 
     543    { 
     544        case TOKadd: 
     545        case TOKmin: 
     546        case TOKmul: 
     547        case TOKdiv: 
     548        case TOKmod: 
     549        case TOKxor: 
     550        case TOKand: 
     551        case TOKor: 
     552        case TOKneg: 
     553        case TOKtilde: 
     554        return 1; 
     555 
     556        default: 
     557        break; 
     558    } 
     559    } 
     560    return 0; 
     561} 
  • dmd/attrib.c

    r1392 r1587  
    2727#include "parse.h" 
    2828#include "template.h" 
     29#if TARGET_NET 
     30 #include "frontend.net/pragma.h" 
     31#endif 
    2932 
    3033#if IN_LLVM 
     
    7376    } 
    7477    return m; 
     78} 
     79 
     80void AttribDeclaration::setScopeNewSc(Scope *sc, 
     81    unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, 
     82    unsigned structalign) 
     83{ 
     84    if (decl) 
     85    { 
     86    Scope *newsc = sc; 
     87    if (stc != sc->stc || 
     88        linkage != sc->linkage || 
     89        protection != sc->protection || 
     90        explicitProtection != sc->explicitProtection || 
     91        structalign != sc->structalign) 
     92    { 
     93        // create new one for changes 
     94        newsc = new Scope(*sc); 
     95        newsc->flags &= ~SCOPEfree; 
     96        newsc->stc = stc; 
     97        newsc->linkage = linkage; 
     98        newsc->protection = protection; 
     99        newsc->explicitProtection = explicitProtection; 
     100        newsc->structalign = structalign; 
     101    } 
     102    for (unsigned i = 0; i < decl->dim; i++) 
     103    {   Dsymbol *s = (Dsymbol *)decl->data[i]; 
     104 
     105        s->setScope(newsc); // yes, the only difference from semanticNewSc() 
     106    } 
     107    if (newsc != sc) 
     108    { 
     109        sc->offset = newsc->offset; 
     110        newsc->pop(); 
     111    } 
     112    } 
     113} 
     114 
     115void AttribDeclaration::semanticNewSc(Scope *sc, 
     116    unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, 
     117    unsigned structalign) 
     118{ 
     119    if (decl) 
     120    { 
     121    Scope *newsc = sc; 
     122    if (stc != sc->stc || 
     123        linkage != sc->linkage || 
     124        protection != sc->protection || 
     125        explicitProtection != sc->explicitProtection || 
     126        structalign != sc->structalign) 
     127    { 
     128        // create new one for changes 
     129        newsc = new Scope(*sc); 
     130        newsc->flags &= ~SCOPEfree; 
     131        newsc->stc = stc; 
     132        newsc->linkage = linkage; 
     133        newsc->protection = protection; 
     134        newsc->explicitProtection = explicitProtection; 
     135        newsc->structalign = structalign; 
     136    } 
     137    for (unsigned i = 0; i < decl->dim; i++) 
     138    {   Dsymbol *s = (Dsymbol *)decl->data[i]; 
     139 
     140        s->semantic(newsc); 
     141    } 
     142    if (newsc != sc) 
     143    { 
     144        sc->offset = newsc->offset; 
     145        newsc->pop(); 
     146    } 
     147    } 
    75148} 
    76149 
     
    303376} 
    304377 
     378void StorageClassDeclaration::setScope(Scope *sc) 
     379{ 
     380    if (decl) 
     381    { 
     382    unsigned scstc = sc->stc; 
     383 
     384    /* These sets of storage classes are mutually exclusive, 
     385     * so choose the innermost or most recent one. 
     386     */ 
     387    if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 
     388        scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 
     389    if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared)) 
     390        scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared); 
     391    if (stc & (STCconst | STCimmutable | STCmanifest)) 
     392        scstc &= ~(STCconst | STCimmutable | STCmanifest); 
     393    if (stc & (STCgshared | STCshared | STCtls)) 
     394        scstc &= ~(STCgshared | STCshared | STCtls); 
     395    scstc |= stc; 
     396 
     397    setScopeNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); 
     398    } 
     399} 
     400 
    305401void StorageClassDeclaration::semantic(Scope *sc) 
    306402{ 
    307403    if (decl) 
    308     {   unsigned stc_save = sc->stc; 
    309  
    310     if (stc & (STCauto | STCscope | STCstatic | STCextern)) 
    311         sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 
    312     sc->stc |= stc; 
    313     for (unsigned i = 0; i < decl->dim; i++) 
    314     { 
    315         Dsymbol *s = (Dsymbol *)decl->data[i]; 
    316  
    317         s->semantic(sc); 
    318     } 
    319     sc->stc = stc_save; 
    320     } 
    321     else 
    322     sc->stc = stc; 
     404    { 
     405    unsigned scstc = sc->stc; 
     406 
     407    /* These sets of storage classes are mutually exclusive, 
     408     * so choose the innermost or most recent one. 
     409     */ 
     410    if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 
     411        scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 
     412    if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared)) 
     413        scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared); 
     414    if (stc & (STCconst | STCimmutable | STCmanifest)) 
     415        scstc &= ~(STCconst | STCimmutable | STCmanifest); 
     416    if (stc & (STCgshared | STCshared | STCtls)) 
     417        scstc &= ~(STCgshared | STCshared | STCtls); 
     418    scstc |= stc; 
     419 
     420    semanticNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); 
     421    } 
    323422} 
    324423 
     
    338437    { STCextern,       TOKextern }, 
    339438    { STCconst,        TOKconst }, 
    340 //  { STCinvariant,    TOKimmutable }, 
    341 //  { STCshared,       TOKshared }, 
    342439    { STCfinal,        TOKfinal }, 
    343440    { STCabstract,     TOKabstract }, 
     
    345442    { STCdeprecated,   TOKdeprecated }, 
    346443    { STCoverride,     TOKoverride }, 
    347 //  { STCnothrow,      TOKnothrow }, 
    348 //  { STCpure,         TOKpure }, 
    349 //  { STCref,          TOKref }, 
    350 //  { STCtls,          TOKtls }, 
    351444    }; 
    352445 
     
    385478} 
    386479 
     480void LinkDeclaration::setScope(Scope *sc) 
     481{ 
     482    //printf("LinkDeclaration::setScope(linkage = %d, decl = %p)\n", linkage, decl); 
     483    if (decl) 
     484    { 
     485    setScopeNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); 
     486    } 
     487} 
     488 
    387489void LinkDeclaration::semantic(Scope *sc) 
    388490{ 
    389491    //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl); 
    390492    if (decl) 
    391     {   enum LINK linkage_save = sc->linkage; 
    392  
    393     sc->linkage = linkage; 
    394     for (unsigned i = 0; i < decl->dim; i++) 
    395     { 
    396         Dsymbol *s = (Dsymbol *)decl->data[i]; 
    397  
    398         s->semantic(sc); 
    399     } 
    400     sc->linkage = linkage_save; 
    401     } 
    402     else 
    403     { 
    404     sc->linkage = linkage; 
     493    { 
     494    semanticNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); 
    405495    } 
    406496} 
     
    474564} 
    475565 
     566void ProtDeclaration::setScope(Scope *sc) 
     567{ 
     568    if (decl) 
     569    { 
     570    setScopeNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); 
     571    } 
     572} 
     573 
     574void ProtDeclaration::importAll(Scope *sc) 
     575{ 
     576    Scope *newsc = sc; 
     577    if (sc->protection != protection || 
     578       sc->explicitProtection != 1) 
     579    { 
     580       // create new one for changes 
     581       newsc = new Scope(*sc); 
     582       newsc->flags &= ~SCOPEfree; 
     583       newsc->protection = protection; 
     584       newsc->explicitProtection = 1; 
     585    } 
     586 
     587    for (int i = 0; i < decl->dim; i++) 
     588    { 
     589       Dsymbol *s = (Dsymbol *)decl->data[i]; 
     590       s->importAll(newsc); 
     591    } 
     592 
     593    if (newsc != sc) 
     594       newsc->pop(); 
     595} 
     596 
    476597void ProtDeclaration::semantic(Scope *sc) 
    477598{ 
    478599    if (decl) 
    479     {   enum PROT protection_save = sc->protection; 
    480     int explicitProtection_save = sc->explicitProtection; 
    481  
    482     sc->protection = protection; 
    483     sc->explicitProtection = 1; 
    484     for (unsigned i = 0; i < decl->dim; i++) 
    485     { 
    486         Dsymbol *s = (Dsymbol *)decl->data[i]; 
    487  
    488         s->semantic(sc); 
    489     } 
    490     sc->protection = protection_save; 
    491     sc->explicitProtection = explicitProtection_save; 
    492     } 
    493     else 
    494     {   sc->protection = protection; 
    495     sc->explicitProtection = 1; 
    496     } 
    497 
    498  
    499 void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    500 {   const char *p; 
     600    { 
     601    semanticNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); 
     602    } 
     603
     604 
     605void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, enum PROT protection) 
     606
     607    const char *p; 
    501608 
    502609    switch (protection) 
     
    512619    } 
    513620    buf->writestring(p); 
     621    buf->writeByte(' '); 
     622} 
     623 
     624void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
     625{ 
     626    protectionToCBuffer(buf, protection); 
    514627    AttribDeclaration::toCBuffer(buf, hgs); 
    515628} 
     
    533646} 
    534647 
     648void AlignDeclaration::setScope(Scope *sc) 
     649{ 
     650    //printf("\tAlignDeclaration::setScope '%s'\n",toChars()); 
     651    if (decl) 
     652    { 
     653    setScopeNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); 
     654    } 
     655} 
     656 
    535657void AlignDeclaration::semantic(Scope *sc) 
    536658{ 
     
    538660// we only support packed structs, as from the spec: align(1) struct Packed { ... } 
    539661// other alignments are simply ignored. my tests show this is what llvm-gcc does too ... 
    540  
    541     //printf("\tAlignDeclaration::semantic '%s'\n",toChars()); 
    542     if (decl) 
    543     {   unsigned salign_save = sc->structalign; 
    544  
    545     for (unsigned i = 0; i < decl->dim; i++) 
    546     { 
    547         Dsymbol *s = (Dsymbol *)decl->data[i]; 
    548  
    549         if (s->isStructDeclaration() && salign == 1) 
    550         { 
    551             sc->structalign = salign; 
    552             s->semantic(sc); 
    553             sc->structalign = salign_save; 
    554         } 
    555         else 
    556         { 
    557             s->semantic(sc); 
    558         } 
    559     } 
    560     sc->structalign = salign_save; 
    561     } 
    562     else 
    563     assert(0 && "what kind of align use triggers this?"); 
     662    { 
     663    semanticNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); 
     664    } 
    564665} 
    565666 
     
    578679    this->loc = loc; 
    579680    this->isunion = isunion; 
    580     this->scope = NULL; 
    581681    this->sem = 0; 
    582682} 
     
    781881} 
    782882 
     883void PragmaDeclaration::setScope(Scope *sc) 
     884{ 
     885#if TARGET_NET 
     886    if (ident == Lexer::idPool("assembly")) 
     887    { 
     888        if (!args || args->dim != 1) 
     889        { 
     890            error("pragma has invalid number of arguments"); 
     891        } 
     892        else 
     893        { 
     894            Expression *e = (Expression *)args->data[0]; 
     895            e = e->semantic(sc); 
     896            e = e->optimize(WANTvalue | WANTinterpret); 
     897            args->data[0] = (void *)e; 
     898            if (e->op != TOKstring) 
     899            { 
     900                error("string expected, not '%s'", e->toChars()); 
     901            } 
     902            PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e)); 
     903 
     904            assert(sc); 
     905            pragma->setScope(sc); 
     906 
     907            //add to module members 
     908            assert(sc->module); 
     909            assert(sc->module->members); 
     910            sc->module->members->push(pragma); 
     911        } 
     912    } 
     913#endif // TARGET_NET 
     914} 
     915 
    783916void PragmaDeclaration::semantic(Scope *sc) 
    784917{   // Should be merged with PragmaStatement 
     
    804937        { 
    805938            StringExp *se = (StringExp *)e; 
    806             fprintf(stdmsg, "%.*s", (int)se->len, (char*)se->string); 
     939            fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); 
    807940        } 
    808941        else 
    809             error("string expected for message, not '%s'", e->toChars()); 
     942            fprintf(stdmsg, e->toChars()); 
    810943        } 
    811944        fprintf(stdmsg, "\n"); 
     
    8741007    } 
    8751008#endif 
     1009#if TARGET_NET 
     1010    else if (ident == Lexer::idPool("assembly")) 
     1011    { 
     1012        if (!args || args->dim != 1) 
     1013            error("pragma has invalid number of arguments"); 
     1014        else 
     1015        { 
     1016            Expression *e = (Expression *)args->data[0]; 
     1017            e = e->semantic(sc); 
     1018            e = e->optimize(WANTvalue | WANTinterpret); 
     1019            args->data[0] = (void *)e; 
     1020            if (e->op != TOKstring) 
     1021            { 
     1022                error("string expected, not '%s'", e->toChars()); 
     1023            } 
     1024            PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e)); 
     1025            decl = new Array; 
     1026            decl->push(pragma); 
     1027        } 
     1028    } 
     1029#endif // TARGET_NET 
    8761030 
    8771031// LDC 
     
    10011155 
    10021156#endif // LDC 
     1157 
    10031158 
    10041159    else if (ignoreUnsupportedPragmas) 
     
    12991454} 
    13001455 
     1456void ConditionalDeclaration::setScope(Scope *sc) 
     1457{ 
     1458    Array *d = include(sc, NULL); 
     1459 
     1460    //printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d); 
     1461    if (d) 
     1462    { 
     1463       for (unsigned i = 0; i < d->dim; i++) 
     1464       { 
     1465           Dsymbol *s = (Dsymbol *)d->data[i]; 
     1466 
     1467           s->setScope(sc); 
     1468       } 
     1469    } 
     1470} 
     1471 
     1472void ConditionalDeclaration::importAll(Scope *sc) 
     1473{ 
     1474    Array *d = include(sc, NULL); 
     1475 
     1476    //printf("\tConditionalDeclaration::importAll '%s', d = %p\n",toChars(), d); 
     1477    if (d) 
     1478    { 
     1479       for (unsigned i = 0; i < d->dim; i++) 
     1480       { 
     1481           Dsymbol *s = (Dsymbol *)d->data[i]; 
     1482 
     1483           s->importAll(sc); 
     1484       } 
     1485    } 
     1486} 
    13011487 
    13021488void ConditionalDeclaration::addComment(unsigned char *comment) 
     
    14191605 
    14201606 
     1607void StaticIfDeclaration::importAll(Scope *sc) 
     1608{ 
     1609    // do not evaluate condition before semantic pass 
     1610} 
     1611 
     1612void StaticIfDeclaration::setScope(Scope *sc) 
     1613{ 
     1614    // do not evaluate condition before semantic pass 
     1615} 
     1616 
    14211617void StaticIfDeclaration::semantic(Scope *sc) 
    14221618{ 
  • dmd/attrib.h

    r1228 r1587  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2007 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    3737    virtual Array *include(Scope *sc, ScopeDsymbol *s); 
    3838    int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 
     39    void setScopeNewSc(Scope *sc, 
     40    unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection, 
     41    unsigned structalign); 
     42    void semanticNewSc(Scope *sc, 
     43    unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection, 
     44    unsigned structalign); 
    3945    void semantic(Scope *sc); 
    4046    void semantic2(Scope *sc); 
     
    4955    void addLocalClass(ClassDeclarations *); 
    5056    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     57    void toJsonBuffer(OutBuffer *buf); 
    5158    AttribDeclaration *isAttribDeclaration() { return this; } 
    5259 
     
    6774    StorageClassDeclaration(unsigned stc, Array *decl); 
    6875    Dsymbol *syntaxCopy(Dsymbol *s); 
     76    void setScope(Scope *sc); 
    6977    void semantic(Scope *sc); 
    7078    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    7987    LinkDeclaration(enum LINK p, Array *decl); 
    8088    Dsymbol *syntaxCopy(Dsymbol *s); 
     89    void setScope(Scope *sc); 
    8190    void semantic(Scope *sc); 
    8291    void semantic3(Scope *sc); 
     
    91100    ProtDeclaration(enum PROT p, Array *decl); 
    92101    Dsymbol *syntaxCopy(Dsymbol *s); 
    93     void semantic(Scope *sc); 
    94     void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     102    void importAll(Scope *sc); 
     103    void setScope(Scope *sc); 
     104    void semantic(Scope *sc); 
     105    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     106 
     107    static void protectionToCBuffer(OutBuffer *buf, enum PROT protection); 
    95108}; 
    96109 
     
    101114    AlignDeclaration(Loc loc, unsigned sa, Array *decl); 
    102115    Dsymbol *syntaxCopy(Dsymbol *s); 
     116    void setScope(Scope *sc); 
    103117    void semantic(Scope *sc); 
    104118    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    108122{ 
    109123    int isunion; 
    110     Scope *scope;       // !=NULL means context to use 
    111124    int sem;            // 1 if successful semantic() 
    112125 
     
    125138    Dsymbol *syntaxCopy(Dsymbol *s); 
    126139    void semantic(Scope *sc); 
     140    void setScope(Scope *sc); 
    127141    int oneMember(Dsymbol **ps); 
    128142    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    150164    void addComment(unsigned char *comment); 
    151165    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     166    void toJsonBuffer(OutBuffer *buf); 
     167    void importAll(Scope *sc); 
     168    void setScope(Scope *sc); 
    152169}; 
    153170 
     
    161178    int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 
    162179    void semantic(Scope *sc); 
     180    void importAll(Scope *sc); 
     181    void setScope(Scope *sc); 
    163182    const char *kind(); 
    164183}; 
  • dmd/cast.c

    r1367 r1587  
    10791079Expression *SymOffExp::castTo(Scope *sc, Type *t) 
    10801080{ 
    1081     Type *tb; 
    1082  
    10831081#if 0 
    10841082    printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", 
     
    10871085    Expression *e = this; 
    10881086 
    1089     tb = t->toBasetype(); 
    1090     type = type->toBasetype(); 
    1091     if (tb != type
     1087    Type *tb = t->toBasetype(); 
     1088    Type *typeb = type->toBasetype(); 
     1089    if (tb != typeb
    10921090    { 
    10931091    // Look for pointers to functions where the functions are overloaded. 
    10941092    FuncDeclaration *f; 
    10951093 
    1096     if (type->ty == Tpointer && type->next->ty == Tfunction && 
     1094    if (typeb->ty == Tpointer && typeb->next->ty == Tfunction && 
    10971095        tb->ty == Tpointer && tb->next->ty == Tfunction) 
    10981096    { 
     
    11031101        if (f) 
    11041102        { 
    1105             e = new SymOffExp(loc, f, 0); 
    1106             e->type = t; 
     1103#if DMDV2 
     1104            if (tb->ty == Tdelegate) 
     1105            { 
     1106            if (f->needThis() && hasThis(sc)) 
     1107            { 
     1108                e = new DelegateExp(loc, new ThisExp(loc), f); 
     1109                e = e->semantic(sc); 
     1110            } 
     1111            else if (f->isNested()) 
     1112            { 
     1113                e = new DelegateExp(loc, new IntegerExp(0), f); 
     1114                e = e->semantic(sc); 
     1115            } 
     1116            else if (f->needThis()) 
     1117            {   error("no 'this' to create delegate for %s", f->toChars()); 
     1118                e = new ErrorExp(); 
     1119            } 
     1120            else 
     1121            {   error("cannot cast from function pointer to delegate"); 
     1122                e = new ErrorExp(); 
     1123            } 
     1124            } 
     1125            else 
     1126#endif 
     1127            { 
     1128            e = new SymOffExp(loc, f, 0); 
     1129            e->type = t; 
     1130            } 
     1131#if DMDV2 
     1132            f->tookAddressOf++; 
     1133#endif 
    11071134            return e; 
    11081135        } 
     
    11111138    e = Expression::castTo(sc, t); 
    11121139    } 
    1113     e->type = t; 
     1140    else 
     1141    { 
     1142    e->type = t; 
     1143    } 
    11141144    return e; 
    11151145} 
     
    14851515    assert(0); 
    14861516    } 
    1487     else if (e1->op == TOKslice && t1->ty == Tarray && 
     1517    else if (e1->isArrayOperand() && t1->ty == Tarray && 
    14881518         e2->implicitConvTo(t1->nextOf())) 
    14891519    {   // T[] op T 
     
    14911521    t = t1->nextOf()->arrayOf(); 
    14921522    } 
    1493     else if (e2->op == TOKslice && t2->ty == Tarray && 
     1523    else if (e2->isArrayOperand() && t2->ty == Tarray && 
    14941524         e1->implicitConvTo(t2->nextOf())) 
    14951525    {   // T op T[] 
  • dmd/class.c

    r1530 r1587  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2008 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    162162        Type::typeinfoinvariant = this; 
    163163        } 
     164 
     165        if (id == Id::TypeInfo_Shared) 
     166        {   if (Type::typeinfoshared) 
     167            Type::typeinfoshared->error("%s", msg); 
     168        Type::typeinfoshared = this; 
     169        } 
    164170#endif 
    165171    } 
     
    227233 
    228234    if (!ident)     // if anonymous class 
    229     {   char *id = "__anonclass"; 
     235    {   const char *id = "__anonclass"; 
    230236 
    231237    ident = Identifier::generateId(id); 
    232238    } 
    233239 
    234     if (!scope
    235     { 
    236    if (!parent && sc->parent && !sc->parent->isModule()) 
    237         parent = sc->parent; 
    238  
    239    type = type->semantic(loc, sc); 
    240    handle = handle->semantic(loc, sc)
    241     } 
     240    if (!sc
     241    sc = scope; 
     242    if (!parent && sc->parent && !sc->parent->isModule()) 
     243    parent = sc->parent; 
     244 
     245    type = type->semantic(loc, sc); 
     246    handle = type
     247 
    242248    if (!members)           // if forward reference 
    243249    {   //printf("\tclass '%s' is forward referenced\n", toChars()); 
     
    330336            } 
    331337        } 
     338        if (!tc->sym->symtab || tc->sym->sizeok == 0) 
     339        {   // Try to resolve forward reference 
     340            if (sc->mustsemantic && tc->sym->scope) 
     341            tc->sym->semantic(NULL); 
     342        } 
    332343        if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0) 
    333344        { 
     345            //printf("%s: forward reference of base class %s\n", toChars(), tc->sym->toChars()); 
    334346            //error("forward reference of base class %s", baseClass->toChars()); 
    335347            // Forward reference of base class, try again later 
     
    337349            scope = scx ? scx : new Scope(*sc); 
    338350            scope->setNoFree(); 
     351            if (tc->sym->scope) 
     352                tc->sym->scope->module->addDeferredSemantic(tc->sym); 
    339353            scope->module->addDeferredSemantic(this); 
    340354            return; 
     
    390404        } 
    391405 
     406        if (!tc->sym->symtab) 
     407        {   // Try to resolve forward reference 
     408        if (sc->mustsemantic && tc->sym->scope) 
     409            tc->sym->semantic(NULL); 
     410        } 
     411 
    392412        b->base = tc->sym; 
    393413        if (!b->base->symtab || b->base->scope) 
     
    398418        scope = scx ? scx : new Scope(*sc); 
    399419        scope->setNoFree(); 
     420        if (tc->sym->scope) 
     421            tc->sym->scope->module->addDeferredSemantic(tc->sym); 
    400422        scope->module->addDeferredSemantic(this); 
    401423        return; 
     
    501523        if (s) 
    502524        { 
    503         ClassDeclaration *cd = s->isClassDeclaration(); 
     525        AggregateDeclaration *ad = s->isClassDeclaration(); 
    504526        FuncDeclaration *fd = s->isFuncDeclaration(); 
    505527 
    506528 
    507         if (cd || fd) 
     529        if (ad || fd) 
    508530        {   isnested = 1; 
    509531            Type *t; 
    510             if (cd) 
    511             t = cd->type; 
     532            if (ad) 
     533            t = ad->handle; 
    512534            else if (fd) 
    513535            {   AggregateDeclaration *ad = fd->isMember2(); 
     
    565587    } 
    566588    else 
    567     {   sc->offset = PTRSIZE * 2;   // allow room for vptr[] and monitor 
     589    {   sc->offset = PTRSIZE * 2;   // allow room for __vptr and __monitor 
    568590    alignsize = PTRSIZE; 
    569591    } 
     
    704726    b->type->toCBuffer(buf, NULL, hgs); 
    705727    } 
    706     buf->writenl(); 
    707     buf->writeByte('{'); 
    708     buf->writenl(); 
    709     for (int i = 0; i < members->dim; i++) 
    710     { 
    711     Dsymbol *s = (Dsymbol *)members->data[i]; 
    712  
    713     buf->writestring("    "); 
    714     s->toCBuffer(buf, hgs); 
    715     } 
    716     buf->writestring("}"); 
     728    if (members) 
     729    { 
     730    buf->writenl(); 
     731    buf->writeByte('{'); 
     732    buf->writenl(); 
     733    for (int i = 0; i < members->dim; i++) 
     734    { 
     735        Dsymbol *s = (Dsymbol *)members->data[i]; 
     736 
     737        buf->writestring("    "); 
     738        s->toCBuffer(buf, hgs); 
     739    } 
     740    buf->writestring("}"); 
     741    } 
     742    else 
     743    buf->writeByte(';'); 
    717744    buf->writenl(); 
    718745} 
     
    778805{ 
    779806    Dsymbol *s; 
    780  
    781807    //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 
     808 
    782809    if (scope) 
    783     semantic(scope); 
     810    {   Scope *sc = scope; 
     811    sc->mustsemantic++; 
     812    semantic(sc); 
     813    sc->mustsemantic--; 
     814    } 
    784815 
    785816    if (!members || !symtab || scope) 
    786     {   error("is forward referenced when looking for '%s'", ident->toChars()); 
     817    { 
     818    error("is forward referenced when looking for '%s'", ident->toChars()); 
    787819    //*(char*)0=0; 
    788820    return NULL; 
     
    832864int ClassDeclaration::isFuncHidden(FuncDeclaration *fd) 
    833865{ 
    834     //printf("ClassDeclaration::isFuncHidden(%s)\n", fd->toChars()); 
     866    //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars()); 
    835867    Dsymbol *s = search(0, fd->ident, 4|2); 
    836868    if (!s) 
     
    917949} 
    918950 
     951#if DMDV2 
     952int ClassDeclaration::isCPPinterface() 
     953{ 
     954    return 0; 
     955} 
     956#endif 
     957 
    919958 
    920959/**************************************** 
     
    10071046    if (inuse) 
    10081047    return; 
    1009     if (!scope) 
    1010     {   type = type->semantic(loc, sc); 
    1011     handle = handle->semantic(loc, sc); 
    1012     } 
     1048 
     1049    if (!sc) 
     1050    sc = scope; 
     1051    if (!parent && sc->parent && !sc->parent->isModule()) 
     1052    parent = sc->parent; 
     1053 
     1054    type = type->semantic(loc, sc); 
     1055    handle = type; 
     1056 
    10131057    if (!members)           // if forward reference 
    10141058    {   //printf("\tinterface '%s' is forward referenced\n", toChars()); 
     
    10901134        baseclasses.remove(i); 
    10911135        continue; 
     1136        } 
     1137        if (!b->base->symtab) 
     1138        {   // Try to resolve forward reference 
     1139        if (sc->mustsemantic && b->base->scope) 
     1140            b->base->semantic(NULL); 
    10921141        } 
    10931142        if (!b->base->symtab || b->base->scope || b->base->inuse) 
     
    12631312} 
    12641313 
     1314#if DMDV2 
     1315int InterfaceDeclaration::isCPPinterface() 
     1316{ 
     1317    return cpp; 
     1318} 
     1319#endif 
     1320 
    12651321/******************************************* 
    12661322 */ 
  • dmd/constfold.c

    r1367 r1587  
    7171 
    7272int ComplexExp::isConst() 
     73{ 
     74    return 1; 
     75} 
     76 
     77int NullExp::isConst() 
    7378{ 
    7479    return 1; 
     
    846851    cmp = e1->toComplex() == e2->toComplex(); 
    847852    } 
    848     else if (e1->type->isintegral()
     853    else if (e1->type->isintegral() || e1->type->toBasetype()->ty == Tpointer
    849854    { 
    850855    cmp = (e1->toInteger() == e2->toInteger()); 
     
    863868    int cmp; 
    864869 
    865     if (e1->op == TOKnull && e2->op == TOKnull) 
    866     { 
    867     cmp = 1; 
     870    if (e1->op == TOKnull) 
     871    { 
     872    cmp = (e2->op == TOKnull); 
     873    } 
     874    else if (e2->op == TOKnull) 
     875    { 
     876    cmp = 0; 
    868877    } 
    869878    else if (e1->op == TOKsymoff && e2->op == TOKsymoff) 
     
    10471056 
    10481057    Type *tb = to->toBasetype(); 
    1049     Type *typeb = type->toBasetype(); 
    1050  
    1051     // LDC: ported from D2 to allow char[] ~ char[n] arguments in CTFE 
     1058 
     1059    /* Allow casting from one string type to another 
     1060    */ 
    10521061    if (e1->op == TOKstring) 
    10531062    { 
     1063    Type *typeb = type->toBasetype(); 
    10541064    if (tb->ty == Tarray && typeb->ty == Tarray && 
    10551065        tb->nextOf()->size() == typeb->nextOf()->size()) 
     
    10701080        real_t r = e1->toReal(); 
    10711081 
    1072         switch (typeb->ty) 
     1082        switch (type->toBasetype()->ty) 
    10731083        { 
    10741084        case Tint8: result = (d_int8)r; break; 
  • dmd/declaration.c

    r1538 r1587  
    6868 
    6969int Declaration::isDataseg() 
     70{ 
     71    return FALSE; 
     72} 
     73 
     74int Declaration::isThreadlocal() 
    7075{ 
    7176    return FALSE; 
     
    133138    if (v && v->canassign == 0) 
    134139    { 
    135         char *p = NULL; 
     140        const char *p = NULL; 
    136141        if (isConst()) 
    137142        p = "const"; 
    138143        else if (isInvariant()) 
    139         p = "invariant"; 
     144        p = "immutable"; 
    140145        else if (storage_class & STCmanifest) 
    141         p = "manifest constant"; 
     146        p = "enum"; 
    142147        else if (!t->isAssignable()) 
    143148        p = "struct with immutable members"; 
    144149        if (p) 
    145150        {   error(loc, "cannot modify %s", p); 
    146         halt(); 
    147151        } 
    148152    } 
     
    201205    args->setDim(objects->dim); 
    202206    OutBuffer buf; 
     207    int hasdeco = 1; 
    203208    for (size_t i = 0; i < objects->dim; i++) 
    204209    {   Type *t = (Type *)objects->data[i]; 
     
    214219#endif 
    215220        args->data[i] = (void *)arg; 
     221        if (!t->deco) 
     222        hasdeco = 0; 
    216223    } 
    217224 
    218225    tupletype = new TypeTuple(args); 
     226    if (hasdeco) 
     227        return tupletype->semantic(0, NULL); 
    219228    } 
    220229 
     
    457466     */ 
    458467    s = type->toDsymbol(sc); 
    459     if (s) 
     468    if (s 
     469#if DMDV2 
     470`   && ((s->getType() && type->equals(s->getType())) || s->isEnumMember()) 
     471#endif 
     472    ) 
    460473    goto L2;            // it's a symbolic alias 
    461474 
    462     //printf("alias type is %s\n", type->toChars()); 
    463     type->resolve(loc, sc, &e, &t, &s); 
     475#if DMDV2 
     476    if (storage_class & (STCref | STCnothrow | STCpure)) 
     477    {   // For 'ref' to be attached to function types, and picked 
     478    // up by Type::resolve(), it has to go into sc. 
     479    sc = sc->push(); 
     480    sc->stc |= storage_class & (STCref | STCnothrow | STCpure); 
     481    type->resolve(loc, sc, &e, &t, &s); 
     482    sc = sc->pop(); 
     483    } 
     484    else 
     485#endif 
     486    type->resolve(loc, sc, &e, &t, &s); 
    464487    if (s) 
    465488    { 
     
    524547    } 
    525548    } 
    526     aliassym = s; 
     549    if (!aliassym) 
     550    aliassym = s; 
    527551    this->inSemantic = 0; 
    528552} 
     
    536560    //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars()); 
    537561    if (overnext == NULL) 
    538     {   overnext = s; 
     562    { 
     563    if (s == this) 
     564    { 
     565        return TRUE; 
     566    } 
     567    overnext = s; 
    539568    return TRUE; 
    540569    } 
     
    552581Type *AliasDeclaration::getType() 
    553582{ 
     583    //printf("AliasDeclaration::getType() %s\n", type->toChars()); 
     584#if 0 
     585    if (!type->deco && scope) 
     586    semantic(scope); 
     587    if (type && !type->deco) 
     588    error("forward reference to alias %s\n", toChars()); 
     589#endif 
    554590    return type; 
    555591} 
     
    559595    //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); 
    560596    assert(this != aliassym); 
    561     //static int count; if (++count == 10) *(char*)0=0; 
     597    //static int count; if (++count == 75) exit(0); //*(char*)0=0; 
    562598    if (inSemantic) 
    563599    {   error("recursive alias declaration"); 
     
    621657    offset = 0; 
    622658    noscope = 0; 
     659#if DMDV1 
    623660    nestedref = 0; 
     661#endif 
    624662    ctorinit = 0; 
    625663    aliassym = NULL; 
     
    685723void VarDeclaration::semantic(Scope *sc) 
    686724{ 
    687     //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 
    688     //printf(" type = %s\n", type ? type->toChars() : "null"); 
    689     //printf(" stc = x%x\n", sc->stc); 
    690     //printf(" storage_class = x%x\n", storage_class); 
    691     //printf("linkage = %d\n", sc->linkage); 
     725#if 0 
     726    printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 
     727    printf(" type = %s\n", type ? type->toChars() : "null"); 
     728    printf(" stc = x%x\n", sc->stc); 
     729    printf(" storage_class = x%x\n", storage_class); 
     730    printf("linkage = %d\n", sc->linkage); 
    692731    //if (strcmp(toChars(), "mul") == 0) halt(); 
     732#endif 
    693733 
    694734    storage_class |= sc->stc; 
     
    725765    //printf("sc->stc = %x\n", sc->stc); 
    726766    //printf("storage_class = x%x\n", storage_class); 
     767 
     768#if DMDV2 
     769    if (storage_class & STCgshared && global.params.safe && !sc->module->safe) 
     770    { 
     771    error("__gshared not allowed in safe mode; use shared"); 
     772    } 
     773#endif 
    727774 
    728775    Dsymbol *parent = toParent(); 
     
    833880    if (aad) 
    834881    { 
    835         aad->addField(sc, this); 
     882#if DMDV2 
     883        assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared))); 
     884 
     885        if (storage_class & (STCconst | STCimmutable) && init) 
     886        { 
     887        if (!type->toBasetype()->isTypeBasic()) 
     888            storage_class |= STCstatic; 
     889        } 
     890        else 
     891#endif 
     892        aad->addField(sc, this); 
    836893    } 
    837894 
     
    865922    } 
    866923 
     924#if DMDV2 
     925    if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 
     926    ident != Id::This) 
     927    { 
     928    error("only parameters or foreach declarations can be ref"); 
     929    } 
     930#endif 
     931 
    867932    if (type->isscope() && !noscope) 
    868933    { 
     
    879944    } 
    880945 
     946    enum TOK op = TOKconstruct; 
    881947    if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 
    882948    !(storage_class & (STCfield | STCin | STCforeach)) && 
     
    897963        e1 = new VarExp(loc, this); 
    898964        e = new AssignExp(loc, e1, e); 
    899         e->type = e1->type; 
    900         init = new ExpInitializer(loc, e/*->type->defaultInit()*/); 
     965        e->op = TOKconstruct; 
     966        e->type = e1->type;     // don't type check this, it would fail 
     967        init = new ExpInitializer(loc, e); 
    901968        return; 
    902969    } 
     
    917984        init = getExpInitializer(); 
    918985    } 
     986    // Default initializer is always a blit 
     987    op = TOKblit; 
    919988    } 
    920989 
     
    922991    { 
    923992    sc = sc->push(); 
    924     sc->stc &= ~(STCconst | STCinvariant | STCpure); 
     993    sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCref); 
    925994 
    926995    ArrayInitializer *ai = init->isArrayInitializer(); 
     
    9331002    ExpInitializer *ei = init->isExpInitializer(); 
    9341003 
    935     // See if we can allocate on the stack 
     1004    // See if initializer is a NewExp that can be allocated on the stack 
    9361005    if (ei && isScope() && ei->exp->op == TOKnew) 
    9371006    {   NewExp *ne = (NewExp *)ei->exp; 
     
    9711040 
    9721041        Type *t = type->toBasetype(); 
    973         if (t->ty == Tsarray
     1042        if (t->ty == Tsarray && !(storage_class & (STCref | STCout))
    9741043        { 
    9751044            ei->exp = ei->exp->semantic(sc); 
     
    9921061        { 
    9931062            ei->exp = ei->exp->semantic(sc); 
     1063            ei->exp = resolveProperties(sc, ei->exp); 
     1064            StructDeclaration *sd = ((TypeStruct *)t)->sym; 
     1065#if DMDV2 
     1066            /* Look to see if initializer is a call to the constructor 
     1067             */ 
     1068            if (sd->ctor &&     // there are constructors 
     1069            ei->exp->type->ty == Tstruct && // rvalue is the same struct 
     1070            ((TypeStruct *)ei->exp->type)->sym == sd && 
     1071            ei->exp->op == TOKstar) 
     1072            { 
     1073            /* Look for form of constructor call which is: 
     1074             *    *__ctmp.ctor(arguments...) 
     1075             */ 
     1076            PtrExp *pe = (PtrExp *)ei->exp; 
     1077            if (pe->e1->op == TOKcall) 
     1078            {   CallExp *ce = (CallExp *)pe->e1; 
     1079                if (ce->e1->op == TOKdotvar) 
     1080                {   DotVarExp *dve = (DotVarExp *)ce->e1; 
     1081                if (dve->var->isCtorDeclaration()) 
     1082                {   /* It's a constructor call, currently constructing 
     1083                     * a temporary __ctmp. 
     1084                     */ 
     1085                    /* Before calling the constructor, initialize 
     1086                     * variable with a bit copy of the default 
     1087                     * initializer 
     1088                     */ 
     1089                    Expression *e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc)); 
     1090                    e->op = TOKblit; 
     1091                    e->type = t; 
     1092                    ei->exp = new CommaExp(loc, e, ei->exp); 
     1093 
     1094                    /* Replace __ctmp being constructed with e1 
     1095                     */ 
     1096                    dve->e1 = e1; 
     1097                    return; 
     1098                } 
     1099                } 
     1100            } 
     1101            } 
     1102#endif 
    9941103            if (!ei->exp->implicitConvTo(type)) 
    995             ei->exp = new CastExp(loc, ei->exp, type); 
     1104            { 
     1105            /* Look for opCall 
     1106             * See bugzilla 2702 for more discussion 
     1107             */ 
     1108            Type *ti = ei->exp->type->toBasetype(); 
     1109            // Don't cast away invariant or mutability in initializer 
     1110            if (search_function(sd, Id::call) && 
     1111                /* Initializing with the same type is done differently 
     1112                 */ 
     1113                !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc))) 
     1114            {   // Rewrite as e1.call(arguments) 
     1115                Expression * eCall = new DotIdExp(loc, e1, Id::call); 
     1116                ei->exp = new CallExp(loc, eCall, ei->exp); 
     1117            } 
     1118            } 
    9961119        } 
    9971120        ei->exp = new AssignExp(loc, e1, ei->exp); 
     
    10111134        } 
    10121135    } 
    1013     else if (isConst() || isFinal()) 
     1136    else if (isConst() || isFinal() || 
     1137         parent->isAggregateDeclaration()) 
    10141138    { 
    10151139        /* Because we may need the results of a const declaration in a 
     
    10441168            if (global.gag == 0) 
    10451169            global.errors = errors; // act as if nothing happened 
     1170#if DMDV2 
     1171            /* Save scope for later use, to try again 
     1172             */ 
     1173            scope = new Scope(*sc); 
     1174            scope->setNoFree(); 
     1175#endif 
    10461176        } 
    10471177        else if (ei) 
    10481178        { 
    10491179            e = e->optimize(WANTvalue | WANTinterpret); 
    1050             if (e->op == TOKint64 || e->op == TOKstring
     1180            if (e->op == TOKint64 || e->op == TOKstring || e->op == TOKfloat64
    10511181            { 
    10521182            ei->exp = e;        // no errors, keep result 
    10531183            } 
     1184#if DMDV2 
     1185            else 
     1186            { 
     1187            /* Save scope for later use, to try again 
     1188             */ 
     1189            scope = new Scope(*sc); 
     1190            scope->setNoFree(); 
     1191            } 
     1192#endif 
    10541193        } 
    10551194        else 
     
    11321271    if (init) 
    11331272    {   buf->writestring(" = "); 
    1134     init->toCBuffer(buf, hgs); 
     1273#if DMDV2 
     1274    ExpInitializer *ie = init->isExpInitializer(); 
     1275    if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit)) 
     1276        ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs); 
     1277    else 
     1278#endif 
     1279        init->toCBuffer(buf, hgs); 
    11351280    } 
    11361281    buf->writeByte(';'); 
     
    12111356} 
    12121357 
     1358/************************************ 
     1359 * Does symbol go into thread local storage? 
     1360 */ 
     1361 
     1362int VarDeclaration::isThreadlocal() 
     1363{ 
     1364    return 0; 
     1365} 
     1366 
    12131367int VarDeclaration::hasPointers() 
    12141368{ 
     1369    //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); 
    12151370    return (!isDataseg() && type->hasPointers()); 
    12161371} 
     
    12291384 */ 
    12301385 
    1231 Expression *VarDeclaration::callScopeDtor(
     1386Expression *VarDeclaration::callScopeDtor(Scope *sc
    12321387{   Expression *e = NULL; 
    12331388 
     
    13421497#endif 
    13431498 
     1499/***************************** TypeInfoSharedDeclaration **********************/ 
     1500 
     1501#if DMDV2 
     1502TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo) 
     1503    : TypeInfoDeclaration(tinfo, 0) 
     1504{ 
     1505} 
     1506#endif 
     1507 
    13441508/***************************** TypeInfoStructDeclaration **********************/ 
    13451509 
     
    14511615    storage_class |= STCconst; 
    14521616} 
    1453  
  • dmd/declaration.h

    r1530 r1587  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2008 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    9393}; 
    9494 
    95 void overloadResolveX(Match *m, FuncDeclaration *f, Expressions *arguments, Module* from); 
     95void overloadResolveX(Match *m, FuncDeclaration *f, 
     96    Expression *ethis, Expressions *arguments, Module *from); 
    9697int overloadApply(Module* from, FuncDeclaration *fstart, 
    9798    int (*fp)(void *, FuncDeclaration *), 
     
    116117 
    117118    void emitComment(Scope *sc); 
     119    void toJsonBuffer(OutBuffer *buf); 
    118120    void toDocBuffer(OutBuffer *buf); 
    119121 
     
    124126    virtual int isDelete(); 
    125127    virtual int isDataseg(); 
     128    virtual int isThreadlocal(); 
    126129    virtual int isCodeseg(); 
    127130    int isCtorinit()     { return storage_class & STCctorinit; } 
     
    129132    int isAbstract()     { return storage_class & STCabstract; } 
    130133    int isConst()        { return storage_class & STCconst; } 
    131     int isInvariant()    { return 0; } 
     134    int isInvariant()    { return storage_class & STCinvariant; } 
    132135    int isAuto()         { return storage_class & STCauto; } 
    133136    int isScope()        { return storage_class & STCscope; } 
     
    256259    unsigned offset; 
    257260    int noscope;        // no scope semantics 
     261#if DMDV2 
     262    FuncDeclarations nestedrefs; // referenced by these lexically nested functions 
     263#else 
    258264    int nestedref;      // referenced by a lexically nested function 
     265#endif 
    259266    int ctorinit;       // it has been initialized in a ctor 
    260267    int onstack;        // 1: it has been allocated on the stack 
     
    264271    Expression *value;      // when interpreting, this is the value 
    265272                // (NULL if value not determinable) 
    266     Scope *scope;       // !=NULL means context to use 
     273#if DMDV2 
     274    VarDeclaration *rundtor;    // if !NULL, rundtor is tested at runtime to see 
     275                // if the destructor should be run. Used to prevent 
     276                // dtor calls on postblitted vars 
     277#endif 
    267278 
    268279    VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init); 
     
    279290    int isImportedSymbol(); 
    280291    int isDataseg(); 
     292    int isThreadlocal(); 
    281293    int hasPointers(); 
    282     Expression *callScopeDtor(); 
     294#if DMDV2 
     295    int canTakeAddressOf(); 
     296    int needsAutoDtor(); 
     297#endif 
     298    Expression *callScopeDtor(Scope *sc); 
    283299    ExpInitializer *getExpInitializer(); 
     300    Expression *getConstInitializer(); 
    284301    void checkCtorConstInit(); 
    285302    void checkNestedReference(Scope *sc, Loc loc); 
     
    346363 
    347364    void emitComment(Scope *sc); 
     365    void toJsonBuffer(OutBuffer *buf); 
    348366 
    349367#if IN_DMD 
     
    363381 
    364382    void emitComment(Scope *sc); 
     383    void toJsonBuffer(OutBuffer *buf); 
    365384 
    366385#if IN_DMD 
     
    378397 
    379398    void emitComment(Scope *sc); 
     399    void toJsonBuffer(OutBuffer *buf); 
    380400 
    381401#if IN_DMD 
     
    617637Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments); 
    618638 
     639#else 
     640enum BUILTIN { }; 
    619641#endif 
    620642 
     
    625647    Statement *fensure; 
    626648    Statement *fbody; 
     649 
     650    FuncDeclarations foverrides;    // functions this function overrides 
     651    FuncDeclaration *fdrequire;     // function that does the in contract 
     652    FuncDeclaration *fdensure;      // function that does the out contract 
    627653 
    628654    Identifier *outId;          // identifier for out statement 
     
    659685                    // this one is overriding 
    660686    int inferRetType;           // !=0 if return type is to be inferred 
    661     Scope *scope;           // !=NULL means context to use 
    662687 
    663688    // Things that should really go into Scope 
     
    693718    void semantic2(Scope *sc); 
    694719    void semantic3(Scope *sc); 
     720    // called from semantic3 
     721    void varArgs(Scope *sc, TypeFunction*, VarDeclaration *&, VarDeclaration *&); 
     722 
    695723    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    696724    void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    699727    int overloadInsert(Dsymbol *s); 
    700728    FuncDeclaration *overloadExactMatch(Type *t, Module* from); 
    701     FuncDeclaration *overloadResolve(Loc loc, Expressions *arguments, Module* from); 
     729    FuncDeclaration *overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, Module *from, int flags = 0); 
     730    MATCH leastAsSpecialized(FuncDeclaration *g); 
    702731    LabelDsymbol *searchLabel(Identifier *ident); 
    703732    AggregateDeclaration *isThis(); 
     
    707736    void appendState(Statement *s); 
    708737    char *mangle(); 
     738    const char *toPrettyChars(); 
    709739    int isMain(); 
    710740    int isWinMain(); 
    711741    int isDllMain(); 
     742    enum BUILTIN isBuiltin(); 
    712743    int isExport(); 
    713744    int isImportedSymbol(); 
    714745    int isAbstract(); 
    715746    int isCodeseg(); 
     747    int isOverloadable(); 
     748    int isPure(); 
    716749    virtual int isNested(); 
    717750    int needThis(); 
     
    720753    virtual int addPreInvariant(); 
    721754    virtual int addPostInvariant(); 
    722     Expression *interpret(InterState *istate, Expressions *arguments); 
     755    Expression *interpret(InterState *istate, Expressions *arguments, Expression *thisexp = NULL); 
    723756    void inlineScan(); 
    724757    int canInline(int hasthis, int hdrscan = 0); 
     
    726759    const char *kind(); 
    727760    void toDocBuffer(OutBuffer *buf); 
     761    FuncDeclaration *isUnique(); 
     762    int needsClosure(); 
     763    Statement *mergeFrequire(Statement *); 
     764    Statement *mergeFensure(Statement *); 
    728765 
    729766// LDC: give argument types to runtime functions 
     
    736773    void toObjFile(int multiobj);           // compile to .obj file 
    737774    int cvMember(unsigned char *p); 
     775    void buildClosure(IRState *irs); 
    738776#endif 
    739777 
     
    771809#endif 
    772810}; 
     811 
     812#if DMDV2 
     813FuncDeclaration *resolveFuncCall(Scope *sc, Loc loc, Dsymbol *s, 
     814    Objects *tiargs, 
     815    Expression *ethis, 
     816    Expressions *arguments, 
     817    int flags); 
     818#endif 
    773819 
    774820struct FuncAliasDeclaration : FuncDeclaration 
     
    832878    int overloadInsert(Dsymbol *s); 
    833879    void emitComment(Scope *sc); 
     880    void toJsonBuffer(OutBuffer *buf); 
    834881 
    835882    PostBlitDeclaration *isPostBlitDeclaration() { return this; } 
     
    844891    void semantic(Scope *sc); 
    845892    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     893    const char *kind(); 
     894    char *toChars(); 
    846895    int isVirtual(); 
    847896    int addPreInvariant(); 
     
    849898    int overloadInsert(Dsymbol *s); 
    850899    void emitComment(Scope *sc); 
     900    void toJsonBuffer(OutBuffer *buf); 
    851901 
    852902    DtorDeclaration *isDtorDeclaration() { return this; } 
     
    864914    int addPostInvariant(); 
    865915    void emitComment(Scope *sc); 
     916    void toJsonBuffer(OutBuffer *buf); 
    866917    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    867918 
     
    881932    int addPostInvariant(); 
    882933    void emitComment(Scope *sc); 
     934    void toJsonBuffer(OutBuffer *buf); 
    883935    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    884936 
     
    895947    int addPostInvariant(); 
    896948    void emitComment(Scope *sc); 
     949    void toJsonBuffer(OutBuffer *buf); 
    897950    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    898951 
  • dmd/doc.c

    r1133 r1587  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2008 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    3434#include "doc.h" 
    3535#include "mtype.h" 
     36#include "utf.h" 
    3637 
    3738struct Escape 
     
    9091int isDitto(unsigned char *comment); 
    9192unsigned char *skipwhitespace(unsigned char *p); 
    92 unsigned skiptoident(OutBuffer *buf, unsigned i); 
    93 unsigned skippastident(OutBuffer *buf, unsigned i); 
    94 unsigned skippastURL(OutBuffer *buf, unsigned i); 
     93unsigned skiptoident(OutBuffer *buf, size_t i); 
     94unsigned skippastident(OutBuffer *buf, size_t i); 
     95unsigned skippastURL(OutBuffer *buf, size_t i); 
    9596void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 
    9697void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 
    9798void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 
    9899Argument *isFunctionParameter(Dsymbol *s, unsigned char *p, unsigned len); 
     100 
     101int isIdStart(unsigned char *p); 
     102int isIdTail(unsigned char *p); 
     103int utfStride(unsigned char *p); 
    99104 
    100105static unsigned char ddoc_default[] = "\ 
     
    239244 
    240245    // Set the title to be the name of the module 
    241     {   char *p = toPrettyChars(); 
     246    {   const char *p = toPrettyChars(); 
    242247    Macro::define(&macrotable, (unsigned char *)"TITLE", 5, (unsigned char *)p, strlen(p)); 
    243248    } 
     
    675680#if DMDV2 
    676681    if (d->isInvariant()) 
    677         buf->writestring("invariant "); 
     682        buf->writestring("immutable "); 
    678683#endif 
    679684    if (d->isFinal()) 
     
    949954    unsigned char *pstart; 
    950955    unsigned char *pend; 
    951     unsigned char *q; 
    952956    unsigned char *idstart; 
    953957    unsigned idlen; 
     
    964968 
    965969    /* Find end of section, which is ended by one of: 
    966      *  'identifier:' 
     970     *  'identifier:' (but not inside a code section) 
    967971     *  '\0' 
    968972     */ 
    969973    idlen = 0; 
     974    int inCode = 0; 
    970975    while (1) 
    971976    { 
    972         if (isalpha(*p) || *p == '_') 
     977        // Check for start/end of a code section 
     978        if (*p == '-') 
    973979        { 
    974         q = p + 1; 
    975         while (isalnum(*q) || *q == '_') 
    976             q++; 
     980        int numdash = 0; 
     981        while (*p == '-') 
     982        { 
     983            ++numdash; 
     984            p++; 
     985        } 
     986        // BUG: handle UTF PS and LS too 
     987        if (!*p || *p == '\r' || *p == '\n' && numdash >= 3) 
     988            inCode ^= 1; 
     989        } 
     990 
     991        if (!inCode && isIdStart(p)) 
     992        { 
     993        unsigned char *q = p + utfStride(p); 
     994        while (isIdTail(q)) 
     995            q += utfStride(q); 
    977996        if (*q == ':')  // identifier: ends it 
    978997        {   idlen = q - p; 
     
    11421161    { 
    11431162    // Skip to start of macro 
    1144     for (; 1; p++
     1163    while (1
    11451164    { 
    11461165        switch (*p) 
     
    11481167        case ' ': 
    11491168        case '\t': 
     1169            p++; 
    11501170            continue; 
    11511171 
     
    11551175 
    11561176        default: 
    1157             if (!(isalpha(*p) || *p == '_')) 
    1158             { 
    1159             if (namelen) 
    1160                 goto Ltext;     // continuation of prev macro 
    1161             goto Lskipline; 
    1162             } 
    1163             break; 
     1177            if (isIdStart(p)) 
     1178            break; 
     1179            if (namelen) 
     1180            goto Ltext;     // continuation of prev macro 
     1181            goto Lskipline; 
    11641182        } 
    11651183        break; 
     
    11671185    tempstart = p; 
    11681186 
    1169     while (isalnum(*p) || *p == '_'
    1170         p++
     1187    while (isIdTail(p)
     1188        p += utfStride(p)
    11711189    templen = p - tempstart; 
    11721190 
     
    12701288    { 
    12711289    // Skip to start of macro 
    1272     for (; 1; p++
     1290    while (1
    12731291    { 
    12741292        if (p >= pend) 
     
    12781296        case ' ': 
    12791297        case '\t': 
     1298            p++; 
    12801299            continue; 
    12811300 
     
    12851304 
    12861305        default: 
    1287             if (!(isalpha(*p) || *p == '_')) 
    1288             { 
    1289             if (namelen) 
    1290                 goto Ltext;     // continuation of prev macro 
    1291             goto Lskipline; 
    1292             } 
    1293             break; 
     1306            if (isIdStart(p)) 
     1307            break; 
     1308            if (namelen) 
     1309            goto Ltext;     // continuation of prev macro 
     1310            goto Lskipline; 
    12941311        } 
    12951312        break; 
     
    13011318        if (p >= pend) 
    13021319        goto Ldone; 
    1303         if (!(isalnum(*p) || *p == '_')) 
     1320        if (!isIdTail(p)) 
    13041321        break; 
    1305         p++
     1322        p += utfStride(p)
    13061323    } 
    13071324    templen = p - tempstart; 
     
    14871504 */ 
    14881505 
    1489 unsigned skiptoident(OutBuffer *buf, unsigned i) 
    1490 
    1491     for (; i < buf->offset; i++) 
    1492     { 
    1493     // BUG: handle unicode alpha's 
    1494     unsigned char c = buf->data[i]; 
    1495     if (isalpha(c) || c == '_') 
     1506unsigned skiptoident(OutBuffer *buf, size_t i) 
     1507
     1508    while (i < buf->offset) 
     1509    {   dchar_t c; 
     1510 
     1511    size_t oi = i; 
     1512    if (utf_decodeChar((unsigned char *)buf->data, buf->offset, &i, &c)) 
     1513        /* Ignore UTF errors, but still consume input 
     1514         */ 
    14961515        break; 
    1497     if (c == '\n') 
    1498         break; 
     1516    if (c >= 0x80) 
     1517    { 
     1518        if (!isUniAlpha(c)) 
     1519        continue; 
     1520    } 
     1521    else if (!(isalpha(c) || c == '_' || c == '\n')) 
     1522        continue; 
     1523    i = oi; 
     1524    break; 
    14991525    } 
    15001526    return i; 
     
    15051531 */ 
    15061532 
    1507 unsigned skippastident(OutBuffer *buf, unsigned i) 
    1508 
    1509     for (; i < buf->offset; i++) 
    1510     { 
    1511     // BUG: handle unicode alpha's 
    1512     unsigned char c = buf->data[i]; 
    1513     if (!(isalnum(c) || c == '_')) 
     1533unsigned skippastident(OutBuffer *buf, size_t i) 
     1534
     1535    while (i < buf->offset) 
     1536    {   dchar_t c; 
     1537 
     1538    size_t oi = i; 
     1539    if (utf_decodeChar((unsigned char *)buf->data, buf->offset, &i, &c)) 
     1540        /* Ignore UTF errors, but still consume input 
     1541         */ 
    15141542        break; 
     1543    if (c >= 0x80) 
     1544    { 
     1545        if (isUniAlpha(c)) 
     1546        continue; 
     1547    } 
     1548    else if (isalnum(c) || c == '_') 
     1549        continue; 
     1550    i = oi; 
     1551    break; 
    15151552    } 
    15161553    return i; 
     
    15261563 */ 
    15271564 
    1528 unsigned skippastURL(OutBuffer *buf, unsigned i) 
     1565unsigned skippastURL(OutBuffer *buf, size_t i) 
    15291566{   unsigned length = buf->offset - i; 
    15301567    unsigned char *p = &buf->data[i]; 
     
    18111848        default: 
    18121849        leadingBlank = 0; 
    1813         if (sc && !inCode && (isalpha(c) || c == '_')) 
     1850        if (sc && !inCode && isIdStart(&buf->data[i])) 
    18141851        {   unsigned j; 
    18151852 
     
    18821919        i--;        // point to ';' 
    18831920    } 
    1884     else if (isalpha(c) || c == '_'
     1921    else if (isIdStart(&buf->data[i])
    18851922    {   unsigned j; 
    18861923 
     
    20182055} 
    20192056 
     2057/**************************************** 
     2058 * Determine if p points to the start of an identifier. 
     2059 */ 
     2060 
     2061int isIdStart(unsigned char *p) 
     2062{ 
     2063    unsigned c = *p; 
     2064    if (isalpha(c) || c == '_') 
     2065    return 1; 
     2066    if (c >= 0x80) 
     2067    {   size_t i = 0; 
     2068    if (utf_decodeChar(p, 4, &i, &c)) 
     2069        return 0;   // ignore errors 
     2070    if (isUniAlpha(c)) 
     2071        return 1; 
     2072    } 
     2073    return 0; 
     2074} 
     2075 
     2076/**************************************** 
     2077 * Determine if p points to the rest of an identifier. 
     2078 */ 
     2079 
     2080int isIdTail(unsigned char *p) 
     2081{ 
     2082    unsigned c = *p; 
     2083    if (isalnum(c) || c == '_') 
     2084    return 1; 
     2085    if (c >= 0x80) 
     2086    {   size_t i = 0; 
     2087    if (utf_decodeChar(p, 4, &i, &c)) 
     2088        return 0;   // ignore errors 
     2089    if (isUniAlpha(c)) 
     2090        return 1; 
     2091    } 
     2092    return 0; 
     2093} 
     2094 
     2095/***************************************** 
     2096 * Return number of bytes in UTF character. 
     2097 */ 
     2098 
     2099int utfStride(unsigned char *p) 
     2100{ 
     2101    unsigned c = *p; 
     2102    if (c < 0x80) 
     2103    return 1; 
     2104    size_t i = 0; 
     2105    utf_decodeChar(p, 4, &i, &c);   // ignore errors, but still consume input 
     2106    return i; 
     2107} 
  • dmd/dsymbol.c

    r1358 r1587  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2008 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    2929#include "import.h" 
    3030#include "template.h" 
    31  
     31#include "attrib.h" 
    3232#include "../gen/enums.h" 
    3333 
     
    4646    this->loc = 0; 
    4747    this->comment = NULL; 
    48  
     48    this->scope = NULL; 
    4949#if IN_LLVM 
    5050    this->llvmInternal = LLVMnone; 
     
    6565    this->loc = 0; 
    6666    this->comment = NULL; 
    67  
     67    this->scope = NULL; 
    6868#if IN_LLVM 
    6969    this->llvmInternal = LLVMnone; 
     
    165165} 
    166166 
    167 char *Dsymbol::toPrettyChars() 
     167const char *Dsymbol::toPrettyChars() 
    168168{   Dsymbol *p; 
    169169    char *s; 
     
    191191        break; 
    192192    q--; 
     193#if TARGET_NET 
     194    if (AggregateDeclaration* ad = p->isAggregateDeclaration()) 
     195    { 
     196        if (ad->isNested() && p->parent && p->parent->isAggregateDeclaration()) 
     197        { 
     198            *q = '/'; 
     199            continue; 
     200        } 
     201    } 
     202#endif 
    193203    *q = '.'; 
    194204    } 
     
    267277} 
    268278 
     279/************************************* 
     280 * Set scope for future semantic analysis so we can 
     281 * deal better with forward references. 
     282 */ 
     283 
     284void Dsymbol::setScope(Scope *sc) 
     285{ 
     286    //printf("Dsymbol::setScope() %p %s\n", this, toChars()); 
     287    if (!sc->nofree) 
     288    sc->setNoFree();        // may need it even after semantic() finishes 
     289    scope = sc; 
     290} 
     291 
     292void Dsymbol::importAll(Scope *sc) 
     293{ 
     294} 
     295 
     296/************************************* 
     297 * Does semantic analysis on the public face of declarations. 
     298 */ 
     299 
    269300void Dsymbol::semantic(Scope *sc) 
    270301{ 
     
    272303} 
    273304 
     305/************************************* 
     306 * Does semantic analysis on initializers and members of aggregates. 
     307 */ 
     308 
    274309void Dsymbol::semantic2(Scope *sc) 
    275310{ 
     
    277312} 
    278313 
     314/************************************* 
     315 * Does semantic analysis on function bodies. 
     316 */ 
     317 
    279318void Dsymbol::semantic3(Scope *sc) 
    280319{ 
     
    282321} 
    283322 
     323/************************************* 
     324 * Look for function inlining possibilities. 
     325 */ 
     326 
    284327void Dsymbol::inlineScan() 
    285328{ 
    286     // Most Dsymbols have no further semantic analysis needed 
     329    // Most Dsymbols aren't functions 
    287330} 
    288331 
     
    342385        } 
    343386        ti->tempdecl = td; 
    344         if (!ti->semanticdone
     387        if (!ti->semanticRun
    345388        ti->semantic(sc); 
    346389        sm = ti->toAlias(); 
     
    408451    return FALSE; 
    409452} 
     453 
     454#if DMDV2 
     455int Dsymbol::isOverloadable() 
     456{ 
     457    return 0; 
     458} 
     459#endif 
    410460 
    411461LabelDsymbol *Dsymbol::isLabel()        // is this a LabelDsymbol()? 
     
    440490    if (!isAnonymous())     // no name, so can't add it to symbol table 
    441491    { 
    442     if (!sd->symtab->insert(this))    // if name is already defined 
     492    if (!sd->symtabInsert(this))  // if name is already defined 
    443493    { 
    444494        Dsymbol *s2; 
     
    632682void Dsymbol::addComment(unsigned char *comment) 
    633683{ 
    634 //    if (comment) 
    635 // printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); 
     684    //if (comment) 
     685   //printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); 
    636686 
    637687    if (!this->comment) 
     
    644694#endif 
    645695} 
     696 
     697/********************************* OverloadSet ****************************/ 
     698 
     699#if DMDV2 
     700OverloadSet::OverloadSet() 
     701    : Dsymbol() 
     702{ 
     703} 
     704 
     705void OverloadSet::push(Dsymbol *s) 
     706{ 
     707    a.push(s); 
     708} 
     709 
     710const char *OverloadSet::kind() 
     711{ 
     712    return "overloadset"; 
     713} 
     714#endif 
    646715 
    647716 
     
    682751{ 
    683752    //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags); 
     753    //if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0; 
    684754 
    685755    // Look in symbols declared in this module 
     
    772842 
    773843        ss = (ScopeDsymbol *) imports->data[i]; 
    774         if (ss == s) 
     844        if (ss == s)           // if already imported 
    775845        { 
    776846            if (protection > prots[i]) 
     
    850920} 
    851921 
     922Dsymbol *ScopeDsymbol::symtabInsert(Dsymbol *s) 
     923{ 
     924    return symtab->insert(s); 
     925} 
     926 
     927/*************************************** 
     928 * Determine number of Dsymbols, folding in AttribDeclaration members. 
     929 */ 
     930 
     931#if DMDV2 
     932size_t ScopeDsymbol::dim(Array *members) 
     933{ 
     934    size_t n = 0; 
     935    if (members) 
     936    { 
     937    for (size_t i = 0; i < members->dim; i++) 
     938    {   Dsymbol *s = (Dsymbol *)members->data[i]; 
     939        AttribDeclaration *a = s->isAttribDeclaration(); 
     940 
     941        if (a) 
     942        { 
     943        n += dim(a->decl); 
     944        } 
     945        else 
     946        n++; 
     947    } 
     948    } 
     949    return n; 
     950} 
     951#endif 
     952 
     953/*************************************** 
     954 * Get nth Dsymbol, folding in AttribDeclaration members. 
     955 * Returns: 
     956 *  Dsymbol*    nth Dsymbol 
     957 *  NULL        not found, *pn gets incremented by the number 
     958 *          of Dsymbols 
     959 */ 
     960 
     961#if DMDV2 
     962Dsymbol *ScopeDsymbol::getNth(Array *members, size_t nth, size_t *pn) 
     963{ 
     964    if (!members) 
     965    return NULL; 
     966 
     967    size_t n = 0; 
     968    for (size_t i = 0; i < members->dim; i++) 
     969    {   Dsymbol *s = (Dsymbol *)members->data[i]; 
     970    AttribDeclaration *a = s->isAttribDeclaration(); 
     971 
     972    if (a) 
     973    { 
     974        s = getNth(a->decl, nth - n, &n); 
     975        if (s) 
     976        return s; 
     977    } 
     978    else if (n == nth) 
     979        return s; 
     980    else 
     981        n++; 
     982    } 
     983 
     984    if (pn) 
     985    *pn += n; 
     986    return NULL; 
     987} 
     988#endif 
    852989 
    853990/******************************************* 
     
    9391076 
    9401077    if (td) 
    941     { 
     1078    {   /* $ gives the number of elements in the tuple 
     1079         */ 
    9421080        VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 
    9431081        Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); 
     
    9481086 
    9491087    if (type) 
    950     { 
     1088    {   /* $ gives the number of type entries in the type tuple 
     1089         */ 
    9511090        VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 
    9521091        Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); 
     
    9571096 
    9581097    if (exp->op == TOKindex) 
    959     { 
     1098    {   /* array[index] where index is some function of $ 
     1099         */ 
    9601100        IndexExp *ie = (IndexExp *)exp; 
    9611101 
     
    9641104    } 
    9651105    else if (exp->op == TOKslice) 
    966     { 
     1106    {   /* array[lwr .. upr] where lwr or upr is some function of $ 
     1107         */ 
    9671108        SliceExp *se = (SliceExp *)exp; 
    9681109 
     
    9711112    } 
    9721113    else 
     1114        /* Didn't find $, look in enclosing scope(s). 
     1115         */ 
    9731116        return NULL; 
    9741117 
     1118    /* If we are indexing into an array that is really a type 
     1119     * tuple, rewrite this as an index into a type tuple and 
     1120     * try again. 
     1121     */ 
    9751122    if (ce->op == TOKtype) 
    9761123    { 
     
    9821129    } 
    9831130 
    984     if (!*pvar) 
    985     { 
     1131    /* *pvar is lazily initialized, so if we refer to $ 
     1132     * multiple times, it gets set only once. 
     1133     */ 
     1134    if (!*pvar)     // if not already initialized 
     1135    {   /* Create variable v and set it to the value of $, 
     1136         * which will be a constant. 
     1137         */ 
    9861138        VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 
    9871139 
     
    10311183 
    10321184Dsymbol *DsymbolTable::lookup(Identifier *ident) 
    1033 {   StringValue *sv; 
    1034  
     1185
    10351186#ifdef DEBUG 
    10361187    assert(ident); 
    10371188    assert(tab); 
    10381189#endif 
    1039     sv = tab->lookup((char*)ident->string, ident->len); 
     1190    StringValue *sv = tab->lookup((char*)ident->string, ident->len); 
    10401191    return (Dsymbol *)(sv ? sv->ptrvalue : NULL); 
    10411192} 
  • dmd/dsymbol.h

    r1372 r1587  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2008 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    2929struct DsymbolTable; 
    3030struct Declaration; 
     31struct ThisDeclaration; 
    3132struct TupleDeclaration; 
    3233struct TypedefDeclaration; 
     
    4243struct FuncLiteralDeclaration; 
    4344struct CtorDeclaration; 
     45struct PostBlitDeclaration; 
    4446struct DtorDeclaration; 
    4547struct StaticCtorDeclaration; 
     
    7173struct TypeInfoDeclaration; 
    7274struct ClassInfoDeclaration; 
    73  
     75struct OverloadSet; 
     76#if TARGET_NET 
     77struct PragmaScope; 
     78#endif 
    7479#if IN_DMD 
    7580struct Symbol; 
    7681#endif 
    77  
    7882#if IN_GCC 
    7983union tree_node; 
     
    8286struct TYPE; 
    8387#endif 
     88 
     89// Back end 
     90struct Classsym; 
    8491 
    8592#if IN_LLVM 
     
    115122    unsigned char *comment; // documentation comment for this Dsymbol 
    116123    Loc loc;            // where defined 
     124    Scope *scope;       // !=NULL means context to use for semantic() 
    117125 
    118126    Dsymbol(); 
    119127    Dsymbol(Identifier *); 
    120128    char *toChars(); 
    121     char *toPrettyChars(); 
    122129    char *locToChars(); 
    123130    int equals(Object *o); 
     
    137144    static Array *arraySyntaxCopy(Array *a); 
    138145 
     146    virtual const char *toPrettyChars(); 
    139147    virtual const char *kind(); 
    140148    virtual Dsymbol *toAlias();         // resolve real symbol 
    141149    virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 
     150    virtual void setScope(Scope *sc); 
     151    virtual void importAll(Scope *sc); 
    142152    virtual void semantic(Scope *sc); 
    143153    virtual void semantic2(Scope *sc); 
     
    153163    virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    154164    virtual void toDocBuffer(OutBuffer *buf); 
     165    virtual void toJsonBuffer(OutBuffer *buf); 
    155166    virtual unsigned size(Loc loc); 
    156167    virtual int isforwardRef(); 
     
    161172    virtual int isImportedSymbol();     // is Dsymbol imported? 
    162173    virtual int isDeprecated();         // is Dsymbol deprecated? 
     174#if DMDV2 
     175    virtual int isOverloadable(); 
     176#endif 
    163177    virtual LabelDsymbol *isLabel();        // is this a LabelDsymbol? 
    164178    virtual AggregateDeclaration *isMember();   // is this symbol a member of an AggregateDeclaration? 
     
    199213    virtual TemplateMixin *isTemplateMixin() { return NULL; } 
    200214    virtual Declaration *isDeclaration() { return NULL; } 
     215    virtual ThisDeclaration *isThisDeclaration() { return NULL; } 
    201216    virtual TupleDeclaration *isTupleDeclaration() { return NULL; } 
    202217    virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; } 
     
    207222    virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; } 
    208223    virtual CtorDeclaration *isCtorDeclaration() { return NULL; } 
     224    virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; } 
    209225    virtual DtorDeclaration *isDtorDeclaration() { return NULL; } 
    210226    virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; } 
     
    231247    virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; } 
    232248 
     249    virtual OverloadSet *isOverloadSet() { return NULL; } 
     250#if TARGET_NET 
     251    virtual PragmaScope* isPragmaScope() { return NULL; } 
     252#endif 
     253 
    233254#if IN_LLVM 
    234255    /// Codegen traversal 
     
    251272 
    252273    Array *imports;     // imported ScopeDsymbol's 
    253     unsigned char *prots;   // PROT for each import 
     274    unsigned char *prots;   // array of PROT, one for each import 
    254275 
    255276    ScopeDsymbol(); 
     
    263284    Dsymbol *nameCollision(Dsymbol *s); 
    264285    const char *kind(); 
     286    FuncDeclaration *findGetMembers(); 
     287    virtual Dsymbol *symtabInsert(Dsymbol *s); 
    265288 
    266289    void emitMemberComments(Scope *sc); 
     290 
     291    static size_t dim(Array *members); 
     292    static Dsymbol *getNth(Array *members, size_t nth, size_t *pn = NULL); 
    267293 
    268294    ScopeDsymbol *isScopeDsymbol() { return this; } 
     
    288314    TypeTuple *type;    // for tuple[length] 
    289315    TupleDeclaration *td;   // for tuples of objects 
     316    Scope *sc; 
    290317 
    291318    ArrayScopeSymbol(Expression *e); 
     
    297324}; 
    298325 
     326// Overload Sets 
     327 
     328#if DMDV2 
     329struct OverloadSet : Dsymbol 
     330{ 
     331    Dsymbols a;     // array of Dsymbols 
     332 
     333    OverloadSet(); 
     334    void push(Dsymbol *s); 
     335    OverloadSet *isOverloadSet() { return this; } 
     336    const char *kind(); 
     337}; 
     338#endif 
     339 
    299340// Table of Dsymbol's 
    300341 
  • dmd/enum.h

    r1195 r1587  
    2828 
    2929struct EnumDeclaration : ScopeDsymbol 
    30 
     30{   /* enum ident : memtype { ... } 
     31     */ 
    3132    Type *type;         // the TypeEnum 
    3233    Type *memtype;      // type of the members 
     
    4041    Expression *minval; 
    4142    Expression *defaultval; // default initializer 
    42  
    43     Scope *scope;       // !=NULL means context to use 
    4443#endif 
    4544    int isdeprecated; 
     
    5857 
    5958    void emitComment(Scope *sc); 
     59    void toJsonBuffer(OutBuffer *buf); 
    6060    void toDocBuffer(OutBuffer *buf); 
    6161 
     
    8787 
    8888    void emitComment(Scope *sc); 
     89    void toJsonBuffer(OutBuffer *buf); 
    8990    void toDocBuffer(OutBuffer *buf); 
    9091 
  • dmd/expression.c

    r1530 r1587  
    3636 
    3737#include "rmem.h" 
    38  
    39 //#include "port.h" 
     38#include "port.h" 
     39 
    4040#include "mtype.h" 
    4141#include "init.h" 
     
    374374 
    375375    } 
     376    else if (e->op == TOKdottd) 
     377    { 
     378    e = new CallExp(e->loc, e); 
     379    e = e->semantic(sc); 
     380    } 
    376381    return e; 
    377382} 
     
    544549 
    545550    if (nargs > nparams && tf->varargs == 0) 
    546     error(loc, "expected %zu arguments, not %zu", nparams, nargs); 
     551    error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars()); 
    547552 
    548553    n = (nargs > nparams) ? nargs : nparams;    // n = max(nargs, nparams) 
     
    569574            if (tf->varargs == 2 && i + 1 == nparams) 
    570575            goto L2; 
    571             error(loc, "expected %zu arguments, not %zu", nparams, nargs); 
     576            error(loc, "expected %zu function arguments, not %zu", nparams, nargs); 
    572577            break; 
    573578        } 
     
    591596        { 
    592597            if (nargs != nparams) 
    593                 error(loc, "expected %zu arguments, not %zu", nparams, nargs); 
     598                error(loc, "expected %zu function arguments, not %zu", nparams, nargs); 
    594599            goto L1; 
    595600        } 
     
    670675    L1: 
    671676        if (!(p->storageClass & STClazy && p->type->ty == Tvoid)) 
    672         arg = arg->implicitCastTo(sc, p->type); 
     677        { 
     678        if (p->type != arg->type) 
     679        { 
     680            //printf("arg->type = %s, p->type = %s\n", arg->type->toChars(), p->type->toChars()); 
     681            if (arg->op == TOKtype) 
     682            arg->error("cannot pass type %s as function argument", arg->toChars()); 
     683            arg = arg->implicitCastTo(sc, p->type); 
     684            arg = arg->optimize(WANTvalue); 
     685        } 
     686        } 
    673687        if (p->storageClass & (STCout | STCref)) 
    674688        { 
     
    774788        arg = callCpCtor(loc, sc, arg); 
    775789        } 
     790#endif 
    776791 
    777792        // Give error for overloaded function addresses 
     793#if DMDV2 
    778794        if (arg->op == TOKsymoff) 
    779795        {   SymOffExp *se = (SymOffExp *)arg; 
    780         if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique()) 
     796        if ( 
     797            se->hasOverloads && 
     798            !se->var->isFuncDeclaration()->isUnique()) 
    781799            arg->error("function %s is overloaded", arg->toChars()); 
    782800        } 
     
    12151233{ 
    12161234    //printf("Expression::deref()\n"); 
    1217     if (type->ty == Treference) 
    1218     {  Expression *e; 
    1219  
    1220     e = new PtrExp(loc, this); 
     1235    // type could be null if forward referencing an 'auto' variable 
     1236    if (type && type->ty == Treference) 
     1237    { 
     1238    Expression *e = new PtrExp(loc, this); 
    12211239    e->type = ((TypeReference *)type)->next; 
    12221240    return e; 
     
    21562174    if (f) 
    21572175    {   //printf("'%s' is a function\n", f->toChars()); 
     2176    if (!f->type->deco) 
     2177    { 
     2178        error("forward reference to %s", toChars()); 
     2179    } 
    21582180    return new VarExp(loc, f); 
    21592181    } 
     
    22102232    TemplateInstance *ti = s->isTemplateInstance(); 
    22112233    if (ti && !global.errors) 
    2212     {   if (!ti->semanticdone
     2234    {   if (!ti->semanticRun
    22132235        ti->semantic(sc); 
    22142236    s = ti->inst->toAlias(); 
     
    31673189        {   e = v->init->toExpression(); 
    31683190        if (!e) 
    3169             error("cannot make expression out of initializer for %s", v->toChars()); 
     3191        {   error("cannot make expression out of initializer for %s", v->toChars()); 
     3192            e = new ErrorExp(); 
     3193        } 
     3194        else if (v->scope) 
     3195        {   // Do deferred semantic anaylsis 
     3196            Initializer *i2 = v->init->syntaxCopy(); 
     3197            i2 = i2->semantic(v->scope, v->type); 
     3198            e = i2->toExpression(); 
     3199            v->scope = NULL; 
     3200        } 
    31703201        } 
    31713202        else 
     
    32013232    if (e) 
    32023233    { 
    3203         e = e->copy(); 
    3204         e->type = type; 
     3234        //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars()); 
     3235 
     3236        /* If type is a static array, and e is an initializer for that array, 
     3237         * then the field initializer should be an array literal of e. 
     3238         */ 
     3239        if (e->type != type && type->ty == Tsarray) 
     3240        {   TypeSArray *tsa = (TypeSArray *)type; 
     3241        uinteger_t length = tsa->dim->toInteger(); 
     3242        Expressions *z = new Expressions; 
     3243        z->setDim(length); 
     3244        for (int q = 0; q < length; ++q) 
     3245            z->data[q] = e->copy(); 
     3246        e = new ArrayLiteralExp(loc, z); 
     3247        e->type = type; 
     3248        } 
     3249        else 
     3250        { 
     3251        e = e->copy(); 
     3252        e->type = type; 
     3253        } 
    32053254    } 
    32063255    } 
     
    32173266    /* Find which field offset is by looking at the field offsets 
    32183267     */ 
    3219     for (size_t i = 0; i < sd->fields.dim; i++) 
    3220     { 
    3221     Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 
    3222     VarDeclaration *v = s->isVarDeclaration(); 
    3223     assert(v); 
    3224  
    3225     if (offset == v->offset && 
    3226         type->size() == v->type->size()) 
    3227     {   Expression *e = (Expression *)elements->data[i]; 
    3228         if (e) 
    3229         { 
    3230         return i; 
    3231         } 
    3232         break; 
     3268    if (elements->dim) 
     3269    { 
     3270    for (size_t i = 0; i < sd->fields.dim; i++) 
     3271    { 
     3272        Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 
     3273        VarDeclaration *v = s->isVarDeclaration(); 
     3274        assert(v); 
     3275 
     3276        if (offset == v->offset && 
     3277        type->size() == v->type->size()) 
     3278        {   Expression *e = (Expression *)elements->data[i]; 
     3279        if (e) 
     3280        { 
     3281            return i; 
     3282        } 
     3283        break; 
     3284        } 
    32333285    } 
    32343286    } 
     
    33663418    if (ti && !global.errors) 
    33673419    {   Dsymbol *s; 
    3368     if (!ti->semanticdone
     3420    if (!ti->semanticRun
    33693421        ti->semantic(sc); 
    33703422    s = ti->inst->toAlias(); 
     
    35843636        error("e.new is only for allocating nested classes"); 
    35853637        else if (fdn) 
    3586       { 
     3638      { 
    35873639        // make sure the parent context fdn of cd is reachable from sc 
    35883640        for (Dsymbol *sp = sc->parent; 1; sp = sp->parent) 
     
    36073659    { 
    36083660        assert(f); 
    3609         f = f->overloadResolve(loc, arguments, sc->module); 
     3661        f = f->overloadResolve(loc, NULL, arguments, sc->module); 
    36103662        checkDeprecated(sc, f); 
    36113663        member = f->isCtorDeclaration(); 
     
    36353687        newargs->shift(e); 
    36363688 
    3637         f = cd->aggNew->overloadResolve(loc, newargs, sc->module); 
     3689        f = cd->aggNew->overloadResolve(loc, NULL, newargs, sc->module); 
    36383690        allocator = f->isNewDeclaration(); 
    36393691        assert(allocator); 
     
    36683720        newargs->shift(e); 
    36693721 
    3670         f = f->overloadResolve(loc, newargs, sc->module); 
     3722        f = f->overloadResolve(loc, NULL, newargs, sc->module); 
    36713723        allocator = f->isNewDeclaration(); 
    36723724        assert(allocator); 
     
    42014253    } 
    42024254    type = new TypeTuple(exps); 
     4255    type = type->semantic(loc, sc); 
    42034256    //printf("-TupleExp::semantic(%s)\n", toChars()); 
    42044257    return this; 
     
    42644317    if (global.errors) 
    42654318    { 
    4266         if (!fd->type->next) 
    4267         fd->type->next = Type::terror; 
    42684319    } 
    42694320    else 
    42704321    { 
    42714322        fd->semantic2(sc); 
    4272         if (!global.errors) 
     4323        if (!global.errors || 
     4324        // need to infer return type 
     4325        (fd->type && fd->type->ty == Tfunction && !fd->type->nextOf())) 
    42734326        { 
    42744327        fd->semantic3(sc); 
     
    42784331        } 
    42794332    } 
     4333 
     4334    // need to infer return type 
     4335    if (global.errors && fd->type && fd->type->ty == Tfunction && !fd->type->nextOf()) 
     4336        ((TypeFunction *)fd->type)->next = Type::terror; 
    42804337 
    42814338    // Type is a "delegate to" or "pointer to" the function literal 
     
    43784435    if (!s->isVarDeclaration()) 
    43794436    { 
    4380     declaration->semantic(sc); 
     4437    Scope *sc2 = sc; 
     4438    if (sc2->stc & (STCpure | STCnothrow)) 
     4439        sc2 = sc->push(); 
     4440    sc2->stc &= ~(STCpure | STCnothrow); 
     4441    declaration->semantic(sc2); 
     4442    if (sc2 != sc) 
     4443        sc2->pop(); 
    43814444    s->parent = sc->parent; 
    43824445    } 
     
    49214984    if (op == TOKmodass && e2->type->iscomplex()) 
    49224985    {   error("cannot perform modulo complex arithmetic"); 
    4923         return new IntegerExp(0); 
     4986        return new ErrorExp(); 
    49244987    } 
    49254988    } 
     
    49865049} 
    49875050 
     5051// generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary 
     5052void BinExp::checkComplexMulAssign() 
     5053{ 
     5054    // Any multiplication by an imaginary or complex number yields a complex result. 
     5055    // r *= c, i*=c, r*=i, i*=i are all forbidden operations. 
     5056    const char *opstr = Token::toChars(op); 
     5057    if ( e1->type->isreal() && e2->type->iscomplex()) 
     5058    { 
     5059        error("%s %s %s is undefined. Did you mean %s %s %s.re ?", 
     5060            e1->type->toChars(), opstr, e2->type->toChars(),  
     5061            e1->type->toChars(), opstr, e2->type->toChars()); 
     5062    } 
     5063    else if (e1->type->isimaginary() && e2->type->iscomplex()) 
     5064    { 
     5065        error("%s %s %s is undefined. Did you mean %s %s %s.im ?", 
     5066            e1->type->toChars(), opstr, e2->type->toChars(), 
     5067            e1->type->toChars(), opstr, e2->type->toChars()); 
     5068    } 
     5069    else if ((e1->type->isreal() || e1->type->isimaginary()) && 
     5070    e2->type->isimaginary()) 
     5071    { 
     5072        error("%s %s %s is an undefined operation", e1->type->toChars(), 
     5073        opstr, e2->type->toChars()); 
     5074    } 
     5075} 
     5076 
     5077// generate an error if this is a nonsensical += or -=, eg real += imaginary 
     5078void BinExp::checkComplexAddAssign() 
     5079{ 
     5080    // Addition or subtraction of a real and an imaginary is a complex result. 
     5081    // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations. 
     5082    if ( (e1->type->isreal() && (e2->type->isimaginary() || e2->type->iscomplex())) || 
     5083         (e1->type->isimaginary() && (e2->type->isreal() || e2->type->iscomplex()))         
     5084        ) 
     5085    { 
     5086        error("%s %s %s is undefined (result is complex)", 
     5087        e1->type->toChars(), Token::toChars(op), e2->type->toChars()); 
     5088    } 
     5089} 
     5090 
    49885091void BinExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    49895092{ 
     
    50955198 
    50965199    if (global.params.verbose) 
    5097     printf("file      %s\t(%s)\n", (char*)se->string, name); 
     5200    printf("file      %s\t(%s)\n", (char *)se->string, name); 
    50985201 
    50995202    {   File f(name); 
     
    51785281int AssertExp::canThrow() 
    51795282{ 
    5180     return (global.params.useAssert != 0); 
     5283    /* assert()s are non-recoverable errors, so functions that 
     5284     * use them can be considered "nothrow" 
     5285     */ 
     5286    return 0; //(global.params.useAssert != 0); 
    51815287} 
    51825288#endif 
     
    54805586         ident != Id::alignof && ident != Id::offsetof && 
    54815587         ident != Id::mangleof && ident != Id::stringof) 
    5482     { 
     5588    {   /* Rewrite: 
     5589         *   p.ident 
     5590         * as: 
     5591         *   (*p).ident 
     5592         */ 
    54835593    e = new PtrExp(loc, e1); 
    54845594    e->type = ((TypePointer *)e1->type)->next; 
     
    55995709    if (!type && global.errors) 
    56005710    {   // var is goofed up, just return 0 
    5601         return new IntegerExp(0); 
     5711        return new ErrorExp(); 
    56025712    } 
    56035713    assert(type); 
     
    59366046{ 
    59376047    Expressions *arguments = new Expressions(); 
    5938     arguments->setDim(1); 
    5939     arguments->data[0] = (void *)earg1; 
    5940  
     6048    if (earg1) 
     6049    {   arguments->setDim(1); 
     6050    arguments->data[0] = (void *)earg1; 
     6051    } 
    59416052    this->arguments = arguments; 
    59426053} 
     
    60416152    {   ScopeExp *se = (ScopeExp *)e1; 
    60426153    TemplateInstance *ti = se->sds->isTemplateInstance(); 
    6043     if (ti && !ti->semanticdone
     6154    if (ti && !ti->semanticRun
    60446155    { 
    60456156        /* Attempt to instantiate ti. If that works, go with it. 
     
    60686179    {   DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1; 
    60696180    TemplateInstance *ti = se->ti; 
    6070     if (!ti->semanticdone
     6181    if (!ti->semanticRun
    60716182    { 
    60726183        /* Attempt to instantiate ti. If that works, go with it. 
     
    61646275    { 
    61656276        ad = ((TypeStruct *)t1)->sym; 
     6277#if DMDV2 
     6278        // First look for constructor 
     6279        if (ad->ctor && arguments && arguments->dim) 
     6280        { 
     6281        // Create variable that will get constructed 
     6282        Identifier *idtmp = Lexer::uniqueId("__ctmp"); 
     6283        VarDeclaration *tmp = new VarDeclaration(loc, t1, idtmp, NULL); 
     6284        Expression *av = new DeclarationExp(loc, tmp); 
     6285        av = new CommaExp(loc, av, new VarExp(loc, tmp)); 
     6286 
     6287        Expression *e; 
     6288        CtorDeclaration *cf = ad->ctor->isCtorDeclaration(); 
     6289        if (cf) 
     6290            e = new DotVarExp(loc, av, cf, 1); 
     6291        else 
     6292        {   TemplateDeclaration *td = ad->ctor->isTemplateDeclaration(); 
     6293            assert(td); 
     6294            e = new DotTemplateExp(loc, av, td); 
     6295        } 
     6296        e = new CallExp(loc, e, arguments); 
     6297#if !STRUCTTHISREF 
     6298        /* Constructors return a pointer to the instance 
     6299         */ 
     6300        e = new PtrExp(loc, e); 
     6301#endif 
     6302        e = e->semantic(sc); 
     6303        return e; 
     6304        } 
     6305#endif 
     6306        // No constructor, look for overload of opCall 
    61666307        if (search_function(ad, Id::call)) 
    61676308        goto L1;    // overload of opCall, therefore it's a call 
     
    62066347        f = dve->var->isFuncDeclaration(); 
    62076348        assert(f); 
    6208         f = f->overloadResolve(loc, arguments, sc->module); 
     6349        f = f->overloadResolve(loc, NULL, arguments, sc->module); 
    62096350 
    62106351        ad = f->toParent()->isAggregateDeclaration(); 
     
    63076448        } 
    63086449 
    6309         f = f->overloadResolve(loc, arguments, sc->module); 
     6450        f = f->overloadResolve(loc, NULL, arguments, sc->module); 
    63106451        checkDeprecated(sc, f); 
    63116452#if DMDV2 
     
    63476488 
    63486489        f = cd->ctor; 
    6349         f = f->overloadResolve(loc, arguments, sc->module); 
     6490        f = f->overloadResolve(loc, NULL, arguments, sc->module); 
    63506491        checkDeprecated(sc, f); 
    63516492#if DMDV2 
     
    64416582    } 
    64426583 
    6443     f = f->overloadResolve(loc, arguments, sc->module); 
     6584    f = f->overloadResolve(loc, NULL, arguments, sc->module); 
    64446585    checkDeprecated(sc, f); 
    64456586#if DMDV2 
     
    65246665int CallExp::canThrow() 
    65256666{ 
     6667    //printf("CallExp::canThrow() %s\n", toChars()); 
    65266668    if (e1->canThrow()) 
    65276669    return 1; 
     
    65326674    {   Expression *e = (Expression *)arguments->data[i]; 
    65336675 
    6534     if (e->canThrow()) 
     6676    if (e && e->canThrow()) 
    65356677        return 1; 
    65366678    } 
     6679 
     6680    if (global.errors && !e1->type) 
     6681    return 0;           // error recovery 
    65376682 
    65386683    /* If calling a function or delegate that is typed as nothrow, 
     
    65536698int CallExp::isLvalue() 
    65546699{ 
    6555     if (type->toBasetype()->ty == Tstruct) 
    6556   return 1; 
     6700//    if (type->toBasetype()->ty == Tstruct) 
     6701//    return 1; 
    65576702    Type *tb = e1->type->toBasetype(); 
    65586703    if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref) 
     
    65646709Expression *CallExp::toLvalue(Scope *sc, Expression *e) 
    65656710{ 
     6711#if 1 
    65666712    if (type->toBasetype()->ty == Tstruct) 
    65676713    return this; 
    65686714    else 
     6715#endif 
    65696716    return Expression::toLvalue(sc, e); 
     6717} 
     6718 
     6719Expression *CallExp::modifiableLvalue(Scope *sc, Expression *e) 
     6720{ 
     6721#if 1 
     6722    return Expression::modifiableLvalue(sc, e); 
     6723#else 
     6724    /* Although function return values being usable as "ref" parameters is 
     6725     * unsound, disabling it breaks existing code. 
     6726     * Bugzilla 3167 
     6727     */ 
     6728    error("cannot assign to function call"); 
     6729    return toLvalue(sc, e); 
     6730#endif 
    65706731} 
    65716732 
     
    66016762    { 
    66026763        error("cannot take address of %s", e1->toChars()); 
    6603         type = Type::tint32; 
    6604         return this; 
     6764        return new ErrorExp(); 
     6765    } 
     6766    if (!e1->type->deco) 
     6767    { 
     6768        /* No deco means semantic() was not run on the type. 
     6769         * We have to run semantic() on the symbol to get the right type: 
     6770         *  auto x = &bar; 
     6771         *  pure: int bar() { return 1;} 
     6772         * otherwise the 'pure' is missing from the type assigned to x. 
     6773         */ 
     6774 
     6775        error("forward reference to %s", e1->toChars()); 
     6776        return new ErrorExp(); 
    66056777    } 
    66066778    type = e1->type->pointerTo(); 
     
    66546826    : UnaExp(loc, TOKstar, sizeof(PtrExp), e) 
    66556827{ 
    6656     if (e->type) 
    6657   type = ((TypePointer *)e->type)->next; 
     6828//    if (e->type) 
     6829//    type = ((TypePointer *)e->type)->next; 
    66586830} 
    66596831 
     
    66656837 
    66666838Expression *PtrExp::semantic(Scope *sc) 
    6667 {   Type *tb; 
    6668  
     6839
    66696840#if LOGSEMANTIC 
    66706841    printf("PtrExp::semantic('%s')\n", toChars()); 
    66716842#endif 
    6672     UnaExp::semantic(sc); 
    6673     e1 = resolveProperties(sc, e1); 
    6674     if (type) 
    6675     return this; 
    6676     if (!e1->type) 
    6677     printf("PtrExp::semantic('%s')\n", toChars()); 
    6678     tb = e1->type->toBasetype(); 
    6679     switch (tb->ty) 
    6680     { 
    6681     case Tpointer: 
    6682         type = tb->next; 
    6683         if (type->isbit()) 
    6684         {   Expression *e; 
    6685  
    6686         // Rewrite *p as p[0] 
    6687         e = new IndexExp(loc, e1, new IntegerExp(0)); 
    6688         return e->semantic(sc); 
    6689         } 
    6690         break; 
    6691  
    6692     case Tsarray: 
    6693     case Tarray: 
    6694         type = tb->next; 
    6695         e1 = e1->castTo(sc, type->pointerTo()); 
    6696         break; 
    6697  
    6698     default: 
    6699         error("can only * a pointer, not a '%s'", e1->type->toChars()); 
    6700         type = Type::tint32; 
    6701         break; 
    6702     } 
    6703     rvalue(); 
     6843    if (!type) 
     6844    { 
     6845    UnaExp::semantic(sc); 
     6846    e1 = resolveProperties(sc, e1); 
     6847    if (!e1->type) 
     6848        printf("PtrExp::semantic('%s')\n", toChars()); 
     6849    Type *tb = e1->type->toBasetype(); 
     6850    switch (tb->ty) 
     6851    { 
     6852        case Tpointer: 
     6853        type = tb->next; 
     6854        break; 
     6855 
     6856        case Tsarray: 
     6857        case Tarray: 
     6858        type = tb->next; 
     6859        e1 = e1->castTo(sc, type->pointerTo()); 
     6860        break; 
     6861 
     6862        default: 
     6863        error("can only * a pointer, not a '%s'", e1->type->toChars()); 
     6864        return new ErrorExp(); 
     6865    } 
     6866    rvalue(); 
     6867    } 
    67046868    return this; 
    67056869} 
     
    67676931 
    67686932    e1->checkNoBool(); 
    6769     if (e1->op != TOKslice
     6933    if (!e1->isArrayOperand()
    67706934        e1->checkArithmetic(); 
    67716935    type = e1->type; 
     
    68176981 
    68186982    e1->checkNoBool(); 
    6819     if (e1->op != TOKslice
     6983    if (!e1->isArrayOperand()
    68206984        e1 = e1->checkIntegral(); 
    68216985    type = e1->type; 
     
    70137177    } 
    70147178 
     7179    if (e1->op == TOKtemplate) 
     7180    { 
     7181        error("cannot cast template %s to type %s", e1->toChars(), to->toChars()); 
     7182        return new ErrorExp(); 
     7183    } 
     7184 
     7185    Type *t1b = e1->type->toBasetype(); 
    70157186    Type *tob = to->toBasetype(); 
    70167187    if (tob->ty == Tstruct && 
    7017         !tob->equals(e1->type->toBasetype()) && 
     7188        !tob->equals(t1b) && 
    70187189        ((TypeStruct *)to)->sym->search(0, Id::call, 0) 
    70197190       ) 
     
    70317202        e = e->semantic(sc); 
    70327203        return e; 
     7204    } 
     7205 
     7206    // Struct casts are possible only when the sizes match 
     7207    if (tob->ty == Tstruct || t1b->ty == Tstruct) 
     7208    { 
     7209        size_t fromsize = t1b->size(loc); 
     7210        size_t tosize = tob->size(loc); 
     7211        if (fromsize != tosize) 
     7212        { 
     7213        error("cannot cast from %s to %s", e1->type->toChars(), to->toChars()); 
     7214        return new ErrorExp(); 
     7215        } 
    70337216    } 
    70347217    } 
     
    77387921/************************************************************/ 
    77397922 
    7740 /* Can be TOKconstruct too */ 
     7923/* op can be TOKassign, TOKconstruct, or TOKblit */ 
    77417924 
    77427925AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2) 
     
    77477930 
    77487931Expression *AssignExp::semantic(Scope *sc) 
    7749 {   Type *t1; 
     7932{ 
    77507933    Expression *e1old = e1; 
    77517934 
     
    77547937#endif 
    77557938    //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op)); 
     7939    //printf("e2->op = %d, '%s'\n", e2->op, Token::toChars(e2->op)); 
     7940 
     7941    if (type) 
     7942    return this; 
     7943 
     7944    if (e2->op == TOKcomma) 
     7945    {   /* Rewrite to get rid of the comma from rvalue 
     7946     */ 
     7947    AssignExp *ea = new AssignExp(loc, e1, ((CommaExp *)e2)->e2); 
     7948    ea->op = op; 
     7949    Expression *e = new CommaExp(loc, ((CommaExp *)e2)->e1, ea); 
     7950    return e->semantic(sc); 
     7951    } 
    77567952 
    77577953    /* Look for operator overloading of a[i]=value. 
     
    77607956     */ 
    77617957    if (e1->op == TOKarray) 
    7762     {  Type *t1; 
     7958    { 
    77637959    ArrayExp *ae = (ArrayExp *)e1; 
    77647960    AggregateDeclaration *ad; 
     
    77667962 
    77677963    ae->e1 = ae->e1->semantic(sc); 
    7768     t1 = ae->e1->type->toBasetype(); 
     7964    Type *t1 = ae->e1->type->toBasetype(); 
    77697965    if (t1->ty == Tstruct) 
    77707966    { 
     
    78818077    } 
    78828078 
    7883     t1 = e1->type->toBasetype(); 
     8079    // Determine if this is an initialization of a reference 
     8080    int refinit = 0; 
     8081    if (op == TOKconstruct && e1->op == TOKvar) 
     8082    {   VarExp *ve = (VarExp *)e1; 
     8083    VarDeclaration *v = ve->var->isVarDeclaration(); 
     8084    if (v->storage_class & (STCout | STCref)) 
     8085        refinit = 1; 
     8086    } 
     8087 
     8088    Type *t1 = e1->type->toBasetype(); 
    78848089 
    78858090    if (t1->ty == Tfunction) 
    78868091    {   // Rewrite f=value to f(value) 
    7887     Expression *e; 
    7888  
    7889     e = new CallExp(loc, e1, e2); 
     8092    Expression *e = new CallExp(loc, e1, e2); 
    78908093    e = e->semantic(sc); 
    78918094    return e; 
     
    79198122    {   // Try to do a decent error message with the expression 
    79208123    // before it got constant folded 
    7921     e1 = e1->modifiableLvalue(sc, e1old); 
     8124    if (op != TOKconstruct) 
     8125        e1 = e1->modifiableLvalue(sc, e1old); 
    79228126    } 
    79238127 
     
    79318135    e2 = e2->implicitCastTo(sc, t1->next); 
    79328136    } 
    7933     else if (t1->ty == Tsarray
     8137    else if (t1->ty == Tsarray && !refinit
    79348138    { 
    79358139    error("cannot assign to static array %s", e1->toChars()); 
     
    80628266        e1->checkArithmetic(); 
    80638267        e2->checkArithmetic(); 
     8268        checkComplexAddAssign(); 
    80648269        if (type->isreal() || type->isimaginary()) 
    80658270        { 
     
    81128317    e1 = e1->checkArithmetic(); 
    81138318    e2 = e2->checkArithmetic(); 
     8319    checkComplexAddAssign(); 
    81148320    type = e1->type; 
    81158321    typeCombine(sc); 
     
    82168422    e1->checkArithmetic(); 
    82178423    e2->checkArithmetic(); 
     8424    checkComplexMulAssign(); 
    82188425    if (e2->type->isfloating()) 
    82198426    {   Type *t1; 
     
    82828489    e1->checkArithmetic(); 
    82838490    e2->checkArithmetic(); 
     8491    checkComplexMulAssign(); 
    82848492    if (e2->type->isimaginary()) 
    82858493    {   Type *t1; 
     
    83298537Expression *ModAssignExp::semantic(Scope *sc) 
    83308538{ 
     8539    BinExp::semantic(sc); 
     8540    checkComplexMulAssign(); 
    83318541    return commonSemanticAssign(sc); 
    83328542} 
     
    87378947 
    87388948    typeCombine(sc); 
    8739     if (e1->op != TOKslice && e2->op != TOKslice) 
    8740     {   e1->checkArithmetic(); 
     8949    if (!e1->isArrayOperand()) 
     8950    e1->checkArithmetic(); 
     8951    if (!e2->isArrayOperand()) 
    87418952    e2->checkArithmetic(); 
    8742     } 
    87438953    if (type->isfloating()) 
    87448954    {   Type *t1 = e1->type; 
     
    88039013 
    88049014    typeCombine(sc); 
    8805     if (e1->op != TOKslice && e2->op != TOKslice) 
    8806     {   e1->checkArithmetic(); 
     9015    if (!e1->isArrayOperand()) 
     9016    e1->checkArithmetic(); 
     9017    if (!e2->isArrayOperand()) 
    88079018    e2->checkArithmetic(); 
    8808     } 
    88099019    if (type->isfloating()) 
    88109020    {   Type *t1 = e1->type; 
     
    88709080 
    88719081    typeCombine(sc); 
    8872     if (e1->op != TOKslice && e2->op != TOKslice) 
    8873     {   e1->checkArithmetic(); 
     9082    if (!e1->isArrayOperand()) 
     9083    e1->checkArithmetic(); 
     9084    if (!e2->isArrayOperand()) 
    88749085    e2->checkArithmetic(); 
    8875     } 
    88769086    if (type->isfloating()) 
    88779087    {   type = e1->type; 
     
    89849194    { 
    89859195        typeCombine(sc); 
    8986         if (e1->op != TOKslice && e2->op != TOKslice) 
    8987         {   e1->checkIntegral(); 
     9196        if (!e1->isArrayOperand()) 
     9197        e1->checkIntegral(); 
     9198        if (!e2->isArrayOperand()) 
    89889199        e2->checkIntegral(); 
    8989         } 
    89909200    } 
    89919201    } 
     
    90179227    { 
    90189228        typeCombine(sc); 
    9019         if (e1->op != TOKslice && e2->op != TOKslice) 
    9020         {   e1->checkIntegral(); 
     9229        if (!e1->isArrayOperand()) 
     9230        e1->checkIntegral(); 
     9231        if (!e2->isArrayOperand()) 
    90219232        e2->checkIntegral(); 
    9022         } 
    90239233    } 
    90249234    } 
     
    90509260    { 
    90519261        typeCombine(sc); 
    9052         if (e1->op != TOKslice && e2->op != TOKslice) 
    9053         {   e1->checkIntegral(); 
     9262        if (!e1->isArrayOperand()) 
     9263        e1->checkIntegral(); 
     9264        if (!e2->isArrayOperand()) 
    90549265        e2->checkIntegral(); 
    9055         } 
    90569266    } 
    90579267    } 
     
    92559465Expression *CmpExp::semantic(Scope *sc) 
    92569466{   Expression *e; 
    9257     Type *t1; 
    9258     Type *t2; 
    92599467 
    92609468#if LOGSEMANTIC 
     
    92669474    BinExp::semanticp(sc); 
    92679475 
    9268     if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull || 
    9269     e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull) 
     9476    Type *t1 = e1->type->toBasetype(); 
     9477    Type *t2 = e2->type->toBasetype(); 
     9478    if (t1->ty == Tclass && e2->op == TOKnull || 
     9479    t2->ty == Tclass && e1->op == TOKnull) 
    92709480    { 
    92719481    error("do not use null when comparing class types"); 
     
    92859495    } 
    92869496    return e; 
     9497    } 
     9498 
     9499    /* Disallow comparing T[]==T and T==T[] 
     9500     */ 
     9501    if (e1->op == TOKslice && t1->ty == Tarray && e2->implicitConvTo(t1->nextOf()) || 
     9502    e2->op == TOKslice && t2->ty == Tarray && e1->implicitConvTo(t2->nextOf())) 
     9503    { 
     9504    incompatibleTypes(); 
     9505    return new ErrorExp(); 
    92879506    } 
    92889507 
     
    93389557Expression *EqualExp::semantic(Scope *sc) 
    93399558{   Expression *e; 
    9340     Type *t1; 
    9341     Type *t2; 
    93429559 
    93439560    //printf("EqualExp::semantic('%s')\n", toChars()); 
     
    93689585    } 
    93699586 
    9370     if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull || 
    9371     e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull) 
     9587    Type *t1 = e1->type->toBasetype(); 
     9588    Type *t2 = e2->type->toBasetype(); 
     9589    if (t1->ty == Tclass && e2->op == TOKnull || 
     9590    t2->ty == Tclass && e1->op == TOKnull) 
    93729591    { 
    93739592    error("use '%s' instead of '%s' when comparing with null", 
     
    93889607        return e; 
    93899608    } 
     9609    } 
     9610 
     9611    /* Disallow comparing T[]==T and T==T[] 
     9612     */ 
     9613    if (e1->op == TOKslice && t1->ty == Tarray && e2->implicitConvTo(t1->nextOf()) || 
     9614    e2->op == TOKslice && t2->ty == Tarray && e1->implicitConvTo(t2->nextOf())) 
     9615    { 
     9616    incompatibleTypes(); 
     9617    return new ErrorExp(); 
    93909618    } 
    93919619 
  • dmd/expression.h

    r1499 r1587  
    8282int arrayExpressionCanThrow(Expressions *exps); 
    8383 
     84struct IntRange 
     85{   uinteger_t imin; 
     86    uinteger_t imax; 
     87}; 
     88 
    8489struct Expression : Object 
    8590{ 
     
    158163    virtual void buildArrayIdent(OutBuffer *buf, Expressions *arguments); 
    159164    virtual Expression *buildArrayLoop(Arguments *fparams); 
     165    int isArrayOperand(); 
    160166 
    161167#if IN_DMD 
     
    292298{ 
    293299    Dsymbol *s; 
     300    int hasOverloads; 
    294301 
    295302    DsymbolExp(Loc loc, Dsymbol *s); 
     
    307314    ThisExp(Loc loc); 
    308315    Expression *semantic(Scope *sc); 
     316    Expression *interpret(InterState *istate); 
    309317    int isBool(int result); 
    310318    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    344352    Expression *semantic(Scope *sc); 
    345353    int isBool(int result); 
     354    int isConst(); 
    346355    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    347356    void toMangleBuffer(OutBuffer *buf); 
     
    592601    Expression *syntaxCopy(); 
    593602    Expression *semantic(Scope *sc); 
     603    Expression *optimize(int result); 
    594604#if IN_DMD 
    595605    elem *toElem(IRState *irs); 
     
    843853    Expression *commonSemanticAssignIntegral(Scope *sc); 
    844854    int checkSideEffect(int flag); 
     855    void checkComplexMulAssign(); 
     856    void checkComplexAddAssign(); 
    845857    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    846858    Expression *scaleFactor(Scope *sc); 
     
    10231035    void scanForNestedRef(Scope *sc); 
    10241036    Expression *toLvalue(Scope *sc, Expression *e); 
     1037    Expression *modifiableLvalue(Scope *sc, Expression *e); 
    10251038 
    10261039    int inlineCost(InlineCostState *ics); 
     
    11831196    void checkEscape(); 
    11841197    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     1198    void buildArrayIdent(OutBuffer *buf, Expressions *arguments); 
     1199    Expression *buildArrayLoop(Arguments *fparams); 
    11851200#if IN_DMD 
    11861201    elem *toElem(IRState *irs); 
  • dmd/func.c

    r1530 r1587  
    11// Compiler implementation of the D programming language 
    2 // Copyright (c) 1999-2008 by Digital Mars 
     2// Copyright (c) 1999-2009 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
     
    3636{ 
    3737    //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type); 
     38    //printf("storage_class = x%x\n", storage_class); 
    3839    this->storage_class = storage_class; 
    3940    this->type = type; 
     
    4243    fthrows = NULL; 
    4344    frequire = NULL; 
     45    fdrequire = NULL; 
     46    fdensure = NULL; 
    4447    outId = NULL; 
    4548    vresult = NULL; 
     
    6467    cantInterpret = 0; 
    6568    semanticRun = 0; 
     69#if DMDV1 
    6670    nestedFrameRef = 0; 
     71#endif 
    6772    fes = NULL; 
    6873    introducing = 0; 
     
    7277     */ 
    7378    inferRetType = (type && type->nextOf() == NULL); 
    74     scope = NULL; 
    7579    hasReturnExp = 0; 
    7680    nrvo_can = 1; 
     
    7882#if IN_DMD 
    7983    shidden = NULL; 
     84#endif 
     85 
     86#if DMDV2 
     87    builtin = BUILTINunknown; 
     88    tookAddressOf = 0; 
    8089#endif 
    8190 
     
    143152    if (isFuncLiteralDeclaration()) 
    144153    printf("\tFuncLiteralDeclaration()\n"); 
    145     printf("sc->parent = %s\n", sc->parent->toChars()); 
     154    printf("sc->parent = %s, parent = %s\n", sc->parent->toChars(), parent ? parent->toChars() : ""); 
    146155    printf("type: %p, %s\n", type, type->toChars()); 
    147156#endif 
     
    159168    semanticRun = 1; 
    160169 
    161     if (type->nextOf()) 
     170    if (!type->deco) 
     171    { 
    162172    type = type->semantic(loc, sc); 
     173    } 
    163174    //type->print(); 
    164175    if (type->ty != Tfunction) 
     
    250261 
    251262    if (isCtorDeclaration() || 
     263#if DMDV2 
     264        isPostBlitDeclaration() || 
     265#endif 
    252266        isDtorDeclaration() || 
    253267        isInvariantDeclaration() || 
     
    398412        vtblIndex = vi; 
    399413 
     414        /* Remember which functions this overrides 
     415         */ 
     416        foverrides.push(fdv); 
     417 
    400418        /* This works by whenever this function is called, 
    401419         * it actually returns tintro, which gets dynamically 
     
    444462        {   FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi]; 
    445463            Type *ti = NULL; 
     464 
     465            /* Remember which functions this overrides 
     466             */ 
     467            foverrides.push(fdv); 
    446468 
    447469            if (fdv->tintro) 
     
    601623    } 
    602624 
    603     if (f->nextOf()->ty != Tint32 && f->nextOf()->ty != Tvoid) 
     625    if (!f->nextOf()) 
     626        error("must return int or void"); 
     627    else if (f->nextOf()->ty != Tint32 && f->nextOf()->ty != Tvoid) 
    604628        error("must return int or void, not %s", f->nextOf()->toChars()); 
    605629    if (f->varargs) 
     
    636660    } 
    637661 
     662    if (isVirtual()) 
     663    { 
     664    /* Rewrite contracts as nested functions, then call them. 
     665     * Doing it as nested functions means that overriding functions 
     666     * can call them. 
     667     */ 
     668    if (frequire) 
     669    {   /*   in { ... } 
     670         * becomes: 
     671         *   void __require() { ... } 
     672         *   __require(); 
     673         */ 
     674        Loc loc = frequire->loc; 
     675        TypeFunction *tf = new TypeFunction(NULL, Type::tvoid, 0, LINKd); 
     676        FuncDeclaration *fd = new FuncDeclaration(loc, loc, 
     677        Id::require, STCundefined, tf); 
     678        fd->fbody = frequire; 
     679        Statement *s1 = new DeclarationStatement(loc, fd); 
     680        Expression *e = new CallExp(loc, new VarExp(loc, fd), (Expressions *)NULL); 
     681        Statement *s2 = new ExpStatement(loc, e); 
     682        frequire = new CompoundStatement(loc, s1, s2); 
     683        fdrequire = fd; 
     684    } 
     685 
     686    if (fensure) 
     687    {   /*   out (result) { ... } 
     688         * becomes: 
     689         *   tret __ensure(ref tret result) { ... } 
     690         *   __ensure(result); 
     691         */ 
     692        if (!outId && f->nextOf()->toBasetype()->ty != Tvoid) 
     693        outId = Id::result; // provide a default 
     694 
     695        Loc loc = fensure->loc; 
     696        Arguments *arguments = new Arguments(); 
     697        Argument *a = NULL; 
     698        if (outId) 
     699        {   a = new Argument(STCref, f->nextOf(), outId, NULL); 
     700        arguments->push(a); 
     701        } 
     702        TypeFunction *tf = new TypeFunction(arguments, Type::tvoid, 0, LINKd); 
     703        FuncDeclaration *fd = new FuncDeclaration(loc, loc, 
     704        Id::ensure, STCundefined, tf); 
     705        fd->fbody = fensure; 
     706        Statement *s1 = new DeclarationStatement(loc, fd); 
     707        Expression *eresult = NULL; 
     708        if (outId) 
     709        eresult = new IdentifierExp(loc, outId); 
     710        Expression *e = new CallExp(loc, new VarExp(loc, fd), eresult); 
     711        Statement *s2 = new ExpStatement(loc, e); 
     712        fensure = new CompoundStatement(loc, s1, s2); 
     713        fdensure = fd; 
     714    } 
     715    } 
     716 
    638717Ldone: 
    639718    /* Save scope for possible later use (if we need the 
     
    656735void FuncDeclaration::semantic3(Scope *sc) 
    657736{   TypeFunction *f; 
    658     AggregateDeclaration *ad; 
    659737    VarDeclaration *argptr = NULL; 
    660738    VarDeclaration *_arguments = NULL; 
     
    669747    //printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars()); 
    670748    //fflush(stdout); 
     749    //printf("storage class = x%x %x\n", sc->stc, storage_class); 
    671750    //{ static int x; if (++x == 2) *(char*)0=0; } 
    672751    //printf("\tlinkage = %d\n", sc->linkage); 
     
    684763    return; 
    685764    f = (TypeFunction *)(type); 
    686     size_t nparams = Argument::dim(f->parameters); 
    687765 
    688766    // Check the 'throws' clause 
     
    698776    } 
    699777    } 
     778 
     779    frequire = mergeFrequire(frequire); 
     780    fensure = mergeFensure(fensure); 
    700781 
    701782    if (fbody || frequire) 
     
    728809 
    729810    // Declare 'this' 
    730     ad = isThis(); 
     811    AggregateDeclaration *ad = isThis(); 
    731812    if (ad) 
    732813    {   VarDeclaration *v; 
     
    767848    // Declare hidden variable _arguments[] and _argptr 
    768849    if (f->varargs == 1) 
    769     {   Type *t; 
     850    { 
     851#if TARGET_NET 
     852        varArgs(sc2, f, argptr, _arguments); 
     853#else 
     854        Type *t; 
    770855 
    771856        if (f->linkage == LINKd) 
     
    804889        argptr->parent = this; 
    805890        } 
     891#endif 
    806892    } 
    807893 
     
    825911                } 
    826912            } 
    827             // update nparams to include expanded tuples 
    828             nparams = Argument::dim(f->parameters); 
    829913        } 
    830914#endif 
     
    836920        {   Argument *arg = (Argument *)f->parameters->data[i]; 
    837921 
     922        //printf("[%d] arg->type->ty = %d %s\n", i, arg->type->ty, arg->type->toChars()); 
    838923        if (arg->type->ty == Ttuple) 
    839924        {   TypeTuple *t = (TypeTuple *)arg->type; 
     
    847932    } 
    848933 
    849     // Declare all the function parameters as variables 
     934    /* Declare all the function parameters as variables 
     935     * and install them in parameters[] 
     936     */ 
     937    size_t nparams = Argument::dim(f->parameters); 
    850938    if (nparams) 
    851939    {   /* parameters[] has all the tuples removed, as the back end 
     
    865953            arg->ident = id = Identifier::generateId("_param_", i); 
    866954        } 
    867         VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL); 
     955        Type *vtype = arg->type; 
     956        VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL); 
    868957        //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars()); 
    869958        v->storage_class |= STCparameter; 
     
    9361025    {   /* fensure is composed of the [out] contracts 
    9371026         */ 
     1027        if (!type->nextOf()) 
     1028        {   // Have to do semantic() on fbody first 
     1029        error("post conditions are not supported if the return type is inferred"); 
     1030        return; 
     1031        } 
     1032 
    9381033        ScopeDsymbol *sym = new ScopeDsymbol(); 
    9391034        sym->parent = sc2->scopesym; 
     
    9621057        v = new VarDeclaration(loc, type->nextOf(), outId, NULL); 
    9631058        v->noscope = 1; 
     1059#if DMDV2 
     1060        if (f->isref) 
     1061        { 
     1062            v->storage_class |= STCref | STCforeach; 
     1063        } 
     1064#endif 
    9641065        sc2->incontract--; 
    9651066        v->semantic(sc2); 
     
    10121113        else 
    10131114        {   // Call invariant virtually 
    1014             ThisExp *v = new ThisExp(0); 
     1115            Expression *v = new ThisExp(0); 
    10151116            v->type = vthis->type; 
     1117#if STRUCTTHISREF 
     1118            if (ad->isStructDeclaration()) 
     1119            v = v->addressOf(sc); 
     1120#endif 
    10161121            e = new AssertExp(0, v); 
    10171122        } 
     
    11351240        else if (!inlineAsm) 
    11361241        { 
     1242#if DMDV2 
     1243        int blockexit = fbody ? fbody->blockExit() : BEfallthru; 
     1244        if (f->isnothrow && blockexit & BEthrow) 
     1245            error("'%s' is nothrow yet may throw", toChars()); 
     1246 
     1247        int offend = blockexit & BEfallthru; 
     1248#endif 
    11371249        if (type->nextOf()->ty == Tvoid) 
    11381250        { 
     
    11471259            if (offend) 
    11481260            {   Expression *e; 
    1149  
    1150             warning(loc, "no return at end of function"); 
    1151  
     1261#if DMDV1 
     1262            warning(loc, "no return exp; or assert(0); at end of function"); 
     1263#else 
     1264            error("no return exp; or assert(0); at end of function"); 
     1265#endif 
    11521266            if (global.params.useAssert && 
    11531267                !global.params.useInline) 
     
    12101324        else 
    12111325            p = v_arguments;        // last parameter is _arguments[] 
    1212         offset = p->type->size(); 
     1326        if (p->storage_class & STClazy) 
     1327            // If the last parameter is lazy, it's the size of a delegate 
     1328            offset = PTRSIZE * 2; 
     1329        else 
     1330            offset = p->type->size(); 
    12131331        offset = (offset + 3) & ~3; // assume stack aligns on 4 
    12141332        e = new SymOffExp(0, p, offset); 
     
    12281346        Expression *e1 = new VarExp(0, _arguments); 
    12291347        e = new AssignExp(0, e1, e); 
    1230         e = e->semantic(sc); 
     1348        e->op = TOKconstruct; 
     1349        e = e->semantic(sc2); 
    12311350        a->push(new ExpStatement(0, e)); 
    12321351        } 
     
    12851404                    ThisExp* v = new ThisExp(0); 
    12861405                    v->type = vthis->type; 
     1406#if STRUCTTHISREF 
     1407            if (ad->isStructDeclaration()) 
     1408            v = v->addressOf(sc); 
     1409#endif                     
    12871410                    v->var = vthis; 
    12881411 
     
    13331456 
    13341457        fbody = new CompoundStatement(0, a); 
     1458#if DMDV2 
     1459        /* Append destructor calls for parameters as finally blocks. 
     1460         */ 
     1461        if (parameters) 
     1462        {   for (size_t i = 0; i < parameters->dim; i++) 
     1463        { 
     1464            VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 
     1465 
     1466            if (v->storage_class & (STCref | STCout)) 
     1467            continue; 
     1468 
     1469            /* Don't do this for static arrays, since static 
     1470             * arrays are called by reference. Remove this 
     1471             * when we change them to call by value. 
     1472             */ 
     1473            if (v->type->toBasetype()->ty == Tsarray) 
     1474            continue; 
     1475 
     1476            Expression *e = v->callAutoDtor(sc); 
     1477            if (e) 
     1478            {   Statement *s = new ExpStatement(0, e); 
     1479            s = s->semantic(sc); 
     1480            if (fbody->blockExit() == BEfallthru) 
     1481                fbody = new CompoundStatement(0, fbody, s); 
     1482            else 
     1483                fbody = new TryFinallyStatement(0, fbody, s); 
     1484            } 
     1485        } 
     1486        } 
     1487#endif 
    13351488 
    13361489        // wrap body of synchronized functions in a synchronized statement 
     
    14311584 
    14321585/**************************************************** 
     1586 * Merge into this function the 'in' contracts of all it overrides. 
     1587 * 'in's are OR'd together, i.e. only one of them needs to pass. 
     1588 */ 
     1589 
     1590Statement *FuncDeclaration::mergeFrequire(Statement *sf) 
     1591{ 
     1592    /* Implementing this is done by having the overriding function call 
     1593     * nested functions (the fdrequire functions) nested inside the overridden 
     1594     * function. This requires that the stack layout of the calling function's 
     1595     * parameters and 'this' pointer be in the same place (as the nested 
     1596     * function refers to them). 
     1597     * This is easy for the parameters, as they are all on the stack in the same 
     1598     * place by definition, since it's an overriding function. The problem is 
     1599     * getting the 'this' pointer in the same place, since it is a local variable. 
     1600     * We did some hacks in the code generator to make this happen: 
     1601     *  1. always generate exception handler frame, or at least leave space for it 
     1602     *     in the frame (Windows 32 SEH only) 
     1603     *  2. always generate an EBP style frame 
     1604     *  3. since 'this' is passed in a register that is subsequently copied into 
     1605     *     a stack local, allocate that local immediately following the exception 
     1606     *     handler block, so it is always at the same offset from EBP. 
     1607     */ 
     1608    for (int i = 0; i < foverrides.dim; i++) 
     1609    { 
     1610    FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; 
     1611    sf = fdv->mergeFrequire(sf); 
     1612    if (fdv->fdrequire) 
     1613    { 
     1614        //printf("fdv->frequire: %s\n", fdv->frequire->toChars()); 
     1615        /* Make the call: 
     1616         *   try { __require(); } 
     1617         *   catch { frequire; } 
     1618         */ 
     1619        Expression *eresult = NULL; 
     1620        Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdrequire), eresult); 
     1621        Statement *s2 = new ExpStatement(loc, e); 
     1622 
     1623        if (sf) 
     1624        {   Catch *c = new Catch(loc, NULL, NULL, sf); 
     1625        Array *catches = new Array(); 
     1626        catches->push(c); 
     1627        sf = new TryCatchStatement(loc, s2, catches); 
     1628        } 
     1629        else 
     1630        sf = s2; 
     1631    } 
     1632    } 
     1633    return sf; 
     1634} 
     1635 
     1636/**************************************************** 
     1637 * Merge into this function the 'out' contracts of all it overrides. 
     1638 * 'out's are AND'd together, i.e. all of them need to pass. 
     1639 */ 
     1640 
     1641Statement *FuncDeclaration::mergeFensure(Statement *sf) 
     1642{ 
     1643    /* Same comments as for mergeFrequire(), except that we take care 
     1644     * of generating a consistent reference to the 'result' local by 
     1645     * explicitly passing 'result' to the nested function as a reference 
     1646     * argument. 
     1647     * This won't work for the 'this' parameter as it would require changing 
     1648     * the semantic code for the nested function so that it looks on the parameter 
     1649     * list for the 'this' pointer, something that would need an unknown amount 
     1650     * of tweaking of various parts of the compiler that I'd rather leave alone. 
     1651     */ 
     1652    for (int i = 0; i < foverrides.dim; i++) 
     1653    { 
     1654    FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; 
     1655    sf = fdv->mergeFensure(sf); 
     1656    if (fdv->fdensure) 
     1657    { 
     1658        //printf("fdv->fensure: %s\n", fdv->fensure->toChars()); 
     1659        // Make the call: __ensure(result) 
     1660        Expression *eresult = NULL; 
     1661        if (outId) 
     1662        eresult = new IdentifierExp(loc, outId); 
     1663        Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdensure), eresult); 
     1664        Statement *s2 = new ExpStatement(loc, e); 
     1665 
     1666        if (sf) 
     1667        { 
     1668        sf = new CompoundStatement(fensure->loc, s2, sf); 
     1669        } 
     1670        else 
     1671        sf = s2; 
     1672    } 
     1673    } 
     1674    return sf; 
     1675} 
     1676 
     1677/**************************************************** 
    14331678 * Determine if 'this' overrides fd. 
    14341679 * Return !=0 if it does. 
     
    16051850 
    16061851/******************************************** 
     1852 * If there are no overloads of function f, return that function, 
     1853 * otherwise return NULL. 
     1854 */ 
     1855 
     1856static int fpunique(void *param, FuncDeclaration *f) 
     1857{   FuncDeclaration **pf = (FuncDeclaration **)param; 
     1858 
     1859    if (*pf) 
     1860    {   *pf = NULL; 
     1861    return 1;       // ambiguous, done 
     1862    } 
     1863    else 
     1864    {   *pf = f; 
     1865    return 0; 
     1866    } 
     1867} 
     1868 
     1869FuncDeclaration *FuncDeclaration::isUnique() 
     1870{   FuncDeclaration *result = NULL; 
     1871 
     1872    overloadApply(getModule(), this, &fpunique, &result); 
     1873    return result; 
     1874} 
     1875 
     1876/******************************************** 
    16071877 * Find function in overload list that exactly matches t. 
    16081878 */ 
     
    17482018 
    17492019 
    1750 void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments, Module* from) 
     2020void overloadResolveX(Match *m, FuncDeclaration *fstart, 
     2021    Expression *ethis, Expressions *arguments, Module *from) 
    17512022{ 
    17522023    Param2 p; 
     
    17742045    if (fa) 
    17752046    { 
    1776         overloadResolveX(m, fa->funcalias, arguments); 
     2047        overloadResolveX(m, fa->funcalias, NULL, arguments); 
    17772048        next = fa->overnext; 
    17782049    } 
     
    18382109#endif 
    18392110 
    1840 FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expressions *arguments, Module* from
     2111FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, Module *from, int flags
    18412112{ 
    18422113    TypeFunction *tf; 
     
    18612132    memset(&m, 0, sizeof(m)); 
    18622133    m.last = MATCHnomatch; 
    1863     overloadResolveX(&m, this, arguments, from); 
     2134    overloadResolveX(&m, this, NULL, arguments, from); 
    18642135 
    18652136    if (m.count == 1)       // exactly one match 
     
    20402311} 
    20412312 
     2313const char *FuncDeclaration::toPrettyChars() 
     2314{ 
     2315    if (isMain()) 
     2316    return "D main"; 
     2317    else 
     2318    return Dsymbol::toPrettyChars(); 
     2319} 
    20422320 
    20432321int FuncDeclaration::isMain() 
     
    24052683    tret = cd->type; //->referenceTo(); 
    24062684    type = new TypeFunction(arguments, tret, varargs, LINKd); 
     2685#if STRUCTTHISREF 
     2686    if (ad && ad->isStructDeclaration()) 
     2687    ((TypeFunction *)type)->isref = 1; 
     2688#endif 
    24072689    if (!originalType) 
    24082690    originalType = type; 
     
    24162698    // to the function body 
    24172699    if (fbody) 
    2418     {   Expression *e; 
    2419     Statement *s; 
    2420  
    2421     e = new ThisExp(0); 
    2422     s = new ReturnStatement(0, e); 
    2423     fbody = new CompoundStatement(0, fbody, s); 
     2700    { 
     2701    Expression *e = new ThisExp(loc); 
     2702    Statement *s = new ReturnStatement(loc, e); 
     2703    fbody = new CompoundStatement(loc, fbody, s); 
    24242704    } 
    24252705 
     
    24662746} 
    24672747 
     2748/********************************* PostBlitDeclaration ****************************/ 
     2749 
     2750#if DMDV2 
     2751PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc) 
     2752    : FuncDeclaration(loc, endloc, Id::_postblit, STCundefined, NULL) 
     2753{ 
     2754} 
     2755 
     2756PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc, Identifier *id) 
     2757    : FuncDeclaration(loc, endloc, id, STCundefined, NULL) 
     2758{ 
     2759} 
     2760 
     2761Dsymbol *PostBlitDeclaration::syntaxCopy(Dsymbol *s) 
     2762{ 
     2763    assert(!s); 
     2764    PostBlitDeclaration *dd = new PostBlitDeclaration(loc, endloc, ident); 
     2765    return FuncDeclaration::syntaxCopy(dd); 
     2766} 
     2767 
     2768 
     2769void PostBlitDeclaration::semantic(Scope *sc) 
     2770{ 
     2771    //printf("PostBlitDeclaration::semantic() %s\n", toChars()); 
     2772    //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor); 
     2773    parent = sc->parent; 
     2774    Dsymbol *parent = toParent(); 
     2775    StructDeclaration *ad = parent->isStructDeclaration(); 
     2776    if (!ad) 
     2777    { 
     2778    error("post blits are only for struct/union definitions, not %s %s", parent->kind(), parent->toChars()); 
     2779    } 
     2780    else if (ident == Id::_postblit) 
     2781    ad->postblits.push(this); 
     2782    type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 
     2783 
     2784    sc = sc->push(); 
     2785    sc->stc &= ~STCstatic;      // not static 
     2786    sc->linkage = LINKd; 
     2787 
     2788    FuncDeclaration::semantic(sc); 
     2789 
     2790    sc->pop(); 
     2791} 
     2792 
     2793int PostBlitDeclaration::overloadInsert(Dsymbol *s) 
     2794{ 
     2795    return FALSE;   // cannot overload postblits 
     2796} 
     2797 
     2798int PostBlitDeclaration::addPreInvariant() 
     2799{ 
     2800    return FALSE; 
     2801} 
     2802 
     2803int PostBlitDeclaration::addPostInvariant() 
     2804{ 
     2805    return (isThis() && vthis && global.params.useInvariants); 
     2806} 
     2807 
     2808int PostBlitDeclaration::isVirtual() 
     2809{ 
     2810    return FALSE; 
     2811} 
     2812 
     2813void PostBlitDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
     2814{ 
     2815    if (hgs->hdrgen) 
     2816    return; 
     2817    buf->writestring("=this()"); 
     2818    bodyToCBuffer(buf, hgs); 
     2819} 
     2820#endif 
     2821 
    24682822/********************************* DtorDeclaration ****************************/ 
    24692823 
     
    24882842void DtorDeclaration::semantic(Scope *sc) 
    24892843{ 
    2490     ClassDeclaration *cd
    2491  
     2844    //printf("DtorDeclaration::semantic() %s\n", toChars())
     2845    //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor); 
    24922846    parent = sc->parent; 
    24932847    Dsymbol *parent = toParent(); 
    2494     cd = parent->isClassDeclaration(); 
     2848    ClassDeclaration *cd = parent->isClassDeclaration(); 
    24952849    if (!cd) 
    24962850    { 
    2497     error("destructors only are for class definitions"); 
     2851    error("destructors are only for class/struct/union definitions, not %s %s", parent->kind(), parent->toChars()); 
    24982852    fatal(); 
    24992853    } 
     
    25242878{ 
    25252879    return FALSE; 
     2880} 
     2881 
     2882const char *DtorDeclaration::kind() 
     2883{    
     2884    return "destructor"; 
     2885} 
     2886 
     2887char *DtorDeclaration::toChars() 
     2888{ 
     2889    return (char *)"~this"; 
    25262890} 
    25272891 
     
    28643228    } 
    28653229 
     3230#if 0 
    28663231    // We're going to need ModuleInfo even if the unit tests are not 
    28673232    // compiled in, because other modules may import this module and refer 
    28683233    // to this ModuleInfo. 
     3234    // (This doesn't make sense to me?) 
    28693235    Module *m = getModule(); 
    28703236    if (!m) 
    28713237    m = sc->module; 
    28723238    if (m) 
     3239    { 
     3240    //printf("module3 %s needs moduleinfo\n", m->toChars()); 
    28733241    m->needmoduleinfo = 1; 
     3242    } 
     3243#endif 
    28743244} 
    28753245 
  • dmd/idgen.c

    r1152 r1587  
    3939    { "classInvariant", "__invariant" }, 
    4040    { "unitTest", "_unitTest" }, 
     41    { "require", "__require" }, 
     42    { "ensure", "__ensure" }, 
    4143    { "init" }, 
    4244    { "size" }, 
     
    208210    { "aaValues", "_aaValues" }, 
    209211    { "aaRehash", "_aaRehash" }, 
     212    { "monitorenter", "_d_monitorenter" }, 
     213    { "monitorexit", "_d_monitorexit" }, 
     214    { "criticalenter", "_d_criticalenter" }, 
     215    { "criticalexit", "_d_criticalexit" }, 
    210216 
    211217    // For pragma's 
  • dmd/import.c

    r1402 r1587  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2006 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    2222#include "declaration.h" 
    2323#include "id.h" 
     24#include "attrib.h" 
    2425 
    2526/********************************* Import ****************************/ 
     
    2930    : Dsymbol(id) 
    3031{ 
     32    assert(id); 
    3133    this->loc = loc; 
    3234    this->packages = packages; 
     
    8587void Import::load(Scope *sc) 
    8688{ 
    87     DsymbolTable *dst; 
    88     Dsymbol *s; 
    89  
    9089    //printf("Import::load('%s')\n", toChars()); 
    9190 
    9291    // See if existing module 
    93     dst = Package::resolve(packages, NULL, &pkg); 
    94  
    95     s = dst->lookup(id); 
     92    DsymbolTable *dst = Package::resolve(packages, NULL, &pkg); 
     93 
     94    Dsymbol *s = dst->lookup(id); 
    9695    if (s) 
    9796    { 
     97#if TARGET_NET 
     98    mod = (Module *)s; 
     99#else 
    98100    if (s->isModule()) 
    99101        mod = (Module *)s; 
    100102    else 
    101103        error("package and module have the same name"); 
     104#endif 
    102105    } 
    103106 
     
    117120} 
    118121 
    119 char* escapePath(char* fname, char* buffer, int bufLen) { 
    120     char* res = buffer; 
    121     bufLen -= 2;    // for \0 and an occasional escape char 
    122     int dst = 0; 
    123     for (; dst < bufLen && *fname; ++dst, ++fname) { 
    124     switch (*fname) { 
     122void escapePath(OutBuffer *buf, const char *fname) 
     123
     124    while (1) 
     125    { 
     126    switch (*fname) 
     127    { 
     128        case 0: 
     129        return; 
    125130        case '(': 
    126131        case ')': 
    127132        case '\\': 
    128             buffer[dst++] = '\\'; 
    129             // fall through 
    130  
     133        buf->writebyte('\\'); 
    131134        default: 
    132             buffer[dst] = *fname; 
    133     } 
    134     } 
    135     buffer[dst] = '\0'; 
    136     return buffer; 
     135        buf->writebyte(*fname); 
     136        break; 
     137    } 
     138    fname++; 
     139    } 
     140
     141 
     142void Import::importAll(Scope *sc) 
     143
     144    if (!mod) 
     145    { 
     146       load(sc); 
     147       mod->importAll(0); 
     148 
     149       if (!isstatic && !aliasId && !names.dim) 
     150       { 
     151           /* Default to private importing 
     152            */ 
     153           enum PROT prot = sc->protection; 
     154           if (!sc->explicitProtection) 
     155               prot = PROTprivate; 
     156           sc->scopesym->importScope(mod, prot); 
     157       } 
     158    } 
    137159} 
    138160 
     
    141163    //printf("Import::semantic('%s')\n", toChars()); 
    142164 
    143     load(sc); 
     165    // Load if not already done so 
     166    if (!mod) 
     167    {   load(sc); 
     168    mod->importAll(0); 
     169    } 
    144170 
    145171    if (mod) 
     
    159185    sc->module->aimports.push(mod); 
    160186 
    161     mod->semantic(); 
    162  
    163187    /* Default to private importing 
    164188     */ 
     
    172196    } 
    173197 
     198    mod->semantic(); 
     199 
    174200    if (mod->needmoduleinfo) 
    175201        sc->module->needmoduleinfo = 1; 
     
    190216    //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg); 
    191217 
    192  
    193     if (global.params.moduleDeps != NULL) { 
    194     char fnameBuf[262];     // MAX_PATH+2 
    195  
    196     OutBuffer *const ob = global.params.moduleDeps; 
    197     ob->printf("%s (%s) : ", 
    198         sc->module->toPrettyChars(), 
    199         escapePath(sc->module->srcfile->toChars(), fnameBuf, sizeof(fnameBuf) / sizeof(*fnameBuf)) 
    200     ); 
    201  
    202     char* protStr = ""; 
    203     switch (sc->protection) { 
    204         case PROTpublic: protStr = "public"; break; 
    205         case PROTprivate: protStr = "private"; break; 
    206         case PROTpackage: protStr = "package"; break; 
    207         default: break; 
    208     } 
    209     ob->writestring(protStr); 
    210     if (isstatic) { 
    211         ob->writestring(" static"); 
    212     } 
    213     ob->writestring(" : "); 
    214  
    215     if (this->packages) { 
    216         for (size_t i = 0; i < this->packages->dim; i++) { 
    217         Identifier *pid = (Identifier *)this->packages->data[i]; 
     218    if (global.params.moduleDeps != NULL) 
     219    { 
     220    /* The grammar of the file is: 
     221     *  ImportDeclaration 
     222     *      ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> " 
     223     *  ModuleAliasIdentifier ] "\n" 
     224     * 
     225     *  BasicImportDeclaration 
     226     *      ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection 
     227     *      " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")" 
     228     * 
     229