Changeset 846

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

MERGE: DMD 2.008

Files:

Legend:

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

    r740 r846  
    283283    if (stc & (STCauto | STCscope | STCstatic | STCextern)) 
    284284        sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 
     285    if (stc & (STCconst | STCinvariant)) 
     286        sc->stc &= ~(STCconst | STCinvariant); 
    285287    sc->stc |= stc; 
    286288    for (unsigned i = 0; i < decl->dim; i++) 
     
    311313    { STCextern,       TOKextern }, 
    312314    { STCconst,        TOKconst }, 
     315    { STCinvariant,    TOKinvariant }, 
    313316    { STCfinal,        TOKfinal }, 
    314317    { STCabstract,     TOKabstract }, 
  • branches/dmdfe-2.0/cast.c

    r838 r846  
    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    } 
  • branches/dmdfe-2.0/class.c

    r837 r846  
    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()) 
  • branches/dmdfe-2.0/declaration.c

    r838 r846  
    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 
     
    643644{ 
    644645    //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 
    645     //printf(" type = %s\n", type->toChars()); 
    646     //printf("stc = x%x\n", sc->stc); 
     646    //printf(" type = %s\n", type ? type->toChars() : "null"); 
     647    //printf(" stc = x%x\n", sc->stc); 
    647648    //printf("linkage = %d\n", sc->linkage); 
    648649    //if (strcmp(toChars(), "mul") == 0) halt(); 
     
    665666     */ 
    666667    storage_class &= ~STCauto; 
     668    originalType = type; 
    667669    } 
    668670    else 
     671    {   if (!originalType) 
     672        originalType = type; 
    669673    type = type->semantic(loc, sc); 
     674    } 
     675    //printf(" type = %s\n", type ? type->toChars() : "null"); 
    670676 
    671677    type->checkDeprecated(loc, sc); 
     
    737743    } 
    738744 
    739     if (storage_class & STCfinal && !init && !fd) 
    740     {   // Initialize by constructor only 
    741     storage_class |= STCctorinit; 
    742     } 
    743  
    744745Lagain: 
    745     if (isConst()) 
    746     { 
    747     /* Rewrite things like: 
    748      *  const string s; 
    749      * to: 
    750      *  invariant string s; 
    751      */ 
    752     if (type->nextOf() && type->nextOf()->isInvariant()) 
    753     {   storage_class |= STCinvariant; 
    754         storage_class &= ~STCconst; 
    755         goto Lagain; 
    756     } 
    757     type = type->constOf(); 
    758     if (isParameter()) 
    759     {   storage_class |= STCfinal; 
    760         storage_class &= ~STCconst; 
    761     } 
    762     } 
    763     else if (storage_class & STCinvariant) 
     746    if (storage_class & STCinvariant) 
    764747    { 
    765748    type = type->invariantOf(); 
    766     if (isParameter()) 
    767     {   storage_class |= STCfinal; 
    768         storage_class &= ~STCinvariant; 
    769     } 
    770     } 
    771     type = type->toCanonConst(); 
    772  
    773     if (storage_class & (STCconst | STCinvariant | STCstatic)) 
     749    } 
     750    else if (storage_class & (STCconst | STCin)) 
     751    { 
     752    if (!type->isInvariant()) 
     753        type = type->constOf(); 
     754    } 
     755 
     756    if (storage_class & (STCstatic | STCextern)) 
    774757    { 
    775758    } 
     
    795778        aad = parent->isAggregateDeclaration(); 
    796779    if (aad) 
    797     {   assert(!(storage_class & (STCconst | STCinvariant | STCstatic))); 
    798         aad->addField(sc, this); 
     780    {   assert(!(storage_class & (STCextern | STCstatic))); 
     781 
     782        if (storage_class & (STCconst | STCinvariant) && init) 
     783        { 
     784        if (!type->toBasetype()->isTypeBasic()) 
     785            storage_class |= STCstatic; 
     786        } 
     787        else 
     788        aad->addField(sc, this); 
    799789    } 
    800790 
     
    805795    } 
    806796 
     797    /* Templates cannot add fields to aggregates 
     798     */ 
    807799    TemplateInstance *ti = parent->isTemplateInstance(); 
    808800    if (ti) 
     
    840832    } 
    841833 
    842     if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 
    843     !(storage_class & (STCfield | STCin | STCforeach)) && 
     834    if ((isConst() || isInvariant()) && !init && !fd) 
     835    {   // Initialize by constructor only 
     836    storage_class |= STCctorinit; 
     837    } 
     838 
     839    if (init) 
     840    storage_class |= STCinit;     // remember we had an explicit initializer 
     841 
     842    if (!init && !sc->inunion && !isStatic() && fd && 
     843    (!(storage_class & (STCfield | STCin | STCforeach | STCparameter)) || (storage_class & STCout)) && 
    844844    type->size() != 0) 
    845845    { 
     
    907907        // If local variable, use AssignExp to handle all the various 
    908908        // possibilities. 
    909         if (fd && !isStatic() && !isConst() && !isInvariant() && 
     909        if (fd && !isStatic() && 
    910910        !init->isVoidInitializer()) 
    911911        { 
     
    968968        { 
    969969        init = init->semantic(sc, type); 
    970         if (fd && (isConst() || isInvariant()) && !isStatic()) 
    971         {   // Make it static 
    972             storage_class |= STCstatic; 
    973         } 
    974         } 
    975     } 
    976     else if (isConst() || isInvariant() || isFinal()) 
     970        } 
     971    } 
     972    else if (storage_class & (STCconst | STCinvariant) || 
     973         type->isConst() || type->isInvariant()) 
    977974    { 
    978975        /* Because we may need the results of a const declaration in a 
     
    10151012        else if (ei) 
    10161013        { 
    1017             e = e->optimize(WANTvalue | WANTinterpret); 
     1014            if (isDataseg()) 
     1015            /* static const/invariant does CTFE 
     1016             */ 
     1017            e = e->optimize(WANTvalue | WANTinterpret); 
     1018            else 
     1019            e = e->optimize(WANTvalue); 
    10181020            if (e->op == TOKint64 || e->op == TOKstring) 
    10191021            { 
     
    10351037} 
    10361038 
    1037 ExpInitializer *VarDeclaration::getExpInitializer() 
    1038 { 
    1039     ExpInitializer *ei; 
    1040  
    1041     if (init) 
    1042     ei = init->isExpInitializer(); 
    1043     else 
    1044     { 
    1045     Expression *e = type->defaultInit(); 
    1046     if (e) 
    1047         ei = new ExpInitializer(loc, e); 
    1048     else 
    1049         ei = NULL; 
    1050     } 
    1051     return ei; 
    1052 } 
    1053  
    10541039void VarDeclaration::semantic2(Scope *sc) 
    10551040{ 
     
    10851070void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    10861071{ 
     1072    if (storage_class & STCstatic) 
     1073    buf->writestring("static "); 
    10871074    if (storage_class & STCconst) 
    10881075    buf->writestring("const "); 
    1089     if (storage_class & STCstatic) 
    1090     buf->writestring("static "); 
     1076    if (storage_class & STCinvariant) 
     1077    buf->writestring("invariant "); 
     1078 
    10911079    if (type) 
    10921080    type->toCBuffer(buf, ident, hgs); 
     
    11091097int VarDeclaration::isImportedSymbol() 
    11101098{ 
    1111     if (protection == PROTexport && !init && (isStatic() || isConst() || parent->isModule())) 
     1099    if (protection == PROTexport && !init && 
     1100    (storage_class & STCstatic || parent->isModule())) 
    11121101    return TRUE; 
    11131102    return FALSE; 
     
    11611150} 
    11621151 
     1152/**************************** 
     1153 * Get ExpInitializer for a variable, if there is one. 
     1154 */ 
     1155 
     1156ExpInitializer *VarDeclaration::getExpInitializer() 
     1157{ 
     1158    ExpInitializer *ei; 
     1159 
     1160    if (init) 
     1161    ei = init->isExpInitializer(); 
     1162    else 
     1163    { 
     1164    Expression *e = type->defaultInit(); 
     1165    if (e) 
     1166        ei = new ExpInitializer(loc, e); 
     1167    else 
     1168        ei = NULL; 
     1169    } 
     1170    return ei; 
     1171} 
     1172 
     1173/******************************************* 
     1174 * If variable has a constant expression initializer, get it. 
     1175 * Otherwise, return NULL. 
     1176 */ 
     1177 
     1178Expression *VarDeclaration::getConstInitializer() 
     1179{ 
     1180    if ((isConst() || isInvariant()) && 
     1181    storage_class & STCinit) 
     1182    { 
     1183    ExpInitializer *ei = getExpInitializer(); 
     1184    if (ei) 
     1185        return ei->exp; 
     1186    } 
     1187 
     1188    return NULL; 
     1189} 
     1190 
     1191/************************************* 
     1192 * Return !=0 if we can take the address of this variable. 
     1193 */ 
     1194 
     1195int VarDeclaration::canTakeAddressOf() 
     1196{ 
     1197    /* Global variables and struct/class fields of the form: 
     1198     *  const int x = 3; 
     1199     * are not stored and hence cannot have their address taken. 
     1200     */ 
     1201    if ((isConst() || isInvariant()) && 
     1202    storage_class & STCinit && 
     1203    (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) && 
     1204    (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) && 
     1205    type->toBasetype()->isTypeBasic() 
     1206       ) 
     1207    { 
     1208    return 0; 
     1209    } 
     1210    return 1; 
     1211} 
    11631212 
    11641213/******************************* 
    11651214 * Does symbol go into data segment? 
     1215 * Includes extern variables. 
    11661216 */ 
    11671217 
     
    11741224#endif 
    11751225    Dsymbol *parent = this->toParent(); 
    1176     if (!parent && !(storage_class & (STCstatic | STCconst))) 
     1226    if (!parent && !(storage_class & STCstatic)) 
    11771227    {   error("forward referenced"); 
    1178 halt(); 
    11791228    type = Type::terror; 
    11801229    return 0; 
    11811230    } 
    1182     return (storage_class & (STCstatic | STCconst) || 
    1183        parent->isModule() || 
    1184        parent->isTemplateInstance()); 
     1231    return canTakeAddressOf() && 
     1232    (storage_class & (STCstatic | STCextern) || 
     1233     toParent()->isModule() || 
     1234     toParent()->isTemplateInstance()); 
    11851235} 
    11861236 
  • branches/dmdfe-2.0/declaration.h

    r838 r846  
    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(); 
  • branches/dmdfe-2.0/doc.c

    r783 r846  
    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 
  • branches/dmdfe-2.0/dsymbol.c

    r837 r846  
    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; 
  • branches/dmdfe-2.0/expression.c

    r838 r846  
    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; 
     
    12901290char *RealExp::toChars() 
    12911291{ 
    1292     static char buffer[sizeof(value) * 3 + 8 + 1 + 1]; 
     1292    char buffer[sizeof(value) * 3 + 8 + 1 + 1]; 
    12931293 
    12941294#ifdef IN_GCC 
     
    13001300#endif 
    13011301    assert(strlen(buffer) < sizeof(buffer)); 
    1302     return buffer
     1302    return mem.strdup(buffer)
    13031303} 
    13041304 
     
    13601360    if (this == o || 
    13611361    (((Expression *)o)->op == TOKfloat64 && 
    1362      ((ne = (RealExp *)o), type->equals(ne->type)) && 
     1362     ((ne = (RealExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 
    13631363     RealEquals(value, ne->value) 
    13641364        ) 
     
    15041504char *ComplexExp::toChars() 
    15051505{ 
    1506     static char buffer[sizeof(value) * 3 + 8 + 1]; 
     1506    char buffer[sizeof(value) * 3 + 8 + 1]; 
    15071507 
    15081508#ifdef IN_GCC 
     
    15161516    assert(strlen(buffer) < sizeof(buffer)); 
    15171517#endif 
    1518     return buffer
     1518    return mem.strdup(buffer)
    15191519} 
    15201520 
     
    15571557    if (this == o || 
    15581558    (((Expression *)o)->op == TOKcomplex80 && 
    1559      ((ne = (ComplexExp *)o), type->equals(ne->type)) && 
     1559     ((ne = (ComplexExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 
    15601560     RealEquals(creall(value), creall(ne->value)) && 
    15611561     RealEquals(cimagl(value), cimagl(ne->value)) 
     
    31323132        error("cannot create instance of interface %s", cd->toChars()); 
    31333133    else if (cd->isAbstract()) 
    3134         error("cannot create instance of abstract class %s", cd->toChars()); 
     3134    {   error("cannot create instance of abstract class %s", cd->toChars()); 
     3135        for (int i = 0; i < cd->vtbl.dim; i++) 
     3136        {   FuncDeclaration *fd = ((Dsymbol *)cd->vtbl.data[i])->isFuncDeclaration(); 
     3137        if (fd && fd->isAbstract()) 
     3138            error("function %s is abstract", fd->toChars()); 
     3139        } 
     3140    } 
    31353141    checkDeprecated(sc, cd); 
    31363142    if (cd->isNested()) 
     
    32093215    { 
    32103216        assert(f); 
    3211         f = f->overloadResolve(loc, arguments); 
     3217        f = f->overloadResolve(loc, NULL, arguments); 
    32123218        checkDeprecated(sc, f); 
    32133219        member = f->isCtorDeclaration(); 
     
    32403246        newargs->shift(e); 
    32413247 
    3242         f = f->overloadResolve(loc, newargs); 
     3248        f = f->overloadResolve(loc, NULL, newargs); 
    32433249        allocator = f->isNewDeclaration(); 
    32443250        assert(allocator); 
     
    32743280        newargs->shift(e); 
    32753281 
    3276         f = f->overloadResolve(loc, newargs); 
     3282        f = f->overloadResolve(loc, NULL, newargs); 
    32773283        allocator = f->isNewDeclaration(); 
    32783284        assert(allocator); 
     
    33033309        arg = resolveProperties(sc, arg); 
    33043310        arg = arg->implicitCastTo(sc, Type::tsize_t); 
     3311        arg = arg->optimize(WANTvalue); 
    33053312        if (arg->op == TOKint64 && (long long)arg->toInteger() < 0) 
    33063313        error("negative array index %s", arg->toChars()); 
     
    35013508    if (this == o || 
    35023509    (((Expression *)o)->op == TOKvar && 
    3503      ((ne = (VarExp *)o), type->equals(ne->type)) && 
     3510     ((ne = (VarExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 
    35043511     var == ne->var)) 
    35053512    return 1; 
     
    41184125        tded = targ; 
    41194126        break; 
     4127 
     4128#if V2 
     4129        case TOKconst: 
     4130        if (!targ->isConst()) 
     4131            goto Lno; 
     4132        tded = targ; 
     4133        break; 
     4134 
     4135        case TOKinvariant: 
     4136        if (!targ->isInvariant()) 
     4137            goto Lno; 
     4138        tded = targ; 
     4139        break; 
     4140#endif 
    41204141 
    41214142        case TOKsuper: 
     
    55985619    AggregateDeclaration *ad; 
    55995620    UnaExp *ue = (UnaExp *)(e1); 
    5600          
     5621 
    56015622        if (e1->op == TOKdotvar) 
    56025623        {   // Do overload resolution 
     
    56055626        f = dve->var->isFuncDeclaration(); 
    56065627        assert(f); 
    5607         f = f->overloadResolve(loc, arguments); 
     5628        f = f->overloadResolve(loc, ue->e1, arguments); 
    56085629 
    56095630        ad = f->toParent()->isAggregateDeclaration(); 
     
    56145635        assert(td); 
    56155636        if (!arguments) 
    5616         // Should fix deduce() so it works on NULL argument 
     5637        // Should fix deduceFunctionTemplate() so it works on NULL argument 
    56175638        arguments = new Expressions(); 
    5618         f = td->deduce(sc, loc, NULL, arguments); 
     5639        f = td->deduceFunctionTemplate(sc, loc, NULL, ue->e1, arguments); 
    56195640        if (!f) 
    56205641        {   type = Type::terror; 
     
    56825703#endif 
    56835704        // Const member function can take const/invariant/mutable this 
    5684         if (!(f->storage_class & STCconst)) 
     5705        if (!(f->type->isConst())) 
    56855706        { 
    56865707        // Check for const/invariant compatibility 
     
    56885709        if (tthis->ty == Tpointer) 
    56895710            tthis = tthis->nextOf()->toBasetype(); 
    5690         if (f->storage_class & STCinvariant
     5711        if (f->type->isInvariant()
    56915712        { 
    56925713            if (tthis->mod != MODinvariant) 
     
    56965717        { 
    56975718            if (tthis->mod != 0) 
    5698             error("%s can only be called on a mutable object", e1->toChars()); 
     5719            {   //printf("test1: mod = %x\n", tthis->mod); 
     5720            error("%s can only be called on a mutable object, not %s", e1->toChars(), tthis->toChars()); 
     5721            } 
    56995722        } 
    57005723 
     
    57545777        sc->callSuper |= CSXany_ctor | CSXsuper_ctor; 
    57555778 
    5756         f = f->overloadResolve(loc, arguments); 
     5779        f = f->overloadResolve(loc, NULL, arguments); 
    57575780        checkDeprecated(sc, f); 
    57585781        e1 = new DotVarExp(e1->loc, e1, f); 
     
    57885811 
    57895812        f = cd->ctor; 
    5790         f = f->overloadResolve(loc, arguments); 
     5813        f = f->overloadResolve(loc, NULL, arguments); 
    57915814        checkDeprecated(sc, f); 
    57925815        e1 = new DotVarExp(e1->loc, e1, f); 
     
    58095832        if (f2) 
    58105833        { 
    5811         f2 = f2->overloadResolve(loc, arguments, 1); 
     5834        f2 = f2->overloadResolve(loc, NULL, arguments, 1); 
    58125835        } 
    58135836        else 
    58145837        {   TemplateDeclaration *td = s->isTemplateDeclaration(); 
    58155838        assert(td); 
    5816         f2 = td->deduce(sc, loc, NULL, arguments, 1); 
     5839        f2 = td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments, 1); 
    58175840        } 
    58185841        if (f2) 
     
    58605883    { 
    58615884        TemplateExp *te = (TemplateExp *)e1; 
    5862         f = te->td->deduce(sc, loc, NULL, arguments); 
     5885        f = te->td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments); 
    58635886        if (!f) 
    58645887        {   type = Type::terror; 
     
    58925915 
    58935916    if (ve->hasOverloads) 
    5894         f = f->overloadResolve(loc, arguments); 
     5917        f = f->overloadResolve(loc, NULL, arguments); 
    58955918    checkDeprecated(sc, f); 
    58965919 
     
    59916014    { 
    59926015        DotVarExp *dve = (DotVarExp *)e1; 
    5993         if (dve->var->isFinal()) 
    5994         type = e1->type->constOf()->pointerTo(); 
    59956016 
    59966017        FuncDeclaration *f = dve->var->isFuncDeclaration(); 
     
    60086029    { 
    60096030        VarExp *ve = (VarExp *)e1; 
    6010         if (ve->var->isFinal()) 
    6011         type = e1->type->constOf()->pointerTo(); 
     6031 
     6032        VarDeclaration *v = ve->var->isVarDeclaration(); 
     6033        if (v && !v->canTakeAddressOf()) 
     6034        error("cannot take address of %s", e1->toChars()); 
    60126035 
    60136036        FuncDeclaration *f = ve->var->isFuncDeclaration(); 
     
    60976120Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e) 
    60986121{ 
    6099     //printf("PtrExp::modifiableLvalue() %s\n", toChars()); 
     6122    //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars()); 
    61006123 
    61016124    if (e1->op == TOKsymoff) 
    61026125    {   SymOffExp *se = (SymOffExp *)e1; 
    61036126    se->var->checkModify(loc, sc); 
    6104     return toLvalue(sc, e); 
     6127    //return toLvalue(sc, e); 
    61056128    } 
    61066129 
     
    70797102 
    70807103#if LOGSEMANTIC 
    7081     //printf("AssignExp::semantic('%s')\n", toChars()); 
     7104    printf("AssignExp::semantic('%s')\n", toChars()); 
    70827105#endif 
    70837106    //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op)); 
     
    72447267    {   // Try to do a decent error message with the expression 
    72457268    // before it got constant folded 
    7246     e1 = e1->optimize(WANTvalue); 
     7269    if (e1->op != TOKvar) 
     7270        e1 = e1->optimize(WANTvalue); 
    72477271    e1 = e1->modifiableLvalue(sc, e1old); 
    72487272    } 
     
    79477971 
    79487972    typeCombine(sc); 
    7949 //type->print(); 
    7950     type = type->mutableOf(); 
    7951 //printf("test1\n"); 
    7952 //type->print(); 
     7973    type = type->toHeadMutable(); 
    79537974 
    79547975    Type *tb = type->toBasetype(); 
    79557976    if (tb->ty == Tsarray) 
    79567977        type = tb->nextOf()->arrayOf(); 
    7957 //printf("test2\n"); 
    7958 //type->print(); 
    79597978    if (type->ty == Tarray && tb1->nextOf()->mod != tb2->nextOf()->mod) 
    7960         type = type->nextOf()->toCanonConst()->arrayOf(); 
    7961 //printf("test3\n"); 
    7962 //type->print(); 
     7979        type = type->nextOf()->toHeadMutable()->arrayOf(); 
    79637980#if 0 
    79647981    e1->type->print(); 
     
    87908807        break; 
    87918808    } 
     8809    if (type->toBasetype()->ty == Tarray) 
     8810    { 
     8811        e1 = e1->castTo(sc, type); 
     8812        e2 = e2->castTo(sc, type); 
     8813    } 
    87928814    } 
    87938815#if 0 
  • branches/dmdfe-2.0/func.c

    r838 r846  
    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) 
     
    680725#if BREAKABI 
    681726        v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL); 
    682         v_arguments->storage_class = STCparameter | STCin
     727        v_arguments->storage_class = STCparameter
    683728        v_arguments->semantic(sc2); 
    684729        sc2->insert(v_arguments); 
    685730        v_arguments->parent = this; 
    686731 
     732        //t = Type::typeinfo->type->constOf()->arrayOf(); 
    687733        t = Type::typeinfo->type->arrayOf(); 
    688734        _arguments = new VarDeclaration(0, t, Id::_arguments, NULL); 
     
    11091155        Expression *e1 = new VarExp(0, _arguments); 
    11101156        e = new AssignExp(0, e1, e); 
     1157        e->op = TOKconstruct; 
    11111158        e = e->semantic(sc); 
    11121159        a->push(new ExpStatement(0, e)); 
     
    13001347    if (type && f->type &&  // can be NULL for overloaded constructors 
    13011348    f->type->covariant(type) && 
     1349    f->type->mod == type->mod && 
    13021350    !isFuncAliasDeclaration()) 
    13031351    { 
     
    14471495{ 
    14481496    Match *m; 
     1497    Expression *ethis; 
    14491498    Expressions *arguments; 
    14501499}; 
     
    14621511    m->anyf = f; 
    14631512    tf = (TypeFunction *)f->type; 
    1464     match = (MATCH) tf->callMatch(arguments); 
     1513    match = (MATCH) tf->callMatch(f->needThis() ? p->ethis : NULL, arguments); 
    14651514    //printf("match = %d\n", match); 
    14661515    if (match != MATCHnomatch) 
     
    14971546} 
    14981547 
    1499 void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments) 
     1548void overloadResolveX(Match *m, FuncDeclaration *fstart, 
     1549    Expression *ethis, Expressions *arguments) 
    15001550{ 
    15011551    Param2 p; 
    15021552    p.m = m; 
     1553    p.ethis = ethis; 
    15031554  &nb