Changeset 880

Show
Ignore:
Timestamp:
03/08/08 17:06:46 (7 months ago)
Author:
Gregor
Message:

MERGE: DMD 2.009

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmdfe-2.0/attrib.c

    r846 r880  
    281281    {   unsigned stc_save = sc->stc; 
    282282 
    283     if (stc & (STCauto | STCscope | STCstatic | STCextern)) 
    284         sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 
    285     if (stc & (STCconst | STCinvariant)) 
    286         sc->stc &= ~(STCconst | STCinvariant); 
     283    /* These sets of storage classes are mutually exclusive, 
     284     * so choose the innermost or most recent one. 
     285     */ 
     286    if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 
     287        sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 
     288    if (stc & (STCconst | STCinvariant | STCmanifest)) 
     289        sc->stc &= ~(STCconst | STCinvariant | STCmanifest); 
    287290    sc->stc |= stc; 
    288291    for (unsigned i = 0; i < decl->dim; i++) 
  • branches/dmdfe-2.0/cast.c

    r846 r880  
    5858 
    5959#if 0 
     60printf("ty = %d\n", type->ty); 
    6061print(); 
    6162type->print(); 
     
    139140    toChars(), type->toChars(), t->toChars()); 
    140141#endif 
    141     if (type->equals(t)) 
    142     return MATCHexact; 
     142    MATCH m = type->implicitConvTo(t); 
     143    if (m >= MATCHconst) 
     144    return m; 
    143145 
    144146    TY ty = type->toBasetype()->ty; 
    145147    TY toty = t->toBasetype()->ty; 
    146148 
    147     if (type->implicitConvTo(t) == MATCHnomatch && t->ty == Tenum) 
     149    if (m == MATCHnomatch && t->ty == Tenum) 
    148150    goto Lno; 
    149151 
     
    608610 
    609611Expression *Expression::castTo(Scope *sc, Type *t) 
    610 {   Expression *e; 
    611     Type *tb; 
    612  
     612
    613613    //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars()); 
    614614#if 0 
     
    618618    if (type == t) 
    619619    return this; 
    620     e = this; 
    621     tb = t->toBasetype(); 
    622     type = type->toBasetype(); 
    623     if (tb != type
     620    Expression *e = this; 
     621    Type *tb = t->toBasetype(); 
     622    Type *typeb = type->toBasetype(); 
     623    if (tb != typeb
    624624    { 
    625625    // Do (type *) cast of (type [dim]) 
    626626    if (tb->ty == Tpointer && 
    627         type->ty == Tsarray 
     627        typeb->ty == Tsarray 
    628628       ) 
    629629    { 
    630630        //printf("Converting [dim] to *\n"); 
    631631 
    632         if (type->size(loc) == 0) 
     632        if (typeb->size(loc) == 0) 
    633633        e = new NullExp(loc); 
    634634        else 
     
    648648    } 
    649649    } 
     650    else 
     651    { 
     652    e = e->copy();  // because of COW for assignment to e->type 
     653    } 
     654    assert(e != this); 
    650655    e->type = t; 
    651656    //printf("Returning: %s\n", e->toChars()); 
     
    655660 
    656661Expression *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; 
     662{   Expression *e = this; 
     663    if (type != t) 
     664    { 
     665    if ((type->isreal() && t->isreal()) || 
     666        (type->isimaginary() && t->isimaginary()) 
     667       ) 
     668    {   e = copy(); 
     669        e->type = t; 
     670    } 
     671    else 
     672        e = Expression::castTo(sc, t); 
     673    } 
     674    return e; 
    665675} 
    666676 
    667677 
    668678Expression *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; 
     679{   Expression *e = this; 
     680    if (type != t) 
     681    { 
     682    if (type->iscomplex() && t->iscomplex()) 
     683    {   e = copy(); 
     684        e->type = t; 
     685    } 
     686    else 
     687        e = Expression::castTo(sc, t); 
     688    } 
     689    return e; 
    675690} 
    676691 
    677692 
    678693Expression *NullExp::castTo(Scope *sc, Type *t) 
    679 {   Expression *e; 
     694{   NullExp *e; 
    680695    Type *tb; 
    681696 
    682697    //printf("NullExp::castTo(t = %p)\n", t); 
    683     committed = 1; 
    684     e = this; 
     698    if (type == t) 
     699    { 
     700    committed = 1; 
     701    return this; 
     702    } 
     703    e = (NullExp *)copy(); 
     704    e->committed = 1; 
    685705    tb = t->toBasetype(); 
    686     type = type->toBasetype(); 
    687     if (tb != type) 
     706    e->type = type->toBasetype(); 
     707    if (tb != e->type) 
    688708    { 
    689709    // NULL implicitly converts to any pointer type or dynamic array 
    690     if (type->ty == Tpointer && type->nextOf()->ty == Tvoid && 
     710    if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid && 
    691711        (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray || 
    692712         tb->ty == Tdelegate)) 
     
    708728    else 
    709729    { 
    710         return Expression::castTo(sc, t); 
    711         //e = new CastExp(loc, e, tb); 
     730        return e->Expression::castTo(sc, t); 
    712731    } 
    713732    } 
     
    10061025 
    10071026Expression *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; 
     1027{   TupleExp *e = (TupleExp *)copy(); 
     1028    e->exps = (Expressions *)exps->copy(); 
     1029    for (size_t i = 0; i < e->exps->dim; i++) 
     1030    {   Expression *ex = (Expression *)e->exps->data[i]; 
     1031    ex = ex->castTo(sc, t); 
     1032    e->exps->data[i] = (void *)ex; 
     1033    } 
     1034    return e; 
    10151035} 
    10161036 
     
    10241044    if (type == t) 
    10251045    return this; 
     1046    ArrayLiteralExp *e = this; 
    10261047    Type *typeb = type->toBasetype(); 
    10271048    Type *tb = t->toBasetype(); 
     
    10361057    } 
    10371058 
     1059    e = (ArrayLiteralExp *)copy(); 
     1060    e->elements = (Expressions *)elements->copy(); 
    10381061    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; 
     1062    {   Expression *ex = (Expression *)elements->data[i]; 
     1063        ex = ex->castTo(sc, tb->nextOf()); 
     1064        e->elements->data[i] = (void *)ex; 
     1065    } 
     1066    e->type = t; 
     1067    return e; 
     1068    } 
     1069    if (tb->ty == Tpointer && typeb->ty == Tsarray) 
     1070    { 
     1071    e = (ArrayLiteralExp *)copy(); 
     1072    e->type = typeb->nextOf()->pointerTo(); 
     1073    } 
     1074L1: 
     1075    return e->Expression::castTo(sc, t); 
     1076
     1077 
     1078Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t) 
     1079
     1080    if (type == t) 
    10441081    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 
     1082    AssocArrayLiteralExp *e = this; 
    10561083    Type *typeb = type->toBasetype(); 
    10571084    Type *tb = t->toBasetype(); 
     
    10591086    tb->nextOf()->toBasetype()->ty != Tvoid) 
    10601087    { 
     1088    e = (AssocArrayLiteralExp *)copy(); 
     1089    e->keys = (Expressions *)keys->copy(); 
     1090    e->values = (Expressions *)values->copy(); 
    10611091    assert(keys->dim == values->dim); 
    10621092    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
     1093    {   Expression *ex = (Expression *)values->data[i]; 
     1094        ex = ex->castTo(sc, tb->nextOf()); 
     1095        e->values->data[i] = (void *)ex
     1096 
     1097        ex = (Expression *)keys->data[i]; 
     1098        ex = ex->castTo(sc, ((TypeAArray *)tb)->index); 
     1099        e->keys->data[i] = (void *)ex
     1100    } 
     1101    e->type = t; 
     1102    return e
    10731103    } 
    10741104L1: 
    1075     return Expression::castTo(sc, t); 
     1105    return e->Expression::castTo(sc, t); 
    10761106} 
    10771107 
    10781108Expression *SymOffExp::castTo(Scope *sc, Type *t) 
    10791109{ 
    1080     Type *tb; 
    1081  
    10821110#if 0 
    10831111    printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", 
    10841112    toChars(), type->toChars(), t->toChars()); 
    10851113#endif 
    1086     Expression *e = this; 
    1087  
    1088     tb = t->toBasetype(); 
    1089     type = type->toBasetype(); 
    1090     if (tb != type) 
     1114    if (type == t && hasOverloads == 0) 
     1115    return this; 
     1116    Expression *e; 
     1117    Type *tb = t->toBasetype(); 
     1118    Type *typeb = type->toBasetype(); 
     1119    if (tb != typeb) 
    10911120    { 
    10921121    // Look for pointers to functions where the functions are overloaded. 
     
    10941123 
    10951124    if (hasOverloads && 
    1096         type->ty == Tpointer && type->nextOf()->ty == Tfunction && 
     1125        typeb->ty == Tpointer && typeb->nextOf()->ty == Tfunction && 
    10971126        (tb->ty == Tpointer || tb->ty == Tdelegate) && tb->nextOf()->ty == Tfunction) 
    10981127    { 
     
    11251154    e = Expression::castTo(sc, t); 
    11261155    } 
    1127     if (e == this && hasOverloads) 
    1128     {   e = syntaxCopy(); 
     1156    else 
     1157    {   e = copy(); 
     1158    e->type = t; 
    11291159    ((SymOffExp *)e)->hasOverloads = 0; 
    11301160    } 
    1131     e->type = t; 
    11321161    return e; 
    11331162} 
     
    11351164Expression *DelegateExp::castTo(Scope *sc, Type *t) 
    11361165{ 
    1137     Type *tb; 
    11381166#if 0 
    11391167    printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n", 
    11401168    toChars(), type->toChars(), t->toChars()); 
    11411169#endif 
     1170    static char msg[] = "cannot form delegate due to covariant return type"; 
     1171 
    11421172    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) 
     1173    Type *tb = t->toBasetype(); 
     1174    Type *typeb = type->toBasetype(); 
     1175    if (tb != typeb) 
    11481176    { 
    11491177    // Look for delegates to functions where the functions are overloaded. 
    11501178    FuncDeclaration *f; 
    11511179 
    1152     if (type->ty == Tdelegate && type->nextOf()->ty == Tfunction && 
     1180    if (typeb->ty == Tdelegate && typeb->nextOf()->ty == Tfunction && 
    11531181        tb->ty == Tdelegate && tb->nextOf()->ty == Tfunction) 
    11541182    { 
     
    11771205    if (func->tintro && func->tintro->nextOf()->isBaseOf(func->type->nextOf(), &offset) && offset) 
    11781206        error("%s", msg); 
    1179     } 
    1180     e->type = t; 
     1207    e = copy(); 
     1208    e->type = t; 
     1209    } 
    11811210    return e; 
    11821211} 
     
    12621291    t2 = e2->type; 
    12631292    assert(t1); 
     1293    t = t1; 
    12641294 
    12651295    //if (t1) printf("\tt1 = %s\n", t1->toChars()); 
     
    13171347    return this; 
    13181348    } 
     1349 
     1350    t1 = t1b; 
     1351    t2 = t2b; 
    13191352 
    13201353    if (op == TOKcat) 
     
    13381371        else 
    13391372        e2 = e2->castTo(sc, t2); 
     1373        t = t1; 
    13401374        goto Lagain; 
    13411375    } 
     
    13431377 
    13441378Lagain: 
    1345     t = t1; 
    13461379    if (t1 == t2) 
    13471380    { 
     
    13661399        t1 = t1n->mutableOf()->constOf()->pointerTo(); 
    13671400        t2 = t2n->mutableOf()->constOf()->pointerTo(); 
     1401        t = t1; 
    13681402        goto Lagain; 
    13691403    } 
     
    14291463    else 
    14301464        t2 = t2->nextOf()->mutableOf()->constOf()->arrayOf(); 
     1465    t = t1; 
    14311466    goto Lagain; 
    14321467    } 
     
    15271562 
    15281563Expression *Expression::integralPromotions(Scope *sc) 
    1529 {   Expression *e; 
    1530  
    1531     e = this; 
     1564
     1565    Expression *e = this; 
     1566 
     1567    //printf("integralPromotions %s %s\n", e->toChars(), e->type->toChars()); 
    15321568    switch (type->toBasetype()->ty) 
    15331569    { 
  • branches/dmdfe-2.0/constfold.c

    r836 r880  
    880880    real_t r2; 
    881881 
    882     if (e1->type->isreal()) 
     882    //printf("Cmp(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 
     883 
     884    if (e1->op == TOKstring && e2->op == TOKstring) 
     885    {   StringExp *es1 = (StringExp *)e1; 
     886    StringExp *es2 = (StringExp *)e2; 
     887    size_t sz = es1->sz; 
     888    assert(sz == es2->sz); 
     889 
     890    size_t len = es1->len; 
     891    if (es2->len < len) 
     892        len = es2->len; 
     893 
     894    int cmp = memcmp(es1->string, es2->string, sz * len); 
     895    if (cmp == 0) 
     896        cmp = es1->len - es2->len; 
     897 
     898    switch (op) 
     899    { 
     900        case TOKlt: n = cmp <  0;   break; 
     901        case TOKle: n = cmp <= 0;   break; 
     902        case TOKgt: n = cmp >  0;   break; 
     903        case TOKge: n = cmp >= 0;   break; 
     904 
     905        case TOKleg:   n = 1;       break; 
     906        case TOKlg:    n = cmp != 0;    break; 
     907        case TOKunord: n = 0;       break; 
     908        case TOKue:    n = cmp == 0;    break; 
     909        case TOKug:    n = cmp >  0;    break; 
     910        case TOKuge:   n = cmp >= 0;    break; 
     911        case TOKul:    n = cmp <  0;    break; 
     912        case TOKule:   n = cmp <= 0;    break; 
     913 
     914        default: 
     915        assert(0); 
     916    } 
     917    } 
     918    else if (e1->isConst() != 1 || e2->isConst() != 1) 
     919    return EXP_CANT_INTERPRET; 
     920    else if (e1->type->isreal()) 
    883921    { 
    884922    r1 = e1->toReal(); 
  • branches/dmdfe-2.0/declaration.c

    r846 r880  
    9292    error(loc, "cannot modify parameter '%s' in contract", toChars()); 
    9393 
    94     VarDeclaration *v = isVarDeclaration(); 
    95     if (v && v->canassign == 0 && 
    96         (isConst() || isInvariant()) && !isCtorinit()) 
    97     error(loc, "cannot modify const/invariant variable '%s'", toChars()); 
    98  
    9994    if (isCtorinit()) 
    10095    {   // It's only modifiable if inside the right constructor 
     
    111106           ) 
    112107        { 
     108        VarDeclaration *v = isVarDeclaration(); 
    113109        assert(v); 
    114110        v->ctorinit = 1; 
     
    129125        } 
    130126        break; 
     127    } 
     128    } 
     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 (!type->isAssignable()) 
     142        p = "struct with immutable members"; 
     143        if (p) 
     144        error(loc, "cannot modify %s", p); 
    131145    } 
    132146    } 
     
    753767        type = type->constOf(); 
    754768    } 
    755  
    756     if (storage_class & (STCstatic | STCextern)) 
    757     { 
    758     } 
    759     else if (isSynchronized()) 
     769    else if (type->isConst()) 
     770    storage_class |= STCconst; 
     771    else if (type->isInvariant()) 
     772    storage_class |= STCinvariant; 
     773 
     774    if (isSynchronized()) 
    760775    { 
    761776    error("variable %s cannot be synchronized", toChars()); 
     
    769784    error("abstract cannot be applied to variable"); 
    770785    } 
    771     else if (storage_class & STCtemplateparameter) 
     786    else if (storage_class & STCfinal) 
     787    { 
     788    error("final cannot be applied to variable"); 
     789    } 
     790 
     791    if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter)) 
    772792    { 
    773793    } 
     
    820840    if (type->isauto() && !noauto) 
    821841    { 
    822     if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) 
    823     { 
    824         error("globals, statics, fields, ref and out parameters cannot be auto"); 
     842    if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest) || !fd) 
     843    { 
     844        error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto"); 
    825845    } 
    826846 
     
    839859    if (init) 
    840860    storage_class |= STCinit;     // remember we had an explicit initializer 
     861    else if (storage_class & STCmanifest) 
     862    error("manifest constants must have initializers"); 
    841863 
    842864    if (!init && !sc->inunion && !isStatic() && fd && 
     
    907929        // If local variable, use AssignExp to handle all the various 
    908930        // possibilities. 
    909         if (fd && !isStatic() && 
     931        if (fd && !isStatic() && !(storage_class & STCmanifest) && 
    910932        !init->isVoidInitializer()) 
    911933        { 
     
    970992        } 
    971993    } 
    972     else if (storage_class & (STCconst | STCinvariant) || 
     994    else if (storage_class & (STCconst | STCinvariant | STCmanifest) || 
    973995         type->isConst() || type->isInvariant()) 
    974996    { 
     
    10701092void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    10711093{ 
     1094    if (storage_class & STCmanifest) 
     1095    buf->writestring("manifest "); 
    10721096    if (storage_class & STCstatic) 
    10731097    buf->writestring("static "); 
     
    11161140void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) 
    11171141{ 
    1118     if (parent && !isDataseg() && parent != sc->parent) 
     1142    if (parent && !isDataseg() && parent != sc->parent && 
     1143    !(storage_class & STCmanifest)) 
    11191144    { 
    11201145    // The function that this variable is in 
     
    11781203Expression *VarDeclaration::getConstInitializer() 
    11791204{ 
    1180     if ((isConst() || isInvariant()) && 
     1205    if ((isConst() || isInvariant() || storage_class & STCmanifest) && 
    11811206    storage_class & STCinit) 
    11821207    { 
     
    11951220int VarDeclaration::canTakeAddressOf() 
    11961221{ 
     1222#if 0 
    11971223    /* Global variables and struct/class fields of the form: 
    11981224     *  const int x = 3; 
     
    12081234    return 0; 
    12091235    } 
     1236#else 
     1237    if (storage_class & STCmanifest) 
     1238    return 0; 
     1239#endif 
    12101240    return 1; 
    12111241} 
     
    12231253    printf("parent = '%s'\n", parent->toChars()); 
    12241254#endif 
     1255    if (storage_class & STCmanifest) 
     1256    return 0; 
    12251257    Dsymbol *parent = this->toParent(); 
    12261258    if (!parent && !(storage_class & STCstatic)) 
  • branches/dmdfe-2.0/declaration.h

    r846 r880  
    6565    STCref      = 0x200000, 
    6666    STCinit     = 0x400000,     // has explicit initializer 
     67    STCmanifest     = 0x800000,     // manifest constant 
    6768}; 
    6869 
     
    251252    VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } 
    252253}; 
     254 
    253255 
    254256/**************************************************************/ 
  • branches/dmdfe-2.0/dsymbol.c

    r846 r880  
    809809        s2->locToChars()); 
    810810    } 
     811halt(); 
    811812} 
    812813 
  • branches/dmdfe-2.0/enum.c

    r835 r880  
    11 
    2 // Copyright (c) 1999-2006 by Digital Mars 
     2// Copyright (c) 1999-2007 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
     
    1515#include "mtype.h" 
    1616#include "scope.h" 
     17#include "id.h" 
     18#include "expression.h" 
     19#include "module.h" 
    1720 
    1821/********************************* EnumDeclaration ****************************/ 
     
    2427    type = new TypeEnum(this); 
    2528    this->memtype = memtype; 
    26     maxval = 0
    27     minval = 0
    28     defaultval = 0
     29    maxval = NULL
     30    minval = NULL
     31    defaultval = NULL
    2932    sinit = NULL; 
     33    scope = NULL; 
    3034} 
    3135 
     
    4852 
    4953void EnumDeclaration::semantic(Scope *sc) 
    50 {   int i; 
    51     uinteger_t number; 
     54
    5255    Type *t; 
    5356    Scope *sce; 
    5457 
    55     //printf("EnumDeclaration::semantic(sd = %p, '%s')\n", sc->scopesym, sc->scopesym->toChars()); 
    56     if (symtab)         // if already done 
    57     return; 
    58     if (!memtype) 
    59     memtype = Type::tint32; 
    60     parent = sc->scopesym; 
    61     memtype = memtype->semantic(loc, sc); 
    62  
    63     /* Check to see if memtype is forward referenced 
    64      */ 
    65     if (memtype->ty == Tenum) 
    66     {   EnumDeclaration *sym = (EnumDeclaration *)memtype->toDsymbol(sc); 
    67     if (!sym->memtype) 
    68     { 
    69         error("base enum %s is forward referenced", sym->toChars()); 
    70         memtype = Type::tint32; 
    71     } 
    72     } 
    73  
    74     if (!memtype->isintegral()) 
    75     {   error("base type must be of integral type, not %s", memtype->toChars()); 
    76     memtype = Type::tint32; 
    77     } 
    78  
    79     t = isAnonymous() ? memtype : type; 
    80     symtab = new DsymbolTable(); 
    81     sce = sc->push(this); 
    82     sce->parent = this; 
    83     number = 0; 
     58    //printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc->scopesym, sc->scopesym->toChars(), toChars()); 
     59    //printf("EnumDeclaration::semantic() %s\n", toChars()); 
    8460    if (!members)       // enum ident; 
    8561    return; 
     62 
     63    if (!memtype && !isAnonymous()) 
     64    {   // Set memtype if we can to reduce fwd reference errors 
     65    memtype = Type::tint32; // case 1)  enum ident { ... } 
     66    } 
     67 
     68    if (symtab)         // if already done 
     69    {   if (!scope) 
     70        return;     // semantic() already completed 
     71    } 
     72    else 
     73    symtab = new DsymbolTable(); 
     74 
     75    Scope *scx = NULL; 
     76    if (scope) 
     77    {   sc = scope; 
     78        scx = scope;            // save so we don't make redundant copies 
     79        scope = NULL; 
     80    } 
     81 
     82    parent = sc->parent; 
     83 
     84    /* The separate, and distinct, cases are: 
     85     *  1. enum { ... } 
     86     *  2. enum : memtype { ... } 
     87     *  3. enum ident { ... } 
     88     *  4. enum ident : memtype { ... } 
     89     */ 
     90 
     91    if (memtype) 
     92    { 
     93    memtype = memtype->semantic(loc, sc); 
     94 
     95    /* Check to see if memtype is forward referenced 
     96     */ 
     97    if (memtype->ty == Tenum) 
     98    {   EnumDeclaration *sym = (EnumDeclaration *)memtype->toDsymbol(sc); 
     99        if (!sym->memtype || !sym->members || !sym->symtab || sym->scope) 
     100        {   // memtype is forward referenced, so try again later 
     101        scope = scx ? scx : new Scope(*sc); 
     102        scope->setNoFree(); 
     103        scope->module->addDeferredSemantic(this); 
     104        printf("\tdeferring %s\n", toChars()); 
     105        return; 
     106        } 
     107    } 
     108#if 0   // Decided to abandon this restriction for D 2.0 
     109    if (!memtype->isintegral()) 
     110    {   error("base type must be of integral type, not %s", memtype->toChars()); 
     111        memtype = Type::tint32; 
     112    } 
     113#endif 
     114    } 
     115 
     116    type = type->semantic(loc, sc); 
     117    if (isAnonymous()) 
     118        sce = sc; 
     119    else 
     120    {   sce = sc->push(this); 
     121    sce->parent = this; 
     122    } 
    86123    if (members->dim == 0) 
    87124    error("enum %s must have at least one member", toChars()); 
    88125    int first = 1; 
    89     for (i = 0; i < members->dim; i++) 
     126    Expression *elast = NULL; 
     127    for (int i = 0; i < members->dim; i++) 
    90128    { 
    91129    EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember(); 
     
    98136        continue; 
    99137 
    100     //printf("Enum member '%s'\n",em->toChars()); 
     138    //printf("  Enum member '%s'\n",em->toChars()); 
     139    if (em->type) 
     140        em->type = em->type->semantic(em->loc, sce); 
    101141    e = em->value; 
    102142    if (e) 
     
    105145        e = e->semantic(sce); 
    106146        e = e->optimize(WANTvalue | WANTinterpret); 
    107         // Need to copy it because we're going to change the type 
    108         e = e->copy(); 
    109         e = e->implicitCastTo(sc, memtype); 
     147        if (memtype) 
     148        { 
     149        e = e->implicitCastTo(sce, memtype); 
     150        e = e->optimize(WANTvalue | WANTinterpret); 
     151        if (!isAnonymous()) 
     152            e = e->castTo(sce, type); 
     153        t = memtype; 
     154        } 
     155        else if (em->type) 
     156        { 
     157        e = e->implicitCastTo(sce, em->type); 
     158        e = e->optimize(WANTvalue | WANTinterpret); 
     159        assert(isAnonymous()); 
     160        t = e->type; 
     161        } 
     162        else 
     163        t = e->type; 
     164    } 
     165    else if (first) 
     166    { 
     167        if (memtype) 
     168        t = memtype; 
     169        else if (em->type) 
     170        t = em->type; 
     171        else 
     172        t = Type::tint32; 
     173        e = new IntegerExp(em->loc, 0, Type::tint32); 
     174        e = e->implicitCastTo(sce, t); 
    110175        e = e->optimize(WANTvalue | WANTinterpret); 
    111         number = e->toInteger(); 
    112         e->type = t
     176        if (!isAnonymous()) 
     177       e = e->castTo(sce, type)
    113178    } 
    114179    else 
    115     {   // Default is the previous number plus 1 
    116  
    117         // Check for overflow 
    118         if (!first) 
    119         { 
    120         switch (t->toBasetype()->ty) 
    121         { 
    122             case Tbool: 
    123             if (number == 2)    goto Loverflow; 
    124             break; 
    125  
    126             case Tint8: 
    127             if (number == 128) goto Loverflow; 
    128             break; 
    129  
    130             case Tchar: 
    131             case Tuns8: 
    132             if (number == 256) goto Loverflow; 
    133             break; 
    134  
    135             case Tint16: 
    136             if (number == 0x8000) goto Loverflow; 
    137             break; 
    138  
    139             case Twchar: 
    140             case Tuns16: 
    141             if (number == 0x10000) goto Loverflow; 
    142             break; 
    143  
    144             case Tint32: 
    145             if (number == 0x80000000) goto Loverflow; 
    146             break; 
    147  
    148             case Tdchar: 
    149             case Tuns32: 
    150             if (number == 0x100000000LL) goto Loverflow; 
    151             break; 
    152  
    153             case Tint64: 
    154             if (number == 0x8000000000000000LL) goto Loverflow; 
    155             break; 
    156  
    157             case Tuns64: 
    158             if (number == 0) goto Loverflow; 
    159             break; 
    160  
    161             Loverflow: 
    162             error("overflow of enum value"); 
    163             break; 
    164  
    165             default: 
    166             assert(0); 
    167         } 
    168         } 
    169         e = new IntegerExp(em->loc, number, t); 
    170     } 
     180    { 
     181        // Set value to (elast + 1). 
     182        // But first check that (elast != t.max) 
     183        assert(elast); 
     184        e = new EqualExp(TOKequal, em->loc, elast, t->getProperty(0, Id::max)); 
     185        e = e->semantic(sce); 
     186        e = e->optimize(WANTvalue | WANTinterpret); 
     187        if (e->toInteger()) 
     188        error("overflow of enum value %s", elast->toChars()); 
     189 
     190        // Now set e to (elast + 1) 
     191        e = new AddExp(em->loc, elast, new IntegerExp(em->loc, 1, Type::tint32)); 
     192        e = e->semantic(sce); 
     193        e = e->castTo(sce, elast->type); 
     194        e = e->optimize(WANTvalue | WANTinterpret); 
     195    } 
     196    elast = e; 
    171197    em->value = e; 
    172198 
     
    174200    if (isAnonymous()) 
    175201    { 
    176         //sce->enclosing->insert(em); 
    177         for (Scope *scx = sce->enclosing; scx; scx = scx->enclosing) 
     202        /* Anonymous enum members get added to enclosing scope. 
     203         */ 
     204        for (Scope *scx = sce; scx; scx = scx->enclosing) 
    178205        { 
    179206        if (scx->scopesym) 
     
    189216        em->addMember(sc, this, 1); 
    190217 
    191     if (first) 
    192     {   first = 0; 
    193         defaultval = number; 
    194         minval = number; 
    195         maxval = number; 
    196     } 
    197     else if (memtype->isunsigned()) 
    198     { 
    199         if (number < minval) 
    200         minval = number; 
    201         if (number > maxval) 
    202         maxval = number; 
    203     } 
    204     else 
    205     { 
    206         if ((sinteger_t)number < (sinteger_t)minval) 
    207         minval = number; 
    208         if ((sinteger_t)number > (sinteger_t)maxval) 
    209         maxval = number; 
    210     } 
    211  
    212     number++; 
     218    /* Compute .min, .max and .default values. 
     219     * If enum doesn't have a name, we can never identify the enum type, 
     220     * so there is no purpose for a .min, .max or .default 
     221     */ 
     222    if (!isAnonymous()) 
     223    { 
     224        if (first) 
     225        {   defaultval = e; 
     226        minval = e; 
     227        maxval = e; 
     228        } 
     229        else 
     230        {   Expression *ec; 
     231 
     232        /* In order to work successfully with UDTs, 
     233         * build expressions to do the comparisons, 
     234         * and let the semantic analyzer and constant 
     235         * folder give us the result. 
     236         */ 
     237 
     238        // Compute if(e < minval) 
     239        ec = new CmpExp(TOKlt, em->loc, e, minval); 
     240        ec = ec->semantic(sce); 
     241        ec = ec->optimize(WANTvalue | WANTinterpret); 
     242        if (ec->toInteger()) 
     243            minval = e; 
     244 
     245        ec = new CmpExp(TOKgt, em->loc, e, maxval); 
     246        ec = ec->semantic(sce); 
     247        ec = ec->optimize(WANTvalue | WANTinterpret); 
     248        if (ec->toInteger()) 
     249            maxval = e; 
     250        } 
     251    } 
     252    first = 0; 
    213253    } 
    214254    //printf("defaultval = %lld\n", defaultval); 
    215255 
    216     sce->pop(); 
     256    //if (defaultval) printf("defaultval: %s %s\n", defaultval->toChars(), defaultval->type->toChars()); 
     257    if (sc != sce) 
     258    sce->pop(); 
    217259    //members->print(); 
    218260} 
     
    271313} 
    272314 
     315Dsymbol *EnumDeclaration::search(Loc loc, Identifier *ident, int flags) 
     316{ 
     317    //printf("%s.EnumDeclaration::search('%s')\n", toChars(), ident->toChars()); 
     318    if (scope) 
     319    // Try one last time to resolve this enum 
     320        semantic(scope); 
     321 
     322    if (!members || !symtab || scope) 
     323    {   error("is forward referenced when looking for '%s'", ident->toChars()); 
     324        //*(char*)0=0; 
     325        return NULL; 
     326    } 
     327 
     328    Dsymbol *s = ScopeDsymbol::search(loc, ident, flags); 
     329    return s; 
     330} 
     331 
    273332/********************************* EnumMember ****************************/ 
    274333 
    275 EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value
     334EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value, Type *type
    276335    : Dsymbol(id) 
    277336{ 
    278337    this->value = value; 
     338    this->type = type; 
    279339    this->loc = loc; 
    280340} 
     
    285345    if (value) 
    286346    e = value->syntaxCopy(); 
     347 
     348    Type *t = NULL; 
     349    if (type) 
     350    t = type->syntaxCopy(); 
    287351 
    288352    EnumMember *em; 
     
    291355    em->loc = loc; 
    292356    em->value = e; 
    293     } 
    294     else 
    295     em = new EnumMember(loc, ident, e); 
     357    em->type = t; 
     358    } 
     359    else 
     360    em = new EnumMember(loc, ident, e, t); 
    296361    return em; 
    297362} 
     
    299364void EnumMember::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    300365{ 
    301     buf->writestring(ident->toChars()); 
     366    if (type) 
     367    type->toCBuffer(buf, ident, hgs); 
     368    else 
     369    buf-&