Changeset 900

Show
Ignore:
Timestamp:
06/29/08 18:26:21 (3 months ago)
Author:
Gregor
Message:

MERGE: DMD 2.012

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmdfe-2.0/aggregate.h

    r882 r900  
    200200    VarDeclaration *vthis;      // 'this' parameter if this class is nested 
    201201 
     202    int inuse;              // to prevent recursive attempts 
     203 
    202204    ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 
    203205    Dsymbol *syntaxCopy(Dsymbol *s); 
  • branches/dmdfe-2.0/attrib.c

    r882 r900  
    288288    if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 
    289289        sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 
     290    if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest)) 
     291        sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest); 
    290292    if (stc & (STCconst | STCinvariant | STCmanifest)) 
    291293        sc->stc &= ~(STCconst | STCinvariant | STCmanifest); 
     
    324326    { STCdeprecated,   TOKdeprecated }, 
    325327    { STCoverride,     TOKoverride }, 
     328    { STCnothrow,      TOKnothrow }, 
     329    { STCpure,         TOKpure }, 
     330    { STCtls,          TOKtls }, 
    326331    }; 
    327332 
     
    588593    sc = sc->push(); 
    589594    sc->anonAgg = &aad; 
    590     sc->stc &= ~(STCauto | STCscope | STCstatic); 
     595    sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls); 
    591596    sc->inunion = isunion; 
    592597    sc->offset = 0; 
     
    818823    goto Lnodecl; 
    819824    } 
     825    else if (global.params.ignoreUnsupportedPragmas) 
     826    { 
     827    if (global.params.verbose) 
     828    { 
     829        /* Print unrecognized pragmas 
     830         */ 
     831        printf("pragma    %s", ident->toChars()); 
     832        if (args) 
     833        { 
     834        for (size_t i = 0; i < args->dim; i++) 
     835        { 
     836            Expression *e = (Expression *)args->data[i]; 
     837            e = e->semantic(sc); 
     838            e = e->optimize(WANTvalue | WANTinterpret); 
     839            if (i == 0) 
     840            printf(" ("); 
     841            else 
     842            printf(","); 
     843            printf("%s", e->toChars()); 
     844        } 
     845        if (args->dim) 
     846            printf(")"); 
     847        } 
     848        printf("\n"); 
     849    } 
     850    goto Lnodecl; 
     851    } 
    820852    else 
    821853    error("unrecognized pragma(%s)", ident->toChars()); 
     
    850882void PragmaDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    851883{ 
    852     buf->printf("pragma(%s", ident->toChars()); 
    853     if (args) 
    854     { 
    855     for (size_t i = 0; i < args->dim; i++) 
    856     { 
    857         Expression *e = (Expression *)args->data[i]; 
    858  
    859         buf->writestring(", "); 
    860         e->toCBuffer(buf, hgs); 
    861     } 
    862     } 
    863     buf->writestring(")"); 
     884    buf->printf("pragma (%s", ident->toChars()); 
     885    if (args && args->dim) 
     886    { 
     887        buf->writestring(", "); 
     888        argsToCBuffer(buf, args, hgs); 
     889    } 
     890    buf->writeByte(')'); 
    864891    AttribDeclaration::toCBuffer(buf, hgs); 
    865892} 
  • branches/dmdfe-2.0/cast.c

    r883 r900  
    11 
    2 // Copyright (c) 1999-2007 by Digital Mars 
     2// Copyright (c) 1999-2008 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
     
    3232Expression *Expression::implicitCastTo(Scope *sc, Type *t) 
    3333{ 
    34     //printf("Expression::implicitCastTo(%s) => %s\n", type->toChars(), t->toChars()); 
    35     //printf("%s\n", toChars()); 
     34    //printf("Expression::implicitCastTo(%s of type %s) => %s\n", toChars(), type->toChars(), t->toChars()); 
    3635 
    3736    MATCH match = implicitConvTo(t); 
     
    104103    toChars(), type->toChars(), t->toChars()); 
    105104#endif 
    106     //static int nest; if (++nest == 50) halt(); 
     105    //static int nest; if (++nest == 10) halt(); 
    107106    if (!type) 
    108107    {   error("%s is not an expression", toChars()); 
     
    10871086{ 
    10881087#if 0 
    1089     printf("ArrayLiteralExp::castTo(this=%s, type=%s, t=%s)\n", 
     1088    printf("ArrayLiteralExp::castTo(this=%s, type=%s, => %s)\n", 
    10901089    toChars(), type->toChars(), t->toChars()); 
    10911090#endif 
     
    10971096    if ((tb->ty == Tarray || tb->ty == Tsarray) && 
    10981097    (typeb->ty == Tarray || typeb->ty == Tsarray) && 
    1099     tb->nextOf()->toBasetype()->ty != Tvoid) 
     1098    // Not trying to convert non-void[] to void[] 
     1099    !(tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid)) 
    11001100    { 
    11011101    if (tb->ty == Tsarray) 
  • branches/dmdfe-2.0/class.c

    r882 r900  
    187187    isnested = 0; 
    188188    vthis = NULL; 
     189    inuse = 0; 
    189190} 
    190191 
     
    530531    sc = sc->push(this); 
    531532    sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 
    532          STCabstract | STCdeprecated | STCconst | STCinvariant); 
     533         STCabstract | STCdeprecated | STCconst | STCinvariant | STCtls); 
    533534    sc->stc |= storage_class & (STCconst | STCinvariant); 
    534535    sc->parent = this; 
     
    575576    scope->module->addDeferredSemantic(this); 
    576577 
    577     //printf("\tsemantic('%s') failed\n", toChars()); 
     578    //printf("\tsemantic('%s') failed due to forward references\n", toChars()); 
    578579    return; 
    579580    } 
     
    10141015 
    10151016    //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); 
     1017    if (inuse) 
     1018    return; 
    10161019    if (!scope) 
    10171020    {   type = type->semantic(loc, sc); 
     
    11011104        continue; 
    11021105        } 
    1103         if (!b->base->symtab || b->base->scope
     1106        if (!b->base->symtab || b->base->scope || b->base->inuse
    11041107        { 
    11051108        //error("forward reference of base class %s", baseClass->toChars()); 
     
    11681171    sc = sc->push(this); 
    11691172    sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 
    1170                  STCabstract | STCdeprecated | STCconst | STCinvariant); 
     1173                 STCabstract | STCdeprecated | STCconst | STCinvariant | STCtls); 
    11711174    sc->stc |= storage_class & (STCconst | STCinvariant); 
    11721175    sc->parent = this; 
     
    11781181    structalign = sc->structalign; 
    11791182    sc->offset = 8; 
     1183    inuse++; 
    11801184    for (i = 0; i < members->dim; i++) 
    11811185    { 
     
    11831187    s->semantic(sc); 
    11841188    } 
     1189    inuse--; 
    11851190    //members->print(); 
    11861191    sc->pop(); 
  • branches/dmdfe-2.0/declaration.c

    r883 r900  
    803803    } 
    804804 
    805     if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter)) 
     805    if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls)) 
    806806    { 
    807807    } 
     
    812812        aad = parent->isAggregateDeclaration(); 
    813813    if (aad) 
    814     {   assert(!(storage_class & (STCextern | STCstatic))); 
     814    {   assert(!(storage_class & (STCextern | STCstatic | STCtls))); 
    815815 
    816816        if (storage_class & (STCconst | STCinvariant) && init) 
     
    854854    if (type->isauto() && !noauto) 
    855855    { 
    856     if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest) || !fd) 
     856    if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls) || !fd) 
    857857    { 
    858858        error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto"); 
     
    11131113    if (storage_class & STCstatic) 
    11141114    buf->writestring("static "); 
     1115    if (storage_class & STCtls) 
     1116    buf->writestring("__tls "); 
    11151117    if (storage_class & STCconst) 
    11161118    buf->writestring("const "); 
     
    12841286    } 
    12851287    return canTakeAddressOf() && 
    1286     (storage_class & (STCstatic | STCextern) || 
     1288    (storage_class & (STCstatic | STCextern | STCtls) || 
    12871289     toParent()->isModule() || 
    12881290     toParent()->isTemplateInstance()); 
  • branches/dmdfe-2.0/declaration.h

    r883 r900  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2007 by Digital Mars 
     3// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    6868    STCnodtor       = 0x1000000,    // don't run destructor 
    6969    STCnothrow      = 0x2000000,    // never throws exceptions 
     70    STCpure     = 0x4000000,    // pure function 
     71    STCtls      = 0x8000000,    // thread local 
    7072}; 
    7173 
     
    483485    void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    484486    int overrides(FuncDeclaration *fd); 
     487    int findVtblIndex(Array *vtbl, int dim); 
    485488    int overloadInsert(Dsymbol *s); 
    486489    FuncDeclaration *overloadExactMatch(Type *t); 
    487490    FuncDeclaration *overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags = 0); 
     491    MATCH leastAsSpecialized(FuncDeclaration *g); 
    488492    LabelDsymbol *searchLabel(Identifier *ident); 
    489493    AggregateDeclaration *isThis(); 
  • branches/dmdfe-2.0/e2ir.c

    r883 r900  
    41154115    { 
    41164116    // set to: 
    4117     //  *aaGet(aa, keyti, valuesize, value); 
     4117    //  *aaGet(aa, keyti, valuesize, index); 
    41184118 
    41194119    TypeAArray *taa = (TypeAArray *)t1; 
     
    41244124    Symbol *s; 
    41254125 
     4126    // n2 becomes the index, also known as the key 
    41264127    n2 = e2->toElem(irs); 
    4127     if (n2->Ety == TYstruct
     4128    if (n2->Ety == TYstruct || n2->Ety == TYarray
    41284129    { 
    41294130        n2 = el_una(OPstrpar, TYstruct, n2); 
    41304131        n2->Enumbytes = n2->E1->Enumbytes; 
     4132        //printf("numbytes = %d\n", n2->Enumbytes); 
    41314133        assert(n2->Enumbytes); 
    41324134    } 
    41334135    valuesize = el_long(TYuint, vsize); // BUG: should be TYsize_t 
     4136    //printf("valuesize: "); elem_print(valuesize); 
    41344137    if (modifiable) 
    41354138    { 
     
    41414144        s = taa->aaGetSymbol("GetRvalue", 1); 
    41424145    } 
    4143     //printf("taa->key = %s\n", taa->key->toChars()); 
     4146    //printf("taa->index = %s\n", taa->index->toChars()); 
    41444147    keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs); 
     4148    //keyti = taa->index->getTypeInfo(NULL)->toElem(irs); 
    41454149    //printf("keyti:\n"); 
    41464150    //elem_print(keyti); 
  • branches/dmdfe-2.0/expression.c

    r883 r900  
    112112    precedence[TOKfunction] = PREC_primary; 
    113113    precedence[TOKvar] = PREC_primary; 
     114    precedence[TOKdefault] = PREC_primary; 
    114115 
    115116    // post 
     
    478479            break; 
    479480        } 
    480         arg = p->defaultArg->copy(); 
     481        arg = p->defaultArg; 
     482        if (arg->op == TOKdefault) 
     483        {   DefaultInitExp *de = (DefaultInitExp *)arg; 
     484            arg = de->resolve(loc, sc); 
     485        } 
     486        else 
     487            arg = arg->copy(); 
    481488        arguments->push(arg); 
    482489        nargs++; 
     
    20562063 
    20572064Lerr: 
    2058     error("'this' is only allowed in non-static member functions, not %s", sc->parent->toChars()); 
    2059     type = Type::tint32
     2065    error("'this' is only defined in non-static member functions, not %s", sc->parent->toChars()); 
     2066    type = Type::terror
    20602067    return this; 
    20612068} 
     
    52365243                e1->type = s->isClassDeclaration()->type; 
    52375244 
     5245            e1 = e1->semantic(sc); // get corrected nested refs 
    52385246            goto L1; 
    52395247            } 
     
    52415249            printf("2: "); 
    52425250#endif 
    5243             error("this for %s needs to be type %s not type %s", 
    5244             var->toChars(), ad->toChars(), t->toChars()); 
     5251            error("%s for %s needs to be type %s not type %s", 
     5252            e1->toChars(), var->toChars(), ad->toChars(), t->toChars()); 
    52455253        } 
    52465254        } 
     
    92319239 
    92329240 
     9241/****************************************************************/ 
     9242 
     9243DefaultInitExp::DefaultInitExp(Loc loc, enum TOK subop, int size) 
     9244    : Expression(loc, TOKdefault, size) 
     9245{ 
     9246    this->subop = subop; 
     9247} 
     9248 
     9249void DefaultInitExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
     9250{ 
     9251    buf->writestring(Token::toChars(subop)); 
     9252} 
     9253 
     9254/****************************************************************/ 
     9255 
     9256FileInitExp::FileInitExp(Loc loc) 
     9257    : DefaultInitExp(loc, TOKfile, sizeof(FileInitExp)) 
     9258{ 
     9259} 
     9260 
     9261Expression *FileInitExp::semantic(Scope *sc) 
     9262{ 
     9263    //printf("FileInitExp::semantic()\n"); 
     9264    type = Type::tchar->invariantOf()->arrayOf(); 
     9265    return this; 
     9266} 
     9267 
     9268Expression *FileInitExp::resolve(Loc loc, Scope *sc) 
     9269{ 
     9270    //printf("FileInitExp::resolve() %s\n", toChars()); 
     9271    char *s = loc.filename ? loc.filename : sc->module->ident->toChars(); 
     9272    Expression *e = new StringExp(loc, s); 
     9273    e = e->semantic(sc); 
     9274    e = e->castTo(sc, type); 
     9275    return e; 
     9276} 
     9277 
     9278/****************************************************************/ 
     9279 
     9280LineInitExp::LineInitExp(Loc loc) 
     9281    : DefaultInitExp(loc, TOKline, sizeof(LineInitExp)) 
     9282{ 
     9283} 
     9284 
     9285Expression *LineInitExp::semantic(Scope *sc) 
     9286{ 
     9287    type = Type::tint32; 
     9288    return this; 
     9289} 
     9290 
     9291Expression *LineInitExp::resolve(Loc loc, Scope *sc) 
     9292{ 
     9293    Expression *e = new IntegerExp(loc, loc.linnum, Type::tint32); 
     9294    e = e->castTo(sc, type); 
     9295    return e; 
     9296} 
     9297 
     9298 
  • branches/dmdfe-2.0/expression.h

    r882 r900  
    6262Expression *resolveProperties(Scope *sc, Expression *e); 
    6363void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d); 
     64Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Identifier *id); 
    6465Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid); 
    6566void inferApplyArgTypes(enum TOK op, Arguments *arguments, Expression *aggr); 
     
    13251326/****************************************************************/ 
    13261327 
     1328struct DefaultInitExp : Expression 
     1329{ 
     1330    enum TOK subop;     // which of the derived classes this is 
     1331 
     1332    DefaultInitExp(Loc loc, enum TOK subop, int size); 
     1333    virtual Expression *resolve(Loc loc, Scope *sc) = 0; 
     1334    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     1335}; 
     1336 
     1337struct FileInitExp : DefaultInitExp 
     1338{ 
     1339    FileInitExp(Loc loc); 
     1340    Expression *semantic(Scope *sc); 
     1341    Expression *resolve(Loc loc, Scope *sc); 
     1342}; 
     1343 
     1344struct LineInitExp : DefaultInitExp 
     1345{ 
     1346    LineInitExp(Loc loc); 
     1347    Expression *semantic(Scope *sc); 
     1348    Expression *resolve(Loc loc, Scope *sc); 
     1349}; 
     1350 
     1351/****************************************************************/ 
     1352 
    13271353/* Special values used by the interpreter 
    13281354 */ 
  • branches/dmdfe-2.0/func.c

    r883 r900  
    3636    : Declaration(id) 
    3737{ 
     38    //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type); 
    3839    this->storage_class = storage_class; 
    3940    this->type = type; 
     
    108109    printf("\tFuncLiteralDeclaration()\n"); 
    109110    printf("sc->parent = %s\n", sc->parent->toChars()); 
    110     printf("type: %s\n", type->toChars()); 
     111    printf("type: %p, %s\n", type, type->toChars()); 
    111112#endif 
    112113 
     
    305306 
    306307    // Find index of existing function in vtbl[] to override 
    307     if (cd->baseClass) 
    308     { 
    309         for (vi = 0; vi < cd->baseClass->vtbl.dim; vi++) 
    310         { 
    311         FuncDeclaration *fdv = ((Dsymbol *)cd->vtbl.data[vi])->isFuncDeclaration(); 
    312  
    313         // BUG: should give error if argument types match, 
    314         // but return type does not? 
    315  
    316         //printf("\tvtbl[%d] = '%s'\n", vi, fdv ? fdv->ident->toChars() : ""); 
    317         if (fdv && fdv->ident == ident) 
    318         { 
    319             int cov = type->covariant(fdv->type); 
    320             //printf("\tbaseclass cov = %d\n", cov); 
    321             if (cov == 2) 
     308    vi = findVtblIndex(&cd->vtbl, cd->baseClass ? cd->baseClass->vtbl.dim : 0); 
     309    switch (vi) 
     310    { 
     311        case -1: 
     312        /* Didn't find one, so 
     313         * This is an 'introducing' function which gets a new 
     314         * slot in the vtbl[]. 
     315         */ 
     316 
     317        // Verify this doesn't override previous final function 
     318        if (cd->baseClass) 
     319        {   Dsymbol *s = cd->baseClass->search(loc, ident, 0); 
     320            if (s) 
    322321            { 
    323             //type->print(); 
    324             //fdv->type->print(); 
    325             //printf("%s %s\n", type->deco, fdv->type->deco); 
    326             error("of type %s overrides but is not covariant with %s of type %s", 
    327                 type->toChars(), fdv->toPrettyChars(), fdv->type->toChars()); 
    328             } 
    329             if (cov == 1) 
    330             { 
    331             if (fdv->isFinal()) 
    332                 error("cannot override final function %s", fdv->toPrettyChars()); 
    333  
    334             if (!isOverride() && global.params.warnings) 
    335                 error("overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars()); 
    336  
    337             if (fdv->toParent() == parent) 
    338             { 
    339                 // If both are mixins, then error. 
    340                 // If either is not, the one that is not overrides 
    341                 // the other. 
    342                 if (fdv->parent->isClassDeclaration()) 
    343                 goto L1; 
    344                 if (!this->parent->isClassDeclaration() 
    345 #if !BREAKABI 
    346                 && !isDtorDeclaration() 
    347 #endif 
    348                 && !isPostBlitDeclaration() 
    349                 ) 
    350                 error("multiple overrides of same function"); 
    351             } 
    352             cd->vtbl.data[vi] = (void *)this; 
    353             vtblIndex = vi; 
    354  
    355             /* This works by whenever this function is called, 
    356              * it actually returns tintro, which gets dynamically 
    357              * cast to type. But we know that tintro is a base 
    358              * of type, so we could optimize it by not doing a 
    359              * dynamic cast, but just subtracting the isBaseOf() 
    360              * offset if the value is != null. 
    361              */ 
    362  
    363             if (fdv->tintro) 
    364                 tintro = fdv->tintro; 
    365             else if (!type->equals(fdv->type)) 
    366             { 
    367                 /* Only need to have a tintro if the vptr 
    368                  * offsets differ 
    369                  */ 
    370                 int offset; 
    371                 if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 
    372                 { 
    373                 tintro = fdv->type; 
    374                 } 
    375             } 
    376             goto L1; 
    377             } 
    378             if (cov == 3) 
    379             { 
    380             cd->sizeok = 2; // can't finish due to forward reference 
    381             return; 
     322            FuncDeclaration *f = s->isFuncDeclaration(); 
     323            f = f->overloadExactMatch(type); 
     324            if (f && f->isFinal() && f->prot() != PROTprivate) 
     325                error("cannot override final function %s", f->toPrettyChars()); 
    382326            } 
    383327        } 
    384         } 
    385     } 
    386  
    387     // This is an 'introducing' function. 
    388  
    389     // Verify this doesn't override previous final function 
    390     if (cd->baseClass) 
    391     {   Dsymbol *s = cd->baseClass->search(loc, ident, 0); 
    392         if (s) 
    393         { 
    394         FuncDeclaration *f = s->isFuncDeclaration(); 
    395         f = f->overloadExactMatch(type); 
    396         if (f && f->isFinal() && f->prot() != PROTprivate) 
    397             error("cannot override final function %s", f->toPrettyChars()); 
    398         } 
    399     } 
    400  
    401     if (isFinal()) 
    402     { 
    403         cd->vtblFinal.push(this); 
    404     } 
    405     else 
    406     { 
    407         // Append to end of vtbl[] 
    408         //printf("\tintroducing function\n"); 
    409         introducing = 1; 
    410         vi = cd->vtbl.dim; 
    411         cd->vtbl.push(this); 
    412         vtblIndex = vi; 
    413     } 
    414  
    415     L1: ; 
     328 
     329        if (isFinal()) 
     330        { 
     331            cd->vtblFinal.push(this); 
     332        } 
     333        else 
     334        { 
     335            // Append to end of vtbl[] 
     336            //printf("\tintroducing function\n"); 
     337            introducing = 1; 
     338            vi = cd->vtbl.dim; 
     339            cd->vtbl.push(this); 
     340            vtblIndex = vi; 
     341        } 
     342 
     343        break; 
     344 
     345        case -2:    // can't determine because of fwd refs 
     346        cd->sizeok = 2; // can't finish due to forward reference 
     347        return; 
     348 
     349        default: 
     350        {   FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi]; 
     351        // This function is covariant with fdv 
     352        if (fdv->isFinal()) 
     353            error("cannot override final function %s", fdv->toPrettyChars()); 
     354 
     355        if (!isOverride() && global.params.warnings) 
     356            error("overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars()); 
     357 
     358        if (fdv->toParent() == parent) 
     359        { 
     360            // If both are mixins, then error. 
     361            // If either is not, the one that is not overrides 
     362            // the other. 
     363            if (fdv->parent->isClassDeclaration()) 
     364            break; 
     365            if (!this->parent->isClassDeclaration() 
     366#if !BREAKABI 
     367            && !isDtorDeclaration() 
     368#endif 
     369            && !isPostBlitDeclaration() 
     370            ) 
     371            error("multiple overrides of same function"); 
     372        } 
     373        cd->vtbl.data[vi] = (void *)this; 
     374        vtblIndex = vi; 
     375 
     376        /* This works by whenever this function is called, 
     377         * it actually returns tintro, which gets dynamically 
     378         * cast to type. But we know that tintro is a base 
     379         * of type, so we could optimize it by not doing a 
     380         * dynamic cast, but just subtracting the isBaseOf() 
     381         * offset if the value is != null. 
     382         */ 
     383 
     384        if (fdv->tintro) 
     385            tintro = fdv->tintro; 
     386        else if (!type->equals(fdv->type)) 
     387        { 
     388            /* Only need to have a tintro if the vptr 
     389             * offsets differ 
     390             */ 
     391            int offset; 
     392            if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 
     393            { 
     394            tintro = fdv->type; 
     395            } 
     396        } 
     397        break; 
     398        } 
     399    } 
    416400 
    417401    /* Go through all the interface bases. 
     
    422406    { 
    423407        BaseClass *b = cd->interfaces[i]; 
    424         for (vi = 0; vi < b->base->vtbl.dim; vi++) 
     408        vi = findVtblIndex(&b->base->vtbl, b->base->vtbl.dim); 
     409        switch (vi) 
    425410        { 
    426         Dsymbol *s = (Dsymbol *)b->base->vtbl.data[vi]; 
    427         //printf("interface %d vtbl[%d] %p %s\n", i, vi, s, s->toChars()); 
    428         FuncDeclaration *fdv = s->isFuncDeclaration(); 
    429         if (fdv && fdv->ident == ident) 
    430         { 
    431             int cov = type->covariant(fdv->type); 
    432             //printf("\tcov = %d\n", cov); 
    433             if (cov == 2) 
     411        case -1: 
     412            break; 
     413 
     414        case -2: 
     415            cd->sizeok = 2; // can't finish due to forward reference 
     416            return; 
     417 
     418        default: 
     419        {   FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi]; 
     420            Type *ti = NULL; 
     421 
     422            if (fdv->tintro) 
     423            ti = fdv->tintro; 
     424            else if (!type->equals(fdv->type)) 
    434425            { 
    435             //type->print(); 
    436             //fdv->type->print(); 
    437             //printf("%s %s\n", type->deco, fdv->type->deco); 
    438             error("of type %s overrides but is not covariant with %s of type %s", 
    439                 type->toChars(), fdv->toPrettyChars(), fdv->type->toChars()); 
     426            /* Only need to have a tintro if the vptr 
     427             * offsets differ 
     428             */ 
     429            int offset; 
     430            if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 
     431            { 
     432                ti = fdv->type; 
     433#if 0 
     434                if (offset) 
     435                ti = fdv->type; 
     436                else if (type->nextOf()->ty == Tclass) 
     437                {   ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym; 
     438                if (cdn && cdn->sizeok != 1) 
     439                    ti = fdv->type; 
     440                } 
     441#endif 
     442            } 
    440443            } 
    441             if (cov == 1) 
    442             {   Type *ti = NULL; 
    443  
    444             if (fdv->tintro) 
    445                 ti = fdv->tintro; 
    446             else if (!type->equals(fdv->type)) 
     444            if (ti) 
     445            { 
     446            if (tintro && !tintro->equals(ti)) 
    447447            { 
    448                 /* Only need to have a tintro if the vptr 
    449                  * offsets differ 
    450                  */ 
    451                 int offset; 
    452                 if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 
    453                 { 
    454                 ti = fdv->type; 
    455 #if 0 
    456                 if (offset) 
    457                     ti = fdv->type; 
    458                 else if (type->nextOf()->ty == Tclass) 
    459                 {   ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym; 
    460                     if (cdn && cdn->sizeok != 1) 
    461                     ti = fdv->type; 
    462                 } 
    463 #endif 
    464                 } 
     448                error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars()); 
    465449            } 
    466             if (ti) 
    467             { 
    468                 if (tintro && !tintro->equals(ti)) 
    469                 { 
    470                 error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars()); 
    471                 } 
    472                 tintro = ti; 
    473             } 
    474             goto L2; 
     450            tintro = ti; 
    475451            } 
    476             if (cov == 3) 
    477             { 
    478             cd->sizeok = 2; // can't finish due to forward reference 
    479             return; 
    480             } 
     452            goto L2; 
    481453        } 
    482454        } 
     
    660632    sc2->fes = fes; 
    661633    sc2->linkage = LINKd; 
    662     sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCconst | STCfinal | STCinvariant); 
     634    sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCconst | STCfinal | STCinvariant | STCtls); 
    663635    sc2->protection = PROTpublic; 
    664636    sc2->explicitProtection = 0; 
     
    683655        assert(ad->handle); 
    684656        Type *thandle = ad->handle; 
    685         if (storage_class & STCconst
     657        if (storage_class & STCconst || type->isConst()
    686658        { 
    687659            if (thandle->ty == Tclass) 
     
    692664            } 
    693665        } 
    694         else if (storage_class & STCinvariant
     666        else if (storage_class & STCinvariant || type->isInvariant()
    695667        { 
    696668            if (thandle->ty == Tclass) 
     
    13621334} 
    13631335 
     1336/************************************************* 
     1337 * Find index of function in vtbl[0..dim] that 
     1338 * this function overrides. 
     1339 * Returns: 
     1340 *  -1  didn't find one 
     1341 *  -2  can't determine because of forward references 
     1342 */ 
     1343 
     1344int FuncDeclaration::findVtblIndex(Array *vtbl, int dim) 
     1345{ 
     1346    for (int vi = 0; vi < dim; vi++) 
     1347    { 
     1348    FuncDeclaration *fdv = ((Dsymbol *)vtbl->data[vi])->isFuncDeclaration(); 
     1349    if (fdv && fdv->ident == ident) 
     1350    { 
     1351        int cov = type->covariant(fdv->type); 
     1352        //printf("\tbaseclass cov = %d\n", cov); 
     1353        switch (cov) 
     1354        { 
     1355        case 0:     // types are distinct 
     1356            break; 
     1357 
     1358        case 1: 
     1359            return vi; 
     1360 
     1361        case 2: 
     1362            //type->print(); 
     1363            //fdv->type->print(); 
     1364            //printf("%s %s\n", type->deco, fdv->type->deco); 
     1365            error("of type %s overrides but is not covariant with %s of type %s", 
     1366            type->toChars(), fdv->toPrettyChars(), fdv->type->toChars()); 
     1367            break; 
     1368 
     1369        case 3: 
     1370            return -2;  // forward references 
     1371 
     1372        default: 
     1373            assert(0); 
     1374        } 
     1375    } 
     1376    } 
     1377    return -1; 
     1378} 
     1379 
    13641380/**************************************************** 
    13651381 * Overload this FuncDeclaration with the new one f. 
     
    15641580    if (f != m->lastf)      // skip duplicates 
    15651581    { 
    1566     TypeFunction *tf; 
    1567  
    15681582    m->anyf = f; 
    1569     tf = (TypeFunction *)f->type; 
     1583    TypeFunction *tf = (TypeFunction *)f->type; 
    15701584    match = (MATCH) tf->callMatch(f->needThis() ? p->ethis : NULL, arguments); 
    15711585    //printf("match = %d\n", match); 
     
    15841598        else if (f->overrides(m->lastf)) 
    15851599        goto LfIsBetter; 
     1600 
     1601        /* Try to disambiguate using template-style partial ordering rules. 
     1602         * In essence, if f() and g() are ambiguous, if f() can call g(), 
     1603         * but g() cannot call f(), then pick f(). 
     1604         * This is because f() is "more specialized." 
     1605         */ 
     1606        { 
     1607        MATCH c1 = f->leastAsSpecialized(m->lastf); 
     1608        MATCH c2 = m->lastf->leastAsSpecialized(f); 
     1609        if (c1 > c2) 
     1610        goto LfIsBetter; 
     1611        if (c1 < c2) 
     1612        goto LlastIsBetter; 
     1613        } 
    15861614 
    15871615    Lambiguous: 
     
    16861714    } 
    16871715    } 
     1716} 
     1717 
     1718/************************************* 
     1719 * Determine partial specialization order of 'this' vs g. 
     1720 * This is very similar to TemplateDeclaration::leastAsSpecialized(). 
     1721 * Returns: 
     1722 *  match   'this' is at least as specialized as g 
     1723 *  0   g is more specialized than 'this' 
     1724 */ 
     1725 
     1726MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g) 
     1727{ 
     1728#define LOG_LEASTAS     0 
     1729 
     1730#if LOG_LEASTAS 
     1731    printf("%s.leastAsSpecialized(%s)\n", toChars(), g->toChars()); 
     1732#endif 
     1733 
     1734    /* This works by calling g() with f()'s parameters, and 
     1735     * if that is possible, then f() is at least as specialized 
     1736     * as g() is. 
     1737     */ 
     1738 
     1739    TypeFunction *tf = (TypeFunction *)type; 
     1740    TypeFunction *tg = (TypeFunction *)g->type; 
     1741    size_t nfparams = Argument::dim(tf->parameters); 
     1742    size_t ngparams = Argument::dim(tg->parameters); 
     1743    MATCH match = MATCHexact; 
     1744 
     1745    /* If both functions have a 'this' pointer, and the mods are not 
     1746     * the same and g's is not const, then this is less specialized. 
     1747     */ 
     1748    if (needThis() && g->needThis()) 
     1749    { 
     1750    if (tf->mod != tg->mod) 
     1751    { 
     1752        if (tg->mod == MODconst) 
     1753        match = MATCHconst; 
     1754        else 
     1755        return MATCHnomatch; 
     1756    } 
     1757    } 
     1758 
     1759    /* Create a dummy array of arguments out of the parameters to f() 
     1760     */ 
     1761    Expressions args; 
     1762    args.setDim(nfparams); 
     1763    for (int u = 0; u < nfparams; u++) 
     1764    { 
     1765    Argument *p = Argument::getNth(tf->parameters, u); 
     1766    Expression *e = p->type->defaultInit(); 
     1767    args.data[u] = e; 
     1768    } 
     1769 
     1770    MATCH m = (MATCH) tg->callMatch(NULL, &args); 
     1771    if (m) 
     1772    { 
     1773        /* A variadic template is less specialized than a 
     1774         * non-variadic one. 
     1775         */