Changeset 847

Show
Ignore:
Timestamp:
12/20/07 16:27:15 (10 months ago)
Author:
Gregor
Message:

MERGE: dmdfe-2.0 r846 (DMD 2.008)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/rebuild/attrib.c

    r800 r847  
    310310    if (stc & (STCauto | STCscope | STCstatic | STCextern)) 
    311311        sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 
     312    if (stc & (STCconst | STCinvariant)) 
     313        sc->stc &= ~(STCconst | STCinvariant); 
    312314    sc->stc |= stc; 
    313315    for (unsigned i = 0; i < decl->dim; i++) 
     
    338340    { STCextern,       TOKextern }, 
    339341    { STCconst,        TOKconst }, 
     342    { STCinvariant,    TOKinvariant }, 
    340343    { STCfinal,        TOKfinal }, 
    341344    { STCabstract,     TOKabstract }, 
  • trunk/rebuild/cast.c

    r840 r847  
    13301330//t1 = t1->constOf(); 
    13311331//t2 = t2->constOf(); 
    1332         e1 = e1->castTo(sc, t1); 
    1333         e2 = e2->castTo(sc, t2); 
     1332        if (e1->op == TOKstring && !((StringExp *)e1)->committed) 
     1333        e1->type = t1; 
     1334        else 
     1335        e1 = e1->castTo(sc, t1); 
     1336        if (e2->op == TOKstring && !((StringExp *)e2)->committed) 
     1337        e2->type = t2; 
     1338        else 
     1339        e2 = e2->castTo(sc, t2); 
    13341340        goto Lagain; 
    13351341    } 
  • trunk/rebuild/class.c

    r840 r847  
    450450    isauto = baseClass->isauto; 
    451451    vthis = baseClass->vthis; 
     452    storage_class |= baseClass->storage_class & (STCconst | STCinvariant); 
    452453    } 
    453454    else 
     
    522523    if (storage_class & STCabstract) 
    523524    isabstract = 1; 
     525    if (storage_class & STCinvariant) 
     526    type = type->invariantOf(); 
     527    else if (storage_class & STCconst) 
     528    type = type->constOf(); 
    524529 
    525530    sc = sc->push(this); 
    526531    sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 
    527          STCabstract | STCdeprecated); 
     532         STCabstract | STCdeprecated | STCconst | STCinvariant); 
     533    sc->stc |= storage_class & (STCconst | STCinvariant); 
    528534    sc->parent = this; 
    529535    sc->inunion = 0; 
     
    938944} 
    939945 
     946 
    940947/**************************************** 
    941948 * Returns !=0 if there's an extra member which is the 'this' 
     
    11041111        } 
    11051112    } 
     1113#if 0 
     1114    // Inherit const/invariant from base class 
     1115    storage_class |= b->base->storage_class & (STCconst | STCinvariant); 
     1116#endif 
    11061117    i++; 
    11071118    } 
     
    11451156    } 
    11461157 
     1158    protection = sc->protection; 
     1159    storage_class |= sc->stc & (STCconst | STCinvariant); 
     1160 
    11471161    for (i = 0; i < members->dim; i++) 
    11481162    { 
     
    11521166 
    11531167    sc = sc->push(this); 
     1168    sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 
     1169                 STCabstract | STCdeprecated | STCconst | STCinvariant); 
     1170    sc->stc |= storage_class & (STCconst | STCinvariant); 
    11541171    sc->parent = this; 
    11551172    if (isCOMinterface()) 
  • trunk/rebuild/declaration.c

    r840 r847  
    3131{ 
    3232    type = NULL; 
     33    originalType = NULL; 
    3334    storage_class = STCundefined; 
    3435    protection = PROTundefined; 
     
    9394    VarDeclaration *v = isVarDeclaration(); 
    9495    /* if (v && v->canassign == 0 && 
    95         (isConst() || isInvariant() || (isFinal() && !isCtorinit()))) 
    96     error(loc, "cannot modify final/const/invariant variable '%s'", toChars()); */ 
     96        (isConst() || isInvariant()) && !isCtorinit()) 
     97    error(loc, "cannot modify const/invariant variable '%s'", toChars()); */ 
    9798 
    9899    if (isCtorinit()) 
     
    434435     */ 
    435436    s = type->toDsymbol(sc); 
    436     if (s
     437    if (s && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())
    437438    goto L2;            // it's a symbolic alias 
    438439 
     
    642643{ 
    643644    //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 
    644     //printf(" type = %s\n", type->toChars()); 
    645     //printf("stc = x%x\n", sc->stc); 
     645    //printf(" type = %s\n", type ? type->toChars() : "null"); 
     646    //printf(" stc = x%x\n", sc->stc); 
    646647    //printf("linkage = %d\n", sc->linkage); 
    647648    //if (strcmp(toChars(), "mul") == 0) halt(); 
     
    664665     */ 
    665666    storage_class &= ~STCauto; 
     667    originalType = type; 
    666668    } 
    667669    else 
     670    {   if (!originalType) 
     671        originalType = type; 
    668672    type = type->semantic(loc, sc); 
     673    } 
     674    //printf(" type = %s\n", type ? type->toChars() : "null"); 
    669675 
    670676    type->checkDeprecated(loc, sc); 
     
    736742    } 
    737743 
    738     if (storage_class & STCfinal && !init && !fd) 
    739     {   // Initialize by constructor only 
    740     storage_class |= STCctorinit; 
    741     } 
    742  
    743744Lagain: 
    744     if (isConst()) 
    745     { 
    746     /* Rewrite things like: 
    747      *  const string s; 
    748      * to: 
    749      *  invariant string s; 
    750      */ 
    751     if (type->nextOf() && type->nextOf()->isInvariant()) 
    752     {   storage_class |= STCinvariant; 
    753         storage_class &= ~STCconst; 
    754         goto Lagain; 
    755     } 
    756     type = type->constOf(); 
    757     if (isParameter()) 
    758     {   storage_class |= STCfinal; 
    759         storage_class &= ~STCconst; 
    760     } 
    761     } 
    762     else if (storage_class & STCinvariant) 
     745    if (storage_class & STCinvariant) 
    763746    { 
    764747    type = type->invariantOf(); 
    765     if (isParameter()) 
    766     {   storage_class |= STCfinal; 
    767         storage_class &= ~STCinvariant; 
    768     } 
    769     } 
    770     type = type->toCanonConst(); 
    771  
    772     if (storage_class & (STCconst | STCinvariant | STCstatic)) 
     748    } 
     749    else if (storage_class & (STCconst | STCin)) 
     750    { 
     751    if (!type->isInvariant()) 
     752        type = type->constOf(); 
     753    } 
     754 
     755    if (storage_class & (STCstatic | STCextern)) 
    773756    { 
    774757    } 
     
    794777        aad = parent->isAggregateDeclaration(); 
    795778    if (aad) 
    796     {   assert(!(storage_class & (STCconst | STCinvariant | STCstatic))); 
    797         aad->addField(sc, this); 
     779    {   assert(!(storage_class & (STCextern | STCstatic))); 
     780 
     781        if (storage_class & (STCconst | STCinvariant) && init) 
     782        { 
     783        if (!type->toBasetype()->isTypeBasic()) 
     784            storage_class |= STCstatic; 
     785        } 
     786        else 
     787        aad->addField(sc, this); 
    798788    } 
    799789 
     
    804794    } 
    805795 
     796    /* Templates cannot add fields to aggregates 
     797     */ 
    806798    TemplateInstance *ti = parent->isTemplateInstance(); 
    807799    if (ti) 
     
    839831    } 
    840832 
    841     if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 
    842     !(storage_class & (STCfield | STCin | STCforeach)) && 
     833    if ((isConst() || isInvariant()) && !init && !fd) 
     834    {   // Initialize by constructor only 
     835    storage_class |= STCctorinit; 
     836    } 
     837 
     838    if (init) 
     839    storage_class |= STCinit;     // remember we had an explicit initializer 
     840 
     841    if (!init && !sc->inunion && !isStatic() && fd && 
     842    (!(storage_class & (STCfield | STCin | STCforeach | STCparameter)) || (storage_class & STCout)) && 
    843843    type->size() != 0) 
    844844    { 
     
    906906        // If local variable, use AssignExp to handle all the various 
    907907        // possibilities. 
    908         if (fd && !isStatic() && !isConst() && !isInvariant() && 
     908        if (fd && !isStatic() && 
    909909        !init->isVoidInitializer()) 
    910910        { 
     
    967967        { 
    968968        init = init->semantic(sc, type); 
    969         if (fd && (isConst() || isInvariant()) && !isStatic()) 
    970         {   // Make it static 
    971             storage_class |= STCstatic; 
    972         } 
    973         } 
    974     } 
    975     else if (isConst() || isInvariant() || isFinal()) 
     969        } 
     970    } 
     971    else if (storage_class & (STCconst | STCinvariant) || 
     972         type->isConst() || type->isInvariant()) 
    976973    { 
    977974        /* Because we may need the results of a const declaration in a 
     
    10141011        else if (ei) 
    10151012        { 
    1016             e = e->optimize(WANTvalue | WANTinterpret); 
     1013            if (isDataseg()) 
     1014            /* static const/invariant does CTFE 
     1015             */ 
     1016            e = e->optimize(WANTvalue | WANTinterpret); 
     1017            else 
     1018            e = e->optimize(WANTvalue); 
    10171019            if (e->op == TOKint64 || e->op == TOKstring) 
    10181020            { 
     
    10341036} 
    10351037 
    1036 ExpInitializer *VarDeclaration::getExpInitializer() 
    1037 { 
    1038     ExpInitializer *ei; 
    1039  
    1040     if (init) 
    1041     ei = init->isExpInitializer(); 
    1042     else 
    1043     { 
    1044     Expression *e = type->defaultInit(); 
    1045     if (e) 
    1046         ei = new ExpInitializer(loc, e); 
    1047     else 
    1048         ei = NULL; 
    1049     } 
    1050     return ei; 
    1051 } 
    1052  
    10531038void VarDeclaration::semantic2(Scope *sc) 
    10541039{ 
     
    10841069void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    10851070{ 
     1071    if (storage_class & STCstatic) 
     1072    buf->writestring("static "); 
    10861073    if (storage_class & STCconst) 
    10871074    buf->writestring("const "); 
    1088     if (storage_class & STCstatic) 
    1089     buf->writestring("static "); 
     1075    if (storage_class & STCinvariant) 
     1076    buf->writestring("invariant "); 
     1077 
    10901078    if (type) 
    10911079    type->toCBuffer(buf, ident, hgs); 
     
    11081096int VarDeclaration::isImportedSymbol() 
    11091097{ 
    1110     if (protection == PROTexport && !init && (isStatic() || isConst() || parent->isModule())) 
     1098    if (protection == PROTexport && !init && 
     1099    (storage_class & STCstatic || parent->isModule())) 
    11111100    return TRUE; 
    11121101    return FALSE; 
     
    11601149} 
    11611150 
     1151/**************************** 
     1152 * Get ExpInitializer for a variable, if there is one. 
     1153 */ 
     1154 
     1155ExpInitializer *VarDeclaration::getExpInitializer() 
     1156{ 
     1157    ExpInitializer *ei; 
     1158 
     1159    if (init) 
     1160    ei = init->isExpInitializer(); 
     1161    else 
     1162    { 
     1163    Expression *e = type->defaultInit(); 
     1164    if (e) 
     1165        ei = new ExpInitializer(loc, e); 
     1166    else 
     1167        ei = NULL; 
     1168    } 
     1169    return ei; 
     1170} 
     1171 
     1172/******************************************* 
     1173 * If variable has a constant expression initializer, get it. 
     1174 * Otherwise, return NULL. 
     1175 */ 
     1176 
     1177Expression *VarDeclaration::getConstInitializer() 
     1178{ 
     1179    if ((isConst() || isInvariant()) && 
     1180    storage_class & STCinit) 
     1181    { 
     1182    ExpInitializer *ei = getExpInitializer(); 
     1183    if (ei) 
     1184        return ei->exp; 
     1185    } 
     1186 
     1187    return NULL; 
     1188} 
     1189 
     1190/************************************* 
     1191 * Return !=0 if we can take the address of this variable. 
     1192 */ 
     1193 
     1194int VarDeclaration::canTakeAddressOf() 
     1195{ 
     1196    /* Global variables and struct/class fields of the form: 
     1197     *  const int x = 3; 
     1198     * are not stored and hence cannot have their address taken. 
     1199     */ 
     1200    if ((isConst() || isInvariant()) && 
     1201    storage_class & STCinit && 
     1202    (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) && 
     1203    (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) && 
     1204    type->toBasetype()->isTypeBasic() 
     1205       ) 
     1206    { 
     1207    return 0; 
     1208    } 
     1209    return 1; 
     1210} 
    11621211 
    11631212/******************************* 
    11641213 * Does symbol go into data segment? 
     1214 * Includes extern variables. 
    11651215 */ 
    11661216 
     
    11731223#endif 
    11741224    Dsymbol *parent = this->toParent(); 
    1175     if (!parent && !(storage_class & (STCstatic | STCconst))) 
     1225    if (!parent && !(storage_class & STCstatic)) 
    11761226    {   //error("forward referenced"); 
    1177 halt(); 
    11781227    type = Type::terror; 
    11791228    return 0; 
    11801229    } 
    1181     return (storage_class & (STCstatic | STCconst) || 
    1182        parent->isModule() || 
    1183        parent->isTemplateInstance()); 
     1230    return canTakeAddressOf() && 
     1231    (storage_class & (STCstatic | STCextern) || 
     1232     toParent()->isModule() || 
     1233     toParent()->isTemplateInstance()); 
    11841234} 
    11851235 
  • trunk/rebuild/declaration.h

    r840 r847  
    6464    STCinvariant    = 0x100000, 
    6565    STCref      = 0x200000, 
     66    STCinit     = 0x400000,     // has explicit initializer 
    6667}; 
    6768 
     
    7576}; 
    7677 
    77 void overloadResolveX(Match *m, FuncDeclaration *f, Expressions *arguments); 
     78void overloadResolveX(Match *m, FuncDeclaration *f, 
     79    Expression *ethis, Expressions *arguments); 
    7880int overloadApply(FuncDeclaration *fstart, 
    7981    int (*fp)(void *, FuncDeclaration *), 
     
    8587{ 
    8688    Type *type; 
     89    Type *originalType;     // before semantic analysis 
    8790    unsigned storage_class; 
    8891    enum PROT protection; 
     
    237240    int isDataseg(); 
    238241    int hasPointers(); 
     242    int canTakeAddressOf(); 
    239243    Expression *callAutoDtor(); 
    240244    ExpInitializer *getExpInitializer(); 
     245    Expression *getConstInitializer(); 
    241246    void checkCtorConstInit(); 
    242247    void checkNestedReference(Scope *sc, Loc loc); 
     
    475480    int overloadInsert(Dsymbol *s); 
    476481    FuncDeclaration *overloadExactMatch(Type *t); 
    477     FuncDeclaration *overloadResolve(Loc loc, Expressions *arguments, int flags = 0); 
     482    FuncDeclaration *overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags = 0); 
    478483    LabelDsymbol *searchLabel(Identifier *ident); 
    479484    AggregateDeclaration *isThis(); 
  • trunk/rebuild/doc.c

    r785 r847  
    270270 
    271271    buf.printf("$(DDOC_COMMENT Generated by Ddoc from %s)\n", srcfile->toChars()); 
    272  
    273272    if (isDocFile) 
    274273    { 
     
    284283    else 
    285284    { 
    286  
    287285    dc->writeSections(sc, this, sc->docbuf); 
    288286    emitMemberComments(sc); 
     
    655653    if (d->isConst()) 
    656654        buf->writestring("const "); 
     655#if V2 
     656    if (d->isInvariant()) 
     657        buf->writestring("invariant "); 
     658#endif 
    657659    if (d->isFinal()) 
    658660        buf->writestring("final "); 
     
    664666void Declaration::toDocBuffer(OutBuffer *buf) 
    665667{ 
    666     //printf("Declaration::toDocbuffer() %s\n", toChars()); 
     668    //printf("Declaration::toDocbuffer() %s, originalType = %p\n", toChars(), originalType); 
    667669    if (ident) 
    668670    { 
     
    672674    {   HdrGenState hgs; 
    673675        hgs.ddoc = 1; 
    674         type->toCBuffer(buf, ident, &hgs); 
     676        if (originalType) 
     677        {   //originalType->print(); 
     678        originalType->toCBuffer(buf, ident, &hgs); 
     679        } 
     680        else 
     681        type->toCBuffer(buf, ident, &hgs); 
    675682    } 
    676683    else 
  • trunk/rebuild/dsymbol.c

    r840 r847  
    934934        Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); 
    935935        v->init = new ExpInitializer(0, e); 
    936         v->storage_class |= STCconst; 
     936        v->storage_class |= STCstatic | STCconst; 
    937937        v->semantic(sc); 
    938938        return v; 
     
    944944        Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); 
    945945        v->init = new ExpInitializer(0, e); 
    946         v->storage_class |= STCconst; 
     946        v->storage_class |= STCstatic | STCconst; 
    947947        v->semantic(sc); 
    948948        return v; 
     
    990990        Expression *e = new IntegerExp(0, ((StringExp *)ce)->len, Type::tsize_t); 
    991991        v->init = new ExpInitializer(0, e); 
    992         v->storage_class |= STCconst; 
     992        v->storage_class |= STCstatic | STCconst; 
    993993        } 
    994994        else if (ce->op == TOKarrayliteral) 
     
    998998        Expression *e = new IntegerExp(0, ((ArrayLiteralExp *)ce)->elements->dim, Type::tsize_t); 
    999999        v->init = new ExpInitializer(0, e); 
    1000         v->storage_class |= STCconst; 
     1000        v->storage_class |= STCstatic | STCconst; 
    10011001        } 
    10021002        else if (ce->op == TOKtuple) 
     
    10061006        Expression *e = new IntegerExp(0, ((TupleExp *)ce)->exps->dim, Type::tsize_t); 
    10071007        v->init = new ExpInitializer(0, e); 
    1008         v->storage_class |= STCconst; 
     1008        v->storage_class |= STCstatic | STCconst; 
    10091009        } 
    10101010        *pvar = v; 
  • trunk/rebuild/expression.c

    r840 r847  
    833833Expression *Expression::modifiableLvalue(Scope *sc, Expression *e) 
    834834{ 
    835     //printf("Expression::modifiableLvalue() %s\n", toChars()); 
     835    //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars()); 
    836836 
    837837    // See if this expression is a modifiable lvalue (i.e. not const) 
     
    10501050    if (this == o || 
    10511051    (((Expression *)o)->op == TOKint64 && 
    1052      ((ne = (IntegerExp *)o), type->equals(ne->type)) && 
     1052     ((ne = (IntegerExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 
    10531053     value == ne->value)) 
    10541054    return 1; 
     
    12911291char *RealExp::toChars() 
    12921292{ 
    1293     static char buffer[sizeof(value) * 3 + 8 + 1 + 1]; 
     1293    char buffer[sizeof(value) * 3 + 8 + 1 + 1]; 
    12941294 
    12951295#ifdef IN_GCC 
     
    13011301#endif 
    13021302    assert(strlen(buffer) < sizeof(buffer)); 
    1303     return buffer
     1303    return mem.strdup(buffer)
    13041304} 
    13051305 
     
    13611361    if (this == o || 
    13621362    (((Expression *)o)->op == TOKfloat64 && 
    1363      ((ne = (RealExp *)o), type->equals(ne->type)) && 
     1363     ((ne = (RealExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 
    13641364     RealEquals(value, ne->value) 
    13651365        ) 
     
    15051505char *ComplexExp::toChars() 
    15061506{ 
    1507     static char buffer[sizeof(value) * 3 + 8 + 1]; 
     1507    char buffer[sizeof(value) * 3 + 8 + 1]; 
    15081508 
    15091509#ifdef IN_GCC 
     
    15171517    assert(strlen(buffer) < sizeof(buffer)); 
    15181518#endif 
    1519     return buffer
     1519    return mem.strdup(buffer)
    15201520} 
    15211521 
     
    15581558    if (this == o || 
    15591559    (((Expression *)o)->op == TOKcomplex80 && 
    1560      ((ne = (ComplexExp *)o), type->equals(ne->type)) && 
     1560     ((ne = (ComplexExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 
    15611561     RealEquals(creall(value), creall(ne->value)) && 
    15621562     RealEquals(cimagl(value), cimagl(ne->value)) 
     
    31333133        error("cannot create instance of interface %s", cd->toChars()); 
    31343134    else if (cd->isAbstract()) 
    3135         error("cannot create instance of abstract class %s", cd->toChars()); */ 
     3135    {   error("cannot create instance of abstract class %s", cd->toChars()); 
     3136        for (int i = 0; i < cd->vtbl.dim; i++) 
     3137        {   FuncDeclaration *fd = ((Dsymbol *)cd->vtbl.data[i])->isFuncDeclaration(); 
     3138        if (fd && fd->isAbstract()) 
     3139            error("function %s is abstract", fd->toChars()); 
     3140        } 
     3141    } */ 
    31363142    checkDeprecated(sc, cd); 
    31373143    if (cd->isNested()) 
     
    32103216    { 
    32113217        assert(f); 
    3212         f = f->overloadResolve(loc, arguments); 
     3218        f = f->overloadResolve(loc, NULL, arguments); 
    32133219        checkDeprecated(sc, f); 
    32143220        member = f->isCtorDeclaration(); 
     
    32413247        newargs->shift(e); 
    32423248 
    3243         f = f->overloadResolve(loc, newargs); 
     3249        f = f->overloadResolve(loc, NULL, newargs); 
    32443250        allocator = f->isNewDeclaration(); 
    32453251        assert(allocator); 
     
    32753281        newargs->shift(e); 
    32763282 
    3277         f = f->overloadResolve(loc, newargs); 
     3283        f = f->overloadResolve(loc, NULL, newargs); 
    32783284        allocator = f->isNewDeclaration(); 
    32793285        assert(allocator); 
     
    33043310        arg = resolveProperties(sc, arg); 
    33053311        arg = arg->implicitCastTo(sc, Type::tsize_t); 
    3306         /*if (arg->op == TOKint64 && (long long)arg->toInteger() < 0) 
     3312        arg = arg->optimize(WANTvalue); 
     3313        /* if (arg->op == TOKint64 && (long long)arg->toInteger() < 0) 
    33073314        error("negative array index %s", arg->toChars()); */ 
    33083315        arguments->data[i] = (void *) arg; 
     
    35023509    if (this == o || 
    35033510    (((Expression *)o)->op == TOKvar && 
    3504      ((ne = (VarExp *)o), type->equals(ne->type)) && 
     3511     ((ne = (VarExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 
    35053512     var == ne->var)) 
    35063513    return 1; 
     
    41194126        tded = targ; 
    41204127        break; 
     4128 
     4129#if V2 
     4130        case TOKconst: 
     4131        if (!targ->isConst()) 
     4132            goto Lno; 
     4133        tded = targ; 
     4134        break; 
     4135 
     4136        case TOKinvariant: 
     4137        if (!targ->isInvariant()) 
     4138            goto Lno; 
     4139        tded = targ; 
     4140        break; 
     4141#endif 
    41214142 
    41224143        case TOKsuper: 
     
    55995620    AggregateDeclaration *ad; 
    56005621    UnaExp *ue = (UnaExp *)(e1); 
    5601          
     5622 
    56025623        if (e1->op == TOKdotvar) 
    56035624        {   // Do overload resolution 
     
    56065627        f = dve->var->isFuncDeclaration(); 
    56075628        assert(f); 
    5608         f = f->overloadResolve(loc, arguments); 
     5629        f = f->overloadResolve(loc, ue->e1, arguments); 
    56095630 
    56105631        ad = f->toParent()->isAggregateDeclaration(); 
     
    56155636        assert(td); 
    56165637        if (!arguments) 
    5617         // Should fix deduce() so it works on NULL argument 
     5638        // Should fix deduceFunctionTemplate() so it works on NULL argument 
    56185639        arguments = new Expressions(); 
    5619         f = td->deduce(sc, loc, NULL, arguments); 
     5640        f = td->deduceFunctionTemplate(sc, loc, NULL, ue->e1, arguments); 
    56205641        if (!f) 
    56215642        {   type = Type::terror; 
     
    56835704#endif 
    56845705        // Const member function can take const/invariant/mutable this 
    5685         if (!(f->storage_class & STCconst)) 
     5706        if (!(f->type->isConst())) 
    56865707        { 
    56875708        // Check for const/invariant compatibility 
     
    56895710        if (tthis->ty == Tpointer) 
    56905711            tthis = tthis->nextOf()->toBasetype(); 
    5691         if (f->storage_class & STCinvariant
     5712        if (f->type->isInvariant()
    56925713        { 
    56935714            /* if (tthis->mod != MODinvariant) 
     
    56975718        { 
    56985719            /* if (tthis->mod != 0) 
    5699             error("%s can only be called on a mutable object", e1->toChars()); */ 
     5720            {   //printf("test1: mod = %x\n", tthis->mod); 
     5721            error("%s can only be called on a mutable object, not %s", e1->toChars(), tthis->toChars()); 
     5722            } */ 
    57005723        } 
    57015724 
     
    57555778        sc->callSuper |= CSXany_ctor | CSXsuper_ctor; 
    57565779 
    5757         f = f->overloadResolve(loc, arguments); 
     5780        f = f->overloadResolve(loc, NULL, arguments); 
    57585781        checkDeprecated(sc, f); 
    57595782        e1 = new DotVarExp(e1->loc, e1, f); 
     
    57895812 
    57905813        f = cd->ctor; 
    5791         f = f->overloadResolve(loc, arguments); 
     5814        f = f->overloadResolve(loc, NULL, arguments); 
    57925815        checkDeprecated(sc, f); 
    57935816        e1 = new DotVarExp(e1->loc, e1, f); 
     
    58105833        if (f2) 
    58115834        { 
    5812         f2 = f2->overloadResolve(loc, arguments, 1); 
     5835        f2 = f2->overloadResolve(loc, NULL, arguments, 1); 
    58135836        } 
    58145837        else 
    58155838        {   TemplateDeclaration *td = s->isTemplateDeclaration(); 
    58165839        assert(td); 
    5817         f2 = td->deduce(sc, loc, NULL, arguments, 1); 
     5840        f2 = td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments, 1); 
    58185841        } 
    58195842        if (f2) 
     
    58615884    { 
    58625885        TemplateExp *te = (TemplateExp *)e1; 
    5863         f = te->td->deduce(sc, loc, NULL, arguments); 
     5886        f = te->td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments); 
    58645887        if (!f) 
    58655888        {   type = Type::terror; 
     
    58935916 
    58945917    if (ve->hasOverloads) 
    5895         f = f->overloadResolve(loc, arguments); 
     5918        f = f->overloadResolve(loc, NULL, arguments); 
    58965919    checkDeprecated(sc, f); 
    58975920 
     
    59926015    { 
    59936016        DotVarExp *dve = (DotVarExp *)e1; 
    5994         if (dve->var->isFinal()) 
    5995         type = e1->type->constOf()->pointerTo(); 
    59966017 
    59976018        FuncDeclaration *f = dve->var->isFuncDeclaration(); 
     
    60096030    { 
    60106031        VarExp *ve = (VarExp *)e1; 
    6011         if (ve->var->isFinal()) 
    6012         type = e1->type->constOf()->pointerTo(); 
     6032 
     6033        VarDeclaration *v = ve->var->isVarDeclaration(); 
     6034        if (v && !v->canTakeAddressOf()) 
     6035        error("cannot take address of %s", e1->toChars()); 
    60136036 
    60146037        FuncDeclaration *f = ve->var->isFuncDeclaration(); 
     
    60986121Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e) 
    60996122{ 
    6100     //printf("PtrExp::modifiableLvalue() %s\n", toChars()); 
     6123    //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars()); 
    61016124 
    61026125    if (e1->op == TOKsymoff) 
    61036126    {   SymOffExp *se = (SymOffExp *)e1; 
    61046127    se->var->checkModify(loc, sc); 
    6105     return toLvalue(sc, e); 
     6128    //return toLvalue(sc, e); 
    61066129    } 
    61076130 
     
    70807103 
    70817104#if LOGSEMANTIC 
    7082     //printf("AssignExp::semantic('%s')\n", toChars()); 
     7105    printf("AssignExp::semantic('%s')\n", toChars()); 
    70837106#endif 
    70847107    //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op)); 
     
    72457268    {   // Try to do a decent error message with the expression 
    72467269    // before it got constant folded 
    7247     e1 = e1->optimize(WANTvalue); 
     7270    if (e1->op != TOKvar) 
     7271        e1 = e1->optimize(WANTvalue); 
    72487272    e1 = e1->modifiableLvalue(sc, e1old); 
    72497273    } 
     
    79487972 
    79497973    typeCombine(sc); 
    7950 //type->print(); 
    7951     type = type->mutableOf(); 
    7952 //printf("test1\n"); 
    7953 //type->print(); 
     7974    type = type->toHeadMutable(); 
    79547975 
    79557976    Type *tb = type->toBasetype(); 
    79567977    if (tb->ty == Tsarray) 
    79577978        type = tb->nextOf()->arrayOf(); 
    7958 //printf("test2\n"); 
    7959 //type->print(); 
    79607979    if (type->ty == Tarray && tb1->nextOf()->mod != tb2->nextOf()->mod) 
    7961         type = type->nextOf()->toCanonConst()->arrayOf(); 
    7962 //printf("test3\n"); 
    7963 //type->print(); 
     7980        type = type->nextOf()->toHeadMutable()->arrayOf(); 
    79647981#if 0 
    79657982    e1->type->print(); 
     
    87918808        break; 
    87928809    } 
     8810    if (type->toBasetype()->ty == Tarray) 
     8811    { 
     8812        e1 = e1->castTo(sc, type); 
     8813        e2 = e2->castTo(sc, type); 
     8814    } 
    87938815    } 
    87948816#if 0 
  • trunk/rebuild/func.c

    r840 r847  
    111111#endif 
    112112 
    113     if (type->nextOf()) 
     113    storage_class |= sc->stc; 
     114    //printf("function storage_class = x%x\n", storage_class); 
     115 
     116    if (!originalType) 
     117    originalType = type; 
     118    if (!type->deco && type->nextOf()) 
     119    { 
     120#if 1 
     121    /* Apply const and invariant storage class 
     122     * to the function type 
     123     */ 
    114124    type = type->semantic(loc, sc); 
     125    if (storage_class & STCinvariant) 
     126    {   // Don't use toInvariant(), as that will do a merge() 
     127        type = type->makeInvariant(); 
     128        type->deco = type->merge()->deco; 
     129    } 
     130    else if (storage_class & STCconst) 
     131    { 
     132        if (!type->isInvariant()) 
     133        {   // Don't use toConst(), as that will do a merge() 
     134        type = type->makeConst(); 
     135        type->deco = type->merge()->deco; 
     136        } 
     137    } 
     138#else 
     139    if (storage_class & (STCconst | STCinvariant)) 
     140    { 
     141        /* Apply const and invariant storage class 
     142         * to the function's return type 
     143         */ 
     144        Type *tn = type->nextOf(); 
     145        if (storage_class & STCconst) 
     146        tn = tn->makeConst(); 
     147        if (storage_class & STCinvariant) 
     148        tn = tn->makeInvariant(); 
     149        ((TypeNext *)type)->next = tn; 
     150    } 
     151 
     152    type = type->semantic(loc, sc); 
     153#endif 
     154    } 
    115155    //type->print(); 
    116156    if (type->ty != Tfunction) 
     
    120160    } 
    121161    f = (TypeFunction *)(type); 
     162 
    122163    size_t nparams = Argument::dim(f->parameters); 
    123164 
     
    129170    } 
    130171    protection = sc->protection; 
    131     storage_class |= sc->stc; 
    132     //printf("function storage_class = x%x\n", storage_class); 
    133172    Dsymbol *parent = toParent(); 
    134173 
     
    138177    /*if (isAbstract() && !isVirtual()) 
    139178    error("non-virtual functions cannot be abstract"); */ 
     179 
     180    if ((f->isConst() || f->isInvariant()) && !isThis()) 
     181    error("without 'this' cannot be const/invariant"); 
     182 
     183    if (isAbstract() && isFinal()) 
     184    error("cannot be both final and abstract"); 
    140185#if 0 
    141186    if (isAbstract() && fbody) 
     
    682727#if BREAKABI 
    683728        v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL); 
    684         v_arguments->storage_class = STCparameter | STCin
     729        v_arguments->storage_class = STCparameter
    685730        v_arguments->semantic(sc2); 
    686731        sc2->insert(v_arguments); 
    687732        v_arguments->parent = this; 
    688733 
     734        //t = Type::typeinfo->type->constOf()->arrayOf(); 
    689735        t = Type::typeinfo->type->arrayOf(); 
    690736        _arguments = new VarDeclaration(0, t, Id::_arguments, NULL); 
     
    11111157        Expression *e1 = new VarExp(0, _arguments); 
    11121158        e = new AssignExp(0, e1, e); 
     1159        e->op = TOKconstruct; 
    11131160        e = e->semantic(sc); 
    11141161        a->push(new ExpStatement(0, e)); 
     
    13021349    if (type && f->type &&  // can be NULL for overloaded constructors 
    13031350    f->type->covariant(type) && 
     1351    f->type->mod == type->mod && 
    13041352    !isFuncAliasDeclaration()) 
    13051353    { 
     
    14491497{ 
    14501498    Match *m; 
     1499    Expression *ethis; 
    14511500    Expressions *arguments; 
    14521501}; 
     
    14641513    m->anyf = f; 
    14651514    tf = (TypeFunction *)f->type; 
    1466     match = (MATCH) tf->callMatch(arguments); 
     1515    match = (MATCH) tf->callMatch(f->needThis() ? p->ethis : NULL, arguments); 
    14671516    //printf("match = %d\n", match); 
    14681517    if (match != MATCHnomatch) 
     
    14991548} 
    15001549 
    1501 void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments) 
     1550void overloadResolveX(Match *m, FuncDeclaration *fstart, 
     1551    Expression *ethis, Expressions *arguments) 
    15021552{ 
    15031553    Param2 p; 
    15041554    p.m = m; 
     1555    p.ethis = ethis; 
    15051556    p.arguments = arguments; 
    15061557    overloadApply(fstart, &fp2, &p); 
     
    15081559 
    15091560 
    1510 FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expressions *arguments, int flags) 
     1561FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags) 
    15111562{ 
    15121563    TypeFunction *tf; 
     
    15311582    m