Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

Ticket #229: d2.diff

File d2.diff, 181.0 kB (added by Matt, 3 years ago)

new clean updated patch

  • a/.hgignore

    old new  
    1414CMakeCache.txt 
    1515cmake_install.cmake 
    1616.DS_Store 
     17.svn 
    1718 
    1819syntax: regexp 
    1920^obj/ 
    2021^tests/dstress/ 
    2122^tests/reference/ 
    2223^tango/ 
    23 ^druntime/ 
    2424^import/ 
    2525^bin/ldc2?$ 
    2626^bin/ldc2?\.conf$ 
  • a/CMakeLists.txt

    old new  
    140140    -DIN_LLVM 
    141141    -D_DH 
    142142    -DOPAQUE_VTBLS 
     143    -D__STDC_LIMIT_MACROS 
     144    -D__STDC_CONSTANT_MACROS 
    143145) 
    144146 
    145147if(UNIX) 
  • a/dmd/mars.h

    old new  
    6767}; 
    6868 
    6969// make it easier to test new linkage types 
    70 #define TEMPLATE_LINKAGE_TYPE   llvm::GlobalValue::LinkOnceLinkage 
    71 #define TYPEINFO_LINKAGE_TYPE   llvm::GlobalValue::LinkOnceLinkage 
     70#define TEMPLATE_LINKAGE_TYPE   llvm::GlobalValue::LinkOnceAnyLinkage 
     71#define TYPEINFO_LINKAGE_TYPE   llvm::GlobalValue::LinkOnceAnyLinkage 
    7272 
    7373// Put command line switches in here 
    7474struct Param 
  • a/dmd2/access.c

    old new  
    253253    if (!result) 
    254254    { 
    255255    error(loc, "member %s is not accessible", smember->toChars()); 
    256 halt(); 
    257256    } 
    258257} 
    259258 
  • a/dmd2/aggregate.h

    old new  
    6464    int isdeprecated;       // !=0 if deprecated 
    6565    Scope *scope;       // !=NULL means context to use 
    6666 
     67    int isnested;       // !=0 if is nested 
     68    VarDeclaration *vthis;  // 'this' parameter if this aggregate is nested 
     69 
    6770    // Special member functions 
    6871    InvariantDeclaration *inv;      // invariant 
    6972    NewDeclaration *aggNew;     // allocator 
     
    9194    void addField(Scope *sc, VarDeclaration *v); 
    9295    int isDeprecated();     // is aggregate deprecated? 
    9396    FuncDeclaration *buildDtor(Scope *sc); 
     97    int isNested(); 
    9498 
    9599    void emitComment(Scope *sc); 
    96100    void toDocBuffer(OutBuffer *buf); 
     
    216220    int isauto;             // !=0 if this is an auto class 
    217221    int isabstract;         // !=0 if abstract class 
    218222 
    219     int isnested;           // !=0 if is nested 
    220     VarDeclaration *vthis;      // 'this' parameter if this class is nested 
    221  
    222223    int inuse;              // to prevent recursive attempts 
    223224 
    224225    ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 
     
    236237#endif 
    237238    FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 
    238239    void interfaceSemantic(Scope *sc); 
    239     int isNested(); 
    240240    int isCOMclass(); 
    241241    virtual int isCOMinterface(); 
    242242#if DMDV2 
  • a/dmd2/arrayop.c

    old new  
    1111#include <string.h> 
    1212#include <assert.h> 
    1313 
    14 #if _WIN32 || IN_GCC  || IN_LLVM 
    1514#include "mem.h" 
    16 #else 
    17 #include "../root/mem.h" 
    18 #endif 
    1915 
    2016#include "stringtable.h" 
    2117 
  • a/dmd2/attrib.c

    old new  
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414 
    15 #if _WIN32 || IN_GCC || IN_LLVM 
    1615#include "mem.h" 
    17 #elif POSIX 
    18 #include "../root/mem.h" 
    19 #endif 
    2016 
    2117#include "init.h" 
    2218#include "declaration.h" 
     
    151147{ 
    152148    //printf("AttribDeclaration::emitComment(sc = %p)\n", sc); 
    153149 
    154     /* If generating doc comment, skip this because if we're inside 
    155      * a template, then include(NULL, NULL) will fail. 
     150    /* A general problem with this, illustrated by BUGZILLA 2516, 
     151     * is that attributes are not transmitted through to the underlying 
     152     * member declarations for template bodies, because semantic analysis 
     153     * is not done for template declaration bodies 
     154     * (only template instantiations). 
     155     * Hence, Ddoc omits attributes from template members. 
    156156     */ 
    157 //    if (sc->docbuf) 
    158 //  return; 
    159157 
    160158    Array *d = include(NULL, NULL); 
    161159 
     
    771769 
    772770Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s) 
    773771{ 
     772    //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars()); 
    774773    PragmaDeclaration *pd; 
    775774 
    776775    assert(!s); 
     
    12481247    { 
    12491248    AttribDeclaration::emitComment(sc); 
    12501249    } 
     1250    else if (sc->docbuf) 
     1251    { 
     1252    /* If generating doc comment, be careful because if we're inside 
     1253     * a template, then include(NULL, NULL) will fail. 
     1254     */ 
     1255    Array *d = decl ? decl : elsedecl; 
     1256    for (unsigned i = 0; i < d->dim; i++) 
     1257    {   Dsymbol *s = (Dsymbol *)d->data[i]; 
     1258        s->emitComment(sc); 
     1259    } 
     1260    } 
    12511261} 
    12521262 
    12531263// Decide if 'then' or 'else' code should be included 
  • a/dmd2/builtin.c

    old new  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2007 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
     
    2323#include "id.h" 
    2424#include "module.h" 
    2525 
     26#if DMDV2 
     27 
    2628/********************************** 
    2729 * Determine if function is a builtin one. 
    2830 */ 
    2931enum BUILTIN FuncDeclaration::isBuiltin() 
    3032{ 
    31     static const char FeZe[] = "FeZe"; // real function(real) 
     33    static const char FeZe[] = "FNaNbeZe"; // pure nothrow real function(real) 
    3234 
    3335    //printf("FuncDeclaration::isBuiltin() %s\n", toChars()); 
    3436    if (builtin == BUILTINunknown) 
     
    4042        parent->parent && parent->parent->ident == Id::std && 
    4143        !parent->parent->parent) 
    4244        { 
     45        //printf("deco = %s\n", type->deco); 
    4346        if (strcmp(type->deco, FeZe) == 0) 
    4447        { 
    4548            if (ident == Id::sin) 
     
    5457            builtin = BUILTINfabs; 
    5558            //printf("builtin = %d\n", builtin); 
    5659        } 
     60        else if (strcmp(type->deco, "FNaNbdZd") == 0 || 
     61             strcmp(type->deco, "FNaNbfZf") == 0) 
     62            builtin = BUILTINsqrt; 
    5763        } 
    5864    } 
    5965    } 
     
    100106    } 
    101107    return e; 
    102108} 
     109 
     110#endif 
  • a/dmd2/cast.c

    old new  
    1010#include <stdio.h> 
    1111#include <assert.h> 
    1212 
    13 #if _WIN32 || IN_GCC || IN_LLVM 
    1413#include "mem.h" 
    15 #else 
    16 #include "../root/mem.h" 
    17 #endif 
    1814 
    1915#include "expression.h" 
    2016#include "mtype.h" 
     
    109105    return castTo(sc, t); 
    110106} 
    111107 
     108Expression *StringExp::implicitCastTo(Scope *sc, Type *t) 
     109{ 
     110    //printf("StringExp::implicitCastTo(%s of type %s) => %s\n", toChars(), type->toChars(), t->toChars()); 
     111    unsigned char committed = this->committed; 
     112    Expression *e = Expression::implicitCastTo(sc, t); 
     113    if (e->op == TOKstring) 
     114    { 
     115    // Retain polysemous nature if it started out that way 
     116    ((StringExp *)e)->committed = committed; 
     117    } 
     118    return e; 
     119} 
     120 
    112121/******************************************* 
    113122 * Return !=0 if we can implicitly convert this to type t. 
    114123 * Don't do the actual cast. 
     
    446455            if (tynto == Tchar || tynto == Twchar || tynto == Tdchar) 
    447456                return MATCHexact; 
    448457            } 
     458            else if (type->ty == Tarray) 
     459            { 
     460            if (length() > 
     461                ((TypeSArray *)t)->dim->toInteger()) 
     462                return MATCHnomatch; 
     463            TY tynto = t->nextOf()->ty; 
     464            if (tynto == Tchar || tynto == Twchar || tynto == Tdchar) 
     465                return MATCHexact; 
     466            } 
    449467        case Tarray: 
    450468        case Tpointer: 
    451469            tn = t->nextOf(); 
     
    851869    return se; 
    852870    } 
    853871 
     872    if (committed && tb->ty == Tsarray && typeb->ty == Tarray) 
     873    { 
     874    se = (StringExp *)copy(); 
     875    se->sz = tb->nextOf()->size(); 
     876    se->len = (len * sz) / se->sz; 
     877    se->committed = 1; 
     878    se->type = t; 
     879    return se; 
     880    } 
     881 
    854882    if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer) 
    855883    {   if (!copied) 
    856884    {   se = (StringExp *)copy(); 
     
    17031731    return e; 
    17041732} 
    17051733 
     1734/*********************************** 
     1735 * See if both types are arrays that can be compared 
     1736 * for equality. Return !=0 if so. 
     1737 * If they are arrays, but incompatible, issue error. 
     1738 * This is to enable comparing things like an immutable 
     1739 * array with a mutable one. 
     1740 */ 
     1741 
     1742int arrayTypeCompatible(Loc loc, Type *t1, Type *t2) 
     1743{ 
     1744    t1 = t1->toBasetype(); 
     1745    t2 = t2->toBasetype(); 
     1746 
     1747    if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && 
     1748    (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer)) 
     1749    { 
     1750    if (t1->nextOf()->implicitConvTo(t2->nextOf()) < MATCHconst && 
     1751        t2->nextOf()->implicitConvTo(t1->nextOf()) < MATCHconst && 
     1752        (t1->nextOf()->ty != Tvoid && t2->nextOf()->ty != Tvoid)) 
     1753    { 
     1754        error("array equality comparison type mismatch, %s vs %s", t1->toChars(), t2->toChars()); 
     1755    } 
     1756    return 1; 
     1757    } 
     1758    return 0; 
     1759} 
  • a/dmd2/class.c

    old new  
    157157            Type::typeinfoinvariant->error("%s", msg); 
    158158        Type::typeinfoinvariant = this; 
    159159        } 
     160 
     161        if (id == Id::TypeInfo_Shared) 
     162        {   if (Type::typeinfoshared) 
     163            Type::typeinfoshared->error("%s", msg); 
     164        Type::typeinfoshared = this; 
     165        } 
    160166#endif 
    161167    } 
    162168 
     
    182188    com = 0; 
    183189    isauto = 0; 
    184190    isabstract = 0; 
    185     isnested = 0; 
    186     vthis = NULL; 
    187191    inuse = 0; 
    188192} 
    189193 
     
    500504    {   Dsymbol *s = toParent2(); 
    501505        if (s) 
    502506        { 
    503         ClassDeclaration *cd = s->isClassDeclaration(); 
     507        AggregateDeclaration *ad = s->isClassDeclaration(); 
    504508        FuncDeclaration *fd = s->isFuncDeclaration(); 
    505509 
    506510 
    507         if (cd || fd) 
     511        if (ad || fd) 
    508512        {   isnested = 1; 
    509513            Type *t; 
    510             if (cd) 
    511             t = cd->type; 
     514            if (ad) 
     515            t = ad->handle; 
    512516            else if (fd) 
    513517            {   AggregateDeclaration *ad = fd->isMember2(); 
    514518            if (ad) 
    515519                t = ad->handle; 
    516520            else 
    517521            { 
    518                 t = new TypePointer(Type::tvoid); 
    519                 t = t->semantic(0, sc); 
     522                t = Type::tvoidptr; 
    520523            } 
    521524            } 
    522525            else 
    523526            assert(0); 
     527            if (t->ty == Tstruct)   // ref to struct 
     528            t = Type::tvoidptr; 
    524529            assert(!vthis); 
    525530            vthis = new ThisDeclaration(t); 
    526531            members->push(vthis); 
     
    546551    sc->inunion = 0; 
    547552 
    548553    if (isCOMclass()) 
     554    { 
     555#if _WIN32 
    549556    sc->linkage = LINKwindows; 
     557#else 
     558    /* This enables us to use COM objects under Linux and 
     559     * work with things like XPCOM 
     560     */ 
     561    sc->linkage = LINKc; 
     562#endif 
     563    } 
    550564    sc->protection = PROTpublic; 
    551565    sc->explicitProtection = 0; 
    552566    sc->structalign = 8; 
     
    870884    { 
    871885    for (size_t i = 0; i < vtbl->dim; i++) 
    872886    { 
    873         FuncDeclaration *fd = (FuncDeclaration *)vtbl->data[i]; 
     887        FuncDeclaration *fd = ((Dsymbol*)vtbl->data[i])->isFuncDeclaration(); 
     888        if (!fd) 
     889        continue;       // the first entry might be a ClassInfo 
    874890 
    875891        //printf("\t[%d] = %s\n", i, fd->toChars()); 
    876892        if (ident == fd->ident && 
     
    957973 
    958974 
    959975/**************************************** 
    960  * Returns !=0 if there's an extra member which is the 'this' 
    961  * pointer to the enclosing context (enclosing class or function) 
    962  */ 
    963  
    964 int ClassDeclaration::isNested() 
    965 { 
    966     return isnested; 
    967 } 
    968  
    969 /**************************************** 
    970976 * Determine if slot 0 of the vtbl[] is reserved for something else. 
    971977 * For class objects, yes, this is where the classinfo ptr goes. 
    972978 * For COM interfaces, no. 
  • a/dmd2/clone.c

    old new  
    4747    Dsymbol *s = (Dsymbol *)fields.data[i]; 
    4848    VarDeclaration *v = s->isVarDeclaration(); 
    4949    assert(v && v->storage_class & STCfield); 
     50    if (v->storage_class & STCref) 
     51        continue; 
    5052    Type *tv = v->type->toBasetype(); 
    5153    while (tv->ty == Tsarray) 
    5254    {   TypeSArray *ta = (TypeSArray *)tv; 
     
    264266    Dsymbol *s = (Dsymbol *)fields.data[i]; 
    265267    VarDeclaration *v = s->isVarDeclaration(); 
    266268    assert(v && v->storage_class & STCfield); 
     269    if (v->storage_class & STCref) 
     270        continue; 
    267271    Type *tv = v->type->toBasetype(); 
    268272    size_t dim = 1; 
    269273    while (tv->ty == Tsarray) 
     
    359363    Dsymbol *s = (Dsymbol *)fields.data[i]; 
    360364    VarDeclaration *v = s->isVarDeclaration(); 
    361365    assert(v && v->storage_class & STCfield); 
     366    if (v->storage_class & STCref) 
     367        continue; 
    362368    Type *tv = v->type->toBasetype(); 
    363369    size_t dim = 1; 
    364370    while (tv->ty == Tsarray) 
  • a/dmd2/declaration.c

    old new  
    135135        if (isConst()) 
    136136        p = "const"; 
    137137        else if (isInvariant()) 
    138         p = "invariant"; 
     138        p = "mutable"; 
    139139        else if (storage_class & STCmanifest) 
    140         p = "manifest constant"; 
     140        p = "enum"; 
    141141        else if (!t->isAssignable()) 
    142142        p = "struct with immutable members"; 
    143143        if (p) 
    144144        {   error(loc, "cannot modify %s", p); 
    145         halt(); 
    146145        } 
    147146    } 
    148147    } 
     
    456455    if (s && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())) 
    457456    goto L2;            // it's a symbolic alias 
    458457 
    459     //printf("alias type is %s\n", type->toChars()); 
    460     type->resolve(loc, sc, &e, &t, &s); 
     458    if (storage_class & STCref) 
     459    {   // For 'ref' to be attached to function types, and picked 
     460    // up by Type::resolve(), it has to go into sc. 
     461    sc = sc->push(); 
     462    sc->stc |= STCref; 
     463    type->resolve(loc, sc, &e, &t, &s); 
     464    sc = sc->pop(); 
     465    } 
     466    else 
     467    type->resolve(loc, sc, &e, &t, &s); 
    461468    if (s) 
    462469    { 
    463470    goto L2; 
     
    780787    } 
    781788 
    782789Lagain: 
    783     if (storage_class & STCinvariant) 
    784     { 
    785     type = type->invariantOf(); 
     790    /* Storage class can modify the type 
     791     */ 
     792    type = type->addStorageClass(storage_class); 
     793 
     794    /* Adjust storage class to reflect type 
     795     */ 
     796    if (type->isConst()) 
     797    {   storage_class |= STCconst; 
     798    if (type->isShared()) 
     799        storage_class |= STCshared; 
    786800    } 
    787     else if (storage_class & (STCconst | STCin)) 
    788     { 
    789     if (!type->isInvariant()) 
    790         type = type->constOf(); 
    791     } 
    792     else if (type->isConst()) 
    793     storage_class |= STCconst; 
    794801    else if (type->isInvariant()) 
    795802    storage_class |= STCinvariant; 
     803    else if (type->isShared()) 
     804    storage_class |= STCshared; 
    796805 
    797806    if (isSynchronized()) 
    798807    { 
     
    860869    } 
    861870    } 
    862871 
    863     if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref) 
     872    if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 
     873    ident != Id::This) 
     874    { 
    864875    error("only parameters or foreach declarations can be ref"); 
     876    } 
    865877 
    866878    if (type->isauto() && !noauto) 
    867879    { 
    868880    if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls) || !fd) 
    869881    { 
    870         error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto"); 
     882        error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope"); 
    871883    } 
    872884 
    873885    if (!(storage_class & (STCauto | STCscope))) 
     
    906918        Expression *e1; 
    907919        e1 = new VarExp(loc, this); 
    908920        e = new AssignExp(loc, e1, e); 
     921        e->op = TOKconstruct; 
    909922        e->type = e1->type;     // don't type check this, it would fail 
    910923        init = new ExpInitializer(loc, e); 
    911924        return; 
     
    11711184    buf->writestring("auto "); 
    11721185#if DMDV2 
    11731186    if (storage_class & STCmanifest) 
    1174     buf->writestring("manifest "); 
     1187    buf->writestring("enum "); 
    11751188    if (storage_class & STCinvariant) 
    1176     buf->writestring("invariant "); 
     1189    buf->writestring("immutable "); 
     1190    if (storage_class & STCshared) 
     1191    buf->writestring("shared "); 
    11771192    if (storage_class & STCtls) 
    11781193    buf->writestring("__thread "); 
    11791194#endif 
     
    15481563} 
    15491564#endif 
    15501565 
     1566/***************************** TypeInfoSharedDeclaration **********************/ 
     1567 
     1568#if DMDV2 
     1569TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo) 
     1570    : TypeInfoDeclaration(tinfo, 0) 
     1571{ 
     1572} 
     1573#endif 
     1574 
    15511575/***************************** TypeInfoStructDeclaration **********************/ 
    15521576 
    15531577TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) 
  • a/dmd2/declaration.h

    old new  
    502502    void llvmDeclare(); 
    503503    void llvmDefine(); 
    504504}; 
     505 
     506struct TypeInfoSharedDeclaration : TypeInfoDeclaration 
     507{ 
     508    TypeInfoSharedDeclaration(Type *tinfo); 
     509 
     510    void toDt(dt_t **pdt); 
     511}; 
    505512#endif 
    506513 
    507514/**************************************************************/ 
     
    510517{ 
    511518    ThisDeclaration(Type *t); 
    512519    Dsymbol *syntaxCopy(Dsymbol *); 
     520    ThisDeclaration *isThisDeclaration() { return this; } 
    513521}; 
    514522 
    515523enum ILS 
     
    629637    int isAbstract(); 
    630638    int isCodeseg(); 
    631639    int isOverloadable(); 
     640    int isPure(); 
    632641    virtual int isNested(); 
    633642    int needThis(); 
    634643    virtual int isVirtual(); 
  • a/dmd2/doc.c

    old new  
    1616#include <ctype.h> 
    1717#include <assert.h> 
    1818 
    19 #if IN_GCC || IN_LLVM 
    2019#include "mem.h" 
    21 #else 
    22 #if _WIN32 
    23 #include "..\root\mem.h" 
    24 #elif POSIX 
    25 #include "../root/mem.h" 
    26 #else 
    27 #error "fix this" 
    28 #endif 
    29 #endif 
    30  
    3120#include "root.h" 
    3221 
    3322#include "mars.h" 
     
    857846    } 
    858847    else 
    859848    { 
     849        if (isAbstract()) 
     850        buf->writestring("abstract "); 
    860851        buf->printf("%s $(DDOC_PSYMBOL %s)", kind(), toChars()); 
    861852    } 
    862853    int any = 0; 
  • a/dmd2/dsymbol.c

    old new  
    867867        s2->toPrettyChars(), 
    868868        s2->locToChars()); 
    869869    } 
    870 halt(); 
    871870} 
    872871 
    873872Dsymbol *ScopeDsymbol::nameCollision(Dsymbol *s) 
     
    10481047    L1: 
    10491048 
    10501049    if (td) 
    1051     { 
     1050    {   /* $ gives the number of elements in the tuple 
     1051         */ 
    10521052        VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 
    10531053        Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); 
    10541054        v->init = new ExpInitializer(0, e); 
     
    10581058    } 
    10591059 
    10601060    if (type) 
    1061     { 
     1061    {   /* $ gives the number of type entries in the type tuple 
     1062         */ 
    10621063        VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 
    10631064        Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); 
    10641065        v->init = new ExpInitializer(0, e); 
     
    10681069    } 
    10691070 
    10701071    if (exp->op == TOKindex) 
    1071     { 
     1072    {   /* array[index] where index is some function of $ 
     1073         */ 
    10721074        IndexExp *ie = (IndexExp *)exp; 
    10731075 
    10741076        pvar = &ie->lengthVar; 
    10751077        ce = ie->e1; 
    10761078    } 
    10771079    else if (exp->op == TOKslice) 
    1078     { 
     1080    {   /* array[lwr .. upr] where lwr or upr is some function of $ 
     1081         */ 
    10791082        SliceExp *se = (SliceExp *)exp; 
    10801083 
    10811084        pvar = &se->lengthVar; 
    10821085        ce = se->e1; 
    10831086    } 
    10841087    else 
     1088        /* Didn't find $, look in enclosing scope(s). 
     1089         */ 
    10851090        return NULL; 
    10861091 
     1092    /* If we are indexing into an array that is really a type 
     1093     * tuple, rewrite this as an index into a type tuple and 
     1094     * try again. 
     1095     */ 
    10871096    if (ce->op == TOKtype) 
    10881097    { 
    10891098        Type *t = ((TypeExp *)ce)->type; 
     
    10931102        } 
    10941103    } 
    10951104 
    1096     if (!*pvar) 
    1097     { 
     1105    /* *pvar is lazily initialized, so if we refer to $ 
     1106     * multiple times, it gets set only once. 
     1107     */ 
     1108    if (!*pvar)     // if not already initialized 
     1109    {   /* Create variable v and set it to the value of $, 
     1110         * which will be a constant. 
     1111         */ 
    10981112        VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 
    10991113 
    11001114        if (ce->op == TOKvar) 
  • a/dmd2/dsymbol.h

    old new  
    2828struct Scope; 
    2929struct DsymbolTable; 
    3030struct Declaration; 
     31struct ThisDeclaration; 
    3132struct TupleDeclaration; 
    3233struct TypedefDeclaration; 
    3334struct AliasDeclaration; 
     
    192193    virtual TemplateInstance *isTemplateInstance() { return NULL; } 
    193194    virtual TemplateMixin *isTemplateMixin() { return NULL; } 
    194195    virtual Declaration *isDeclaration() { return NULL; } 
     196    virtual ThisDeclaration *isThisDeclaration() { return NULL; } 
    195197    virtual TupleDeclaration *isTupleDeclaration() { return NULL; } 
    196198    virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; } 
    197199    virtual AliasDeclaration *isAliasDeclaration() { return NULL; } 
  • a/dmd2/entity.c

    old new  
    11 
    2 // Copyright (c) 1999-2008 by Digital Mars 
     2// Copyright (c) 1999-2009 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
  • a/dmd2/expression.c

    old new  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2008 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
     
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <ctype.h> 
     14#include <math.h> 
    1415#include <assert.h> 
    1516#if _MSC_VER 
    1617#include <complex> 
    1718#else 
    1819#endif 
    19 #include <math.h> 
    2020 
    2121#if _WIN32 && __DMC__ 
    2222extern "C" char * __cdecl __locale_decpoint; 
     
    4343#define integer_t dmd_integer_t 
    4444#endif 
    4545 
    46 #if IN_GCC || IN_LLVM 
    4746#include "mem.h" 
    48 #elif _WIN32 
    49 #include "..\root\mem.h" 
    50 #elif POSIX 
    51 #include "../root/mem.h" 
    52 #endif 
    5347 
    5448//#include "port.h" 
    5549#include "mtype.h" 
     
    172166    precedence[TOKue] = PREC_rel; 
    173167    precedence[TOKin] = PREC_rel; 
    174168 
     169#if 0 
    175170    precedence[TOKequal] = PREC_equal; 
    176171    precedence[TOKnotequal] = PREC_equal; 
    177172    precedence[TOKidentity] = PREC_equal; 
    178173    precedence[TOKnotidentity] = PREC_equal; 
     174#else 
     175    /* Note that we changed precedence, so that < and != have the same 
     176     * precedence. This change is in the parser, too. 
     177     */ 
     178    precedence[TOKequal] = PREC_rel; 
     179    precedence[TOKnotequal] = PREC_rel; 
     180    precedence[TOKidentity] = PREC_rel; 
     181    precedence[TOKnotidentity] = PREC_rel; 
     182#endif 
    179183 
    180184    precedence[TOKand] = PREC_and; 
    181185 
     
    642646                Expression *e = new VarExp(loc, v); 
    643647                e = new IndexExp(loc, e, new IntegerExp(u + 1 - nparams)); 
    644648                AssignExp *ae = new AssignExp(loc, e, a); 
     649#if DMDV2 
    645650                ae->op = TOKconstruct; 
     651#endif 
    646652                if (c) 
    647653                c = new CommaExp(loc, c, ae); 
    648654                else 
     
    698704 
    699705        tb = arg->type->toBasetype(); 
    700706 
    701 // LDC we don't want this! 
    702 #if !IN_LLVM 
    703         // Convert static arrays to pointers 
    704         if (tb->ty == Tsarray) 
    705         { 
    706         arg = arg->checkToPointer(); 
    707         } 
    708 #endif 
    709  
     707#if DMDV2 
    710708 
    711709        if (tb->ty == Tstruct && !(p->storageClass & (STCref | STCout))) 
    712710        { 
    713711        arg = callCpCtor(loc, sc, arg); 
    714712        } 
     713#endif 
    715714 
    716715        // Convert lazy argument to a delegate 
    717716        if (p->storageClass & STClazy) 
    718717        { 
    719718        arg = arg->toDelegate(sc, p->type); 
    720719        } 
    721  
     720#if DMDV2 
    722721        /* Look for arguments that cannot 'escape' from the called 
    723722         * function. 
    724723         */ 
     
    748747            } 
    749748        } 
    750749        } 
     750#endif 
    751751    } 
    752752    else 
    753753    { 
     
    826826void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr) 
    827827{ 
    828828    //if (precedence[e->op] == 0) e->dump(0); 
    829     if (precedence[e->op] < pr) 
     829    if (precedence[e->op] < pr || 
     830    /* Despite precedence, we don't allow a<b<c expressions. 
     831     * They must be parenthesized. 
     832     */ 
     833    (pr == PREC_rel && precedence[e->op] == pr)) 
    830834    { 
    831835    buf->writeByte('('); 
    832836    e->toCBuffer(buf, hgs); 
     
    958962    va_end( ap ); 
    959963} 
    960964 
     965void Expression::warning(const char *format, ...) 
     966{ 
     967    if (global.params.warnings && !global.gag) 
     968    { 
     969    fprintf(stdmsg, "warning - "); 
     970    va_list ap; 
     971    va_start(ap, format); 
     972    ::verror(loc, format, ap); 
     973    va_end( ap ); 
     974    } 
     975} 
     976 
    961977void Expression::rvalue() 
    962978{ 
    963979    if (type && type->toBasetype()->ty == Tvoid) 
     
    10331049/*************************************** 
    10341050 * Return !=0 if expression is an lvalue. 
    10351051 */ 
    1036  
     1052#if DMDV2 
    10371053int Expression::isLvalue() 
    10381054{ 
    10391055    return 0; 
    10401056} 
     1057#endif 
    10411058 
    10421059/******************************* 
    10431060 * Give error if we're not an lvalue. 
     
    10591076    //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars()); 
    10601077 
    10611078    // See if this expression is a modifiable lvalue (i.e. not const) 
     1079#if DMDV2 
    10621080    if (type && (!type->isMutable() || !type->isAssignable())) 
    10631081    error("%s is not mutable", e->toChars()); 
    1064  
     1082#endif 
    10651083    return toLvalue(sc, e); 
    10661084} 
    10671085 
     
    11091127    s->checkDeprecated(loc, sc); 
    11101128} 
    11111129 
     1130#if DMDV2 
     1131void Expression::checkPurity(Scope *sc, FuncDeclaration *f) 
     1132{ 
     1133    if (sc->func && sc->func->isPure() && !sc->intypeof && !f->isPure()) 
     1134    error("pure function '%s' cannot call impure function '%s'\n", 
     1135        sc->func->toChars(), f->toChars()); 
     1136} 
     1137#endif 
     1138 
    11121139/******************************** 
    11131140 * Check for expressions that have no use. 
    11141141 * Input: 
     
    12351262 
    12361263int Expression::canThrow() 
    12371264{ 
     1265#if DMDV2 
    12381266    return FALSE; 
     1267#else 
     1268    return TRUE; 
     1269#endif 
    12391270} 
    12401271 
    12411272 
     
    17011732     * 0X1.9P+2         => 19P2 
    17021733     */ 
    17031734 
     1735#if __APPLE__ 
     1736    if (__inline_isnan(value)) 
     1737#else 
    17041738    if (isnan(value)) 
     1739#endif 
    17051740    buf->writestring("NAN");    // no -NAN bugs 
    17061741    else 
    17071742    { 
     
    19491984    buf->writestring(ident->toChars()); 
    19501985} 
    19511986 
     1987#if DMDV2 
    19521988int IdentifierExp::isLvalue() 
    19531989{ 
    19541990    return 1; 
    19551991} 
     1992#endif 
    19561993 
    19571994Expression *IdentifierExp::toLvalue(Scope *sc, Expression *e) 
    19581995{ 
     
    20192056    // BUG: This should happen after overload resolution for functions, not before 
    20202057    if (s->needThis()) 
    20212058    { 
    2022     if (hasThis(sc) && !s->isFuncDeclaration()) 
     2059    if (hasThis(sc) 
     2060#if DMDV2 
     2061        && !s->isFuncDeclaration() 
     2062#endif 
     2063        ) 
    20232064    { 
    20242065        // Supply an implicit 'this', as in 
    20252066        //    this.ident 
     
    21542195    buf->writestring(s->toChars()); 
    21552196} 
    21562197 
     2198#if DMDV2 
    21572199int DsymbolExp::isLvalue() 
    21582200{ 
    21592201    return 1; 
    21602202} 
     2203#endif 
    21612204 
    21622205Expression *DsymbolExp::toLvalue(Scope *sc, Expression *e) 
    21632206{ 
     
    22202263#if STRUCTTHISREF 
    22212264        type = sd->type; 
    22222265#else 
     2266        assert(0); 
    22232267        type = sd->type->pointerTo(); 
    22242268#endif 
    22252269        return this; 
     
    22572301    buf->writestring("this"); 
    22582302} 
    22592303 
     2304#if DMDV2 
    22602305int ThisExp::isLvalue() 
    22612306{ 
    22622307    return 1; 
    22632308} 
     2309#endif 
    22642310 
    22652311Expression *ThisExp::toLvalue(Scope *sc, Expression *e) 
    22662312{ 
     
    24942540        string = buffer.extractData(); 
    24952541        len = newlen; 
    24962542        sz = 4; 
    2497         type = new TypeSArray(Type::tdchar, new IntegerExp(loc, len, Type::tindex)); 
     2543        //type = new TypeSArray(Type::tdchar, new IntegerExp(loc, len, Type::tindex)); 
     2544        type = new TypeDArray(Type::tdchar->invariantOf()); 
    24982545        committed = 1; 
    24992546        break; 
    25002547 
     
    25172564        string = buffer.extractData(); 
    25182565        len = newlen; 
    25192566        sz = 2; 
    2520         type = new TypeSArray(Type::twchar, new IntegerExp(loc, len, Type::tindex)); 
     2567        //type = new TypeSArray(Type::twchar, new IntegerExp(loc, len, Type::tindex)); 
     2568        type = new TypeDArray(Type::twchar->invariantOf()); 
    25212569        committed = 1; 
    25222570        break; 
    25232571 
    25242572        case 'c': 
    25252573        committed = 1; 
    25262574        default: 
    2527         type = new TypeSArray(Type::tchar, new IntegerExp(loc, len, Type::tindex)); 
     2575        //type = new TypeSArray(Type::tchar, new IntegerExp(loc, len, Type::tindex)); 
     2576        type = new TypeDArray(Type::tchar->invariantOf()); 
    25282577        break; 
    25292578    } 
    25302579    type = type->semantic(loc, sc); 
    2531     type = type->invariantOf(); 
     2580    //type = type->invariantOf(); 
    25322581    //printf("type = %s\n", type->toChars()); 
    25332582    } 
    25342583    return this; 
    25352584} 
    25362585 
     2586/********************************** 
     2587 * Return length of string. 
     2588 */ 
     2589 
     2590size_t StringExp::length() 
     2591{ 
     2592    size_t result = 0; 
     2593    dchar_t c; 
     2594    const char *p; 
     2595 
     2596    switch (sz) 
     2597    { 
     2598    case 1: 
     2599        for (size_t u = 0; u < len;) 
     2600        { 
     2601        p = utf_decodeChar((unsigned char *)string, len, &u, &c); 
     2602        if (p) 
     2603        {   error("%s", p); 
     2604            break; 
     2605        } 
     2606        else 
     2607            result++; 
     2608        } 
     2609        break; 
     2610 
     2611    case 2: 
     2612        for (size_t u = 0; u < len;) 
     2613        { 
     2614        p = utf_decodeWchar((unsigned short *)string, len, &u, &c); 
     2615        if (p) 
     2616        {   error("%s", p); 
     2617            break; 
     2618        } 
     2619        else 
     2620            result++; 
     2621        } 
     2622        break; 
     2623 
     2624    case 4: 
     2625        result = len; 
     2626        break; 
     2627 
     2628    default: 
     2629        assert(0); 
     2630    } 
     2631    return result; 
     2632} 
     2633 
    25372634/**************************************** 
    25382635 * Convert string to char[]. 
    25392636 */ 
     
    28142911    return result ? (dim != 0) : (dim == 0); 
    28152912} 
    28162913 
     2914#if DMDV2 
    28172915int ArrayLiteralExp::canThrow() 
    28182916{ 
    28192917    return 1;   // because it can fail allocating memory 
    28202918} 
     2919#endif 
    28212920 
    28222921void ArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    28232922{ 
     
    29373036    return result ? (dim != 0) : (dim == 0); 
    29383037} 
    29393038 
     3039#if DMDV2 
    29403040int AssocArrayLiteralExp::canThrow() 
    29413041{ 
    29423042    return 1; 
    29433043} 
     3044#endif 
    29443045 
    29453046void AssocArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    29463047{ 
     
    29923093 
    29933094Expression *StructLiteralExp::semantic(Scope *sc) 
    29943095{   Expression *e; 
     3096    int nfields = sd->fields.dim - sd->isnested; 
    29953097 
    29963098#if LOGSEMANTIC 
    29973099    printf("StructLiteralExp::semantic('%s')\n", toChars()); 
     
    30173119    if (!e->type) 
    30183120        error("%s has no value", e->toChars()); 
    30193121    e = resolveProperties(sc, e); 
    3020     if (i >= sd->fields.dim
     3122    if (i >= nfields
    30213123    {   error("more initializers than fields of %s", sd->toChars()); 
    30223124        break; 
    30233125    } 
     
    30433145 
    30443146    /* Fill out remainder of elements[] with default initializers for fields[] 
    30453147     */ 
    3046     for (size_t i = elements->dim; i < sd->fields.dim; i++) 
     3148    for (size_t i = elements->dim; i < nfields; i++) 
    30473149    {   Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 
    30483150    VarDeclaration *v = s->isVarDeclaration(); 
    30493151    assert(v); 
     3152    assert(!v->isThisDeclaration()); 
    30503153 
    30513154    if (v->offset < offset) 
    30523155    {   e = NULL; 
     
    31263229    return -1; 
    31273230} 
    31283231 
     3232#if DMDV2 
    31293233int StructLiteralExp::isLvalue() 
    31303234{ 
    31313235    return 1; 
    31323236} 
     3237#endif 
    31333238 
    31343239Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e) 
    31353240{ 
     
    31523257    return f; 
    31533258} 
    31543259 
     3260#if DMDV2 
    31553261int StructLiteralExp::canThrow() 
    31563262{ 
    31573263    return arrayExpressionCanThrow(elements); 
    31583264} 
     3265#endif 
    31593266 
    31603267void StructLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    31613268{ 
     
    32313338    this->type = type; 
    32323339} 
    32333340 
     3341Expression *TypeExp::syntaxCopy() 
     3342{ 
     3343    //printf("TypeExp::syntaxCopy()\n"); 
     3344    return new TypeExp(loc, type->syntaxCopy()); 
     3345} 
     3346 
    32343347Expression *TypeExp::semantic(Scope *sc) 
    32353348{ 
    32363349    //printf("TypeExp::semantic(%s)\n", type->toChars()); 
     
    36613774    return 1; 
    36623775} 
    36633776 
     3777#if DMDV2 
    36643778int NewExp::canThrow() 
    36653779{ 
    36663780    return 1; 
    36673781} 
     3782#endif 
    36683783 
    36693784void NewExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    36703785{   int i; 
     
    37333848    return 1; 
    37343849} 
    37353850 
     3851#if DMDV2 
    37363852int NewAnonClassExp::canThrow() 
    37373853{ 
    37383854    return 1; 
    37393855} 
     3856#endif 
    37403857 
    37413858void NewAnonClassExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    37423859{   int i; 
     
    37683885 
    37693886/********************** SymbolExp **************************************/ 
    37703887 
     3888#if DMDV2 
    37713889SymbolExp::SymbolExp(Loc loc, enum TOK op, int size, Declaration *var, int hasOverloads) 
    37723890    : Expression(loc, op, size) 
    37733891{ 
     
    37753893    this->var = var; 
    37763894    this->hasOverloads = hasOverloads; 
    37773895} 
     3896#endif 
    37783897 
    37793898/********************** SymOffExp **************************************/ 
    37803899 
     
    38653984    } 
    38663985#endif 
    38673986    } 
     3987    /* Fix for 1161 doesn't work because it causes protection 
     3988     * problems when instantiating imported templates passing private 
     3989     * variables as alias template parameters. 
     3990     */ 
     3991    //accessCheck(loc, sc, NULL, var); 
    38683992 
    38693993    VarDeclaration *v = var->isVarDeclaration(); 
    38703994    if (v) 
     
    38824006    } 
    38834007#endif 
    38844008    v->checkNestedReference(sc, loc); 
     4009#if DMDV2 
     4010    if (sc->func && sc->func->isPure() && !sc->intypeof) 
     4011    { 
     4012        if (v->isDataseg() && !v->isInvariant()) 
     4013        error("pure function '%s' cannot access mutable static data '%s'", sc->func->toChars(), v->toChars()); 
     4014    } 
     4015#endif 
    38854016    } 
    38864017#if 0 
    38874018    else if ((fd = var->isFuncLiteralDeclaration()) != NULL) 
     
    39134044    if (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tclass) 
    39144045    { 
    39154046        if ((v->isAuto() || v->isScope()) && !v->noauto) 
    3916         error("escaping reference to auto local %s", v->toChars()); 
     4047        error("escaping reference to scope local %s", v->toChars()); 
    39174048        else if (v->storage_class & STCvariadic) 
    39184049        error("escaping reference to variadic parameter %s", v->toChars()); 
    39194050    } 
    39204051    } 
    39214052} 
    39224053 
     4054#if DMDV2 
    39234055int VarExp::isLvalue() 
    39244056{ 
    39254057    if (var->storage_class & STClazy) 
    39264058    return 0; 
    39274059    return 1; 
    39284060} 
     4061#endif 
    39294062 
    39304063Expression *VarExp::toLvalue(Scope *sc, Expression *e) 
    39314064{ 
     
    40994232    return f; 
    41004233} 
    41014234 
     4235#if DMDV2 
    41024236int TupleExp::canThrow() 
    41034237{ 
    41044238    return arrayExpressionCanThrow(exps); 
    41054239} 
     4240#endif 
    41064241 
    41074242void TupleExp::checkEscape() 
    41084243{ 
     
    42724407    return 1; 
    42734408} 
    42744409 
     4410#if DMDV2 
    42754411int DeclarationExp::canThrow() 
    42764412{ 
    42774413    VarDeclaration *v = declaration->isVarDeclaration(); 
     
    42814417    } 
    42824418    return 0; 
    42834419} 
     4420#endif 
    42844421 
    42854422void DeclarationExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    42864423{ 
     
    45954732    m = targ->deduceType(NULL, tspec, parameters, &dedtypes); 
    45964733    if (m == MATCHnomatch || 
    45974734        (m != MATCHexact && tok == TOKequal)) 
     4735    { 
    45984736        goto Lno; 
     4737    } 
    45994738    else 
    46004739    { 
    46014740        tded = (Type *)dedtypes.data[0]; 
     
    46374776    else if (tspec) 
    46384777    { 
    46394778    /* Evaluate to TRUE if targ matches tspec 
     4779     * is(targ == tspec) 
     4780     * is(targ : tspec) 
    46404781     */ 
    46414782    tspec = tspec->semantic(loc, sc); 
    46424783    //printf("targ  = %s\n", targ->toChars()); 
     
    47324873    return this; 
    47334874} 
    47344875 
     4876#if DMDV2 
    47354877int UnaExp::canThrow() 
    47364878{ 
    47374879    return e1->canThrow(); 
    47384880} 
     4881#endif 
    47394882 
    47404883void UnaExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    47414884{ 
     
    49065049    return e1->type->isunsigned() || e2->type->isunsigned(); 
    49075050} 
    49085051 
     5052#if DMDV2 
    49095053int BinExp::canThrow() 
    49105054{ 
    49115055    return e1->canThrow() || e2->canThrow(); 
    49125056} 
     5057#endif 
    49135058 
    49145059void BinExp::incompatibleTypes() 
    49155060{ 
     
    50795224    return 1; 
    50805225} 
    50815226 
     5227#if DMDV2 
    50825228int AssertExp::canThrow() 
    50835229{ 
    50845230    return (global.params.useAssert != 0); 
    50855231} 
     5232#endif 
    50865233 
    50875234void AssertExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    50885235{ 
     
    53105457        } 
    53115458        return e; 
    53125459        } 
    5313  
     5460#if DMDV2 
    53145461        OverloadSet *o = s->isOverloadSet(); 
    53155462        if (o) 
    53165463        {   //printf("'%s' is an overload set\n", o->toChars()); 
    53175464        return new OverExp(o); 
    53185465        } 
     5466#endif 
    53195467 
    53205468        Type *t = s->getType(); 
    53215469        if (t) 
     
    53825530    e->type = ((TypePointer *)t1b)->next; 
    53835531    return e->type->dotExp(sc, e, ident); 
    53845532    } 
     5533#if DMDV2 
    53855534    else if (t1b->ty == Tarray || 
    53865535             t1b->ty == Tsarray || 
    53875536         t1b->ty == Taarray) 
     
    54035552    e = e->semantic(sc); 
    54045553    return e; 
    54055554    } 
     5555#endif 
    54065556    else 
    54075557    { 
    54085558    e = e1->type->dotExp(sc, e1, ident); 
     
    55045654        Type *t1 = e1->type; 
    55055655        if (t1->ty == Tpointer) 
    55065656        t1 = t1->nextOf(); 
    5507         if (t1->isConst()) 
    5508         type = type->constOf(); 
    5509         else if (t1->isInvariant()) 
    5510         type = type->invariantOf(); 
     5657 
     5658        type = type->addMod(t1->mod); 
    55115659 
    55125660        AggregateDeclaration *ad = var->toParent()->isAggregateDeclaration(); 
    55135661        e1 = getRightThis(loc, sc, ad, e1, var); 
     
    55245672    return this; 
    55255673} 
    55265674 
     5675#if DMDV2 
    55275676int DotVarExp::isLvalue() 
    55285677{ 
    55295678    return 1; 
    55305679} 
     5680#endif 
    55315681 
    55325682Expression *DotVarExp::toLvalue(Scope *sc, Expression *e) 
    55335683{ 
     
    55795729        break; 
    55805730    } 
    55815731    } 
     5732#if DMDV2 
    55825733    else 
    55835734    { 
    55845735    Type *t1 = e1->type->toBasetype(); 
     
    55895740        !var->type->isAssignable() || 
    55905741        var->storage_class & STCmanifest 
    55915742       ) 
    5592         error("cannot modify const/invariant %s", toChars()); 
    5593     } 
     5743        error("cannot modify const/immutable %s", toChars()); 
     5744    } 
     5745#endif 
    55945746    return this; 
    55955747} 
    55965748 
     
    58566008    Type *t1; 
    58576009    int istemp; 
    58586010    Objects *targsi = NULL; // initial list of template arguments 
     6011    TemplateInstance *tierror = NULL; 
    58596012 
    58606013#if LOGSEMANTIC 
    58616014    printf("CallExp::semantic() %s\n", toChars()); 
     
    59136066        if (!arguments) 
    59146067            arguments = new Expressions(); 
    59156068        arguments->shift(dotid->e1); 
     6069#if DMDV2 
    59166070        e1 = new DotIdExp(dotid->loc, new IdentifierExp(dotid->loc, Id::empty), dotid->ident); 
     6071#else 
     6072        e1 = new IdentifierExp(dotid->loc, dotid->ident); 
     6073#endif 
    59176074        } 
    59186075    } 
    59196076    } 
     
    59416098         */ 
    59426099        global.errors = errors; 
    59436100        targsi = ti->tiargs; 
     6101        tierror = ti;           // for error reporting 
    59446102        e1 = new IdentifierExp(loc, ti->name); 
    59456103        } 
    59466104    } 
     
    59676125        { 
    59686126        global.errors = errors; 
    59696127        targsi = ti->tiargs; 
     6128        tierror = ti;       // for error reporting 
    59706129        e1 = new DotIdExp(loc, se->e1, ti->name); 
    59716130        } 
    59726131        else 
     
    60656224         */ 
    60666225        e = new PtrExp(loc, e); 
    60676226#endif 
     6227        assert(0); 
    60686228        e = e->semantic(sc); 
    60696229        return e; 
    60706230        } 
     
    61436303        f->addPostInvariant() 
    61446304       ) 
    61456305    { 
    6146         error("cannot call public/export function %s from invariant", f->toChars()); 
     6306        error("cannot call public/export function %s from immutable", f->toChars()); 
    61476307    } 
    61486308 
    61496309    checkDeprecated(sc, f); 
     6310#if DMDV2 
     6311    checkPurity(sc, f); 
     6312#endif 
    61506313    accessCheck(loc, sc, ue->e1, f); 
    61516314    if (!f->needThis()) 
    61526315    { 
     
    61686331        printf("e1 = %s\n", e1->toChars()); 
    61696332        printf("e1->type = %s\n", e1->type->toChars()); 
    61706333#endif 
    6171         // Const member function can take const/invariant/mutable this 
     6334        // Const member function can take const/immutable/mutable this 
    61726335        if (!(f->type->isConst())) 
    61736336        { 
    6174         // Check for const/invariant compatibility 
     6337        // Check for const/immutable compatibility 
    61756338        Type *tthis = ue->e1->type->toBasetype(); 
    61766339        if (tthis->ty == Tpointer) 
    61776340            tthis = tthis->nextOf()->toBasetype(); 
     
    62486411 
    62496412        f = f->overloadResolve(loc, NULL, arguments); 
    62506413        checkDeprecated(sc, f); 
     6414#if DMDV2 
     6415        checkPurity(sc, f); 
     6416#endif 
    62516417        e1 = new DotVarExp(e1->loc, e1, f); 
    62526418        e1 = e1->semantic(sc); 
    62536419        t1 = e1->type; 
     
    62856451        f = cd->ctor; 
    62866452        f = f->overloadResolve(loc, NULL, arguments); 
    62876453        checkDeprecated(sc, f); 
     6454#if DMDV2 
     6455        checkPurity(sc, f); 
     6456#endif 
    62886457        e1 = new DotVarExp(e1->loc, e1, f); 
    62896458        e1 = e1->semantic(sc); 
    62906459        t1 = e1->type; 
     
    63576526        TemplateExp *te = (TemplateExp *)e1; 
    63586527        f = te->td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments); 
    63596528        if (!f) 
    6360         {   type = Type::terror; 
     6529        {   if (tierror) 
     6530            tierror->error("errors instantiating template");    // give better error message 
     6531        type = Type::terror; 
    63616532        return this; 
    63626533        } 
    63636534        if (f->needThis() && hasThis(sc)) 
     
    63896560    if (ve->hasOverloads) 
    63906561        f = f->overloadResolve(loc, NULL, arguments); 
    63916562    checkDeprecated(sc, f); 
     6563#if DMDV2 
     6564    checkPurity(sc, f); 
     6565#endif 
    63926566 
    63936567    if (f->needThis() && hasThis(sc)) 
    63946568    { 
     
    64376611 
    64386612int CallExp::checkSideEffect(int flag) 
    64396613{ 
    6440     return 1; 
    6441 
    6442  
     6614#if DMDV2 
     6615    if (flag != 2) 
     6616    return 1; 
     6617 
     6618    if (e1->checkSideEffect(2)) 
     6619    return 1; 
     6620 
     6621    /* If any of the arguments have side effects, this expression does 
     6622     */ 
     6623    for (size_t i = 0; i < arguments->dim; i++) 
     6624    {   Expression *e = (Expression *)arguments->data[i]; 
     6625 
     6626    if (e->checkSideEffect(2)) 
     6627        return 1; 
     6628    } 
     6629 
     6630    /* If calling a function or delegate that is typed as pure, 
     6631     * then this expression has no side effects. 
     6632     */ 
     6633    Type *t = e1->type->toBasetype(); 
     6634    if (t->ty == Tfunction && ((TypeFunction *)t)->ispure) 
     6635    return 0; 
     6636    if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->ispure) 
     6637    return 0; 
     6638#endif 
     6639    return 1; 
     6640
     6641 
     6642#if DMDV2 
    64436643int CallExp::canThrow() 
    64446644{ 
    6445     return 1; 
    6446 
    6447  
     6645    if (e1->canThrow()) 
     6646    return 1; 
     6647 
     6648    /* If any of the arguments can throw, then this expression can throw 
     6649     */ 
     6650    for (size_t i = 0; i < arguments->dim; i++) 
     6651    {   Expression *e = (Expression *)arguments->data[i]; 
     6652 
     6653    if (e && e->canThrow()) 
     6654        return 1; 
     6655    } 
     6656 
     6657    /* If calling a function or delegate that is typed as nothrow, 
     6658     * then this expression cannot throw. 
     6659     * Note that pure functions can throw. 
     6660     */ 
     6661    Type *t = e1->type->toBasetype(); 
     6662    if (t->ty == Tfunction && ((TypeFunction *)t)->isnothrow) 
     6663    return 0; 
     6664    if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->isnothrow) 
     6665    return 0; 
     6666 
     6667    return 1; 
     6668
     6669#endif 
     6670 
     6671#if DMDV2 
    64486672int CallExp::isLvalue() 
    64496673{ 
    6450     if (type->toBasetype()->ty == Tstruct) 
    6451   return 1; 
     6674//    if (type->toBasetype()->ty == Tstruct) 
     6675//    return 1; 
    64526676    Type *tb = e1->type->toBasetype(); 
    64536677    if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref) 
    64546678    return 1;       // function returns a reference 
    64556679    return 0; 
    64566680} 
     6681#endif 
    64576682 
    64586683Expression *CallExp::toLvalue(Scope *sc, Expression *e) 
    64596684{ 
     
    66146839    return this; 
    66156840} 
    66166841 
     6842#if DMDV2 
    66176843int PtrExp::isLvalue() 
    66186844{ 
    66196845    return 1; 
    66206846} 
     6847#endif 
    66216848 
    66226849Expression *PtrExp::toLvalue(Scope *sc, Expression *e) 
    66236850{ 
     
    66316858    return this; 
    66326859} 
    66336860 
     6861#if DMDV2 
    66346862Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e) 
    66356863{ 
    66366864    //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars()); 
     
    66436871 
    66446872    return Expression::modifiableLvalue(sc, e); 
    66456873} 
    6646  
     6874#endif 
    66476875 
    66486876void PtrExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    66496877{ 
     
    69097137    : UnaExp(loc, TOKcast, sizeof(CastExp), e) 
    69107138{ 
    69117139    to = t; 
    6912     this->tok = TOKreserved; 
    6913 
    6914  
    6915 /* For cast(const) and cast(invariant) 
    6916  */ 
    6917 CastExp::CastExp(Loc loc, Expression *e, enum TOK tok) 
     7140    this->mod = ~0; 
     7141
     7142 
     7143#if DMDV2 
     7144/* For cast(const) and cast(immutable) 
     7145 */ 
     7146CastExp::CastExp(Loc loc, Expression *e, unsigned mod) 
    69187147    : UnaExp(loc, TOKcast, sizeof(CastExp), e) 
    69197148{ 
    69207149    to = NULL; 
    6921     this->tok = tok; 
    6922 
     7150    this->mod = mod; 
     7151
     7152#endif 
    69237153 
    69247154Expression *CastExp::syntaxCopy() 
    69257155{ 
    69267156    return to ? new CastExp(loc, e1->syntaxCopy(), to->syntaxCopy()) 
    6927           : new CastExp(loc, e1->syntaxCopy(), tok); 
     7157          : new CastExp(loc, e1->syntaxCopy(), mod); 
    69287158} 
    69297159 
    69307160 
     
    69467176    { 
    69477177    e1 = resolveProperties(sc, e1); 
    69487178 
    6949     /* Handle cast(const) and cast(invariant) 
    6950      */ 
    69517179    if (!to) 
    6952     {   if (tok == TOKconst) 
    6953         to = e1->type->constOf(); 
    6954         else if (tok == TOKinvariant || tok == TOKimmutable) 
    6955         to = e1->type->invariantOf(); 
    6956         else 
    6957         assert(0); 
     7180    { 
     7181        /* Handle cast(const) and cast(immutable), etc. 
     7182         */ 
     7183        to = e1->type->castMod(mod); 
    69587184    } 
    69597185    else 
    69607186        to = to->semantic(loc, sc); 
     
    69897215    {   error("cannot cast tuple"); 
    69907216    to = Type::terror; 
    69917217    } 
     7218 
     7219    if (global.params.safe && !sc->module->safe && !sc->intypeof) 
     7220    {   // Disallow unsafe casts 
     7221    Type *tob = to->toBasetype(); 
     7222    Type *t1b = e1->type->toBasetype(); 
     7223    if (!t1b->isMutable() && tob->isMutable()) 
     7224    {   // Cast not mutable to mutable 
     7225      Lunsafe: 
     7226        error("cast from %s to %s not allowed in safe mode", e1->type->toChars(), to->toChars()); 
     7227    } 
     7228    else if (t1b->isShared() && !tob->isShared()) 
     7229        // Cast away shared 
     7230        goto Lunsafe; 
     7231    else if (tob->ty == Tpointer) 
     7232    {   if (t1b->ty != Tpointer) 
     7233        goto Lunsafe; 
     7234        Type *tobn = tob->nextOf()->toBasetype(); 
     7235        Type *t1bn = t1b->nextOf()->toBasetype(); 
     7236 
     7237        if (!t1bn->isMutable() && tobn->isMutable()) 
     7238        // Cast away pointer to not mutable 
     7239        goto Lunsafe; 
     7240 
     7241        if (t1bn->isShared() && !tobn->isShared()) 
     7242        // Cast away pointer to shared 
     7243        goto Lunsafe; 
     7244 
     7245        if (tobn->isTypeBasic() && tobn->size() < t1bn->size()) 
     7246        // Allow things like casting a long* to an int* 
     7247        ; 
     7248        else if (tobn->ty != Tvoid) 
     7249        // Cast to a pointer other than void* 
     7250        goto Lunsafe; 
     7251    } 
     7252 
     7253    // BUG: Check for casting array types, such as void[] to int*[] 
     7254    } 
     7255 
    69927256    e = e1->castTo(sc, to); 
    69937257    return e; 
    69947258} 
     
    70227286void CastExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    70237287{ 
    70247288    buf->writestring("cast("); 
     7289#if V1 
     7290    to->toCBuffer(buf, NULL, hgs); 
     7291#else 
    70257292    if (to) 
    70267293    to->toCBuffer(buf, NULL, hgs); 
    70277294    else 
    7028     buf->writestring(Token::tochars[tok]); 
     7295    { 
     7296    switch (mod) 
     7297    {   case 0: 
     7298        break; 
     7299        case MODconst: 
     7300        buf->writestring(Token::tochars[TOKconst]); 
     7301        break; 
     7302        case MODinvariant: 
     7303        buf->writestring(Token::tochars[TOKimmutable]); 
     7304        break; 
     7305        case MODshared: 
     7306        buf->writestring(Token::tochars[TOKshared]); 
     7307        break; 
     7308        case MODshared | MODconst: 
     7309        buf->writestring(Token::tochars[TOKshared]); 
     7310        buf->writeByte(' '); 
     7311        buf->writestring(Token::tochars[TOKconst]); 
     7312        break; 
     7313        default: 
     7314        assert(0); 
     7315    } 
     7316    } 
     7317#endif 
    70297318    buf->writeByte(')'); 
    70307319    expToCBuffer(buf, hgs, e1, precedence[op]); 
    70317320} 
     
    72007489    return e; 
    72017490    } 
    72027491 
    7203     type = t->nextOf()->arrayOf(); 
     7492    if (t->ty == Tarray) 
     7493    { 
     7494    type = e1->type; 
     7495    } 
     7496    else 
     7497    type = t->nextOf()->arrayOf(); 
    72047498    return e; 
    72057499 
    72067500Lerror: 
     
    72107504    else 
    72117505    s = t->toChars(); 
    72127506    error("%s cannot be sliced with []", s); 
    7213     type = Type::terror
     7507    e = new IntegerExp(0)
    72147508    return e; 
    72157509} 
    72167510 
     
    72197513    e1->checkEscape(); 
    72207514} 
    72217515 
     7516#if DMDV2 
    72227517int SliceExp::isLvalue() 
    72237518{ 
    72247519    return 1; 
    72257520} 
     7521#endif 
    72267522 
    72277523Expression *SliceExp::toLvalue(Scope *sc, Expression *e) 
    72287524{ 
     
    73387634    return e; 
    73397635} 
    73407636 
    7341  
     7637#if DMDV2 
    73427638int ArrayExp::isLvalue() 
    73437639{ 
    73447640    if (type && type->toBasetype()->ty == Tvoid) 
    73457641    return 0; 
    73467642    return 1; 
    73477643} 
     7644#endif 
    73487645 
    73497646Expression *ArrayExp::toLvalue(Scope *sc, Expression *e) 
    73507647{ 
     
    74157712    e2->checkEscape(); 
    74167713} 
    74177714 
     7715#if DMDV2 
    74187716int CommaExp::isLvalue() 
    74197717{ 
    74207718    return e2->isLvalue(); 
    74217719} 
     7720#endif 
    74227721 
    74237722Expression *CommaExp::toLvalue(Scope *sc, Expression *e) 
    74247723{ 
     
    75327831 
    75337832    case Taarray: 
    75347833    {   TypeAArray *taa = (TypeAArray *)t1; 
    7535  
    7536         e2 = e2->implicitCastTo(sc, taa->index);    // type checking 
     7834        if (!arrayTypeCompatible(e2->loc, e2->type, taa->index)) 
     7835        { 
     7836        e2 = e2->implicitCastTo(sc, taa->index);    // type checking 
     7837        } 
    75377838        type = taa->next; 
    75387839        break; 
    75397840    } 
     
    75857886    return e; 
    75867887} 
    75877888 
     7889#if DMDV2 
    75887890int IndexExp::isLvalue() 
    75897891{ 
    75907892    return 1; 
    75917893} 
     7894#endif 
    75927895 
    75937896Expression *IndexExp::toLvalue(Scope *sc, Expression *e) 
    75947897{ 
     
    91169419    e2 = e2->checkToPointer(); 
    91179420 
    91189421    type = Type::tboolean; 
    9119     if (e1->type->ty == Tvoid) 
     9422    if (e2->type->ty == Tvoid) 
    91209423    type = Type::tvoid; 
    91219424    if (e2->op == TOKtype || e2->op == TOKimport) 
    91229425    error("%s is not an expression", e2->toChars()); 
     
    91819484    e2 = e2->checkToPointer(); 
    91829485 
    91839486    type = Type::tboolean; 
    9184     if (e1->type->ty == Tvoid) 
     9487    if (e2->type->ty == Tvoid) 
    91859488    type = Type::tvoid; 
    91869489    if (e2->op == TOKtype || e2->op == TOKimport) 
    91879490    error("%s is not an expression", e2->toChars()); 
     
    92419544    { 
    92429545    TypeAArray *ta = (TypeAArray *)t2b; 
    92439546 
    9244     // Convert key to type of key 
    9245     e1 = e1->implicitCastTo(sc, ta->index); 
     9547    // Special handling for array keys 
     9548    if (!arrayTypeCompatible(e1->loc, e1->type, ta->index)) 
     9549    { 
     9550        // Convert key to type of key 
     9551        e1 = e1->implicitCastTo(sc, ta->index); 
     9552    } 
    92469553 
    92479554    // Return type is pointer to value 
    92489555    type = ta->nextOf()->pointerTo(); 
     
    94109717    type = Type::tboolean; 
    94119718 
    94129719    // Special handling for array comparisons 
    9413     t1 = e1->type->toBasetype(); 
    9414     t2 = e2->type->toBasetype(); 
    9415  
    9416     if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && 
    9417     (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer)) 
    9418     { 
    9419     if (t1->nextOf()->implicitConvTo(t2->nextOf()) < MATCHconst && 
    9420         t2->nextOf()->implicitConvTo(t1->nextOf()) < MATCHconst && 
    9421         (t1->nextOf()->ty != Tvoid && t2->nextOf()->ty != Tvoid)) 
    9422         error("array equality comparison type mismatch, %s vs %s", t1->toChars(), t2->toChars()); 
    9423     } 
    9424     else 
     9720    if (!arrayTypeCompatible(loc, e1->type, e2->type)) 
    94259721    { 
    94269722    if (e1->type != e2->type && e1->type->isfloating() && e2->type->isfloating()) 
    94279723    { 
     
    95759871    return this; 
    95769872} 
    95779873 
     9874#if DMDV2 
    95789875int CondExp::isLvalue() 
    95799876{ 
    95809877    return e1->isLvalue() && e2->isLvalue(); 
    95819878} 
     9879#endif 
    95829880 
    95839881Expression *CondExp::toLvalue(Scope *sc, Expression *ex) 
    95849882{ 
     
    96359933    } 
    96369934} 
    96379935 
     9936#if DMDV2 
    96389937int CondExp::canThrow() 
    96399938{ 
    96409939    return econd->canThrow() || e1->canThrow() || e2->canThrow(); 
    96419940} 
    9642  
     9941#endif 
    96439942 
    96449943void CondExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    96459944{ 
  • a/dmd2/expression.h

    old new  
    9999    char *toChars(); 
    100100    virtual void dump(int indent); 
    101101    void error(const char *format, ...); 
     102    void warning(const char *format, ...); 
    102103    virtual void rvalue(); 
    103104 
    104105    static Expression *combine(Expression *e1, Expression *e2); 
     
    114115    virtual int isLvalue(); 
    115116    virtual Expression *toLvalue(Scope *sc, Expression *e); 
    116117    virtual Expression *modifiableLvalue(Scope *sc, Expression *e); 
    117     Expression *implicitCastTo(Scope *sc, Type *t); 
     118    virtual Expression *implicitCastTo(Scope *sc, Type *t); 
    118119    virtual MATCH implicitConvTo(Type *t); 
    119120    virtual Expression *castTo(Scope *sc, Type *t); 
    120121    virtual void checkEscape(); 
     
    123124    Expression *checkIntegral(); 
    124125    Expression *checkArithmetic(); 
    125126    void checkDeprecated(Scope *sc, Dsymbol *s); 
     127    void checkPurity(Scope *sc, FuncDeclaration *f); 
    126128    virtual Expression *checkToBoolean(); 
    127129    Expression *checkToPointer(); 
    128130    Expression *addressOf(Scope *sc); 
     
    344346    char *toChars(); 
    345347    Expression *semantic(Scope *sc); 
    346348    Expression *interpret(InterState *istate); 
     349    size_t length(); 
    347350    StringExp *toUTF8(Scope *sc); 
     351    Expression *implicitCastTo(Scope *sc, Type *t); 
    348352    MATCH implicitConvTo(Type *t); 
    349353    Expression *castTo(Scope *sc, Type *t); 
    350354    int compare(Object *obj); 
     
    491495struct TypeExp : Expression 
    492496{ 
    493497    TypeExp(Loc loc, Type *type); 
     498    Expression *syntaxCopy(); 
    494499    Expression *semantic(Scope *sc); 
    495500    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    496501    Expression *optimize(int result); 
     
    858863    int isLvalue(); 
    859864    Expression *toLvalue(Scope *sc, Expression *e); 
    860865    Expression *modifiableLvalue(Scope *sc, Expression *e); 
     866    Expression *optimize(int result); 
     867    Expression *interpret(InterState *istate); 
    861868    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    862869    void dump(int indent); 
    863870    elem *toElem(IRState *irs); 
    864  
    865     //LDC: since we don't convert abc.def -> *(&abc + ABC.def.offsetof) 
    866     // these are needed 
    867     Expression *optimize(int result); 
    868     Expression *interpret(InterState *istate); 
    869871}; 
    870872 
    871873struct DotTemplateInstanceExp : UnaExp 
     
    10341036{ 
    10351037    // Possible to cast to one type while painting to another type 
    10361038    Type *to;           // type to cast to 
    1037     enum TOK tok;      // TOKconst or TOKinvariant 
     1039    unsigned mod;      // MODxxxxx 
    10381040 
    10391041    CastExp(Loc loc, Expression *e, Type *t); 
    1040     CastExp(Loc loc, Expression *e, enum TOK tok); 
     1042    CastExp(Loc loc, Expression *e, unsigned mod); 
    10411043    Expression *syntaxCopy(); 
    10421044    Expression *semantic(Scope *sc); 
    10431045    Expression *optimize(int result); 
  • a/dmd2/func.c

    old new  
    129129    originalType = type; 
    130130    if (!type->deco && type->nextOf()) 
    131131    { 
    132 #if 1 
    133132    /* Apply const and invariant storage class 
    134133     * to the function type 
    135134     */ 
     
    147146        type->deco = type->merge()->deco; 
    148147        } 
    149148    } 
    150 #else 
    151     if (storage_class & (STCconst | STCinvariant)) 
    152     { 
    153         /* Apply const and invariant storage class 
    154          * to the function's return type 
    155          */ 
    156         Type *tn = type->nextOf(); 
    157         if (storage_class & STCconst) 
    158         tn = tn->makeConst(); 
    159         if (storage_class & STCinvariant) 
    160         tn = tn->makeInvariant(); 
    161         ((TypeNext *)type)->next = tn; 
    162     } 
    163  
    164     type = type->semantic(loc, sc); 
    165 #endif 
    166149    } 
    167150    //type->print(); 
    168151    if (type->ty != Tfunction) 
     
    190173    error("non-virtual functions cannot be abstract"); 
    191174 
    192175    if ((f->isConst() || f->isInvariant()) && !isThis()) 
    193     error("without 'this' cannot be const/invariant"); 
     176    error("without 'this' cannot be const/immutable"); 
    194177 
    195178    if (isAbstract() && isFinal()) 
    196179    error("cannot be both final and abstract"); 
    197 #if 0 
    198     if (isAbstract() && fbody) 
    199     error("abstract functions cannot have bodies"); 
    200 #endif 
    201180 
    202 #if 0 
    203     if (isStaticConstructor() || isStaticDestructor()) 
    204     { 
    205     if (!isStatic() || type->nextOf()->ty != Tvoid) 
    206         error("static constructors / destructors must be static void"); 
    207     if (f->arguments && f->arguments->dim) 
    208         error("static constructors / destructors must have empty parameter list"); 
    209     // BUG: check for invalid storage classes 
    210     } 
    211 #endif 
    212  
    213 #ifdef IN_GCC 
    214     AggregateDeclaration *ad; 
    215  
    216     ad = parent->isAggregateDeclaration(); 
    217     if (ad) 
    218     ad->methods.push(this); 
    219 #endif 
    220181    sd = parent->isStructDeclaration(); 
    221182    if (sd) 
    222183    { 
     
    224185    { 
    225186        return; 
    226187    } 
    227 #if 0 
    228     // Verify no constructors, destructors, etc. 
    229     if (isCtorDeclaration() 
    230         //||isDtorDeclaration() 
    231         //|| isInvariantDeclaration() 
    232         //|| isUnitTestDeclaration() 
    233        ) 
    234     { 
    235         error("special member functions not allowed for %ss", sd->kind()); 
    236     } 
    237  
    238     if (!sd->inv) 
    239         sd->inv = isInvariantDeclaration(); 
    240  
    241     if (!sd->aggNew) 
    242         sd->aggNew = isNewDeclaration(); 
    243  
    244     if (isDelete()) 
    245     { 
    246         if (sd->aggDelete) 
    247         error("multiple delete's for struct %s", sd->toChars()); 
    248         sd->aggDelete = (DeleteDeclaration *)(this); 
    249     } 
    250 #endif 
    251188    } 
    252189 
    253190    id = parent->isInterfaceDeclaration(); 
     
    292229        return; 
    293230    } 
    294231 
    295 #if 0 
    296     dtor = isDtorDeclaration(); 
    297     if (dtor) 
    298     { 
    299         if (cd->dtor) 
    300         error("multiple destructors for class %s", cd->toChars()); 
    301         cd->dtor = dtor; 
    302     } 
    303  
    304     inv = isInvariantDeclaration(); 
    305     if (inv) 
    306     { 
    307         cd->inv = inv; 
    308     } 
    309  
    310     if (isNewDeclaration()) 
    311     { 
    312         if (!cd->aggNew) 
    313         cd->aggNew = (NewDeclaration *)(this); 
    314     } 
    315  
    316     if (isDelete()) 
    317     { 
    318         if (cd->aggDelete) 
    319         error("multiple delete's for class %s", cd->toChars()); 
    320         cd->aggDelete = (DeleteDeclaration *)(this); 
    321     } 
    322 #endif 
    323  
    324232    if (storage_class & STCabstract) 
    325233        cd->isabstract = 1; 
    326234 
     
    355263 
    356264        if (isFinal()) 
    357265        { 
     266            if (isOverride()) 
     267            error("does not override any function"); 
    358268            cd->vtblFinal.push(this); 
    359269        } 
    360270        else 
     
    379289            error("cannot override final function %s", fdv->toPrettyChars()); 
    380290 
    381291#if DMDV2 
    382         if (!isOverride() && global.params.warnings
     292        if (!isOverride()
    383293            warning("%s: overrides base class function %s, but is not marked with 'override'", locToChars(), fdv->toPrettyChars()); 
    384294#endif 
    385295 
     
    460370            if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 
    461371            { 
    462372                ti = fdv->type; 
    463 #if 0 
    464                 if (offset) 
    465                 ti = fdv->type; 
    466                 else if (type->nextOf()->ty == Tclass) 
    467                 {   ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym; 
    468                 if (cdn && cdn->sizeok != 1) 
    469                     ti = fdv->type; 
    470                 } 
    471 #endif 
    472373            } 
    473374            } 
    474375            if (ti) 
     
    616517    } 
    617518    //printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars()); 
    618519    //fflush(stdout); 
     520    //printf("storage class = x%x %x\n", sc->stc, storage_class); 
    619521    //{ static int x; if (++x == 2) *(char*)0=0; } 
    620522    //printf("\tlinkage = %d\n", sc->linkage); 
    621523 
     
    660562    sc2->sw = NULL; 
    661563    sc2->fes = fes; 
    662564    sc2->linkage = LINKd; 
    663     sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCconst | STCfinal | STCinvariant | STCtls); 
     565    sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCconst | STCfinal | STCinvariant | STCtls | STCref); 
    664566    sc2->protection = PROTpublic; 
    665567    sc2->explicitProtection = 0; 
    666568    sc2->structalign = 8; 
     
    684586        assert(!isNested());    // can't be both member and nested 
    685587        assert(ad->handle); 
    686588        Type *thandle = ad->handle; 
     589#if STRUCTTHISREF 
     590        thandle = thandle->addMod(type->mod); 
     591        thandle = thandle->addStorageClass(storage_class); 
     592        if (isPure()) 
     593            thandle = thandle->addMod(MODconst); 
     594#else 
     595        assert(0); 
    687596        if (storage_class & STCconst || type->isConst()) 
    688597        { 
    689 #if STRUCTTHISREF 
    690             thandle = thandle->constOf(); 
    691 #else 
     598            assert(0); // BUG: shared not handled 
    692599            if (thandle->ty == Tclass) 
    693600            thandle = thandle->constOf(); 
    694601            else 
    695602            {   assert(thandle->ty == Tpointer); 
    696603            thandle = thandle->nextOf()->constOf()->pointerTo(); 
    697604            } 
    698 #endif 
    699605        } 
    700606        else if (storage_class & STCinvariant || type->isInvariant()) 
    701607        { 
    702 #if STRUCTTHISREF 
    703             thandle = thandle->invariantOf(); 
    704 #else 
    705608            if (thandle->ty == Tclass) 
    706609            thandle = thandle->invariantOf(); 
    707610            else 
    708611            {   assert(thandle->ty == Tpointer); 
    709612            thandle = thandle->nextOf()->invariantOf()->pointerTo(); 
    710613            } 
     614        } 
     615        else if (storage_class & STCshared || type->isShared()) 
     616        { 
     617            assert(0);  // not implemented 
     618        } 
    711619#endif 
    712         } 
    713620        v = new ThisDeclaration(thandle); 
    714621        v->storage_class |= STCparameter; 
    715622#if STRUCTTHISREF 
     
    818725             */ 
    819726            arg->ident = id = Identifier::generateId("_param_", i); 
    820727        } 
    821         VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL); 
     728        Type *vtype = arg->type; 
     729        if (isPure()) 
     730            vtype = vtype->addMod(MODconst); 
     731        VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL); 
    822732        //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars()); 
    823733        v->storage_class |= STCparameter; 
    824734        if (f->varargs == 2 && i + 1 == nparams) 
     
    1088998        error("expected to return a value of type %s", type->nextOf()->toChars()); 
    1089999        else if (!inlineAsm) 
    10901000        { 
    1091         int offend = fbody ? fbody->blockExit() & BEfallthru : TRUE; 
    1092         //int offend = fbody ? fbody->fallOffEnd() : TRUE; 
     1001        int blockexit = fbody ? fbody->blockExit() : 0; 
     1002        if (f->isnothrow && blockexit & BEthrow) 
     1003            error("'%s' is nothrow yet may throw", toChars()); 
     1004 
     1005        int offend = blockexit & BEfallthru; 
    10931006 
    10941007        if (type->nextOf()->ty == Tvoid) 
    10951008        { 
     
    11041017            if (offend) 
    11051018            {   Expression *e; 
    11061019 
    1107             if (global.params.warnings) 
     1020            warning(loc, "no return at end of function"); 
    11081021            {   warning("%s: no return at end of function", locToChars()); 
    1109             } 
    11101022 
    11111023            if (global.params.useAssert && 
    11121024                !global.params.useInline) 
     
    11291041        } 
    11301042        } 
    11311043    } 
     1044    } 
    11321045 
    11331046    { 
    11341047        Statements *a = new Statements(); 
     
    11481061        } 
    11491062        } 
    11501063 
    1151 // we'll handle variadics ourselves 
    1152 #if !IN_LLVM 
    1153         if (argptr) 
    1154         {   // Initialize _argptr to point past non-variadic arg 
    1155 #if IN_GCC 
    1156         // Handled in FuncDeclaration::toObjFile 
    1157         v_argptr = argptr; 
    1158         v_argptr->init = new VoidInitializer(loc); 
    1159 #else 
    1160         Expression *e1; 
    1161         Expression *e; 
    1162         Type *t = argptr->type; 
    1163         VarDeclaration *p; 
    1164         unsigned offset; 
    1165  
    1166         e1 = new VarExp(0, argptr); 
    1167         if (parameters && parameters->dim) 
    1168             p = (VarDeclaration *)parameters->data[parameters->dim - 1]; 
    1169         else 
    1170             p = v_arguments;        // last parameter is _arguments[] 
    1171         offset = p->type->size(); 
    1172         offset = (offset + 3) & ~3; // assume stack aligns on 4 
    1173         e = new SymOffExp(0, p, offset); 
    1174         e = new AssignExp(0, e1, e); 
    1175         e->type = t; 
    1176         a->push(new ExpStatement(0, e)); 
    1177 #endif // IN_GCC 
    1178         } 
    1179  
    1180         if (_arguments) 
    1181         { 
    1182         /* Advance to elements[] member of TypeInfo_Tuple with: 
    1183          *  _arguments = v_arguments.elements; 
    1184          */ 
    1185         Expression *e = new VarExp(0, v_arguments); 
    1186         e = new DotIdExp(0, e, Id::elements); 
    1187         Expression *e1 = new VarExp(0, _arguments); 
    1188         e = new AssignExp(0, e1, e); 
    1189         e->op = TOKconstruct; 
    1190         e = e->semantic(sc); 
    1191         a->push(new ExpStatement(0, e)); 
    1192         } 
    1193  
    1194 #endif // !IN_LLVM 
    1195  
    11961064        // Merge contracts together with body into one compound statement 
    11971065 
    11981066#ifdef _DH 
     
    19401808    } 
    19411809    else 
    19421810    { 
    1943         ClassDeclaration *thiscd = s->isClassDeclaration(); 
     1811        AggregateDeclaration *thiscd = s->isAggregateDeclaration(); 
    19441812        if (thiscd) 
    19451813        {   if (!thiscd->isNested()) 
    19461814            goto Lerr; 
     
    20681936    return 1;           // functions can be overloaded 
    20691937} 
    20701938 
     1939int FuncDeclaration::isPure() 
     1940{ 
     1941    //printf("FuncDeclaration::isPure() '%s'\n", toChars()); 
     1942    assert(type->ty == Tfunction); 
     1943    return ((TypeFunction *)this->type)->ispure; 
     1944} 
     1945 
    20711946// Determine if function needs 
    20721947// a static frame pointer to its lexically enclosing function 
    20731948 
     
    28082683    ad = parent->isAggregateDeclaration(); 
    28092684    if (!ad) 
    28102685    { 
    2811     error("invariants only are for struct/union/class definitions"); 
     2686    error("invariants are only for struct/union/class definitions"); 
    28122687    return; 
    28132688    } 
    28142689    else if (ad->inv && ad->inv != this) 
  • a/dmd2/hdrgen.c

    old new  
    2424#include <complex.h> 
    2525#endif 
    2626 
    27 #if IN_GCC || IN_LLVM 
    2827#include "mem.h" 
    29 #else 
    30 #if _WIN32 
    31 #include "..\root\mem.h" 
    32 #elif POSIX 
    33 #include "../root/mem.h" 
    34 #else 
    35 #error "fix this" 
    36 #endif 
    37 #endif 
    3828 
    3929#include "id.h" 
    4030#include "init.h" 
  • a/dmd2/html.c

    old new  
    11 
    2 // Copyright (c) 1999-2006 by Digital Mars 
     2// Copyright (c) 1999-2009 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
     
    1818#include <errno.h> 
    1919#include <wchar.h> 
    2020 
    21 #include "mars.h" 
    2221#include "html.h" 
    23  
    2422#include <assert.h> 
    2523#include "root.h" 
    2624 
     25#if __GNUC__ 
     26int memicmp(const char *s1, const char *s2, int n); 
     27#if 0 
     28{ 
     29    int result = 0; 
     30 
     31    for (int i = 0; i < n; i++) 
     32    {   char c1 = s1[i]; 
     33    char c2 = s2[i]; 
     34 
     35    result = c1 - c2; 
     36    if (result) 
     37    { 
     38        if ('A' <= c1 && c1 <= 'Z') 
     39        c1 += 'a' - 'A'; 
     40        if ('A' <= c2 && c2 <= 'Z') 
     41        c2 += 'a' - 'A'; 
     42        result = c1 - c2; 
     43        if (result) 
     44        break; 
     45    } 
     46    } 
     47    return result; 
     48} 
     49#endif 
     50#endif 
     51 
    2752extern int HtmlNamedEntity(unsigned char *p, int length); 
    2853 
    2954static int isLineSeparator(const unsigned char* p); 
     
    6489 
    6590void Html::error(const char *format, ...) 
    6691{ 
    67     if (!global.gag) 
    68     { 
    69     printf("%s(%d) : HTML Error: ", sourcename, linnum); 
     92    printf("%s(%d) : HTML Error: ", sourcename, linnum); 
    7093 
    7194    va_list ap; 
    7295    va_start(ap, format); 
    7396    vprintf(format, ap); 
    7497    va_end(ap); 
    7598 
    76     printf("\n"); 
    77     fflush(stdout); 
    78     } 
     99    printf("\n"); 
     100    fflush(stdout); 
    79101 
    80     global.errors++
     102    exit(EXIT_FAILURE)
    81103} 
    82104 
    83105/********************************************** 
     
    156178    break; 
    157179    } 
    158180    buf->writeByte(0);              // ending sentinel 
     181#if SCPP 
     182    //printf("Code is: '%s'\n", buf->toString() + 3); 
     183#endif 
     184#if MARS 
    159185    //printf("D code is: '%s'\n", (char *)buf->data); 
     186#endif 
    160187} 
    161188 
    162189/*********************************************** 
     
    530557         * right. 
    531558         */ 
    532559        linnum++; 
    533         dbuf->writeUTF8('\n'); 
     560        dbuf->writeByte('\n'); 
    534561        p += lineSepLength; 
    535562        continue; 
    536563        } 
     
    550577    } 
    551578} 
    552579 
     580 
    553581/******************************************** 
    554582 * Convert an HTML character entity into a character. 
    555583 * Forms are: 
     
    716744    return 0; 
    717745} 
    718746 
     747 
  • a/dmd2/html.h

    old new  
    11 
    2 // Compiler implementation of the D programming language 
    32// Copyright (c) 1999-2006 by Digital Mars 
    43// All Rights Reserved 
    54// written by Walter Bright 
    6 // http://www.digitalmars.com 
     5// www.digitalmars.com 
    76// License for redistribution is by either the Artistic License 
    87// in artistic.txt, or the GNU General Public License in gnu.txt. 
    98// See the included readme.txt for details. 
    109 
    11 #ifndef DMD_HTML_H 
    12 #define DMD_HTML_H 1 
    13  
    1410struct OutBuffer; 
    1511 
    1612struct Html 
     
    3935    int charEntity(); 
    4036    static int namedEntity(unsigned char *p, int length); 
    4137}; 
    42  
    43 #endif 
  • a/dmd2/idgen.c

    old new  
    6060    { "typeinfo" }, 
    6161    { "outer" }, 
    6262    { "Exception" }, 
     63    { "Throwable" }, 
    6364    { "withSym", "__withSym" }, 
    6465    { "result", "__result" }, 
    6566    { "returnLabel", "__returnLabel" }, 
     
    8788    { "TypeInfo_Tuple" }, 
    8889    { "TypeInfo_Const" }, 
    8990    { "TypeInfo_Invariant" }, 
     91    { "TypeInfo_Shared" }, 
    9092    { "elements" }, 
    9193    { "_arguments_typeinfo" }, 
    9294    { "_arguments" }, 
     
    252254    { "main" }, 
    253255    { "WinMain" }, 
    254256    { "DllMain" }, 
     257    { "tls_get_addr", "___tls_get_addr" }, 
    255258 
    256259    // Builtin functions 
    257260    { "std" }, 
  • a/dmd2/import.c

    old new  
    112112    } 
    113113    if (!pkg) 
    114114    pkg = mod; 
    115     mod->semantic(); 
    116115 
    117116    //printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg); 
    118117} 
     
    136135    } 
    137136#endif 
    138137 
     138    // Modules need a list of each imported module 
     139    //printf("%s imports %s\n", sc->module->toChars(), mod->toChars()); 
     140    sc->module->aimports.push(mod); 
     141 
     142    mod->semantic(); 
     143 
    139144    /* Default to private importing 
    140145     */ 
    141146    protection = sc->protection; 
     
    147152        sc->scopesym->importScope(mod, protection); 
    148153    } 
    149154 
    150     // Modules need a list of each imported module 
    151     sc->module->aimports.push(mod); 
    152  
    153155    if (mod->needmoduleinfo) 
    154156        sc->module->needmoduleinfo = 1; 
    155157 
     
    224226    //printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags); 
    225227 
    226228    if (!pkg) 
    227     load(NULL); 
     229    {   load(NULL); 
     230    mod->semantic(); 
     231    } 
    228232 
    229233    // Forward it to the package/module 
    230234    return pkg->search(loc, ident, flags); 
  • a/dmd2/inifile.c

    old new  
    1  
    2 // Copyright (c) 1999-2006 by Digital Mars 
    3 // All Rights Reserved 
    4 // written by Walter Bright 
    5 // http://www.digitalmars.com 
    6  
    7  
    8 #include    <stdio.h> 
    9 #include    <string.h> 
    10 #include    <stdlib.h> 
    11 #include    <ctype.h> 
    12  
    13 #include    "root.h" 
    14 #include    "mem.h" 
    15  
    16 #ifdef __MINGW32__ 
    17 #include <malloc.h> 
    18 #endif 
    19  
    20 #define LOG 0 
    21  
    22 char *skipspace(const char *p); 
    23  
    24 #if __GNUC__ 
    25 char *strupr(char *s) 
    26 
    27     char *t = s; 
    28      
    29     while (*s) 
    30     { 
    31     *s = toupper(*s); 
    32     s++; 
    33     } 
    34  
    35     return t; 
    36 
    37 #endif /* unix */ 
    38  
    39 /***************************** 
    40  * Read and analyze .ini file. 
    41  * Input: 
    42  *  argv0   program name (argv[0]) 
    43  *  inifile .ini file name 
    44  */ 
    45  
    46 void inifile(char *argv0x, const char *inifilex) 
    47 
    48     char *argv0 = (char *)argv0x; 
    49     char *inifile = (char *)inifilex;   // do const-correct later 
    50     char *path;     // need path for @P macro 
    51     char *filename; 
    52     OutBuffer buf; 
    53     int i; 
    54     int k; 
    55     int envsection = 0; 
    56  
    57 #if LOG 
    58     printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile); 
    59 #endif 
    60     if (FileName::absolute(inifile)) 
    61     { 
    62     filename = inifile; 
    63     } 
    64     else 
    65     { 
    66     /* Look for inifile in the following sequence of places: 
    67      *  o current directory 
    68      *  o home directory 
    69      *  o directory off of argv0 
    70      *  o /etc/ 
    71      */ 
    72     if (FileName::exists(inifile)) 
    73     { 
    74         filename = inifile; 
    75     } 
    76     else 
    77     { 
    78         filename = FileName::combine(getenv("HOME"), inifile); 
    79         if (!FileName::exists(filename)) 
    80         { 
    81         filename = FileName::replaceName(argv0, inifile); 
    82         if (!FileName::exists(filename)) 
    83         { 
    84 #if POSIX 
    85  
    86 #if 0 
    87 #if __GLIBC__       // This fix by Thomas Kuehne 
    88             /* argv0 might be a symbolic link, 
    89              * so try again looking past it to the real path 
    90              */ 
    91             char* real_argv0 = realpath(argv0, NULL); 
    92             if (real_argv0) 
    93             { 
    94             filename = FileName::replaceName(real_argv0, inifile); 
    95             free(real_argv0); 
    96             if (FileName::exists(filename)) 
    97                 goto Ldone; 
    98             } 
    99 #else 
    100 #error use of glibc non-standard extension realpath(char*, NULL) 
    101 #endif 
    102 #endif 
    103  
    104     // old way; problem is that argv0 might not be on the PATH at all 
    105     // and some other instance might be found 
    106  
    107             // Search PATH for argv0 
    108             const char *p = getenv("PATH"); 
    109             Array *paths = FileName::splitPath(p); 
    110             filename = FileName::searchPath(paths, argv0, 0); 
    111             if (!filename) 
    112             goto Letc;      // argv0 not found on path 
    113             filename = FileName::replaceName(filename, inifile); 
    114             if (FileName::exists(filename)) 
    115             goto Ldone; 
    116 #endif 
    117  
    118             // Search /etc/ for inifile 
    119         Letc: 
    120             filename = FileName::combine((char *)"/etc/", inifile); 
    121  
    122         Ldone: 
    123             ; 
    124         } 
    125         } 
    126     } 
    127     } 
    128     path = FileName::path(filename); 
    129 #if LOG 
    130     printf("\tpath = '%s', filename = '%s'\n", path, filename); 
    131 #endif 
    132  
    133     File file(filename); 
    134  
    135     if (file.read()) 
    136     return;         // error reading file 
    137  
    138     // Parse into lines 
    139     int eof = 0; 
    140     for (i = 0; i < file.len && !eof; i++) 
    141     { 
    142     int linestart = i; 
    143  
    144     for (; i < file.len; i++) 
    145     { 
    146         switch (file.buffer[i]) 
    147         { 
    148         case '\r': 
    149             break; 
    150  
    151         case '\n': 
    152             // Skip if it was preceded by '\r' 
    153             if (i && file.buffer[i - 1] == '\r') 
    154             goto Lskip; 
    155             break; 
    156  
    157         case 0: 
    158         case 0x1A: 
    159             eof = 1; 
    160             break; 
    161  
    162         default: 
    163             continue; 
    164         } 
    165         break; 
    166     } 
    167  
    168     // The line is file.buffer[linestart..i] 
    169     char *line; 
    170     int len; 
    171     char *p; 
    172     char *pn; 
    173  
    174     line = (char *)&file.buffer[linestart]; 
    175     len = i - linestart; 
    176  
    177     buf.reset(); 
    178  
    179     // First, expand the macros. 
    180     // Macros are bracketed by % characters. 
    181  
    182     for (k = 0; k < len; k++) 
    183     { 
    184         if (line[k] == '%') 
    185         { 
    186         int j; 
    187  
    188         for (j = k + 1; j < len; j++) 
    189         { 
    190             if (line[j] == '%') 
    191             { 
    192             if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0) 
    193             { 
    194                 // %@P% is special meaning the path to the .ini file 
    195                 p = path; 
    196                 if (!*p) 
    197                 p = (char *)"."; 
    198             } 
    199             else 
    200             {   int len = j - k; 
    201                 char tmp[10];   // big enough most of the time 
    202  
    203                 if (len <= sizeof(tmp)) 
    204                 p = tmp; 
    205                 else 
    206                 p = (char *)alloca(len); 
    207                 len--; 
    208                 memcpy(p, &line[k + 1], len); 
    209                 p[len] = 0; 
    210                 strupr(p); 
    211                 p = getenv(p); 
    212                 if (!p) 
    213                 p = (char *)""; 
    214             } 
    215             buf.writestring(p); 
    216             k = j; 
    217             goto L1; 
    218             } 
    219         } 
    220         } 
    221         buf.writeByte(line[k]); 
    222      L1: 
    223         ; 
    224     } 
    225  
    226     // Remove trailing spaces 
    227     while (buf.offset && isspace(buf.data[buf.offset - 1])) 
    228         buf.offset--; 
    229  
    230     p = buf.toChars(); 
    231  
    232     // The expanded line is in p. 
    233     // Now parse it for meaning. 
    234  
    235     p = skipspace(p); 
    236     switch (*p) 
    237     { 
    238         case ';':       // comment 
    239         case 0:     // blank 
    240         break; 
    241  
    242         case '[':       // look for [Environment] 
    243         p = skipspace(p + 1); 
    244         for (pn = p; isalnum(*pn); pn++) 
    245             ; 
    246         if (pn - p == 11 && 
    247             memicmp(p, "Environment", 11) == 0 && 
    248             *skipspace(pn) == ']' 
    249            ) 
    250             envsection = 1; 
    251         else 
    252             envsection = 0; 
    253         break; 
    254  
    255         default: 
    256         if (envsection) 
    257         { 
    258             pn = p; 
    259  
    260             // Convert name to upper case; 
    261             // remove spaces bracketing = 
    262             for (p = pn; *p; p++) 
    263             {   if (islower(*p)) 
    264                 *p &= ~0x20; 
    265             else if (isspace(*p)) 
    266                 memmove(p, p + 1, strlen(p)); 
    267             else if (*p == '=') 
    268             { 
    269                 p++; 
    270                 while (isspace(*p)) 
    271                 memmove(p, p + 1, strlen(p)); 
    272                 break; 
    273             } 
    274             } 
    275  
    276             putenv(strdup(pn)); 
    277 #if LOG 
    278             printf("\tputenv('%s')\n", pn); 
    279             //printf("getenv(\"TEST\") = '%s'\n",getenv("TEST")); 
    280 #endif 
    281         } 
    282         break; 
    283     } 
    284  
    285      Lskip: 
    286     ; 
    287     } 
    288 
    289  
    290 /******************** 
    291  * Skip spaces. 
    292  */ 
    293  
    294 char *skipspace(const char *p) 
    295 
    296     while (isspace(*p)) 
    297     p++; 
    298     return (char *)p; 
    299 
    300  
     1/* 
     2 * Some portions copyright (c) 1994-1995 by Symantec 
     3 * Copyright (c) 1999-2009 by Digital Mars 
     4 * All Rights Reserved 
     5 * http://www.digitalmars.com 
     6 * Written by Walter Bright 
     7 * 
     8 * This source file is made available for personal use 
     9 * only. The license is in /dmd/src/dmd/backendlicense.txt 
     10 * For any other uses, please contact Digital Mars. 
     11 */ 
     12 
     13#include    <stdio.h> 
     14#include    <string.h> 
     15#include    <stdlib.h> 
     16#include    <ctype.h> 
     17 
     18#if __APPLE__ 
     19#include    <sys/syslimits.h> 
     20#endif 
     21 
     22#include    "root.h" 
     23#include    "mem.h" 
     24 
     25#ifdef __MINGW32__ 
     26#include <malloc.h> 
     27#endif 
     28 
     29#define LOG 0 
     30 
     31char *skipspace(const char *p); 
     32 
     33#if __GNUC__ 
     34char *strupr(char *s) 
     35
     36    char *t = s; 
     37 
     38    while (*s) 
     39    { 
     40    *s = toupper(*s); 
     41    s++; 
     42    } 
     43 
     44    return t; 
     45
     46#endif /* unix */ 
     47 
     48/***************************** 
     49 * Read and analyze .ini file. 
     50 * Input: 
     51 *  argv0   program name (argv[0]) 
     52 *  inifile .ini file name 
     53 */ 
     54 
     55void inifile(char *argv0x, const char *inifilex) 
     56
     57    char *argv0 = (char *)argv0x; 
     58    char *inifile = (char *)inifilex;   // do const-correct later 
     59    char *path;     // need path for @P macro 
     60    char *filename; 
     61    OutBuffer buf; 
     62    int i; 
     63    int k; 
     64    int envsection = 0; 
     65 
     66#if LOG 
     67    printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile); 
     68#endif 
     69    if (FileName::absolute(inifile)) 
     70    { 
     71    filename = inifile; 
     72    } 
     73    else 
     74    { 
     75    /* Look for inifile in the following sequence of places: 
     76     *  o current directory 
     77     *  o home directory 
     78     *  o directory off of argv0 
     79     *  o /etc/ 
     80     */ 
     81    if (FileName::exists(inifile)) 
     82    { 
     83        filename = inifile; 
     84    } 
     85    else 
     86    { 
     87        filename = FileName::combine(getenv("HOME"), inifile); 
     88        if (!FileName::exists(filename)) 
     89        { 
     90        filename = FileName::replaceName(argv0, inifile); 
     91        if (!FileName::exists(filename)) 
     92        { 
     93#if POSIX 
     94    // old way; problem is that argv0 might not be on the PATH at all 
     95    // and some other instance might be found 
     96 
     97            // Search PATH for argv0 
     98            const char *p = getenv("PATH"); 
     99            Array *paths = FileName::splitPath(p); 
     100            filename = FileName::searchPath(paths, argv0, 0); 
     101            if (!filename) 
     102            goto Letc;      // argv0 not found on path 
     103            filename = FileName::replaceName(filename, inifile); 
     104            if (FileName::exists(filename)) 
     105            goto Ldone; 
     106#endif 
     107 
     108            // Search /etc/ for inifile 
     109        Letc: 
     110            filename = FileName::combine((char *)"/etc/", inifile); 
     111 
     112        Ldone: 
     113            ; 
     114        } 
     115        } 
     116    } 
     117    } 
     118    path = FileName::path(filename); 
     119#if LOG 
     120    printf("\tpath = '%s', filename = '%s'\n", path, filename); 
     121#endif 
     122 
     123    File file(filename); 
     124 
     125    if (file.read()) 
     126    return;         // error reading file 
     127 
     128    // Parse into lines 
     129    int eof = 0; 
     130    for (i = 0; i < file.len && !eof; i++) 
     131    { 
     132    int linestart = i; 
     133 
     134    for (; i < file.len; i++) 
     135    { 
     136        switch (file.buffer[i]) 
     137        { 
     138        case '\r': 
     139            break; 
     140 
     141        case '\n': 
     142            // Skip if it was preceded by '\r' 
     143            if (i && file.buffer[i - 1] == '\r') 
     144            goto Lskip; 
     145            break; 
     146 
     147        case 0: 
     148        case 0x1A: 
     149            eof = 1; 
     150            break; 
     151 
     152        default: 
     153            continue; 
     154        } 
     155        break; 
     156    } 
     157 
     158    // The line is file.buffer[linestart..i] 
     159    char *line; 
     160    int len; 
     161    char *p; 
     162    char *pn; 
     163 
     164    line = (char *)&file.buffer[linestart]; 
     165    len = i - linestart; 
     166 
     167    buf.reset(); 
     168 
     169    // First, expand the macros. 
     170    // Macros are bracketed by % characters. 
     171 
     172    for (k = 0; k < len; k++) 
     173    { 
     174        if (line[k] == '%') 
     175        { 
     176        int j; 
     177 
     178        for (j = k + 1; j < len; j++) 
     179        { 
     180            if (line[j] == '%') 
     181            { 
     182            if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0) 
     183            { 
     184                // %@P% is special meaning the path to the .ini file 
     185                p = path; 
     186                if (!*p) 
     187                p = (char *)"."; 
     188            } 
     189            else 
     190            {   int len = j - k; 
     191                char tmp[10];   // big enough most of the time 
     192 
     193                if (len <= sizeof(tmp)) 
     194                p = tmp; 
     195                else 
     196                p = (char *)alloca(len); 
     197                len--; 
     198                memcpy(p, &line[k + 1], len); 
     199                p[len] = 0; 
     200                strupr(p); 
     201                p = getenv(p); 
     202                if (!p) 
     203                p = (char *)""; 
     204            } 
     205            buf.writestring(p); 
     206            k = j; 
     207            goto L1; 
     208            } 
     209        } 
     210        } 
     211        buf.writeByte(line[k]); 
     212     L1: 
     213        ; 
     214    } 
     215 
     216    // Remove trailing spaces 
     217    while (buf.offset && isspace(buf.data[buf.offset - 1])) 
     218        buf.offset--; 
     219 
     220    p = buf.toChars(); 
     221 
     222    // The expanded line is in p. 
     223    // Now parse it for meaning. 
     224 
     225    p = skipspace(p); 
     226    switch (*p) 
     227    { 
     228        case ';':       // comment 
     229        case 0:     // blank 
     230        break; 
     231 
     232        case '[':       // look for [Environment] 
     233        p = skipspace(p + 1); 
     234        for (pn = p; isalnum(*pn); pn++) 
     235            ; 
     236        if (pn - p == 11 && 
     237            memicmp(p, "Environment", 11) == 0 && 
     238            *skipspace(pn) == ']' 
     239           ) 
     240            envsection = 1; 
     241        else 
     242            envsection = 0; 
     243        break; 
     244 
     245        default: 
     246        if (envsection) 
     247        { 
     248            pn = p; 
     249 
     250            // Convert name to upper case; 
     251            // remove spaces bracketing = 
     252            for (p = pn; *p; p++) 
     253            {   if (islower(*p)) 
     254                *p &= ~0x20; 
     255            else if (isspace(*p)) 
     256                memmove(p, p + 1, strlen(p)); 
     257            else if (*p == '=') 
     258            { 
     259                p++; 
     260                while (isspace(*p)) 
     261                memmove(p, p + 1, strlen(p)); 
     262                break; 
     263            } 
     264            } 
     265 
     266            putenv(strdup(pn)); 
     267#if LOG 
     268            printf("\tputenv('%s')\n", pn); 
     269            //printf("getenv(\"TEST\") = '%s'\n",getenv("TEST")); 
     270#endif 
     271        } 
     272        break; 
     273    } 
     274 
     275     Lskip: 
     276    ; 
     277    } 
     278
     279 
     280/******************** 
     281 * Skip spaces. 
     282 */ 
     283 
     284char *skipspace(const char *p) 
     285
     286    while (isspace(*p)) 
     287    p++; 
     288    return (char *)p; 
     289
     290 
  • a/dmd2/inline.c

    old new  
    13821382    else 
    13831383        vthis->storage_class = STCin; 
    13841384#else 
     1385    assert(0); 
    13851386    if (ethis->type->ty != Tclass && ethis->type->ty != Tpointer) 
    13861387    { 
    13871388        ethis = ethis->addressOf(NULL); 
  • a/dmd2/interpret.c

    old new  
    15131513    } 
    15141514    } 
    15151515    /* Assignment to struct member of the form: 
     1516     *   v.var = e2 
     1517     */ 
     1518    else if (e1->op == TOKdotvar && ((DotVarExp *)e1)->e1->op == TOKvar) 
     1519    {   VarExp *ve = (VarExp *)((DotVarExp *)e1)->e1; 
     1520    VarDeclaration *v = ve->var->isVarDeclaration(); 
     1521 
     1522    if (v->isDataseg()) 
     1523        return EXP_CANT_INTERPRET; 
     1524    if (fp && !v->value) 
     1525    {   error("variable %s is used before initialization", v->toChars()); 
     1526        return e; 
     1527    } 
     1528    Expression *vie = v->value; 
     1529    if (vie->op == TOKvar) 
     1530    { 
     1531        Declaration *d = ((VarExp *)vie)->var; 
     1532        vie = getVarExp(e1->loc, istate, d); 
     1533    } 
     1534    if (vie->op != TOKstructliteral) 
     1535        return EXP_CANT_INTERPRET; 
     1536    StructLiteralExp *se = (StructLiteralExp *)vie; 
     1537    VarDeclaration *vf = ((DotVarExp *)e1)->var->isVarDeclaration(); 
     1538    if (!vf) 
     1539        return EXP_CANT_INTERPRET; 
     1540    int fieldi = se->getFieldIndex(type, vf->offset); 
     1541    if (fieldi == -1) 
     1542        return EXP_CANT_INTERPRET; 
     1543    Expression *ev = se->getField(type, vf->offset); 
     1544    if (fp) 
     1545        e2 = (*fp)(type, ev, e2); 
     1546    else 
     1547        e2 = Cast(type, type, e2); 
     1548    if (e2 == EXP_CANT_INTERPRET) 
     1549        return e2; 
     1550 
     1551    if (!v->isParameter()) 
     1552    { 
     1553        for (size_t i = 0; 1; i++) 
     1554        { 
     1555        if (i == istate->vars.dim) 
     1556        {   istate->vars.push(v); 
     1557            break; 
     1558        } 
     1559        if (v == (VarDeclaration *)istate->vars.data[i]) 
     1560            break; 
     1561        } 
     1562    } 
     1563 
     1564    /* Create new struct literal reflecting updated fieldi 
     1565     */ 
     1566    Expressions *expsx = new Expressions(); 
     1567    expsx->setDim(se->elements->dim); 
     1568    for (size_t j = 0; j < expsx->dim; j++) 
     1569    { 
     1570        if (j == fieldi) 
     1571        expsx->data[j] = (void *)e2; 
     1572        else 
     1573        expsx->data[j] = se->elements->data[j]; 
     1574    } 
     1575    v->value = new StructLiteralExp(se->loc, se->sd, expsx); 
     1576    v->value->type = se->type; 
     1577 
     1578    e = Cast(type, type, post ? ev : e2); 
     1579    } 
     1580    /* Assignment to struct member of the form: 
    15161581     *   *(symoffexp) = e2 
    15171582     */ 
    15181583    else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff) 
  • a/dmd2/lexer.c

    old new  
    1818#include <wchar.h> 
    1919#include <stdlib.h> 
    2020#include <assert.h> 
     21#if _MSC_VER 
     22#include <time.h> 
     23#else 
    2124#include <sys/time.h> 
     25#endif 
    2226#include <math.h> 
    2327 
    24 #ifdef IN_GCC 
     28#include <time.h> 
    2529 
    26 #include <time.h> 
     30 
    2731#include "mem.h" 
    2832 
    29 #else 
    30  
    31 #if __GNUC__ 
    32 #include <time.h> 
    33 #endif 
    34  
    35 #if IN_LLVM 
    36 #include "mem.h" 
    37 #elif _WIN32 
    38 #include "..\root\mem.h" 
    39 #else 
    40 #include "../root/mem.h" 
    41 #endif 
    42 #endif 
    43  
    4433#include "stringtable.h" 
    4534 
    4635#include "lexer.h" 
     
    5443extern "C" char * __cdecl __locale_decpoint; 
    5544#endif 
    5645 
     46#if _MSC_VER // workaround VC++ bug, labels and types should be in separate namespaces 
     47#define Lstring Lstr 
     48#endif 
     49 
    5750extern int HtmlNamedEntity(unsigned char *p, int length); 
    5851 
    5952#define LS 0x2028   // UTF line separator 
     
    403396    return peek(&token)->value; 
    404397} 
    405398 
     399/*********************** 
     400 * Look 2 tokens ahead at value. 
     401 */ 
     402 
     403TOK Lexer::peekNext2() 
     404{ 
     405    Token *t = peek(&token); 
     406    return peek(t)->value; 
     407} 
     408 
    406409/********************************* 
    407410 * tk is on the opening (. 
    408411 * Look ahead and return token that is past the closing ). 
     
    599602        case '"': 
    600603        t->value = escapeStringConstant(t,0); 
    601604        return; 
    602  
     605#if ! TEXTUAL_ASSEMBLY_OUT 
    603606        case '\\':          // escaped string literal 
    604607        {   unsigned c; 
     608        unsigned char *pstart = p; 
    605609 
    606610        stringbuffer.reset(); 
    607611        do 
     
    628632        memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); 
    629633        t->postfix = 0; 
    630634        t->value = TOKstring; 
     635        if (!global.params.useDeprecated) 
     636            error("Escape String literal %.*s is deprecated, use double quoted string literal \"%.*s\" instead", p - pstart, pstart, p - pstart, pstart); 
    631637        return; 
    632638        } 
    633  
     639#endif 
    634640        case 'l': 
    635641        case 'L': 
    636642#endif 
     
    12281234 */ 
    12291235 
    12301236unsigned Lexer::escapeSequence() 
    1231 {   unsigned c; 
     1237{   unsigned c = *p; 
     1238 
     1239#ifdef TEXTUAL_ASSEMBLY_OUT 
     1240    return c; 
     1241#endif 
    12321242    int n; 
    12331243    int ndigits; 
    12341244 
    1235     c = *p; 
    12361245    switch (c) 
    12371246    { 
    12381247    case '\'': 
     
    15871596        else 
    15881597        {   delimright = c; 
    15891598        nest = 0; 
     1599        if (isspace(c)) 
     1600            error("delimiter cannot be whitespace"); 
    15901601        } 
    15911602    } 
    15921603    else 
     
    16081619        } 
    16091620        else if (c == delimright) 
    16101621        goto Ldone; 
    1611         if (startline && isalpha(c)
     1622        if (startline && isalpha(c) && hereid
    16121623        {   Token t; 
    16131624        unsigned char *psave = p; 
    16141625        p--; 
     
    17171728    c = *p++; 
    17181729    switch (c) 
    17191730    { 
     1731#if !( TEXTUAL_ASSEMBLY_OUT ) 
    17201732        case '\\': 
    17211733        switch (*p) 
    17221734        { 
     
    17321744            break; 
    17331745        } 
    17341746        break; 
    1735  
     1747#endif 
    17361748        case '\n': 
    17371749        loc.linnum++; 
    17381750        break; 
     
    17931805    c = *p++; 
    17941806    switch (c) 
    17951807    { 
     1808#if ! TEXTUAL_ASSEMBLY_OUT 
    17961809    case '\\': 
    17971810        switch (*p) 
    17981811        { 
     
    18121825            break; 
    18131826        } 
    18141827        break; 
    1815  
     1828#endif 
    18161829    case '\n': 
    18171830    L1: 
    18181831        loc.linnum++; 
  • a/dmd2/lexer.h

    old new  
    278278 
    279279    TOK nextToken(); 
    280280    TOK peekNext(); 
     281    TOK peekNext2(); 
    281282    void scan(Token *t); 
    282283    Token *peek(Token *t); 
    283284    Token *peekPastParen(Token *t); 
  • a/dmd2/macro.c

    old new  
    1616#include <ctype.h> 
    1717#include <assert.h> 
    1818 
    19 #if IN_GCC || IN_LLVM 
    2019#include "mem.h" 
    21 #else 
    22 #if _WIN32 
    23 #include "..\root\mem.h" 
    24 #elif POSIX 
    25 #include "../root/mem.h" 
    26 #else 
    27 #error "fix this" 
    28 #endif 
    29 #endif 
     20#include "root.h" 
    3021 
    31 #include "root.h" 
    3222#include "macro.h" 
    3323 
    3424#define isidstart(c) (isalpha(c) || (c) == '_') 
  • a/dmd2/man.c

    old new  
    1  
    2 // Compiler implementation of the D programming language 
    3 // Copyright (c) 2008-2008 by Digital Mars 
    4 // All Rights Reserved 
    5 // written by Walter Bright 
    6 // http://www.digitalmars.com 
    7 // License for redistribution is by either the Artistic License 
    8 // in artistic.txt, or the GNU General Public License in gnu.txt. 
    9 // See the included readme.txt for details. 
    10  
    11 #include <stdio.h> 
    12 #include <string.h> 
    13 #include <stdlib.h> 
    14 #include <assert.h> 
    15  
    16 #if _WIN32 
    17  
    18 #include <windows.h> 
    19  
    20 #pragma comment(lib,"shell32.lib") 
    21  
    22 void browse(const char *url) 
    23 
    24     ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); 
    25 
    26  
    27 #endif 
    28  
    29 #if linux || __APPLE__ 
    30  
    31 #include    <sys/types.h> 
    32 #include    <sys/wait.h> 
    33 #include    <unistd.h> 
    34  
    35 void browse(const char *url) 
    36 
    37     pid_t childpid; 
    38     const char *args[3]; 
    39  
    40     const char *browser = getenv("BROWSER"); 
    41     if (browser) 
    42     browser = strdup(browser); 
    43     else 
    44     browser = "firefox"; 
    45  
    46     args[0] = browser; 
    47     args[1] = url; 
    48     args[2] = NULL; 
    49  
    50     childpid = fork(); 
    51     if (childpid == 0) 
    52     { 
    53     execvp(args[0], (char**)args); 
    54     perror(args[0]);        // failed to execute 
    55     return; 
    56     } 
    57 
    58  
    59 #endif 
    60  
     1 
     2// Compiler implementation of the D programming language 
     3// Copyright (c) 2008-2009 by Digital Mars 
     4// All Rights Reserved 
     5// written by Walter Bright 
     6// http://www.digitalmars.com 
     7// License for redistribution is by either the Artistic License 
     8// in artistic.txt, or the GNU General Public License in gnu.txt. 
     9// See the included readme.txt for details. 
     10 
     11#include <stdio.h> 
     12#include <string.h> 
     13#include <stdlib.h> 
     14#include <assert.h> 
     15 
     16#if _WIN32 
     17 
     18#include <windows.h> 
     19 
     20#pragma comment(lib,"shell32.lib") 
     21 
     22void browse(const char *url) 
     23
     24    ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); 
     25
     26 
     27#endif 
     28 
     29#if linux || __APPLE__ 
     30 
     31#include    <sys/types.h> 
     32#include    <sys/wait.h> 
     33#include    <unistd.h> 
     34 
     35void browse(const char *url) 
     36
     37    pid_t childpid; 
     38    const char *args[3]; 
     39 
     40    char *browser = getenv("BROWSER"); 
     41    if (browser) 
     42    browser = strdup(browser); 
     43    else 
     44    browser = "x-www-browser"; 
     45 
     46    args[0] = browser; 
     47    args[1] = url; 
     48    args[2] = NULL; 
     49 
     50    childpid = fork(); 
     51    if (childpid == 0) 
     52    { 
     53    execvp(args[0], (char**)args); 
     54    perror(args[0]);        // failed to execute 
     55    return; 
     56    } 
     57
     58 
     59#endif 
     60 
     61#if __APPLE__ 
     62 
     63#include    <sys/types.h> 
     64#include    <sys/wait.h> 
     65#include    <unistd.h> 
     66 
     67void browse(const char *url) 
     68
     69    pid_t childpid; 
     70    const char *args[5]; 
     71 
     72    char *browser = getenv("BROWSER"); 
     73    if (browser) 
     74    {   browser = strdup(browser); 
     75    args[0] = browser; 
     76    args[1] = url; 
     77    args[2] = NULL; 
     78    } 
     79    else 
     80    { 
     81    //browser = "/Applications/Safari.app/Contents/MacOS/Safari"; 
     82    args[0] = "open"; 
     83    args[1] = "-a"; 
     84    args[2] = "/Applications/Safari.app"; 
     85    args[3] = url; 
     86    args[4] = NULL; 
     87    } 
     88 
     89    childpid = fork(); 
     90    if (childpid == 0) 
     91    { 
     92    execvp(args[0], (char**)args); 
     93    perror(args[0]);        // failed to execute 
     94    return; 
     95    } 
     96
     97 
     98#endif 
     99 
     100 
     101#if __FreeBSD__ 
     102#endif 
  • a/dmd2/mangle.c

    old new  
    2424#include "id.h" 
    2525#include "module.h" 
    2626 
    27 #if TARGET_LINUX 
     27#if TARGET_LINUX || TARGET_OSX 
    2828char *cpp_mangle(Dsymbol *s); 
    2929#endif 
    3030 
     
    117117            return ident->toChars(); 
    118118 
    119119        case LINKcpp: 
    120 #if TARGET_LINUX 
     120#if DMDV2 && (TARGET_LINUX || TARGET_OSX) 
    121121            return cpp_mangle(this); 
    122122#else 
    123123            // Windows C++ mangling is done by C++ back end 
  • a/dmd2/mars.c

    old new  
    5959 
    6060    copyright = "Copyright (c) 1999-2009 by Digital Mars and Tomas Lindquist Olsen"; 
    6161    written = "written by Walter Bright and Tomas Lindquist Olsen"; 
    62     version = "v2.021"; 
     62    version = "v2.026"; 
    6363    ldc_version = LDC_REV; 
    6464    llvm_version = LLVM_REV; 
    6565    global.structalign = 8; 
     
    105105    va_end( ap ); 
    106106} 
    107107 
     108void warning(Loc loc, const char *format, ...) 
     109{ 
     110    if (global.params.warnings && !global.gag) 
     111    { 
     112    fprintf(stdmsg, "warning - "); 
     113    va_list ap; 
     114    va_start(ap, format); 
     115    verror(loc, format, ap); 
     116    va_end( ap ); 
     117    } 
     118} 
     119 
    108120void verror(Loc loc, const char *format, va_list ap) 
    109121{ 
    110122    if (!global.gag) 
     
    116128    mem.free(p); 
    117129 
    118130    fprintf(stdmsg, "Error: "); 
     131#if _MSC_VER 
     132    // MS doesn't recognize %zu format 
     133    OutBuffer tmp; 
     134    tmp.vprintf(format, ap); 
     135    fprintf(stdmsg, "%s", tmp.toChars()); 
     136#else 
    119137    vfprintf(stdmsg, format, ap); 
     138#endif 
    120139    fprintf(stdmsg, "\n"); 
    121140    fflush(stdmsg); 
    122141    } 
     
    136155    exit(EXIT_FAILURE); 
    137156} 
    138157 
    139 /************************************** 
    140  * Try to stop forgetting to remove the breakpoints from 
    141  * release builds. 
    142  */ 
    143 void halt() 
    144 { 
    145 #ifdef DEBUG 
    146     *(char*)0=0; 
    147 #endif 
    148 } 
    149  
    150158/*********************************** 
    151159 * Parse and append contents of environment variable envvar 
    152160 * to argc and argv[]. 
  • a/dmd2/mars.h

    old new  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2007 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
     
    1313 
    1414#ifdef __DMC__ 
    1515#pragma once 
    16 #endif /* __DMC__ */ 
     16#endif 
     17 
     18/* 
     19It is very important to use version control macros correctly - the 
     20idea is that host and target are independent. If these are done 
     21correctly, cross compilers can be built. 
     22The host compiler and host operating system are also different, 
     23and are predefined by the host compiler. The ones used in 
     24dmd are: 
     25 
     26Macros defined by the compiler, not the code: 
     27 
     28    Compiler: 
     29    __DMC__     Digital Mars compiler 
     30    _MSC_VER    Microsoft compiler 
     31    __GNUC__    Gnu compiler 
     32 
     33    Host operating system: 
     34    _WIN32      Microsoft NT, Windows 95, Windows 98, Win32s, 
     35            Windows 2000, Win XP, Vista 
     36    _WIN64      Windows for AMD64 
     37    linux       Linux 
     38    __APPLE__   Mac OSX 
     39 
     40For the target systems, there are the target operating system and 
     41the target object file format: 
     42 
     43    Target operating system: 
     44    TARGET_WINDOS   Covers 32 bit windows and 64 bit windows 
     45    TARGET_LINUX    Covers 32 and 64 bit linux 
     46    TARGET_OSX  Covers 32 and 64 bit Mac OSX 
     47 
     48    It is expected that the compiler for each platform will be able 
     49    to generate 32 and 64 bit code from the same compiler binary. 
     50 
     51    Target object module format: 
     52    OMFOBJ      Intel Object Module Format, used on Windows 
     53    ELFOBJ      Elf Object Module Format, used on linux 
     54    MACHOBJ     Mach-O Object Module Format, used on Mac OSX 
     55 
     56    There are currently no macros for byte endianness order. 
     57 */ 
     58 
    1759 
    1860#include <stdint.h> 
    1961#include <stdarg.h> 
     
    3476#endif 
    3577 
    3678#define BREAKABI 1  // 0 if not ready to break the ABI just yet 
    37 #define STRUCTTHISREF V2    // if 'this' for struct is a reference, not a pointer 
     79#define STRUCTTHISREF 1    // if 'this' for struct is a reference, not a pointer 
     80 
     81/* Other targets are TARGET_LINUX and TARGET_OSX, which are 
     82 * set on the command line via the compiler makefile. 
     83 */ 
     84 
     85#if _WIN32 
     86#define TARGET_WINDOS 1     // Windows dmd generates Windows targets 
     87#define OMFOBJ 1 
     88#endif 
     89 
     90#if TARGET_LINUX 
     91#ifndef ELFOBJ 
     92#define ELFOBJ 1 
     93#endif 
     94#endif 
     95 
     96#if TARGET_OSX 
     97#ifndef MACHOBJ 
     98#define MACHOBJ 1 
     99#endif 
     100#endif 
     101 
    38102 
    39103struct Array; 
    40104 
     
    67131}; 
    68132 
    69133// make it easier to test new linkage types 
    70 #define TEMPLATE_LINKAGE_TYPE   llvm::GlobalValue::LinkOnceLinkage 
    71 #define TYPEINFO_LINKAGE_TYPE   llvm::GlobalValue::LinkOnceLinkage 
     134#define TEMPLATE_LINKAGE_TYPE   llvm::GlobalValue::LinkOnceAnyLinkage 
     135#define TYPEINFO_LINKAGE_TYPE   llvm::GlobalValue::LinkOnceAnyLinkage 
    72136 
    73137// Put command line switches in here 
    74138struct Param 
     
    338402    MATCHexact      // exact match 
    339403}; 
    340404 
     405void warning(Loc loc, const char *format, ...); 
    341406void error(Loc loc, const char *format, ...); 
    342407void verror(Loc loc, const char *format, va_list); 
    343408void fatal(); 
  • a/dmd2/module.c

    old new  
    8484#ifdef IN_GCC 
    8585    strictlyneedmoduleinfo = 0; 
    8686#endif 
     87    selfimports = 0; 
    8788    insearch = 0; 
    8889    searchCacheIdent = NULL; 
    8990    searchCacheSymbol = NULL; 
     
    145146    this->doHdrGen = doHdrGen; 
    146147} 
    147148 
    148 File* Module::buildFilePath(char* forcename, const char* path, const char* ext) 
     149File* Module::buildFilePath(char* forcename, char* path, char* ext) 
    149150{ 
    150151    char *argobj; 
    151152    if (forcename) 
     
    903904    //printf("-Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim); 
    904905} 
    905906 
     907/************************************ 
     908 * Recursively look at every module this module imports, 
     909 * return TRUE if it imports m. 
     910 * Can be used to detect circular imports. 
     911 */ 
     912 
     913int Module::imports(Module *m) 
     914{ 
     915    //printf("%s Module::imports(%s)\n", toChars(), m->toChars()); 
     916    int aimports_dim = aimports.dim; 
     917#if 0 
     918    for (int i = 0; i < aimports.dim; i++) 
     919    {   Module *mi = (Module *)aimports.data[i]; 
     920    printf("\t[%d] %s\n", i, mi->toChars()); 
     921    } 
     922#endif 
     923    for (int i = 0; i < aimports.dim; i++) 
     924    {   Module *mi = (Module *)aimports.data[i]; 
     925    if (mi == m) 
     926        return TRUE; 
     927    if (!mi->insearch) 
     928    { 
     929        mi->insearch = 1; 
     930        int r = mi->imports(m); 
     931        if (r) 
     932        return r; 
     933    } 
     934    } 
     935    return FALSE; 
     936} 
     937 
     938/************************************* 
     939 * Return !=0 if module imports itself. 
     940 */ 
     941 
     942int Module::selfImports() 
     943{ 
     944    //printf("Module::selfImports() %s\n", toChars()); 
     945    if (!selfimports) 
     946    { 
     947    for (int i = 0; i < amodules.dim; i++) 
     948    {   Module *mi = (Module *)amodules.data[i]; 
     949        //printf("\t[%d] %s\n", i, mi->toChars()); 
     950        mi->insearch = 0; 
     951    } 
     952 
     953    selfimports = imports(this) + 1; 
     954 
     955    for (int i = 0; i < amodules.dim; i++) 
     956    {   Module *mi = (Module *)amodules.data[i]; 
     957        //printf("\t[%d] %s\n", i, mi->toChars()); 
     958        mi->insearch = 0; 
     959    } 
     960    } 
     961    return selfimports - 1; 
     962} 
     963 
     964 
    906965/* =========================== ModuleDeclaration ===================== */ 
    907966 
    908967ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id, bool safe) 
  • a/dmd2/module.h

    old new  
    3030#if IN_LLVM 
    3131struct DValue; 
    3232typedef DValue elem; 
     33namespace llvm { class Module; } 
    3334#else 
    3435#ifdef IN_GCC 
    3536union tree_node; typedef union tree_node elem; 
     
    7980    int strictlyneedmoduleinfo; 
    8081#endif 
    8182 
     83    int selfimports;        // 0: don't know, 1: does not, 2: does 
     84    int selfImports();      // returns !=0 if module imports itself 
     85 
    8286    int insearch; 
    8387    Identifier *searchCacheIdent; 
    8488    Dsymbol *searchCacheSymbol; // cached value of search 
     
    143147    void deleteObjFile(); 
    144148    void addDeferredSemantic(Dsymbol *s); 
    145149    void runDeferredSemantic(); 
     150    int imports(Module *m); 
    146151 
    147152    // Back end 
    148153 
     
    172177    void genmoduleinfo(); 
    173178 
    174179    // LDC 
     180    llvm::Module* genLLVMModule(int multiobj); 
    175181    void buildTargetFiles(); 
    176     File* buildFilePath(char* forcename, const char* path, const char* ext); 
     182    File* buildFilePath(char* forcename, char* path, char* ext); 
    177183    Module *isModule() { return this; } 
    178184     
    179185    bool llvmForceLogging; 
  • a/dmd2/mtype.c

    old new  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2008 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
     
    106106ClassDeclaration *Type::typeinfotypelist; 
    107107ClassDeclaration *Type::typeinfoconst; 
    108108ClassDeclaration *Type::typeinfoinvariant; 
     109ClassDeclaration *Type::typeinfoshared; 
    109110 
    110111Type *Type::tvoidptr; 
    111112Type *Type::basic[TMAX]; 
     
    122123#if DMDV2 
    123124    this->cto = NULL; 
    124125    this->ito = NULL; 
     126    this->sto = NULL; 
     127    this->scto = NULL; 
    125128#endif 
    126129    this->pto = NULL; 
    127130    this->rto = NULL; 
     
    327330    return MATCHnomatch; 
    328331} 
    329332 
     333/******************************** 
     334 * Convert to 'const'. 
     335 */ 
     336 
    330337Type *Type::constOf() 
    331338{ 
     339#if 0 
    332340    //printf("Type::constOf() %p %s\n", this, toChars()); 
    333341    if (isConst()) 
    334342    return this; 
     
    342350    //if (t->nextOf()) assert(t->nextOf()->isConst()); 
    343351    //printf("-Type::constOf() %p %s\n", t, toChars()); 
    344352    return t; 
    345 
     353#else 
     354    //printf("Type::constOf() %p %s\n", this, toChars()); 
     355    if (mod == MODconst) 
     356    return this; 
     357    if (cto) 
     358    {   assert(cto->mod == MODconst); 
     359    return cto; 
     360    } 
     361    Type *t = makeConst(); 
     362    t = t->merge(); 
     363    t->fixTo(this); 
     364    //printf("-Type::constOf() %p %s\n", t, toChars()); 
     365    return t; 
     366#endif 
     367
     368 
     369/******************************** 
     370 * Convert to 'immutable'. 
     371 */ 
    346372 
    347373Type *Type::invariantOf() 
    348374{ 
     375#if 0 
    349376    //printf("Type::invariantOf() %p %s\n", this, toChars()); 
    350377    if (isInvariant()) 
    351378    { 
     
    370397#endif 
    371398    //printf("\t%p\n", t); 
    372399    return t; 
    373 
     400#else 
     401    //printf("Type::invariantOf() %p %s\n", this, toChars()); 
     402    if (isInvariant()) 
     403    { 
     404    return this; 
     405    } 
     406    if (ito) 
     407    { 
     408    assert(ito->isInvariant()); 
     409    return ito; 
     410    } 
     411    Type *t = makeInvariant(); 
     412    t = t->merge(); 
     413    t->fixTo(this); 
     414    //printf("\t%p\n", t); 
     415    return t; 
     416#endif 
     417
     418 
     419/******************************** 
     420 * Make type mutable. 
     421 */ 
    374422 
    375423Type *Type::mutableOf() 
    376424{ 
     425#if 0 
    377426    //printf("Type::mutableOf() %p, %s\n", this, toChars()); 
    378427    Type *t = this; 
    379428    if (isConst()) 
     
    396445    t->rto = NULL; 
    397446    t->cto = NULL; 
    398447    t->ito = NULL; 
     448    t->sto = NULL; 
     449    t->scto = NULL; 
    399450    t->vtinfo = NULL; 
    400451    if (ty == Tsarray) 
    401452    {   TypeSArray *ta = (TypeSArray *)t; 
     
    416467    } 
    417468    } 
    418469    return t; 
     470#else 
     471    //printf("Type::mutableOf() %p, %s\n", this, toChars()); 
     472    Type *t = this; 
     473    if (isConst()) 
     474    {   if (isShared()) 
     475        t = sto;        // shared const => shared 
     476    else 
     477        t = cto; 
     478    assert(!t || t->isMutable()); 
     479    } 
     480    else if (isInvariant()) 
     481    {   t = ito; 
     482    assert(!t || (t->isMutable() && !t->isShared())); 
     483    } 
     484    if (!t) 
     485    { 
     486    unsigned sz = sizeTy[ty]; 
     487    t = (Type *)mem.malloc(sz); 
     488    memcpy(t, this, sz); 
     489    t->mod = 0; 
     490    t->deco = NULL; 
     491    t->arrayof = NULL; 
     492    t->pto = NULL; 
     493    t->rto = NULL; 
     494    t->cto = NULL; 
     495    t->ito = NULL; 
     496    t->sto = NULL; 
     497    t->scto = NULL; 
     498    t->vtinfo = NULL; 
     499    t = t->merge(); 
     500 
     501    t->fixTo(this); 
     502 
     503    switch (mod) 
     504    { 
     505        case MODconst: 
     506        t->cto = this; 
     507        break; 
     508 
     509        case MODinvariant: 
     510        t->ito = this; 
     511        break; 
     512 
     513        case MODshared: 
     514        t->sto = this; 
     515        break; 
     516 
     517        case MODshared | MODconst: 
     518        t->scto = this; 
     519        break; 
     520 
     521        default: 
     522        assert(0); 
     523    } 
     524    } 
     525    return t; 
     526#endif 
     527} 
     528 
     529Type *Type::sharedOf() 
     530{ 
     531    //printf("Type::sharedOf() %p, %s\n", this, toChars()); 
     532    if (mod == MODshared) 
     533    { 
     534    return this; 
     535    } 
     536    if (sto) 
     537    { 
     538    assert(sto->isShared()); 
     539    return sto; 
     540    } 
     541    Type *t = makeShared(); 
     542    t = t->merge(); 
     543    t->fixTo(this); 
     544    //printf("\t%p\n", t); 
     545    return t; 
     546} 
     547 
     548Type *Type::sharedConstOf() 
     549{ 
     550    //printf("Type::sharedConstOf() %p, %s\n", this, toChars()); 
     551    if (mod == (MODshared | MODconst)) 
     552    { 
     553    return this; 
     554    } 
     555    if (scto) 
     556    { 
     557    assert(scto->mod == (MODshared | MODconst)); 
     558    return scto; 
     559    } 
     560    Type *t = makeSharedConst(); 
     561    t = t->merge(); 
     562    t->fixTo(this); 
     563    //printf("\t%p\n", t); 
     564    return t; 
     565} 
     566 
     567 
     568/********************************** 
     569 * For our new type 'this', which is type-constructed from t, 
     570 * fill in the cto, ito, sto, scto shortcuts. 
     571 */ 
     572 
     573void Type::fixTo(Type *t) 
     574{ 
     575    ito = t->ito; 
     576#if 0 
     577    /* Cannot do these because these are not fully transitive: 
     578     * there can be a shared ptr to immutable, for example. 
     579     * Immutable subtypes are always immutable, though. 
     580     */ 
     581    cto = t->cto; 
     582    sto = t->sto; 
     583    scto = t->scto; 
     584#endif 
     585 
     586    assert(mod != t->mod); 
     587#define X(m, n) (((m) << 3) | (n)) 
     588    switch (X(mod, t->mod)) 
     589    { 
     590    case X(0, MODconst): 
     591        cto = t; 
     592        break; 
     593 
     594    case X(0, MODinvariant): 
     595        ito = t; 
     596        break; 
     597 
     598    case X(0, MODshared): 
     599        sto = t; 
     600        break; 
     601 
     602    case X(0, MODshared | MODconst): 
     603        scto = t; 
     604        break; 
     605 
     606 
     607    case X(MODconst, 0): 
     608        cto = NULL; 
     609        goto L2; 
     610 
     611    case X(MODconst, MODinvariant): 
     612        ito = t; 
     613        goto L2; 
     614 
     615    case X(MODconst, MODshared): 
     616        sto = t; 
     617        goto L2; 
     618 
     619    case X(MODconst, MODshared | MODconst): 
     620        scto = t; 
     621    L2: 
     622        t->cto = this; 
     623        break; 
     624 
     625 
     626    case X(MODinvariant, 0): 
     627        ito = NULL; 
     628        goto L3; 
     629 
     630    case X(MODinvariant, MODconst): 
     631        cto = t; 
     632        goto L3; 
     633 
     634    case X(MODinvariant, MODshared): 
     635        sto = t; 
     636        goto L3; 
     637 
     638    case X(MODinvariant, MODshared | MODconst): 
     639        scto = t; 
     640    L3: 
     641        t->ito = this; 
     642        if (t->cto) t->cto->ito = this; 
     643        if (t->sto) t->sto->ito = this; 
     644        if (t->scto) t->scto->ito = this; 
     645        break; 
     646 
     647 
     648    case X(MODshared, 0): 
     649        sto = NULL; 
     650        goto L4; 
     651 
     652    case X(MODshared, MODconst): 
     653        cto = t; 
     654        goto L4; 
     655 
     656    case X(MODshared, MODinvariant): 
     657        ito = t; 
     658        goto L4; 
     659 
     660    case X(MODshared, MODshared | MODconst): 
     661        scto = t; 
     662    L4: 
     663        t->sto = this; 
     664        break; 
     665 
     666 
     667    case X(MODshared | MODconst, 0): 
     668        scto = NULL; 
     669        break; 
     670 
     671    case X(MODshared | MODconst, MODconst): 
     672        cto = t; 
     673        break; 
     674 
     675    case X(MODshared | MODconst, MODinvariant): 
     676        ito = t; 
     677        break; 
     678 
     679    case X(MODshared | MODconst, MODshared): 
     680        sto = t; 
     681    L5: 
     682        t->scto = this; 
     683        break; 
     684 
     685    default: 
     686        assert(0); 
     687    } 
     688#undef X 
     689 
     690    check(); 
     691    t->check(); 
     692    //printf("fixTo: %s, %s\n", toChars(), t->toChars()); 
     693} 
     694 
     695/*************************** 
     696 * Look for bugs in constructing types. 
     697 */ 
     698 
     699void Type::check() 
     700{ 
     701    switch (mod) 
     702    { 
     703    case 0: 
     704        if (cto) assert(cto->mod == MODconst); 
     705        if (ito) assert(ito->mod == MODinvariant); 
     706        if (sto) assert(sto->mod == MODshared); 
     707        if (scto) assert(scto->mod == (MODshared | MODconst)); 
     708        break; 
     709 
     710    case MODconst: 
     711        if (cto) assert(cto->mod == 0); 
     712        if (ito) assert(ito->mod == MODinvariant); 
     713        if (sto) assert(sto->mod == MODshared); 
     714        if (scto) assert(scto->mod == (MODshared | MODconst)); 
     715        break; 
     716 
     717    case MODinvariant: 
     718        if (cto) assert(cto->mod == MODconst); 
     719        if (ito) assert(ito->mod == 0); 
     720        if (sto) assert(sto->mod == MODshared); 
     721        if (scto) assert(scto->mod == (MODshared | MODconst)); 
     722        break; 
     723 
     724    case MODshared: 
     725        if (cto) assert(cto->mod == MODconst); 
     726        if (ito) assert(ito->mod == MODinvariant); 
     727        if (sto) assert(sto->mod == 0); 
     728        if (scto) assert(scto->mod == (MODshared | MODconst)); 
     729        break; 
     730 
     731    case MODshared | MODconst: 
     732        if (cto) assert(cto->mod == MODconst); 
     733        if (ito) assert(ito->mod == MODinvariant); 
     734        if (sto) assert(sto->mod == MODshared); 
     735        if (scto) assert(scto->mod == 0); 
     736        break; 
     737 
     738    default: 
     739        assert(0); 
     740    } 
     741 
     742    Type *tn = nextOf(); 
     743    if (tn && ty != Tfunction && ty != Tdelegate) 
     744    {   // Verify transitivity 
     745    switch (mod) 
     746    { 
     747        case 0: 
     748        break; 
     749 
     750        case MODconst: 
     751        assert(tn->mod & MODinvariant || tn->mod & MODconst); 
     752        break; 
     753 
     754        case MODinvariant: 
     755        assert(tn->mod == MODinvariant); 
     756        break; 
     757 
     758        case MODshared: 
     759        assert(tn->mod & MODinvariant || tn->mod & MODshared); 
     760        break; 
     761 
     762        case MODshared | MODconst: 
     763        assert(tn->mod & MODinvariant || tn->mod & (MODshared | MODconst)); 
     764        break; 
     765 
     766        default: 
     767        assert(0); 
     768    } 
     769    tn->check(); 
     770    } 
    419771} 
    420772 
    421773Type *Type::makeConst() 
     
    433785    t->rto = NULL; 
    434786    t->cto = NULL; 
    435787    t->ito = NULL; 
     788    t->sto = NULL; 
     789    t->scto = NULL; 
    436790    t->vtinfo = NULL; 
    437791    //printf("-Type::makeConst() %p, %s\n", t, toChars()); 
    438792    return t; 
     
    452806    t->rto = NULL; 
    453807    t->cto = NULL; 
    454808    t->ito = NULL; 
     809    t->sto = NULL; 
     810    t->scto = NULL; 
    455811    t->vtinfo = NULL; 
    456812    return t; 
    457813} 
    458814 
     815Type *Type::makeShared() 
     816{ 
     817    if (sto) 
     818    return sto; 
     819    unsigned sz = sizeTy[ty]; 
     820    Type *t = (Type *)mem.malloc(sz); 
     821    memcpy(t, this, sz); 
     822    t->mod = MODshared; 
     823    t->deco = NULL; 
     824    t->arrayof = NULL; 
     825    t->pto = NULL; 
     826    t->rto = NULL; 
     827    t->cto = NULL; 
     828    t->ito = NULL; 
     829    t->sto = NULL; 
     830    t->scto = NULL; 
     831    t->vtinfo = NULL; 
     832    return t; 
     833} 
     834 
     835Type *Type::makeSharedConst() 
     836{ 
     837    if (scto) 
     838    return scto; 
     839    unsigned sz = sizeTy[ty]; 
     840    Type *t = (Type *)mem.malloc(sz); 
     841    memcpy(t, this, sz); 
     842    t->mod = MODshared | MODconst; 
     843    t->deco = NULL; 
     844    t->arrayof = NULL; 
     845    t->pto = NULL; 
     846    t->rto = NULL; 
     847    t->cto = NULL; 
     848    t->ito = NULL; 
     849    t->sto = NULL; 
     850    t->scto = NULL; 
     851    t->vtinfo = NULL; 
     852    return t; 
     853} 
     854 
     855/************************************ 
     856 * Apply MODxxxx bits to existing type. 
     857 */ 
     858 
     859Type *Type::castMod(unsigned mod) 
     860{   Type *t; 
     861 
     862    switch (mod) 
     863    { 
     864    case 0: 
     865        t = mutableOf(); 
     866        break; 
     867 
     868    case MODconst: 
     869        t = constOf(); 
     870        break; 
     871 
     872    case MODinvariant: 
     873        t = invariantOf(); 
     874        break; 
     875 
     876    case MODshared: 
     877        t = sharedOf(); 
     878        break; 
     879 
     880    case MODshared | MODconst: 
     881        t = sharedConstOf(); 
     882        break; 
     883 
     884    default: 
     885        assert(0); 
     886    } 
     887    return t; 
     888} 
     889 
     890/************************************ 
     891 * Add MODxxxx bits to existing type. 
     892 * We're adding, not replacing, so adding const to 
     893 * a shared type => "shared const" 
     894 */ 
     895 
     896Type *Type::addMod(unsigned mod) 
     897{   Type *t = this; 
     898 
     899    /* Add anything to immutable, and it remains immutable 
     900     */ 
     901    if (!t->isInvariant()) 
     902    { 
     903    switch (mod) 
     904    { 
     905        case 0: 
     906        break; 
     907 
     908        case MODconst: 
     909        if (isShared()) 
     910            t = sharedConstOf(); 
     911        else 
     912            t = constOf(); 
     913        break; 
     914 
     915        case MODinvariant: 
     916        t = invariantOf(); 
     917        break; 
     918 
     919        case MODshared: 
     920        if (isConst()) 
     921            t = sharedConstOf(); 
     922        else 
     923            t = sharedOf(); 
     924        break; 
     925 
     926        case MODshared | MODconst: 
     927        t = sharedConstOf(); 
     928        break; 
     929 
     930        default: 
     931        assert(0); 
     932    } 
     933    } 
     934    return t; 
     935} 
     936 
     937/************************************ 
     938 * Add storage class modifiers to type. 
     939 */ 
     940 
     941Type *Type::addStorageClass(unsigned stc) 
     942{ 
     943    /* Just translate to MOD bits and let addMod() do the work 
     944     */ 
     945    unsigned mod = 0; 
     946 
     947    if (stc & STCinvariant) 
     948    mod = MODinvariant; 
     949    else 
     950    {   if (stc & (STCconst | STCin)) 
     951        mod = MODconst; 
     952    if (stc & STCshared) 
     953        mod |= MODshared; 
     954    } 
     955    return addMod(mod); 
     956} 
     957 
    459958/************************** 
    460959 * Return type with the top level of it being mutable. 
    461960 */ 
     
    5851084        p = "const("; 
    5861085        goto L1; 
    5871086        case MODinvariant: 
    588         p = "invariant("; 
     1087        p = "immutable("; 
    5891088        L1: buf->writestring(p); 
    5901089        toCBuffer2(buf, hgs, this->mod); 
    5911090        buf->writeByte(')'); 
     
    8961395    va_end( ap ); 
    8971396} 
    8981397 
     1398void Type::warning(Loc loc, const char *format, ...) 
     1399{ 
     1400    if (global.params.warnings && !global.gag) 
     1401    { 
     1402    fprintf(stdmsg, "warning - "); 
     1403    va_list ap; 
     1404    va_start(ap, format); 
     1405    ::verror(loc, format, ap); 
     1406    va_end( ap ); 
     1407    } 
     1408} 
     1409 
    8991410Identifier *Type::getTypeInfoIdent(int internal) 
    9001411{ 
    9011412    // _init_10TypeInfo_%s 
     
    10161527{ 
    10171528    //printf("TypeNext::makeConst() %p, %s\n", this, toChars()); 
    10181529    if (cto) 
     1530    {   assert(cto->mod == MODconst); 
    10191531    return cto; 
     1532    } 
    10201533    TypeNext *t = (TypeNext *)Type::makeConst(); 
    10211534    if (ty != Tfunction && ty != Tdelegate && next->deco && 
    1022         !next->isInvariant()) 
    1023     t->next = next->constOf(); 
     1535        !next->isInvariant() && !next->isConst()) 
     1536    {   if (next->isShared()) 
     1537        t->next = next->sharedConstOf(); 
     1538    else 
     1539        t->next = next->constOf(); 
     1540    } 
    10241541    //printf("TypeNext::makeConst() returns %p, %s\n", t, t->toChars()); 
    10251542    return t; 
    10261543} 
     
    10331550    return ito; 
    10341551    } 
    10351552    TypeNext *t = (TypeNext *)Type::makeInvariant(); 
    1036     if (ty != Tfunction && ty != Tdelegate && next->deco) 
     1553    if (ty != Tfunction && ty != Tdelegate && next->deco && 
     1554    !next->isInvariant()) 
    10371555    {   t->next = next->invariantOf(); 
    10381556    } 
    10391557    return t; 
    10401558} 
    10411559 
     1560Type *TypeNext::makeShared() 
     1561{ 
     1562    //printf("TypeNext::makeShared() %s\n", toChars()); 
     1563    if (sto) 
     1564    {   assert(sto->mod == MODshared); 
     1565    return sto; 
     1566    } 
     1567    TypeNext *t = (TypeNext *)Type::makeShared(); 
     1568    if (ty != Tfunction && ty != Tdelegate && next->deco && 
     1569        !next->isInvariant() && !next->isShared()) 
     1570    { 
     1571    if (next->isConst()) 
     1572        t->next = next->sharedConstOf(); 
     1573    else 
     1574        t->next = next->sharedOf(); 
     1575    } 
     1576    //printf("TypeNext::makeShared() returns %p, %s\n", t, t->toChars()); 
     1577    return t; 
     1578} 
     1579 
     1580Type *TypeNext::makeSharedConst() 
     1581{ 
     1582    //printf("TypeNext::makeSharedConst() %s\n", toChars()); 
     1583    if (scto) 
     1584    {   assert(scto->mod == (MODshared | MODconst)); 
     1585    return scto; 
     1586    } 
     1587    TypeNext *t = (TypeNext *)Type::makeSharedConst(); 
     1588    if (ty != Tfunction && ty != Tdelegate && next->deco && 
     1589        !next->isInvariant() && !next->isSharedConst()) 
     1590    { 
     1591    t->next = next->sharedConstOf(); 
     1592    } 
     1593    //printf("TypeNext::makeSharedConst() returns %p, %s\n", t, t->toChars()); 
     1594    return t; 
     1595} 
     1596 
    10421597MATCH TypeNext::constConv(Type *to) 
    10431598{   MATCH m = Type::constConv(to); 
    10441599 
     
    10491604} 
    10501605 
    10511606 
     1607void TypeNext::transitive() 
     1608{ 
     1609    /* Invoke transitivity of type attributes 
     1610     */ 
     1611    next = next->addMod(mod); 
     1612} 
     1613 
    10521614/* ============================= TypeBasic =========================== */ 
    10531615 
    10541616TypeBasic::TypeBasic(TY ty) 
     
    12351797    if (ty == Tvoid) 
    12361798        return 1; 
    12371799    return getABITypeAlign(DtoType(this)); 
     1800#if TARGET_OSX 
     1801        sz = 16; 
     1802#else 
     1803#endif 
    12381804} 
    12391805 
    12401806 
     
    18692435    if (ident == Id::idup) 
    18702436    {   Type *einv = next->invariantOf(); 
    18712437        if (next->implicitConvTo(einv) < MATCHconst) 
    1872         error(e->loc, "cannot implicitly convert element type %s to invariant", next->toChars()); 
     2438        error(e->loc, "cannot implicitly convert element type %s to immutable", next->toChars()); 
    18732439        e->type = einv->arrayOf(); 
    18742440    } 
    18752441    else 
     
    20952661    } 
    20962662 
    20972663    next = next->semantic(loc,sc); 
    2098     if (mod == MODconst && !next->isInvariant()) 
    2099     next = next->constOf(); 
    2100     else if (mod == MODinvariant) 
    2101     next = next->invariantOf(); 
     2664    transitive(); 
    21022665 
    21032666    Type *tbn = next->toBasetype(); 
    21042667 
     
    21642727        Argument *arg = (Argument *)tt->arguments->data[(size_t)d]; 
    21652728        return arg->type; 
    21662729    } 
     2730    case Tstruct: 
     2731    {   TypeStruct *ts = (TypeStruct *)tbn; 
     2732        if (ts->sym->isnested) 
     2733        error(loc, "cannot have array of inner structs %s", ts->toChars()); 
     2734        break; 
     2735    } 
    21672736    case Tfunction: 
    21682737    case Tnone: 
    21692738        error(loc, "can't have array of %s", tbn->toChars()); 
     
    23752944        error(loc, "can't have array of %s", tbn->toChars()); 
    23762945        tn = next = tint32; 
    23772946        break; 
     2947    case Tstruct: 
     2948    {   TypeStruct *ts = (TypeStruct *)tbn; 
     2949        if (ts->sym->isnested) 
     2950        error(loc, "cannot have array of inner structs %s", ts->toChars()); 
     2951        break; 
     2952    } 
    23782953    } 
    23792954    if (tn->isauto()) 
    23802955    error(loc, "cannot have array of auto %s", tn->toChars()); 
    23812956 
    2382     if (mod == MODconst && !tn->isInvariant()) 
    2383     tn = tn->constOf(); 
    2384     else if (mod == MODinvariant) 
    2385     tn = tn->invariantOf(); 
    2386  
    23872957    next = tn; 
     2958    transitive(); 
    23882959    return merge(); 
    23892960} 
    23902961 
     
    25853156    if (index->nextOf() && !index->nextOf()->isInvariant()) 
    25863157    { 
    25873158    index = index->constOf()->mutableOf(); 
     3159#if 0 
     3160printf("index is %p %s\n", index, index->toChars()); 
     3161index->check(); 
     3162printf("index->mod = x%x\n", index->mod); 
     3163printf("index->ito = x%x\n", index->ito); 
     3164if (index->ito) { 
     3165printf("index->ito->mod = x%x\n", index->ito->mod); 
     3166printf("index->ito->ito = x%x\n", index->ito->ito); 
     3167} 
     3168#endif 
    25883169    } 
    25893170 
    25903171    switch (index->toBasetype()->ty) 
     
    25973178        break; 
    25983179    } 
    25993180    next = next->semantic(loc,sc); 
    2600     if (mod == MODconst && !next->isInvariant()) 
    2601     next = next->constOf(); 
    2602     else if (mod == MODinvariant) 
    2603     next = next->invariantOf(); 
     3181    transitive(); 
    26043182 
    26053183    switch (next->toBasetype()->ty) 
    26063184    { 
     
    28653443    if (n != next) 
    28663444    deco = NULL; 
    28673445    next = n; 
    2868     if (mod == MODconst && !next->isInvariant()) 
    2869     next = next->constOf(); 
    2870