Changeset 884

Show
Ignore:
Timestamp:
03/08/08 17:29:17 (6 months ago)
Author:
Gregor
Message:

MERGE: dmdfe-2.0 r883 (DMD 2.012)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/rebuild/Makefile

    r785 r884  
    2121  cast.o \ 
    2222  class.o \ 
     23  clone.o \ 
    2324  compile.o \ 
    2425  cond.o \ 
  • trunk/rebuild/access.c

    r459 r884  
    254254    { 
    255255    //error(loc, "member %s is not accessible", smember->toChars()); 
     256halt(); 
    256257    } 
    257258} 
  • trunk/rebuild/aggregate.h

    r840 r884  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2007 by Digital Mars 
     3// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    5858    DeleteDeclaration *aggDelete;   // deallocator 
    5959 
     60    FuncDeclarations dtors; // Array of destructors 
     61    FuncDeclaration *dtor;  // aggregate destructor 
     62 
    6063#ifdef IN_GCC 
    6164    Array methods;              // flat list of all methods for debug information 
     
    7174    void addField(Scope *sc, VarDeclaration *v); 
    7275    int isDeprecated();     // is aggregate deprecated? 
     76    FuncDeclaration *buildDtor(Scope *sc); 
    7377 
    7478    void emitComment(Scope *sc); 
     
    103107{ 
    104108    int zeroInit;       // !=0 if initialize with 0 fill 
     109    int hasIdentityAssign;  // !=0 if has identity opAssign 
     110    FuncDeclaration *cpctor;    // generated copy-constructor, if any 
     111 
     112    FuncDeclarations postblits; // Array of postblit functions 
     113    FuncDeclaration *postblit;  // aggregate postblit 
    105114 
    106115    StructDeclaration(Loc loc, Identifier *id); 
     
    110119    char *mangle(); 
    111120    char *kind(); 
     121    int needOpAssign(); 
     122    FuncDeclaration *buildOpAssign(Scope *sc); 
     123    FuncDeclaration *buildPostBlit(Scope *sc); 
     124    FuncDeclaration *buildCpCtor(Scope *sc); 
    112125    void toDocBuffer(OutBuffer *buf); 
    113126 
     
    149162}; 
    150163 
     164#if V2 
    151165#define CLASSINFO_SIZE  (0x3C+16)   // value of ClassInfo.size 
     166#else 
     167#define CLASSINFO_SIZE  (0x3C+12)   // value of ClassInfo.size 
     168#endif 
    152169 
    153170struct ClassDeclaration : AggregateDeclaration 
     
    159176    CtorDeclaration *ctor; 
    160177    CtorDeclaration *defaultCtor;   // default constructor 
    161     FuncDeclarations dtors;     // Array of destructors 
    162178    FuncDeclaration *staticCtor; 
    163179    FuncDeclaration *staticDtor; 
     
    194210 
    195211    Dsymbol *search(Loc, Identifier *ident, int flags); 
     212#if V2 
    196213    int isFuncHidden(FuncDeclaration *fd); 
     214#endif 
    197215    FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 
    198216    void interfaceSemantic(Scope *sc); 
     
    200218    int isCOMclass(); 
    201219    virtual int isCOMinterface(); 
     220#if V2 
    202221    virtual int isCPPinterface(); 
     222#endif 
    203223    int isAbstract(); 
    204224    virtual int vtblOffset(); 
     
    224244struct InterfaceDeclaration : ClassDeclaration 
    225245{ 
     246#if V2 
    226247    int cpp;                // !=0 if this is a C++ interface 
    227  
     248#endif 
    228249    InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 
    229250    Dsymbol *syntaxCopy(Dsymbol *s); 
     
    233254    char *kind(); 
    234255    int vtblOffset(); 
     256#if V2 
    235257    int isCPPinterface(); 
     258#endif 
    236259    virtual int isCOMinterface(); 
    237260 
  • trunk/rebuild/attrib.c

    r847 r884  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2007 by Digital Mars 
     3// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    3535 
    3636extern void obj_includelib(char *name); 
     37void obj_startaddress(Symbol *s); 
    3738 
    3839 
     
    308309    {   unsigned stc_save = sc->stc; 
    309310 
    310     if (stc & (STCauto | STCscope | STCstatic | STCextern)) 
    311         sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 
    312     if (stc & (STCconst | STCinvariant)) 
    313         sc->stc &= ~(STCconst | STCinvariant); 
     311    /* These sets of storage classes are mutually exclusive, 
     312     * so choose the innermost or most recent one. 
     313     */ 
     314    if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 
     315        sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 
     316    if (stc & (STCconst | STCinvariant | STCmanifest)) 
     317        sc->stc &= ~(STCconst | STCinvariant | STCmanifest); 
    314318    sc->stc |= stc; 
    315319    for (unsigned i = 0; i < decl->dim; i++) 
     
    824828    } 
    825829#endif 
     830    else if (ident == Id::startaddress) 
     831    { 
     832    if (!args || args->dim != 1) 
     833        error("function name expected for start address"); 
     834    else 
     835    { 
     836        Expression *e = (Expression *)args->data[0]; 
     837        e = e->semantic(sc); 
     838        e = e->optimize(WANTvalue | WANTinterpret); 
     839        args->data[0] = (void *)e; 
     840        Dsymbol *sa = getDsymbol(e); 
     841        if (!sa || !sa->isFuncDeclaration()) 
     842        error("function name expected for start address, not '%s'", e->toChars()); 
     843    } 
     844    goto Lnodecl; 
     845    } 
    826846    else 
    827847    error("unrecognized pragma(%s)", ident->toChars()); */ 
  • trunk/rebuild/cast.c

    r847 r884  
    3535    //printf("%s\n", toChars()); 
    3636 
    37     if (implicitConvTo(t)) 
     37    MATCH match = implicitConvTo(t); 
     38    if (match) 
    3839    { 
    3940    if (global.params.warnings && 
     
    5051        toChars(), type->toChars(), t->toChars());*/ 
    5152    } 
     53    if (match == MATCHconst && t == type->constOf()) 
     54    { 
     55        Expression *e = copy(); 
     56        e->type = t; 
     57        return e; 
     58    } 
    5259    return castTo(sc, t); 
    5360    } 
     
    5865 
    5966#if 0 
     67printf("ty = %d\n", type->ty); 
    6068print(); 
    6169type->print(); 
     
    96104    toChars(), type->toChars(), t->toChars()); 
    97105#endif 
    98     //static int nest; if (++nest == 10) halt(); 
     106    //static int nest; if (++nest == 50) halt(); 
    99107    if (!type) 
    100108    {   //error("%s is not an expression", toChars()); 
     
    105113    return MATCHexact; 
    106114    if (e != this) 
    107     {   //printf("optimized to %s\n", e->toChars()); 
     115    {   //printf("\toptimized to %s of type %s\n", e->toChars(), e->type->toChars()); 
    108116    return e->implicitConvTo(t); 
    109117    } 
     
    139147    toChars(), type->toChars(), t->toChars()); 
    140148#endif 
    141     if (type->equals(t)) 
    142     return MATCHexact; 
     149    MATCH m = type->implicitConvTo(t); 
     150    if (m >= MATCHconst) 
     151    return m; 
    143152 
    144153    TY ty = type->toBasetype()->ty; 
    145154    TY toty = t->toBasetype()->ty; 
    146155 
    147     if (type->implicitConvTo(t) == MATCHnomatch && t->ty == Tenum) 
     156    if (m == MATCHnomatch && t->ty == Tenum) 
    148157    goto Lno; 
    149158 
     
    333342    if (this->type->equals(t)) 
    334343    return MATCHexact; 
     344 
     345    /* Allow implicit conversions from invariant to mutable|const, 
     346     * and mutable to invariant. It works because, after all, a null 
     347     * doesn't actually point to anything. 
     348     */ 
     349    if (t->invariantOf()->equals(type->invariantOf())) 
     350    return MATCHconst; 
     351 
    335352    // NULL implicitly converts to any pointer type or dynamic array 
    336353    if (type->ty == Tpointer && type->nextOf()->ty == Tvoid) 
     
    344361    } 
    345362    return Expression::implicitConvTo(t); 
     363} 
     364 
     365MATCH StructLiteralExp::implicitConvTo(Type *t) 
     366{ 
     367#if 0 
     368    printf("StructLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\n", 
     369    toChars(), type->toChars(), t->toChars()); 
     370#endif 
     371    MATCH m = Expression::implicitConvTo(t); 
     372    if (m != MATCHnomatch) 
     373    return m; 
     374    if (type->ty == t->ty && type->ty == Tstruct && 
     375    ((TypeStruct *)type)->sym == ((TypeStruct *)t)->sym) 
     376    { 
     377    m = MATCHconst; 
     378    for (int i = 0; i < elements->dim; i++) 
     379    {   Expression *e = (Expression *)elements->data[i]; 
     380        Type *te = e->type; 
     381        if (t->mod == 0) 
     382        te = te->mutableOf(); 
     383        else 
     384        {   assert(t->mod == MODinvariant); 
     385        te = te->invariantOf(); 
     386        } 
     387        MATCH m2 = e->implicitConvTo(te); 
     388        //printf("\t%s => %s, match = %d\n", e->toChars(), te->toChars(), m2); 
     389        if (m2 < m) 
     390        m = m2; 
     391    } 
     392    } 
     393    return m; 
    346394} 
    347395 
     
    553601        {   if ((t->ty == Tdelegate && (f->needThis() || f->isNested())) || 
    554602            (t->ty == Tpointer && !(f->needThis() || f->isNested()))) 
     603            { 
    555604            result = MATCHexact; 
     605            } 
    556606        } 
    557607        } 
     
    608658 
    609659Expression *Expression::castTo(Scope *sc, Type *t) 
    610 {   Expression *e; 
    611     Type *tb; 
    612  
     660
    613661    //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars()); 
    614662#if 0 
     
    618666    if (type == t) 
    619667    return this; 
    620     e = this; 
    621     tb = t->toBasetype(); 
    622     type = type->toBasetype(); 
    623     if (tb != type
     668    Expression *e = this; 
     669    Type *tb = t->toBasetype(); 
     670    Type *typeb = type->toBasetype(); 
     671    if (tb != typeb
    624672    { 
    625673    // Do (type *) cast of (type [dim]) 
    626674    if (tb->ty == Tpointer && 
    627         type->ty == Tsarray 
     675        typeb->ty == Tsarray 
    628676       ) 
    629677    { 
    630678        //printf("Converting [dim] to *\n"); 
    631679 
    632         if (type->size(loc) == 0) 
     680        if (typeb->size(loc) == 0) 
    633681        e = new NullExp(loc); 
    634682        else 
     
    648696    } 
    649697    } 
     698    else 
     699    { 
     700    e = e->copy();  // because of COW for assignment to e->type 
     701    } 
     702    assert(e != this); 
    650703    e->type = t; 
    651704    //printf("Returning: %s\n", e->toChars()); 
     
    655708 
    656709Expression *RealExp::castTo(Scope *sc, Type *t) 
    657 
    658     if (type->isreal() && t->isreal()) 
    659     type = t; 
    660     else if (type->isimaginary() && t->isimaginary()) 
    661     type = t; 
    662     else 
    663     return Expression::castTo(sc, t); 
    664     return this; 
     710{   Expression *e = this; 
     711    if (type != t) 
     712    { 
     713    if ((type->isreal() && t->isreal()) || 
     714        (type->isimaginary() && t->isimaginary()) 
     715       ) 
     716    {   e = copy(); 
     717        e->type = t; 
     718    } 
     719    else 
     720        e = Expression::castTo(sc, t); 
     721    } 
     722    return e; 
    665723} 
    666724 
    667725 
    668726Expression *ComplexExp::castTo(Scope *sc, Type *t) 
    669 
    670     if (type->iscomplex() && t->iscomplex()) 
    671     type = t; 
    672     else 
    673     return Expression::castTo(sc, t); 
    674     return this; 
     727{   Expression *e = this; 
     728    if (type != t) 
     729    { 
     730    if (type->iscomplex() && t->iscomplex()) 
     731    {   e = copy(); 
     732        e->type = t; 
     733    } 
     734    else 
     735        e = Expression::castTo(sc, t); 
     736    } 
     737    return e; 
    675738} 
    676739 
    677740 
    678741Expression *NullExp::castTo(Scope *sc, Type *t) 
    679 {   Expression *e; 
     742{   NullExp *e; 
    680743    Type *tb; 
    681744 
    682745    //printf("NullExp::castTo(t = %p)\n", t); 
    683     committed = 1; 
    684     e = this; 
     746    if (type == t) 
     747    { 
     748    committed = 1; 
     749    return this; 
     750    } 
     751    e = (NullExp *)copy(); 
     752    e->committed = 1; 
    685753    tb = t->toBasetype(); 
    686     type = type->toBasetype(); 
    687     if (tb != type) 
     754    e->type = type->toBasetype(); 
     755    if (tb != e->type) 
    688756    { 
    689757    // NULL implicitly converts to any pointer type or dynamic array 
    690     if (type->ty == Tpointer && type->nextOf()->ty == Tvoid && 
     758    if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid && 
    691759        (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray || 
    692760         tb->ty == Tdelegate)) 
     
    708776    else 
    709777    { 
    710         return Expression::castTo(sc, t); 
    711         //e = new CastExp(loc, e, tb); 
     778        return e->Expression::castTo(sc, t); 
    712779    } 
    713780    } 
     
    10061073 
    10071074Expression *TupleExp::castTo(Scope *sc, Type *t) 
    1008 
    1009     for (size_t i = 0; i < exps->dim; i++) 
    1010     {   Expression *e = (Expression *)exps->data[i]; 
    1011     e = e->castTo(sc, t); 
    1012     exps->data[i] = (void *)e; 
    1013     } 
    1014     return this; 
     1075{   TupleExp *e = (TupleExp *)copy(); 
     1076    e->exps = (Expressions *)exps->copy(); 
     1077    for (size_t i = 0; i < e->exps->dim; i++) 
     1078    {   Expression *ex = (Expression *)e->exps->data[i]; 
     1079    ex = ex->castTo(sc, t); 
     1080    e->exps->data[i] = (void *)ex; 
     1081    } 
     1082    return e; 
    10151083} 
    10161084 
     
    10241092    if (type == t) 
    10251093    return this; 
     1094    ArrayLiteralExp *e = this; 
    10261095    Type *typeb = type->toBasetype(); 
    10271096    Type *tb = t->toBasetype(); 
     
    10361105    } 
    10371106 
     1107    e = (ArrayLiteralExp *)copy(); 
     1108    e->elements = (Expressions *)elements->copy(); 
    10381109    for (int i = 0; i < elements->dim; i++) 
    1039     {   Expression *e = (Expression *)elements->data[i]; 
    1040         e = e->castTo(sc, tb->nextOf()); 
    1041         elements->data[i] = (void *)e; 
    1042     } 
    1043     type = t; 
     1110    {   Expression *ex = (Expression *)elements->data[i]; 
     1111        ex = ex->castTo(sc, tb->nextOf()); 
     1112        e->elements->data[i] = (void *)ex; 
     1113    } 
     1114    e->type = t; 
     1115    return e; 
     1116    } 
     1117    if (tb->ty == Tpointer && typeb->ty == Tsarray) 
     1118    { 
     1119    e = (ArrayLiteralExp *)copy(); 
     1120    e->type = typeb->nextOf()->pointerTo(); 
     1121    } 
     1122L1: 
     1123    return e->Expression::castTo(sc, t); 
     1124
     1125 
     1126Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t) 
     1127
     1128    if (type == t) 
    10441129    return this; 
    1045     } 
    1046     if (tb->ty == Tpointer && typeb->ty == Tsarray) 
    1047     { 
    1048     type = typeb->nextOf()->pointerTo(); 
    1049     } 
    1050 L1: 
    1051     return Expression::castTo(sc, t); 
    1052 
    1053  
    1054 Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t) 
    1055 
     1130    AssocArrayLiteralExp *e = this; 
    10561131    Type *typeb = type->toBasetype(); 
    10571132    Type *tb = t->toBasetype(); 
     
    10591134    tb->nextOf()->toBasetype()->ty != Tvoid) 
    10601135    { 
     1136    e = (AssocArrayLiteralExp *)copy(); 
     1137    e->keys = (Expressions *)keys->copy(); 
     1138    e->values = (Expressions *)values->copy(); 
    10611139    assert(keys->dim == values->dim); 
    10621140    for (size_t i = 0; i < keys->dim; i++) 
    1063     {   Expression *e = (Expression *)values->data[i]; 
    1064         e = e->castTo(sc, tb->nextOf()); 
    1065         values->data[i] = (void *)e
    1066  
    1067         e = (Expression *)keys->data[i]; 
    1068         e = e->castTo(sc, ((TypeAArray *)tb)->index); 
    1069         keys->data[i] = (void *)e
    1070     } 
    1071     type = t; 
    1072     return this
     1141    {   Expression *ex = (Expression *)values->data[i]; 
     1142        ex = ex->castTo(sc, tb->nextOf()); 
     1143        e->values->data[i] = (void *)ex
     1144 
     1145        ex = (Expression *)keys->data[i]; 
     1146        ex = ex->castTo(sc, ((TypeAArray *)tb)->index); 
     1147        e->keys->data[i] = (void *)ex
     1148    } 
     1149    e->type = t; 
     1150    return e
    10731151    } 
    10741152L1: 
    1075     return Expression::castTo(sc, t); 
     1153    return e->Expression::castTo(sc, t); 
    10761154} 
    10771155 
    10781156Expression *SymOffExp::castTo(Scope *sc, Type *t) 
    10791157{ 
    1080     Type *tb; 
    1081  
    10821158#if 0 
    10831159    printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", 
    10841160    toChars(), type->toChars(), t->toChars()); 
    10851161#endif 
    1086     Expression *e = this; 
    1087  
    1088     tb = t->toBasetype(); 
    1089     type = type->toBasetype(); 
    1090     if (tb != type) 
     1162    if (type == t && hasOverloads == 0) 
     1163    return this; 
     1164    Expression *e; 
     1165    Type *tb = t->toBasetype(); 
     1166    Type *typeb = type->toBasetype(); 
     1167    if (tb != typeb) 
    10911168    { 
    10921169    // Look for pointers to functions where the functions are overloaded. 
     
    10941171 
    10951172    if (hasOverloads && 
    1096         type->ty == Tpointer && type->nextOf()->ty == Tfunction && 
     1173        typeb->ty == Tpointer && typeb->nextOf()->ty == Tfunction && 
    10971174        (tb->ty == Tpointer || tb->ty == Tdelegate) && tb->nextOf()->ty == Tfunction) 
    10981175    { 
     
    11251202    e = Expression::castTo(sc, t); 
    11261203    } 
    1127     if (e == this && hasOverloads) 
    1128     {   e = syntaxCopy(); 
     1204    else 
     1205    {   e = copy(); 
     1206    e->type = t; 
    11291207    ((SymOffExp *)e)->hasOverloads = 0; 
    11301208    } 
    1131     e->type = t; 
    11321209    return e; 
    11331210} 
     
    11351212Expression *DelegateExp::castTo(Scope *sc, Type *t) 
    11361213{ 
    1137     Type *tb; 
    11381214#if 0 
    11391215    printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n", 
    11401216    toChars(), type->toChars(), t->toChars()); 
    11411217#endif 
     1218    static char msg[] = "cannot form delegate due to covariant return type"; 
     1219 
    11421220    Expression *e = this; 
    1143     static char msg[] = "cannot form delegate due to covariant return type"; 
    1144  
    1145     tb = t->toBasetype(); 
    1146     type = type->toBasetype(); 
    1147     if (tb != type) 
     1221    Type *tb = t->toBasetype(); 
     1222    Type *typeb = type->toBasetype(); 
     1223    if (tb != typeb) 
    11481224    { 
    11491225    // Look for delegates to functions where the functions are overloaded. 
    11501226    FuncDeclaration *f; 
    11511227 
    1152     if (type->ty == Tdelegate && type->nextOf()->ty == Tfunction && 
     1228    if (typeb->ty == Tdelegate && typeb->nextOf()->ty == Tfunction && 
    11531229        tb->ty == Tdelegate && tb->nextOf()->ty == Tfunction) 
    11541230    { 
     
    11771253    if (func->tintro && func->tintro->nextOf()->isBaseOf(func->type->nextOf(), &offset) && offset) 
    11781254        error("%s", msg); 
    1179     } 
    1180     e->type = t; 
     1255    e = copy(); 
     1256    e->type = t; 
     1257    } 
    11811258    return e; 
    11821259} 
     
    12621339    t2 = e2->type; 
    12631340    assert(t1); 
     1341    t = t1; 
    12641342 
    12651343    //if (t1) printf("\tt1 = %s\n", t1->toChars()); 
     
    13171395    return this; 
    13181396    } 
     1397 
     1398    t1 = t1b; 
     1399    t2 = t2b; 
    13191400 
    13201401    if (op == TOKcat) 
     
    13381419        else 
    13391420        e2 = e2->castTo(sc, t2); 
     1421        t = t1; 
    13401422        goto Lagain; 
    13411423    } 
     
    13431425 
    13441426Lagain: 
    1345     t = t1; 
    13461427    if (t1 == t2) 
    13471428    { 
     
    13661447        t1 = t1n->mutableOf()->constOf()->pointerTo(); 
    13671448        t2 = t2n->mutableOf()->constOf()->pointerTo(); 
     1449        t = t1; 
    13681450        goto Lagain; 
    13691451    } 
     
    14291511    else 
    14301512        t2 = t2->nextOf()->mutableOf()->constOf()->arrayOf(); 
     1513    t = t1; 
    14311514    goto Lagain; 
    14321515    } 
     
    14671550    goto Lt2; 
    14681551    } 
    1469 //else if (e2->op == TOKstring) { printf("test2\n"); } 
    14701552    else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1)) 
    14711553    { 
     
    15271609 
    15281610Expression *Expression::integralPromotions(Scope *sc) 
    1529 {   Expression *e; 
    1530  
    1531     e = this; 
     1611
     1612    Expression *e = this; 
     1613 
     1614    //printf("integralPromotions %s %s\n", e->toChars(), e->type->toChars()); 
    15321615    switch (type->toBasetype()->ty) 
    15331616    { 
  • trunk/rebuild/class.c

    r847 r884  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2007 by Digital Mars 
     3// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    653653    Module::dprogress++; 
    654654 
     655    dtor = buildDtor(sc); 
    655656 
    656657    sc->pop(); 
  • trunk/rebuild/constfold.c

    r840 r884  
    901901    real_t r2; 
    902902 
    903     if (e1->type->isreal()) 
     903    //printf("Cmp(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 
     904 
     905    if (e1->op == TOKstring && e2->op == TOKstring) 
     906    {   StringExp *es1 = (StringExp *)e1; 
     907    StringExp *es2 = (StringExp *)e2; 
     908    size_t sz = es1->sz; 
     909    assert(sz == es2->sz); 
     910 
     911    size_t len = es1->len; 
     912    if (es2->len < len) 
     913        len = es2->len; 
     914 
     915    int cmp = memcmp(es1->string, es2->string, sz * len); 
     916    if (cmp == 0) 
     917        cmp = es1->len - es2->len; 
     918 
     919    switch (op) 
     920    { 
     921        case TOKlt: n = cmp <  0;   break; 
     922        case TOKle: n = cmp <= 0;   break; 
     923        case TOKgt: n = cmp >  0;   break; 
     924        case TOKge: n = cmp >= 0;   break; 
     925 
     926        case TOKleg:   n = 1;       break; 
     927        case TOKlg:    n = cmp != 0;    break; 
     928        case TOKunord: n = 0;       break; 
     929        case TOKue:    n = cmp == 0;    break; 
     930        case TOKug:    n = cmp >  0;    break; 
     931        case TOKuge:   n = cmp >= 0;    break; 
     932        case TOKul:    n = cmp <  0;    break; 
     933        case TOKule:   n = cmp <= 0;    break; 
     934 
     935        default: 
     936        assert(0); 
     937    } 
     938    } 
     939    else if (e1->isConst() != 1 || e2->isConst() != 1) 
     940    return EXP_CANT_INTERPRET; 
     941    else if (e1->type->isreal()) 
    904942    { 
    905943    r1 = e1->toReal(); 
  • trunk/rebuild/declaration.c

    r847 r884  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2007 by Digital Mars 
     3// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    8787 */ 
    8888 
    89 void Declaration::checkModify(Loc loc, Scope *sc
     89void Declaration::checkModify(Loc loc, Scope *sc, Type *t
    9090{ 
    9191    /* if (sc->incontract && isParameter()) 
    9292    error(loc, "cannot modify parameter '%s' in contract", toChars()); */ 
    93  
    94     VarDeclaration *v = isVarDeclaration(); 
    95     /* if (v && v->canassign == 0 && 
    96         (isConst() || isInvariant()) && !isCtorinit()) 
    97     error(loc, "cannot modify const/invariant variable '%s'", toChars()); */ 
    9893 
    9994    if (isCtorinit()) 
     
    111106           ) 
    112107        { 
     108        VarDeclaration *v = isVarDeclaration(); 
    113109        assert(v); 
    114110        v->ctorinit = 1; 
     
    131127    } 
    132128    } 
     129    else 
     130    { 
     131    VarDeclaration *v = isVarDeclaration(); 
     132    if (v && v->canassign == 0) 
     133    { 
     134        char *p = NULL; 
     135        if (isConst()) 
     136        p = "const"; 
     137        else if (isInvariant()) 
     138        p = "invariant"; 
     139        else if (storage_class & STCmanifest) 
     140        p = "manifest constant"; 
     141        else if (!t->isAssignable()) 
     142        p = "struct with immutable members"; 
     143        if (p) 
     144        {   error(loc, "cannot modify %s", p); 
     145        halt(); 
     146        } 
     147    } 
     148    } 
    133149} 
    134150 
     
    372388Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s) 
    373389{ 
     390    //printf("AliasDeclaration::syntaxCopy()\n"); 
    374391    assert(!s); 
    375392    AliasDeclaration *sa; 
     
    645662    //printf(" type = %s\n", type ? type->toChars() : "null"); 
    646663    //printf(" stc = x%x\n", sc->stc); 
     664    //printf(" storage_class = x%x\n", storage_class); 
    647665    //printf("linkage = %d\n", sc->linkage); 
    648666    //if (strcmp(toChars(), "mul") == 0) halt(); 
     
    672690    type = type->semantic(loc, sc); 
    673691    } 
    674     //printf(" type = %s\n", type ? type->toChars() : "null"); 
     692    //printf(" semantic type = %s\n", type ? type->toChars() : "null"); 
    675693 
    676694    type->checkDeprecated(loc, sc); 
     
    713731    Objects *exps = new Objects(); 
    714732    exps->setDim(nelems); 
     733    Expression *ie = init ? init->toExpression() : NULL; 
    715734 
    716735    for (size_t i = 0; i < nelems; i++) 
     
    723742        Identifier *id = new Identifier(name, TOKidentifier); 
    724743 
    725         VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL); 
     744        Expression *einit = ie; 
     745        if (ie && ie->op == TOKtuple) 
     746        {   einit = (Expression *)((TupleExp *)ie)->exps->data[i]; 
     747        } 
     748        Initializer *ti = init; 
     749        if (einit) 
     750        {   ti = new ExpInitializer(einit->loc, einit); 
     751        } 
     752 
     753        VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); 
    726754        //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); 
    727755        v->semantic(sc); 
     
    752780        type = type->constOf(); 
    753781    } 
    754  
    755     if (storage_class & (STCstatic | STCextern)) 
    756     { 
    757     } 
    758     else if (isSynchronized()) 
     782    else if (type->isConst()) 
     783    storage_class |= STCconst; 
     784    else if (type->isInvariant()) 
     785    storage_class |= STCinvariant; 
     786 
     787    if (isSynchronized()) 
    759788    { 
    760789    //error("variable %s cannot be synchronized", toChars()); 
     
    768797    //error("abstract cannot be applied to variable"); 
    769798    } 
    770     else if (storage_class & STCtemplateparameter) 
     799    else if (storage_class & STCfinal) 
     800    { 
     801    error("final cannot be applied to variable"); 
     802    } 
     803 
     804    if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter)) 
    771805    { 
    772806    } 
     
    819853    if (type->isauto() && !noauto) 
    820854    { 
    821     /* if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) 
    822     { 
    823         error("globals, statics, fields, ref and out parameters cannot be auto"); 
     855    /* if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest) || !fd) 
     856    { 
     857        error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto"); 
    824858    } */ 
    825859 
     
    838872    if (init) 
    839873    storage_class |= STCinit;     // remember we had an explicit initializer 
    840  
     874    else if (storage_class & STCmanifest) 
     875    error("manifest constants must have initializers"); 
     876 
     877    enum TOK op = TOKconstruct; 
    841878    if (!init && !sc->inunion && !isStatic() && fd && 
    842879    (!(storage_class & (STCfield | STCin | STCforeach | STCparameter)) || (storage_class & STCout)) && 
     
    877914        init = getExpInitializer(); 
    878915    } 
     916    // Default initializer is always a blit 
     917    op = TOKblit; 
    879918    } 
    880919 
     
    906945        // If local variable, use AssignExp to handle all the various 
    907946        // possibilities. 
    908         if (fd && !isStatic() && 
     947        if (fd && !isStatic() && !(storage_class & STCmanifest) && 
    909948        !init->isVoidInitializer()) 
    910949        { 
     
    958997        } 
    959998        ei->exp = new AssignExp(loc, e1, ei->exp); 
    960         ei->exp->op = TOKconstruct
     999        ei->exp->op = op
    9611000        canassign++; 
    9621001        ei->exp = ei->exp->semantic(sc); 
     
    9691008        } 
    9701009    } 
    971     else if (storage_class & (STCconst | STCinvariant) || 
     1010    else if (storage_class & (STCconst | STCinvariant | STCmanifest) || 
    9721011         type->isConst() || type->isInvariant()) 
    9731012    { 
     
    10691108void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    10701109{ 
     1110    if (storage_class & STCmanifest) 
     1111    buf->writestring("manifest "); 
    10711112    if (storage_class & STCstatic) 
    10721113    buf->writestring("static "); 
     
    10821123    if (init) 
    10831124    {   buf->writestring(" = "); 
    1084     init->toCBuffer(buf, hgs); 
     1125    ExpInitializer *ie = init->isExpInitializer(); 
     1126    if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit)) 
     1127        ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs); 
     1128    else 
     1129        init->toCBuffer(buf, hgs); 
    10851130    } 
    10861131    buf->writeByte(';'); 
     
    11151160void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) 
    11161161{ 
    1117     if (parent && !isDataseg() && parent != sc->parent) 
     1162    if (parent && !isDataseg() && parent != sc->parent && 
     1163    !(storage_class & STCmanifest)) 
    11181164    { 
    11191165    // The function that this variable is in 
     
    11411187            goto L2; 
    11421188        } 
     1189 
    11431190        fdv->closureVars.push(this); 
    11441191      L2: ; 
     
    11771224Expression *VarDeclaration::getConstInitializer() 
    11781225{ 
    1179     if ((isConst() || isInvariant()) && 
     1226    if ((isConst() || isInvariant() || storage_class & STCmanifest) && 
    11801227    storage_class & STCinit) 
    11811228    { 
     
    11941241int VarDeclaration::canTakeAddressOf() 
    11951242{ 
     1243#if 0 
    11961244    /* Global variables and struct/class fields of the form: 
    11971245     *  const int x = 3; 
     
    12071255    return 0; 
    12081256    } 
     1257#else 
     1258    if (storage_class & STCmanifest) 
     1259    return 0; 
     1260#endif 
    12091261    return 1; 
    12101262} 
     
    12221274    printf("parent = '%s'\n", parent->toChars()); 
    12231275#endif 
     1276    if (storage_class & STCmanifest) 
     1277    return 0; 
    12241278    Dsymbol *parent = this->toParent(); 
    12251279    if (!parent && !(storage_class & STCstatic)) 
     
    12361290int VarDeclaration::hasPointers() 
    12371291{ 
     1292    //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); 
    12381293    return (!isDataseg() && type->hasPointers()); 
    12391294} 
     1295 
     1296/****************************************** 
     1297 * Return TRUE if variable needs to call the destructor. 
     1298 */ 
     1299 
     1300int VarDeclaration::needsAutoDtor() 
     1301{ 
     1302    //printf("VarDeclaration::needsAutoDtor() %s\n", toChars()); 
     1303 
     1304    if (noauto || storage_class & STCnodtor) 
     1305    return FALSE; 
     1306 
     1307  &n