Changeset 694

Show
Ignore:
Timestamp:
07/24/07 01:17:13 (1 year ago)
Author:
Gregor
Message:

MERGE: trunk r693

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/tango/docs/ChangeLog

    r654 r694  
    1 SVN from 0.67: 
     1SVN from 0.68: 
     2    - Added --test option to test built libraries. 
     3 
     40.68 from 0.67: 
    25        - Rebuild: -of<name> now converts / to \ on Windows (see ticket #85). 
    36        - `dsss uninstall` now removes (empty) directories as well as files 
    47          (see ticket #84). 
     8        - Rebuild: Merged DMD 1.018. 
     9        - Rebuild: Added proper documentation for -Dq (see ticket #90). 
     10        - /etc will now be preferred to /usr/etc when installing to the prefix 
     11          /usr. 
     12        - Rebuild: Added -no-export-dynamic flag (see ticket #91). 
    513 
    6140.67 from 0.66: 
  • branches/tango/docs/NEWS

    r654 r694  
    1 2006-06-29: DSSS and Rebuild 0.67 released. 
     12007-07-22: DSSS and Rebuild 0.68 released. 
     2 
     32007-06-29: DSSS and Rebuild 0.67 released. 
    24 
    352007-06-25: DSSS and Rebuild 0.66 released. 
  • branches/tango/dsss.conf

    r654 r694  
    2929# Install this as a sourcelibrary, so it will work on any platform/compiler combination 
    3030type = sourcelibrary 
     31exclude = sss/dsss_lib_test.d sss/dsssdll.d sss/main.d sss/stub.d 
     32buildflags = -Irebuild 
     33 
     34# dsss_lib_test is special, so put it in share/ 
     35postinstall = install sss/dsss_lib_test.d $PREFIX/share/dsss 
    3136 
    3237version (Windows) { 
  • branches/tango/hcf/path.d

    r654 r694  
    2929module hcf.path; 
    3030 
     31import tango.io.FileConst; 
     32import tango.io.FilePath; 
     33import tango.io.FileSystem; 
     34 
     35import tango.text.String; 
     36import tango.text.Util; 
     37 
     38import tango.stdc.stdlib; 
     39import tango.stdc.stringz; 
     40 
     41version (Posix) { 
     42    import tango.stdc.posix.sys.stat; 
     43} 
     44 
    3145version (Windows) { 
    3246    import bcd.windows.windows; 
    3347} 
    3448 
     49/* Simple getDirName, etc */ 
     50char[] getDirName(char[] fname) 
     51{ 
     52    return (new FilePath(fname)).path(); 
     53} 
     54char[] getBaseName(char[] fname) 
     55{ 
     56    return (new FilePath(fname)).file(); 
     57} 
     58char[] getName(char[] fname) 
     59{ 
     60    return (new FilePath(fname)).name(); 
     61} 
     62char[] getExt(char[] fname) 
     63{ 
     64    return (new FilePath(fname)).ext(); 
     65} 
     66 
    3567/** Get the system PATH */ 
    3668char[][] getPath() 
    3769{ 
    38     return split(toString(getenv("PATH")), std.path.pathsep); 
     70    return split(fromUtf8z(getenv("PATH")), FileConst.SystemPathChar~""); 
    3971} 
    4072 
     
    5385    // is this a directory? 
    5486    if (dir != "") { 
    55         if (!std.path.isabs(dir)) { 
     87        if (!(new FilePath(dir)).isAbsolute()) { 
    5688            // make it absolute 
    57             dir = getcwd() ~ std.path.sep ~ dir; 
     89            dir = FileSystem.getDirectory() ~ FileConst.PathSeparatorChar ~ dir; 
    5890        } 
    5991        return true; 
     
    6294    version (Windows) { 
    6395        // is it in cwd? 
    64         char[] cwd = getcwd(); 
    65         if (exists(cwd ~ std.path.sep ~ bname)) { 
     96        char[] cwd = FileSystem.getDirectory(); 
     97        if ((new FilePath(cwd ~ FileConst.PathSeparatorChar ~ bname)).exists()) { 
    6698            dir = cwd; 
    6799            return true; 
     
    72104    char[][] path = getPath(); 
    73105    foreach (pe; path) { 
    74         char[] fullname = pe ~ std.path.sep ~ bname; 
    75         if (exists(fullname)) { 
    76             version (Windows) { 
     106        char[] fullname = pe ~ FileConst.PathSeparatorChar ~ bname; 
     107        if ((new FilePath(fullname)).exists()) { 
     108            //version (Windows) { 
    77109                dir = pe; 
    78110                return true; 
    79             } else { 
    80                 if (getAttributes(fullname) & 0100) { 
     111            /*} else { 
     112                stat_t stats; 
     113                stat(toUtf8z(fullname), &stats); 
     114                if ((cast(int) stats) & 0100) { 
    81115                    dir = pe; 
    82116                    return true; 
    83117                } 
    84             } 
     118            }*/ 
    85119        } 
    86120    } 
     
    107141     
    108142    // expand tildes 
    109     ret = expandTilde(ret); 
     143    // ret = expandTilde(ret); FIXME 
    110144     
    111145    // get rid of any duplicate separators 
    112146    for (int i = 0; i < ret.length; i++) { 
    113         if (ret[i .. (i + 1)] == sep) { 
     147        if (ret[i .. (i + 1)] == FileConst.PathSeparatorChar~"") { 
    114148            // drop the duplicate separator 
    115149            i++; 
    116150            while (i < ret.length && 
    117                    ret[i .. (i + 1)] == sep) { 
     151                   ret[i .. (i + 1)] == FileConst.PathSeparatorChar~"") { 
    118152                ret = ret[0 .. i] ~ ret[(i + 1) .. $]; 
    119153            } 
     
    122156     
    123157    // make sure we don't miss a .. element 
    124     if (ret.length > 3 && ret[($-3) .. $] == std.path.sep ~ "..") { 
    125         ret ~= std.path.sep
     158    if (ret.length > 3 && ret[($-3) .. $] == FileConst.PathSeparatorChar ~ "..") { 
     159        ret ~= FileConst.PathSeparatorChar
    126160    } 
    127161     
    128162    // or a . element 
    129     if (ret.length > 2 && ret[($-2) .. $] == std.path.sep ~ ".") { 
    130         ret ~= std.path.sep
     163    if (ret.length > 2 && ret[($-2) .. $] == FileConst.PathSeparatorChar ~ ".") { 
     164        ret ~= FileConst.PathSeparatorChar
    131165    } 
    132166     
    133167    // search for .. elements 
    134168    for (int i = 0; ret.length > 4 && i <= ret.length - 4; i++) { 
    135         if (ret[i .. (i + 4)] == std.path.sep ~ ".." ~ std.path.sep) { 
     169        if (ret[i .. (i + 4)] == FileConst.PathSeparatorChar ~ ".." ~ FileConst.PathSeparatorChar) { 
    136170            // drop the previous path element 
    137171            int j; 
    138             for (j = i - 1; j > 0 && ret[j..(j+1)] != std.path.sep; j--) {} 
     172            for (j = i - 1; j > 0 && ret[j..(j+1)] != FileConst.PathSeparatorChar~""; j--) {} 
    139173            if (j > 0) { 
    140174                // cut 
     
    142176            } else { 
    143177                // sort of ridiculous, but cut as best we can 
    144                 ret = std.path.sep ~ ret[(i + 3) .. $]; 
     178                ret = FileConst.PathSeparatorChar ~ ret[(i + 3) .. $]; 
    145179            } 
    146180            i = j - 1; 
     
    150184    // search for . elements 
    151185    for (int i = 0; ret.length > 2 && i <= ret.length - 3; i++) { 
    152         if (ret[i .. (i + 3)] == std.path.sep ~ "." ~ std.path.sep) { 
     186        if (ret[i .. (i + 3)] == FileConst.PathSeparatorChar ~ "." ~ FileConst.PathSeparatorChar) { 
    153187            // drop this path element 
    154188            ret = ret[0..i] ~ ret[(i + 2) .. $]; 
     
    159193    // finally, get rid of any trailing separators 
    160194    while (ret.length && 
    161            ret[($ - 1) .. $] == sep) { 
     195           ret[($ - 1) .. $] == FileConst.PathSeparatorChar~"") { 
    162196        ret = ret[0 .. ($ - 1)]; 
    163197    } 
     
    175209     
    176210    // split it into elements 
    177     char[][] dires = split(dir, sep); 
     211    char[][] dires = split(dir, FileConst.PathSeparatorChar~""); 
    178212     
    179213    char[] curdir; 
     
    182216    if (dires.length && 
    183217        dires[0] == "") { 
    184         curdir = std.path.sep
     218        curdir = FileConst.PathSeparatorChar~""
    185219        dires = dires[1..$]; 
    186220    } 
     
    189223    foreach (dire; dires) { 
    190224        if (curdir.length) { 
    191             curdir ~= sep ~ dire; 
     225            curdir ~= FileConst.PathSeparatorChar ~ dire; 
    192226        } else { 
    193227            curdir ~= dire; 
    194228        } 
    195229         
    196         if (!exists(curdir)) { 
    197             mkdir(curdir); 
     230        if (!(new FilePath(curdir)).exists()) { 
     231            (new FilePath(curdir)).createFolder(); 
    198232        } 
    199233    } 
     
    205239    // can only delete writable files on Windows 
    206240    version (Windows) { 
    207         SetFileAttributesA(toStringz(name), 
    208                            GetFileAttributesA(toStringz(name)) & 
     241        SetFileAttributesA(toUtf8z(name), 
     242                           GetFileAttributesA(toUtf8z(name)) & 
    209243                           ~FILE_ATTRIBUTE_READONLY); 
    210244    } 
    211245     
    212     if (isdir(name)) { 
    213         foreach (elem; listdir(name)) { 
     246    if ((new FilePath(name)).isDir()) { 
     247        foreach (elem; (new FilePath(name)).toList()) { 
    214248            // don't delete . or .. 
    215249            if (elem == "." || 
    216250                elem == "..") continue; 
    217             rmRecursive(name ~ std.path.sep ~ elem); 
     251            rmRecursive(name ~ FileConst.PathSeparatorChar ~ elem); 
    218252        } 
    219253         
    220254        // remove the directory itself 
    221         rmdir(name); 
     255        (new FilePath(name)).remove(); 
    222256    } else { 
    223         std.file.remove(name); 
    224     } 
    225 } 
     257        (new FilePath(name)).remove(); 
     258    } 
     259} 
  • branches/tango/rebuild/aggregate.h

    r589 r694  
    4444    unsigned alignsize;     // size of struct for alignment purposes 
    4545    unsigned structalign;   // struct member alignment in effect 
     46    int hasUnions;      // set if aggregate has overlapping fields 
    4647    Array fields;       // VarDeclaration fields 
    4748    unsigned sizeok;        // set when structsize contains valid data 
  • branches/tango/rebuild/attrib.c

    r654 r694  
    12081208    Parser p(sc->module, (unsigned char *)se->string, se->len, 0); 
    12091209    p.loc = loc; 
     1210    p.nextToken(); 
    12101211    decl = p.parseDeclDefs(0); 
    12111212    if (p.token.value != TOKeof) 
  • branches/tango/rebuild/cast.c

    r589 r694  
    333333{   MATCH m; 
    334334 
    335     //printf("StringExp::implicitConvTo(t = %s), '%s' committed = %d\n", t->toChars(), toChars(), committed); 
     335#if 0 
     336    printf("StringExp::implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n", 
     337    toChars(), committed, type->toChars(), t->toChars()); 
     338#endif 
    336339    if (!committed) 
    337340    { 
     
    351354            ((TypeSArray *)t)->dim->toInteger()) 
    352355            return MATCHnomatch; 
     356            goto L1; 
    353357        case Tarray: 
     358            goto L1; 
    354359        case Tpointer: 
     360        L1: 
    355361            if (t->next->ty == Tchar) 
    356362            return MATCHexact; 
  • branches/tango/rebuild/class.c

    r589 r694  
    524524    structalign = 0; 
    525525 
    526     sc->pop(); 
     526    sc = sc->pop(); 
    527527 
    528528    scope = scx ? scx : new Scope(*sc); 
  • branches/tango/rebuild/constfold.c

    r654 r694  
    684684    real_t r2; 
    685685 
     686    //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 
     687 
    686688    assert(op == TOKequal || op == TOKnotequal); 
    687689 
     
    714716        Expression *ee2 = (Expression *)es2->elements->data[i]; 
    715717 
     718        Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); 
     719        if (v == EXP_CANT_INTERPRET) 
     720            return EXP_CANT_INTERPRET; 
     721        cmp = v->toInteger(); 
     722        if (cmp == 0) 
     723            break; 
     724        } 
     725    } 
     726    } 
     727    else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral) 
     728    {   StructLiteralExp *es1 = (StructLiteralExp *)e1; 
     729    StructLiteralExp *es2 = (StructLiteralExp *)e2; 
     730 
     731    if (es1->sd != es2->sd) 
     732        cmp = 0; 
     733    else if ((!es1->elements || !es1->elements->dim) && 
     734        (!es2->elements || !es2->elements->dim)) 
     735        cmp = 1;        // both arrays are empty 
     736    else if (!es1->elements || !es2->elements) 
     737        cmp = 0; 
     738    else if (es1->elements->dim != es2->elements->dim) 
     739        cmp = 0; 
     740    else 
     741    { 
     742        cmp = 1; 
     743        for (size_t i = 0; i < es1->elements->dim; i++) 
     744        {   Expression *ee1 = (Expression *)es1->elements->data[i]; 
     745        Expression *ee2 = (Expression *)es2->elements->data[i]; 
     746 
     747        if (ee1 == ee2) 
     748            continue; 
     749        if (!ee1 || !ee2) 
     750        {   cmp = 0; 
     751            break; 
     752        } 
    716753        Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); 
    717754        if (v == EXP_CANT_INTERPRET) 
     
    10571094    Loc loc = e1->loc; 
    10581095 
    1059     //printf("Index(e1 = %s)\n", e1->toChars()); 
     1096    //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 
    10601097    assert(e1->type); 
    10611098    if (e1->op == TOKstring && e2->op == TOKint64) 
     
    14051442} 
    14061443 
    1407  
     1444Expression *Ptr(Type *type, Expression *e1) 
     1445
     1446    //printf("Ptr(e1 = %s)\n", e1->toChars()); 
     1447    if (e1->op == TOKadd) 
     1448    {   AddExp *ae = (AddExp *)e1; 
     1449    if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64) 
     1450    {   AddrExp *ade = (AddrExp *)ae->e1; 
     1451        if (ade->e1->op == TOKstructliteral) 
     1452        {   StructLiteralExp *se = (StructLiteralExp *)ade->e1; 
     1453        unsigned offset = ae->e2->toInteger(); 
     1454        Expression *e = se->getField(type, offset); 
     1455        if (!e) 
     1456            e = EXP_CANT_INTERPRET; 
     1457        return e; 
     1458        } 
     1459    } 
     1460    } 
     1461    return EXP_CANT_INTERPRET; 
     1462
     1463 
  • branches/tango/rebuild/declaration.c

    r589 r694  
    802802    if (init) 
    803803    { 
     804    ArrayInitializer *ai = init->isArrayInitializer(); 
     805    if (ai && type->toBasetype()->ty == Taarray) 
     806    { 
     807        init = ai->toAssocArrayInitializer(); 
     808    } 
     809 
    804810    ExpInitializer *ei = init->isExpInitializer(); 
    805811 
  • branches/tango/rebuild/delegatize.c

    r589 r694  
    185185 
    186186 
     187void StructLiteralExp::scanForNestedRef(Scope *sc) 
     188{ 
     189    arrayExpressionScanForNestedRef(sc, elements); 
     190} 
     191 
     192 
    187193void TupleExp::scanForNestedRef(Scope *sc) 
    188194{ 
  • branches/tango/rebuild/dsymbol.c

    r589 r694  
    871871        v->storage_class |= STCconst; 
    872872        } 
     873        else if (ce->op == TOKarrayliteral) 
     874        {   /* It is for an array literal, so the 
     875         * length will be a const. 
     876         */ 
     877        Expression *e = new IntegerExp(0, ((ArrayLiteralExp *)ce)->elements->dim, Type::tsize_t); 
     878        v->init = new ExpInitializer(0, e); 
     879        v->storage_class |= STCconst; 
     880        } 
    873881        else if (ce->op == TOKtuple) 
    874882        {   /* It is for an expression tuple, so the 
  • branches/tango/rebuild/enum.c

    r589 r694  
    2727    minval = 0; 
    2828    defaultval = 0; 
     29    sinit = NULL; 
    2930} 
    3031 
  • branches/tango/rebuild/enum.h

    r589 r694  
    2626#endif 
    2727 
     28 
    2829struct EnumDeclaration : ScopeDsymbol 
    2930{ 
     
    4849 
    4950    void toDebug(); 
     51 
     52    Symbol *sinit; 
     53    Symbol *toInitializer(); 
    5054}; 
    5155 
  • branches/tango/rebuild/expression.c

    r589 r694  
    303303void expandTuples(Expressions *exps) 
    304304{ 
     305    //printf("expandTuples()\n"); 
    305306    if (exps) 
    306307    { 
    307308    for (size_t i = 0; i < exps->dim; i++) 
    308309    {   Expression *arg = (Expression *)exps->data[i]; 
     310        if (!arg) 
     311        continue; 
     312 
     313        // Look for tuple with 0 members 
     314        if (arg->op == TOKtype) 
     315        {   TypeExp *e = (TypeExp *)arg; 
     316        if (e->type->toBasetype()->ty == Ttuple) 
     317        {   TypeTuple *tt = (TypeTuple *)e->type->toBasetype(); 
     318 
     319            if (!tt->arguments || tt->arguments->dim == 0) 
     320            { 
     321            exps->remove(i); 
     322            if (i == exps->dim) 
     323                return; 
     324            i--; 
     325            continue; 
     326            } 
     327        } 
     328        } 
    309329 
    310330        // Inline expand all the tuples 
     
    663683    Expression *e; 
    664684    if (!size) 
     685    { 
     686#ifdef DEBUG 
    665687    fprintf(stdmsg, "No expression copy for: %s\n", toChars()); 
     688    printf("op = %d\n", op); 
     689    dump(0); 
     690#endif 
     691    assert(0); 
     692    } 
    666693    e = (Expression *)mem.malloc(size); 
    667694    return (Expression *)memcpy(e, this, size); 
     
    856883{ 
    857884    /*if (flag == 0) 
    858     error("%s has no effect in expression (%s)", 
    859         Token::toChars(op), toChars()); */ 
     885    {   if (op == TOKimport) 
     886    { 
     887        error("%s has no effect", toChars()); 
     888    } 
     889    else 
     890        error("%s has no effect in expression (%s)", 
     891        Token::toChars(op), toChars()); 
     892    } */ 
    860893    return 0; 
    861894} 
     
    10071040char *IntegerExp::toChars() 
    10081041{ 
     1042#if 1 
     1043    return Expression::toChars(); 
     1044#else 
    10091045    static char buffer[sizeof(value) * 3 + 1]; 
    10101046 
    10111047    sprintf(buffer, "%jd", value); 
    10121048    return buffer; 
     1049#endif 
    10131050} 
    10141051 
     
    23502387        case '"': 
    23512388        case '\\': 
    2352         buf->writeByte('\\'); 
     2389        if (!hgs->console) 
     2390            buf->writeByte('\\'); 
    23532391        default: 
    23542392        if (c <= 0xFF) 
    2355         {   if (c <= 0x7F && isprint(c)) 
     2393        {   if (c <= 0x7F && (isprint(c) || hgs->console)) 
    23562394            buf->writeByte(c); 
    23572395            else 
     
    24332471} 
    24342472 
     2473ArrayLiteralExp::ArrayLiteralExp(Loc loc, Expression *e) 
     2474    : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp)) 
     2475{ 
     2476    elements = new Expressions; 
     2477    elements->push(e); 
     2478} 
     2479 
    24352480Expression *ArrayLiteralExp::syntaxCopy() 
    24362481{ 
     
    24592504        error("%s has no value", e->toChars()); */ 
    24602505    e = resolveProperties(sc, e); 
     2506 
     2507    unsigned char committed = 1; 
     2508    if (e->op == TOKstring) 
     2509        committed = ((StringExp *)e)->committed; 
     2510 
    24612511    if (!t0) 
    24622512    {   t0 = e->type; 
     
    24702520    else 
    24712521        e = e->implicitCastTo(sc, t0); 
     2522    if (!committed && e->op == TOKstring) 
     2523    {   StringExp *se = (StringExp *)e; 
     2524        se->committed = 0; 
     2525    } 
    24722526    elements->data[i] = (void *)e; 
    24732527    } 
     
    26432697    key->toMangleBuffer(buf); 
    26442698    value->toMangleBuffer(buf); 
     2699    } 
     2700} 
     2701 
     2702/************************ StructLiteralExp ************************************/ 
     2703 
     2704// sd( e1, e2, e3, ... ) 
     2705 
     2706StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements) 
     2707    : Expression(loc, TOKstructliteral, sizeof(StructLiteralExp)) 
     2708{ 
     2709    this->sd = sd; 
     2710    this->elements = elements; 
     2711    this->sym = NULL; 
     2712    this->soffset = 0; 
     2713    this->fillHoles = 1; 
     2714} 
     2715 
     2716Expression *StructLiteralExp::syntaxCopy() 
     2717{ 
     2718    return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements)); 
     2719} 
     2720 
     2721Expression *StructLiteralExp::semantic(Scope *sc) 
     2722{   Expression *e; 
     2723 
     2724#if LOGSEMANTIC 
     2725    printf("StructLiteralExp::semantic('%s')\n", toChars()); 
     2726#endif 
     2727 
     2728    // Run semantic() on each element 
     2729    for (size_t i = 0; i < elements->dim; i++) 
     2730    {   e = (Expression *)elements->data[i]; 
     2731    if (!e) 
     2732        continue; 
     2733    e = e->semantic(sc); 
     2734    elements->data[i] = (void *)e; 
     2735    } 
     2736    expandTuples(elements); 
     2737    size_t offset = 0; 
     2738    for (size_t i = 0; i < elements->dim; i++) 
     2739    {   e = (Expression *)elements->data[i]; 
     2740    if (!e) 
     2741        continue; 
     2742 
     2743    if (!e->type) 
     2744        error("%s has no value", e->toChars()); 
     2745    e = resolveProperties(sc, e); 
     2746    if (i >= sd->fields.dim) 
     2747    {   error("more initializers than fields of %s", sd->toChars()); 
     2748        break; 
     2749    } 
     2750    Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 
     2751    VarDeclaration *v = s->isVarDeclaration(); 
     2752    assert(v); 
     2753    if (v->offset < offset) 
     2754        error("overlapping initialization for %s", v->toChars()); 
     2755    offset = v->offset + v->type->size(); 
     2756 
     2757    Type *telem = v->type; 
     2758    while (!e->implicitConvTo(telem) && telem->toBasetype()->ty == Tsarray) 
     2759    {   /* Static array initialization, as in: 
     2760         *  T[3][5] = e; 
     2761         */ 
     2762        telem = telem->toBasetype()->nextOf(); 
     2763    } 
     2764 
     2765    e = e->implicitCastTo(sc, telem); 
     2766 
     2767    elements->data[i] = (void *)e; 
     2768    } 
     2769 
     2770    /* Fill out remainder of elements[] with default initializers for fields[] 
     2771     */ 
     2772    for (size_t i = elements->dim; i < sd->fields.dim; i++) 
     2773    {   Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 
     2774    VarDeclaration *v = s->isVarDeclaration(); 
     2775    assert(v); 
     2776 
     2777    if (v->offset < offset) 
     2778    {   e = NULL; 
     2779        sd->hasUnions = 1; 
     2780    } 
     2781    else 
     2782    { 
     2783        if (v->init) 
     2784        {   e = v->init->toExpression(); 
     2785        if (!e) 
     2786            error("cannot make expression out of initializer for %s", v->toChars()); 
     2787        } 
     2788        else 
     2789        {   e = v->type->defaultInit(); 
     2790        e->loc = loc; 
     2791        } 
     2792        offset = v->offset + v->type->size(); 
     2793    } 
     2794    elements->push(e); 
     2795    } 
     2796 
     2797    type = sd->type; 
     2798    return this; 
     2799} 
     2800 
     2801/************************************** 
     2802 * Gets expression at offset of type. 
     2803 * Returns NULL if not found. 
     2804 */ 
     2805 
     2806Expression *StructLiteralExp::getField(Type *type, unsigned offset) 
     2807{   Expression *e = NULL; 
     2808    int i = getFieldIndex(type, offset); 
     2809 
     2810    if (i != -1) 
     2811    {   e = (Expression *)elements->data[i]; 
     2812    if (e) 
     2813    { 
     2814        e = e->copy(); 
     2815        e->type = type; 
     2816    } 
     2817    } 
     2818    return e; 
     2819} 
     2820 
     2821/************************************ 
     2822 * Get index of field. 
     2823 * Returns -1 if not found.  
     2824 */ 
     2825 
     2826int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) 
     2827{ 
     2828    /* Find which field offset is by looking at the field offsets 
     2829     */ 
     2830    for (size_t i = 0; i < sd->fields.dim; i++) 
     2831    { 
     2832    Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 
     2833    VarDeclaration *v = s->isVarDeclaration(); 
     2834    assert(v); 
     2835 
     2836    if (offset == v->offset && 
     2837        type->size() == v->type->size()) 
     2838    {   Expression *e = (Expression *)elements->data[i]; 
     2839        if (e) 
     2840        { 
     2841        return i; 
     2842        } 
     2843        break; 
     2844    } 
     2845    } 
     2846    return -1; 
     2847} 
     2848 
     2849 
     2850Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e) 
     2851{ 
     2852    return this; 
     2853} 
     2854 
     2855 
     2856int StructLiteralExp::checkSideEffect(int flag) 
     2857{   int f = 0; 
     2858 
     2859    for (size_t i = 0; i < elements->dim; i++) 
     2860    {   Expression *e = (Expression *)elements->data[i]; 
     2861    if (!e) 
     2862        continue; 
     2863 
     2864    f |= e->checkSideEffect(2); 
     2865    } 
     2866    if (flag == 0 && f == 0) 
     2867    Expression::checkSideEffect(0); 
     2868    return f; 
     2869} 
     2870 
     2871void StructLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
     2872{ 
     2873    buf->writestring(sd->toChars()); 
     2874    buf->writeByte('('); 
     2875    argsToCBuffer(buf, elements, hgs); 
     2876    buf->writeByte(')'); 
     2877} 
     2878 
     2879void StructLiteralExp::toMangleBuffer(OutBuffer *buf) 
     2880{ 
     2881    size_t dim = elements ? elements->dim : 0; 
     2882    buf->printf("S%u", dim); 
     2883    for (size_t i = 0; i < dim; i++) 
     2884    {   Expression *e = (Expression *)elements->data[i]; 
     2885    if (e) 
     2886        e->toMangleBuffer(buf); 
     2887    else 
     2888        buf->writeByte('v');    // 'v' for void 
    26452889    } 
    26462890} 
     
    32123456    if (v) 
    32133457    { 
    3214     /*if (!v->isDataseg()) 
    3215         error("escaping reference to local %s", v->toChars()); */ 
     3458    /* if (!v->isDataseg()) 
     3459        error("escaping reference to local variable %s", v->toChars()); */ 
    32163460    } 
    32173461} 
     
    41894433    if (e1->op != TOKstring) 
    41904434    {   //error("argument to mixin must be a string, not (%s)", e1->toChars()); 
     4435    type = Type::terror; 
    41914436    return this; 
    41924437    } 
     
    41954440    Parser p(sc->module, (unsigned char *)se->string, se->len, 0); 
    41964441    p.loc = loc; 
     4442    p.nextToken(); 
    41974443    Expression *e = p.parseExpression(); 
    41984444    /* if (p.token.value != TOKeof) 
     
    45634809        assert(0); 
    45644810    } 
     4811    else if (ident == Id::stringof) 
     4812    {   char *s = ie->toChars(); 
     4813        e = new StringExp(loc, s, strlen(s), 'c'); 
     4814        e = e->semantic(sc); 
     4815        return e; 
     4816    } 
    45654817    //error("undefined identifier %s", toChars()); 
    45664818    type = Type::tvoid; 
     
    51585410        e1 = e1->semantic(sc); 
    51595411    } 
     5412#if 1   // patch for #540 by Oskar Linde 
     5413    else if (e1->op == TOKdotexp) 
     5414    { 
     5415        DotExp *de = (DotExp *) e1; 
     5416 
     5417        if (de->e2->op == TOKimport) 
     5418        {   // This should *really* be moved to ScopeExp::semantic() 
     5419        ScopeExp *se = (ScopeExp *)de->e2; 
     5420        de->e2 = new DsymbolExp(loc, se->sds); 
     5421        de->e2 = de->e2->semantic(sc); 
     5422        } 
     5423 
     5424        if (de->e2->op == TOKtemplate) 
     5425        {   TemplateExp *te = (TemplateExp *) de->e2; 
     5426        e1 = new DotTemplateExp(loc,de->e1,te->td); 
     5427        } 
     5428    } 
     5429#endif 
    51605430    } 
    51615431 
     
    51795449    {   AggregateDeclaration *ad; 
    51805450 
    5181     if (t1->ty == Tclass) 
     5451    if (t1->ty == Tstruct) 
     5452    { 
     5453        ad = ((TypeStruct *)t1)->sym; 
     5454        if (search_function(ad, Id::call)) 
     5455        goto L1;    // overload of opCall, therefore it's a call 
     5456        /* It's a struct literal 
     5457         */ 
     5458        Expression *e = new StructLiteralExp(loc, (StructDeclaration *)ad, arguments); 
     5459        e = e->semantic(sc); 
     5460        return e; 
     5461    } 
     5462    else if (t1->ty == Tclass) 
    51825463    { 
    51835464        ad = ((TypeClass *)t1)->sym; 
    51845465        goto L1; 
    5185     } 
    5186     else if (t1->ty == Tstruct) 
    5187     { 
    5188         ad = ((TypeStruct *)t1)->sym; 
    51895466    L1: 
    51905467        // Rewrite as e1.call(arguments) 
     
    59536230    if (v) 
    59546231    { 
    5955         /* if (!v->isDataseg()
     6232        /* if (!v->isDataseg() && !v->isParameter()
    59566233        error("escaping reference to local %s", v->toChars()); */ 
    59576234    } 
     
    63756652    : BinExp(loc, TOKindex, sizeof(IndexExp), e1, e2) 
    63766653{ 
     6654    //printf("IndexExp::IndexExp('%s')\n", toChars()); 
    63776655    lengthVar = NULL; 
    63786656    modifiable = 0; // assume it is an rvalue 
     
    63916669    if (type) 
    63926670    return this; 
     6671    if (!e1->type) 
     6672    e1 = e1->semantic(sc); 
    63936673    assert(e1->type);       // semantic() should already be run on it 
    63946674    e = this; 
     
    65766856    : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2) 
    65776857{ 
     6858    ismemset = 0; 
    65786859} 
    65796860 
     
    69507231    else 
    69517232    { 
    6952     //error("Can only append to dynamic arrays, not %s ~=