Changeset 882

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

MERGE: DMD 2.011

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmdfe-2.0/Makefile

    r783 r882  
    1414  cast.o \ 
    1515  class.o \ 
     16  clone.o \ 
    1617  cond.o \ 
    1718  constfold.o \ 
  • branches/dmdfe-2.0/access.c

    r458 r882  
    254254    { 
    255255    error(loc, "member %s is not accessible", smember->toChars()); 
     256halt(); 
    256257    } 
    257258} 
  • branches/dmdfe-2.0/aggregate.h

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

    r880 r882  
    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 
     
    3030#include "module.h" 
    3131#include "parse.h" 
     32#include "template.h" 
    3233 
    3334extern void obj_includelib(char *name); 
     35void obj_startaddress(Symbol *s); 
    3436 
    3537 
     
    800802    } 
    801803#endif 
     804    else if (ident == Id::startaddress) 
     805    { 
     806    if (!args || args->dim != 1) 
     807        error("function name expected for start address"); 
     808    else 
     809    { 
     810        Expression *e = (Expression *)args->data[0]; 
     811        e = e->semantic(sc); 
     812        e = e->optimize(WANTvalue | WANTinterpret); 
     813        args->data[0] = (void *)e; 
     814        Dsymbol *sa = getDsymbol(e); 
     815        if (!sa || !sa->isFuncDeclaration()) 
     816        error("function name expected for start address, not '%s'", e->toChars()); 
     817    } 
     818    goto Lnodecl; 
     819    } 
    802820    else 
    803821    error("unrecognized pragma(%s)", ident->toChars()); 
  • branches/dmdfe-2.0/cast.c

    r881 r882  
    342342    if (this->type->equals(t)) 
    343343    return MATCHexact; 
     344 
     345    /* Allow implicit conversions from invariant to mutable|const, 
     346     * and mutable to invariant. It works because, after all, a null 
     347     * doesn't actually point to anything. 
     348     */ 
     349    if (t->invariantOf()->equals(type->invariantOf())) 
     350    return MATCHconst; 
     351 
    344352    // NULL implicitly converts to any pointer type or dynamic array 
    345353    if (type->ty == Tpointer && type->nextOf()->ty == Tvoid) 
     
    353361    } 
    354362    return Expression::implicitConvTo(t); 
     363} 
     364 
     365MATCH StructLiteralExp::implicitConvTo(Type *t) 
     366{ 
     367#if 0 
     368    printf("StructLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\n", 
     369    toChars(), type->toChars(), t->toChars()); 
     370#endif 
     371    MATCH m = Expression::implicitConvTo(t); 
     372    if (m != MATCHnomatch) 
     373    return m; 
     374    if (type->ty == t->ty && type->ty == Tstruct && 
     375    ((TypeStruct *)type)->sym == ((TypeStruct *)t)->sym) 
     376    { 
     377    m = MATCHconst; 
     378    for (int i = 0; i < elements->dim; i++) 
     379    {   Expression *e = (Expression *)elements->data[i]; 
     380        Type *te = e->type; 
     381        if (t->mod == 0) 
     382        te = te->mutableOf(); 
     383        else 
     384        {   assert(t->mod == MODinvariant); 
     385        te = te->invariantOf(); 
     386        } 
     387        MATCH m2 = e->implicitConvTo(te); 
     388        //printf("\t%s => %s, match = %d\n", e->toChars(), te->toChars(), m2); 
     389        if (m2 < m) 
     390        m = m2; 
     391    } 
     392    } 
     393    return m; 
    355394} 
    356395 
  • branches/dmdfe-2.0/class.c

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

    r881 r882  
    689689    type = type->semantic(loc, sc); 
    690690    } 
    691     //printf(" type = %s\n", type ? type->toChars() : "null"); 
     691    //printf(" semantic type = %s\n", type ? type->toChars() : "null"); 
    692692 
    693693    type->checkDeprecated(loc, sc); 
     
    730730    Objects *exps = new Objects(); 
    731731    exps->setDim(nelems); 
     732    Expression *ie = init ? init->toExpression() : NULL; 
    732733 
    733734    for (size_t i = 0; i < nelems; i++) 
     
    740741        Identifier *id = new Identifier(name, TOKidentifier); 
    741742 
    742         VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL); 
     743        Expression *einit = ie; 
     744        if (ie && ie->op == TOKtuple) 
     745        {   einit = (Expression *)((TupleExp *)ie)->exps->data[i]; 
     746        } 
     747        Initializer *ti = init; 
     748        if (einit) 
     749        {   ti = new ExpInitializer(einit->loc, einit); 
     750        } 
     751 
     752        VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); 
    743753        //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); 
    744754        v->semantic(sc); 
     
    11091119    if (init) 
    11101120    {   buf->writestring(" = "); 
    1111     init->toCBuffer(buf, hgs); 
     1121    ExpInitializer *ie = init->isExpInitializer(); 
     1122    if (ie && ie->exp->op == TOKconstruct) 
     1123        ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs); 
     1124    else 
     1125        init->toCBuffer(buf, hgs); 
    11121126    } 
    11131127    buf->writeByte(';'); 
     
    12791293 */ 
    12801294 
    1281 Expression *VarDeclaration::callAutoDtor(
     1295Expression *VarDeclaration::callAutoDtor(Scope *sc
    12821296{   Expression *e = NULL; 
    12831297 
    12841298    //printf("VarDeclaration::callAutoDtor() %s\n", toChars()); 
    1285     if (storage_class & (STCauto | STCscope) && !noauto) 
     1299 
     1300    if (noauto || storage_class & STCnodtor) 
     1301    return NULL; 
     1302 
     1303    FuncDeclaration *fd = sc->parent->isFuncDeclaration(); 
     1304    if (fd && fd->nrvo_var == this) 
     1305    return NULL; 
     1306 
     1307    // Destructors for structs and arrays of structs 
     1308    bool array = false; 
     1309    Type *tv = type->toBasetype(); 
     1310    while (tv->ty == Tsarray) 
     1311    {   TypeSArray *ta = (TypeSArray *)tv; 
     1312    array = true; 
     1313    tv = tv->nextOf()->toBasetype(); 
     1314    } 
     1315    if (tv->ty == Tstruct) 
     1316    {   TypeStruct *ts = (TypeStruct *)tv; 
     1317    StructDeclaration *sd = ts->sym; 
     1318    if (sd->dtor) 
     1319    { 
     1320        if (array) 
     1321        { 
     1322        // Typeinfo.destroy(cast(void*)&v); 
     1323        Expression *ea = new SymOffExp(loc, this, 0, 0); 
     1324        ea = new CastExp(loc, ea, Type::tvoid->pointerTo()); 
     1325        Expressions *args = new Expressions(); 
     1326        args->push(ea); 
     1327 
     1328        Expression *et = type->getTypeInfo(sc); 
     1329        et = new DotIdExp(loc, et, Id::destroy); 
     1330 
     1331        e = new CallExp(loc, et, args); 
     1332        } 
     1333        else 
     1334        { 
     1335        e = new VarExp(loc, this); 
     1336        e = new DotVarExp(loc, e, sd->dtor, 0); 
     1337        e = new CallExp(loc, e); 
     1338        } 
     1339        return e; 
     1340    } 
     1341    } 
     1342 
     1343    // Destructors for classes 
     1344    if (storage_class & (STCauto | STCscope)) 
    12861345    { 
    12871346    for (ClassDeclaration *cd = type->isClassHandle(); 
     
    12931352         * could be set. 
    12941353         */ 
    1295         if (cd->isInterfaceDeclaration()) 
    1296         error("interface %s cannot be scope", cd->toChars()); 
     1354        //if (cd->isInterfaceDeclaration()) 
     1355        //error("interface %s cannot be scope", cd->toChars()); 
    12971356        if (1 || onstack || cd->dtors.dim)  // if any destructors 
    12981357        { 
  • branches/dmdfe-2.0/declaration.h

    r880 r882  
    6666    STCinit     = 0x400000,     // has explicit initializer 
    6767    STCmanifest     = 0x800000,     // manifest constant 
     68    STCnodtor       = 0x1000000,    // don't run destructor 
     69    STCnothrow      = 0x2000000,    // never throws exceptions 
    6870}; 
    6971 
     
    242244    int hasPointers(); 
    243245    int canTakeAddressOf(); 
    244     Expression *callAutoDtor(); 
     246    Expression *callAutoDtor(Scope *sc); 
    245247    ExpInitializer *getExpInitializer(); 
    246248    Expression *getConstInitializer(); 
     
    565567}; 
    566568 
     569struct PostBlitDeclaration : FuncDeclaration 
     570{ 
     571    PostBlitDeclaration(Loc loc, Loc endloc); 
     572    PostBlitDeclaration(Loc loc, Loc endloc, Identifier *id); 
     573    Dsymbol *syntaxCopy(Dsymbol *); 
     574    void semantic(Scope *sc); 
     575    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     576    int isVirtual(); 
     577    int addPreInvariant(); 
     578    int addPostInvariant(); 
     579    int overloadInsert(Dsymbol *s); 
     580    void emitComment(Scope *sc); 
     581 
     582    PostBlitDeclaration *isPostBlitDeclaration() { return this; } 
     583}; 
     584 
    567585struct DtorDeclaration : FuncDeclaration 
    568586{ 
    569587    DtorDeclaration(Loc loc, Loc endloc); 
     588    DtorDeclaration(Loc loc, Loc endloc, Identifier *id); 
    570589    Dsymbol *syntaxCopy(Dsymbol *); 
    571590    void semantic(Scope *sc); 
  • branches/dmdfe-2.0/doc.c

    r846 r882  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2006 by Digital Mars 
     3// Copyright (c) 1999-2008 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    103103unsigned skiptoident(OutBuffer *buf, unsigned i); 
    104104unsigned skippastident(OutBuffer *buf, unsigned i); 
     105unsigned skippastURL(OutBuffer *buf, unsigned i); 
    105106void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 
    106107void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 
     
    115116    <h1>$(TITLE)</h1>\n\ 
    116117    $(BODY)\n\ 
    117     <hr>$(SMALL Page generated by $(LINK2 http://www.digitalmars.com/d/ddoc.html, Ddoc). $(COPYRIGHT))\n\ 
     118    <hr>$(SMALL Page generated by $(LINK2 http://www.digitalmars.com/d/2.0/ddoc.html, Ddoc). $(COPYRIGHT))\n\ 
    118119    </body></html>\n\ 
    119120\n\ 
     
    372373void Dsymbol::emitDitto(Scope *sc) 
    373374{ 
     375    //printf("Dsymbol::emitDitto() %s %s\n", kind(), toChars()); 
    374376    OutBuffer *buf = sc->docbuf; 
    375377    unsigned o; 
     
    377379 
    378380    b.writestring("$(DDOC_DITTO "); 
    379     o = b.offset; 
    380     toDocBuffer(&b); 
    381     highlightCode(sc, this, &b, o); 
     381    o = b.offset; 
     382    toDocBuffer(&b); 
     383    //printf("b: '%.*s'\n", b.offset, b.data); 
     384    /* If 'this' is a function template, then highlightCode() was 
     385     * already run by FuncDeclaration::toDocbuffer(). 
     386     */ 
     387    TemplateDeclaration *td; 
     388    if (parent && 
     389        (td = parent->isTemplateDeclaration()) != NULL && 
     390        td->onemember == this) 
     391    { 
     392    } 
     393    else 
     394        highlightCode(sc, this, &b, o); 
    382395    b.writeByte(')'); 
    383396    buf->spread(sc->lastoffset, b.offset); 
     
    436449void Dsymbol::emitComment(Scope *sc)           { } 
    437450void InvariantDeclaration::emitComment(Scope *sc)  { } 
     451void PostBlitDeclaration::emitComment(Scope *sc)   { } 
    438452void DtorDeclaration::emitComment(Scope *sc)       { } 
    439453void StaticCtorDeclaration::emitComment(Scope *sc) { } 
     
    636650    HdrGenState hgs; 
    637651 
     652    hgs.ddoc = 1; 
    638653    toCBuffer(buf, &hgs); 
    639654} 
     
    739754        buf->writestring(ident->toChars()); 
    740755        buf->writeByte('('); 
    741         for (int i = 0; i < td->parameters->dim; i++) 
     756        for (int i = 0; i < td->origParameters->dim; i++) 
    742757        { 
    743         TemplateParameter *tp = (TemplateParameter *)td->parameters->data[i]; 
     758        TemplateParameter *tp = (TemplateParameter *)td->origParameters->data[i]; 
    744759        if (i) 
    745760            buf->writeByte(','); 
     
    14921507 
    14931508 
     1509/************************************************ 
     1510 * Scan forward past URL starting at i. 
     1511 * We don't want to highlight parts of a URL. 
     1512 * Returns: 
     1513 *  i if not a URL 
     1514 *  index just past it if it is a URL 
     1515 */ 
     1516 
     1517unsigned skippastURL(OutBuffer *buf, unsigned i) 
     1518{   unsigned length = buf->offset - i; 
     1519    unsigned char *p = &buf->data[i]; 
     1520    unsigned j; 
     1521    unsigned sawdot = 0; 
     1522 
     1523    if (length > 7 && memicmp((char *)p, "http://", 7) == 0) 
     1524    { 
     1525    j = 7; 
     1526    } 
     1527    else if (length > 8 && memicmp((char *)p, "https://", 8) == 0) 
     1528    { 
     1529    j = 8; 
     1530    } 
     1531    else 
     1532    goto Lno; 
     1533 
     1534    for (; j < length; j++) 
     1535    {   unsigned char c = p[j]; 
     1536    if (isalnum(c)) 
     1537        continue; 
     1538        if (c == '-' || c == '_' || c == '?' || 
     1539            c == '=' || c == '%' || c == '&' || 
     1540            c == '/' || c == '+' || c == '#' || 
     1541            c == '~') 
     1542            continue; 
     1543        if (c == '.') 
     1544        { 
     1545            sawdot = 1; 
     1546            continue; 
     1547        } 
     1548        break; 
     1549    } 
     1550    if (sawdot) 
     1551    return i + j; 
     1552 
     1553Lno: 
     1554    return i; 
     1555} 
     1556 
     1557 
    14941558/**************************************************** 
    14951559 */ 
     
    17361800            if (j > i) 
    17371801            { 
     1802            unsigned k = skippastURL(buf, i); 
     1803            if (k > i) 
     1804            {   i = k - 1; 
     1805                break; 
     1806            } 
     1807 
    17381808            if (buf->data[i] == '_')    // leading '_' means no highlight 
    17391809            { 
  • branches/dmdfe-2.0/dsymbol.h

    r837 r882  
    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 
     
    3939struct FuncLiteralDeclaration; 
    4040struct CtorDeclaration; 
     41struct PostBlitDeclaration; 
    4142struct DtorDeclaration; 
    4243struct StaticCtorDeclaration; 
     
    185186    virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; } 
    186187    virtual CtorDeclaration *isCtorDeclaration() { return NULL; } 
     188    virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; } 
    187189    virtual DtorDeclaration *isDtorDeclaration() { return NULL; } 
    188190    virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; } 
  • branches/dmdfe-2.0/expression.c

    r881 r882  
    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 
     
    177177 
    178178    precedence[TOKassign] = PREC_assign; 
     179    precedence[TOKconstruct] = PREC_assign; 
     180    precedence[TOKblit] = PREC_assign; 
    179181    precedence[TOKaddass] = PREC_assign; 
    180182    precedence[TOKminass] = PREC_assign; 
     
    298300} 
    299301 
     302 
     303/****************************** 
     304 * Perform canThrow() on an array of Expressions. 
     305 */ 
     306 
     307int arrayExpressionCanThrow(Expressions *exps) 
     308{ 
     309    if (exps) 
     310    { 
     311    for (size_t i = 0; i < exps->dim; i++) 
     312    {   Expression *e = (Expression *)exps->data[i]; 
     313        if (e && e->canThrow()) 
     314        return 1; 
     315    } 
     316    } 
     317    return 0; 
     318} 
     319 
     320 
    300321/**************************************** 
    301322 * Expand tuples. 
     
    382403} 
    383404 
     405/********************************************* 
     406 * Call copy constructor for struct value argument. 
     407 */ 
     408 
     409Expression *callCpCtor(Loc loc, Scope *sc, Expression *e) 
     410{ 
     411    Type *tb = e->type->toBasetype(); 
     412    assert(tb->ty == Tstruct); 
     413    StructDeclaration *sd = ((TypeStruct *)tb)->sym; 
     414    if (sd->cpctor) 
     415    { 
     416    /* Create a variable tmp, and replace the argument e with: 
     417     *  (tmp = e),tmp 
     418     * and let AssignExp() handle the construction. 
     419     * This is not the most efficent, ideally tmp would be constructed 
     420     * directly onto the stack. 
     421     */ 
     422    Identifier *idtmp = Lexer::uniqueId("__tmp"); 
     423    VarDeclaration *tmp = new VarDeclaration(loc, tb, idtmp, new ExpInitializer(0, e)); 
     424    Expression *ae = new DeclarationExp(loc, tmp); 
     425    e = new CommaExp(loc, ae, new VarExp(loc, tmp)); 
     426    e = e->semantic(sc); 
     427    } 
     428    return e; 
     429} 
    384430 
    385431/**************************************** 
    386432 * Now that we know the exact type of the function we're calling, 
    387433 * the arguments[] need to be adjusted: 
    388  *  1) implicitly convert argument to the corresponding parameter type 
    389  *  2) add default arguments for any missing arguments 
    390  *  3) do default promotions on arguments corresponding to ... 
    391  *  4) add hidden _arguments[] argument 
     434 *  1. implicitly convert argument to the corresponding parameter type 
     435 *  2. add default arguments for any missing arguments 
     436 *  3. do default promotions on arguments corresponding to ... 
     437 *  4. add hidden _arguments[] argument 
     438 *  5. call copy constructor for struct value arguments 
    392439 */ 
    393440 
     
    395442{ 
    396443    unsigned n; 
    397     int done; 
    398     Type *tb; 
    399444 
    400445    //printf("functionArguments()\n"); 
     
    408453    n = (nargs > nparams) ? nargs : nparams;    // n = max(nargs, nparams) 
    409454 
    410     done = 0; 
     455    int done = 0; 
    411456    for (size_t i = 0; i < n; i++) 
    412457    { 
     
    417462    else 
    418463        arg = NULL; 
     464    Type *tb; 
    419465 
    420466    if (i < nparams) 
     
    463509            } 
    464510#endif 
    465             static int idn; 
    466             char name[10 + sizeof(idn)*3 + 1]; 
    467             sprintf(name, "__arrayArg%d", ++idn); 
    468             Identifier *id = Lexer::idPool(name); 
     511            Identifier *id = Lexer::uniqueId("__arrayArg"); 
    469512            Type *t = new TypeSArray(((TypeArray *)tb)->next, new IntegerExp(nargs - i)); 
    470513            t = t->semantic(loc, sc); 
     
    545588        } 
    546589 
     590        if (tb->ty == Tstruct && !(p->storageClass & (STCref | STCout))) 
     591        { 
     592        arg = callCpCtor(loc, sc, arg); 
     593        } 
     594 
    547595        // Convert lazy argument to a delegate 
    548596        if (p->storageClass & STClazy) 
     
    586634        } 
    587635 
     636        if (tb->ty == Tstruct) 
     637        { 
     638        arg = callCpCtor(loc, sc, arg); 
     639        } 
     640 
    588641        // Give error for overloaded function addresses 
    589642        if (arg->op == TOKsymoff) 
     
    594647        arg->rvalue(); 
    595648    } 
     649 
    596650    arg = arg->optimize(WANTvalue); 
    597651    arguments->data[i] = (void *) arg; 
     
    10111065    return FALSE; 
    10121066} 
     1067 
     1068/******************************** 
     1069 * Can this expression throw an exception? 
     1070 * Valid only after semantic() pass. 
     1071 */ 
     1072 
     1073int Expression::canThrow() 
     1074{ 
     1075    return FALSE; 
     1076} 
     1077 
     1078 
    10131079 
    10141080Expressions *Expression::arraySyntaxCopy(Expressions *exps) 
     
    25512617} 
    25522618 
     2619int ArrayLiteralExp::canThrow() 
     2620{ 
     2621    return 1;   // because it can fail allocating memory 
     2622} 
     2623 
    25532624void ArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    25542625{ 
     
    26672738    size_t dim = keys->dim; 
    26682739    return result ? (dim != 0) : (dim == 0); 
     2740} 
     2741 
     2742int AssocArrayLiteralExp::canThrow() 
     2743{ 
     2744    return 1; 
    26692745} 
    26702746 
     
    28732949    Expression::checkSideEffect(0); 
    28742950    return f; 
     2951} 
     2952 
     2953int StructLiteralExp::canThrow() 
     2954{ 
     2955    return arrayExpressionCanThrow(elements); 
    28752956} 
    28762957 
     
    33483429} 
    33493430 
     3431int NewExp::canThrow() 
     3432{ 
     3433    return 1; 
     3434} 
     3435 
    33503436void NewExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    33513437{   int i; 
     
    34103496 
    34113497int NewAnonClassExp::checkSideEffect(int flag) 
     3498{ 
     3499    return 1; 
     3500} 
     3501 
     3502int NewAnonClassExp::canThrow() 
    34123503{ 
    34133504    return 1; 
     
    37593850} 
    37603851 
     3852int TupleExp::canThrow() 
     3853{ 
     3854    return arrayExpressionCanThrow(exps); 
     3855} 
     3856 
    37613857void TupleExp::checkEscape() 
    37623858{ 
     
    38823978    else if (sc->func) 
    38833979    {   VarDeclaration *v = s->isVarDeclaration(); 
    3884         if ((s->isFuncDeclaration() /*|| v && v->storage_class & STCstatic*/) && 
     3980        if (s->isFuncDeclaration() && 
    38853981        !sc->func->localsymtab->insert(s)) 
    38863982        error("declaration %s is already defined in another scope in %s", s->toPrettyChars(), sc->func->toChars()); 
     
    39254021{ 
    39264022    return 1; 
     4023} 
     4024 
     4025int DeclarationExp::canThrow() 
     4026{ 
     4027    VarDeclaration *v = declaration->isVarDeclaration(); 
     4028    if (v && v->init) 
     4029    {   ExpInitializer *ie = v->init->isExpInitializer(); 
     4030    return ie && ie->exp->canThrow(); 
     4031    } 
     4032    return 0; 
    39274033} 
    39284034 
     
    43704476} 
    43714477 
     4478int UnaExp::canThrow() 
     4479{ 
     4480    return e1->canThrow(); 
     4481} 
     4482 
    43724483void UnaExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    43734484{ 
     
    44914602       op == TOKminusminus || 
    44924603       op == TOKassign || 
     4604       op == TOKconstruct || 
     4605       op == TOKblit || 
    44934606       op == TOKaddass || 
    44944607       op == TOKminass || 
     
    45234636} 
    45244637 
     4638int BinExp::canThrow() 
     4639{ 
     4640    return e1->canThrow() || e2->canThrow(); 
     4641} 
     4642 
    45254643void BinExp::incompatibleTypes() 
    45264644{ 
     
    46894807{ 
    46904808    return 1; 
     4809} 
     4810 
     4811int AssertExp::canThrow() 
     4812{ 
     4813    return (global.params.useAssert != 0); 
    46914814} 
    46924815 
     
    47894912    eleft = NULL; 
    47904913    eright = e1; 
     4914    } 
     4915 
     4916    if (e1->op == TOKtuple && ident == Id::offsetof) 
     4917    {   /* 'distribute' the .offsetof to each of the tuple elements. 
     4918     */ 
     4919    TupleExp *te = (TupleExp *)e1; 
     4920    Expressions *exps = new Expressions(); 
     4921    exps->setDim(te->exps->dim); 
     4922    for (int i = 0; i < exps->dim; i++) 
     4923    {   Expression *e = (Expression *)te->exps->data[i]; 
     4924        e = e->semantic(sc); 
     4925        e = new DotIdExp(e->loc, e, Id::offsetof); 
     4926        exps->data[i] = (void *)e; 
     4927    } 
     4928    e = new TupleExp(loc, exps); 
     4929    e = e->semantic(sc); 
     4930    return e; 
    47914931    } 
    47924932 
     
    51005240        } 
    51015241        } 
    5102         accessCheck(loc, sc, e1, var); 
     5242        if (!sc->noaccesscheck) 
     5243        accessCheck(loc, sc, e1, var); 
    51035244    } 
    51045245    } 
     
    52205361    t1 = t1->toBasetype(); 
    52215362    //t1->print(); 
     5363 
     5364    /* Extract the following from e1: 
     5365     *  s: the symbol which ti should be a member of 
     5366     *  eleft: if not NULL, it is the 'this' pointer for ti 
     5367     */ 
     5368 
    52225369    if (e1->op == TOKdotexp) 
    52235370    {   DotExp *de = (DotExp *)e1; 
     
    54615608    Type *t1; 
    54625609    int istemp; 
     5610    Objects *targsi = NULL; // initial list of template arguments 
    54635611 
    54645612#if LOGSEMANTIC 
    54655613    printf("CallExp::semantic() %s\n", toChars()); 
     5614e1->dump(0); 
    54665615#endif 
    54675616    if (type) 
     
    55235672    } 
    55245673 
     5674    /* This recognizes: 
     5675     *  foo!(tiargs)(funcargs) 
     5676     */ 
     5677    if (e1->op == TOKimport && !e1->type) 
     5678    {   ScopeExp *se = (ScopeExp *)e1; 
     5679    TemplateInstance *ti = se->sds->isTemplateInstance(); 
     5680    if (ti && !ti->semanticdone) 
     5681    { 
     5682        /* Attempt to instantiate ti. If that works, go with it. 
     5683         * If not, go with partial explicit specialization. 
     5684         */ 
     5685        unsigned errors = global.errors; 
     5686        global.gag++; 
     5687        ti->semantic(sc); 
     5688        global.gag--; 
     5689        if (errors != global.errors) 
     5690        { 
     5691        global.errors = errors; 
     5692        targsi = ti->tiargs; 
     5693        e1 = new IdentifierExp(loc, ti->name); 
     5694        } 
     5695    } 
     5696    } 
     5697 
     5698    /* This recognizes: 
     5699     *  expr.foo!(tiargs)(funcargs) 
     5700     */ 
     5701    if (e1->op == TOKdotti && !e1->type) 
     5702    {   DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1; 
     5703    TemplateInstance *ti = se->ti; 
     5704    if (!ti->semanticdone) 
     5705    { 
     5706        /* Attempt to instantiate ti. If that works, go with it. 
     5707         * If not, go with partial explicit specialization. 
     5708         */ 
     5709        Expression *etmp; 
     5710        unsigned errors = global.errors; 
     5711        global.gag++; 
     5712        etmp = e1->semantic(sc); 
     5713        global.gag--; 
     5714        if (errors != global.errors) 
     5715        { 
     5716        global.errors = errors; 
     5717        targsi = ti->tiargs; 
     5718        e1 = new DotIdExp(loc, se->e1, ti->name); 
     5719        } 
     5720        else 
     5721        e1 = etmp; 
     5722    } 
     5723    } 
     5724 
    55255725    istemp = 0; 
    55265726Lagain: 
     
    56495849        // Should fix deduceFunctionTemplate() so it works on NULL argument 
    56505850        arguments = new Expressions(); 
    5651         f = td->deduceFunctionTemplate(sc, loc, NULL, ue->e1, arguments); 
     5851        f = td->deduceFunctionTemplate(sc, loc, targsi, ue->e1, arguments); 
    56525852        if (!f) 
    56535853        {   type = Type::terror; 
     
    58496049        {   TemplateDeclaration *td = s->isTemplateDeclaration(); 
    58506050        assert(td); 
    5851         f2 = td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments, 1); 
     6051        f2 = td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments, 1); 
    58526052        } 
    58536053        if (f2) 
     
    58956095    { 
    58966096        TemplateExp *te = (TemplateExp *)e1; 
    5897         f = te->td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments); 
     6097        f = te->td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments); 
    58986098        if (!f) 
    58996099        {   type = Type::terror; 
     
    59766176 
    59776177int CallExp::checkSideEffect(int flag) 
     6178{ 
     6179    return 1; 
     6180} 
     6181 
     6182int CallExp::canThrow() 
    59786183{ 
    59796184    return 1; 
     
    63086513        StructDeclaration *sd = ts->sym; 
    63096514        FuncDeclaration *f = sd->aggDelete; 
     6515        FuncDeclaration *fd = sd->dtor; 
     6516 
     6517        if (!f && !fd) 
     6518            break; 
     6519 
     6520        /* Construct: 
     6521         *  ea = copy e1 to a tmp to do side effects only once 
     6522         *  eb = call destructor 
     6523         *  ec = call dealloc