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, 15 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     else if (mod == MODinvariant) 
    2871     next = next->invariantOf(); 
     3446    transitive(); 
    28723447    return merge(); 
    28733448} 
    28743449 
     
    29813556    if (n != next) 
    29823557    deco = NULL; 
    29833558    next = n; 
    2984     if (mod == MODconst && !next->isInvariant()) 
    2985     next = next->constOf(); 
    2986     else if (mod == MODinvariant) 
    2987     next = next->invariantOf(); 
     3559    transitive(); 
    29883560    return merge(); 
    29893561} 
    29903562 
     
    30463618    this->ispure = false; 
    30473619    this->isref = false; 
    30483620 
    3049     // LDC 
    3050     this->fty = NULL; 
    30513621} 
    30523622 
    30533623Type *TypeFunction::syntaxCopy() 
     
    32293799 
    32303800void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs) 
    32313801{ 
    3232     //printf("TypeFunction::toCBuffer() this = %p %s\n", this, toChars()); 
     3802    //printf("TypeFunction::toCBuffer() this = %p\n", this); 
    32333803    const char *p = NULL; 
    32343804 
    32353805    if (inuse) 
     
    32433813    if (mod & MODconst) 
    32443814    buf->writestring("const "); 
    32453815    if (mod & MODinvariant) 
    3246     buf->writestring("invariant "); 
     3816    buf->writestring("immutable "); 
    32473817    if (mod & MODshared) 
    32483818    buf->writestring("shared "); 
    32493819 
     
    32863856 
    32873857void TypeFunction::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 
    32883858{ 
    3289     //printf("TypeFunction::toCBuffer2() this = %p %s\n", this, toChars()); 
     3859    //printf("TypeFunction::toCBuffer2() this = %p, ref = %d\n", this, isref); 
    32903860    const char *p = NULL; 
    32913861 
    32923862    if (inuse) 
     
    33483918    return this; 
    33493919    } 
    33503920    //printf("TypeFunction::semantic() this = %p\n", this); 
     3921    //printf("TypeFunction::semantic() %s, sc->stc = %x\n", toChars(), sc->stc); 
    33513922 
    33523923    TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction)); 
    33533924    memcpy(tf, this, sizeof(TypeFunction)); 
     
    33883959    tf->next = Type::terror; 
    33893960    } 
    33903961    if (tf->next->isauto() && !(sc->flags & SCOPEctor)) 
    3391     error(loc, "functions cannot return auto %s", tf->next->toChars()); 
     3962    error(loc, "functions cannot return scope %s", tf->next->toChars()); 
    33923963 
    33933964    if (tf->parameters) 
    33943965    {   size_t dim = Argument::dim(tf->parameters); 
     
    34003971        arg->type = arg->type->semantic(loc,sc); 
    34013972        if (tf->inuse == 1) tf->inuse--; 
    34023973 
    3403         if (arg->storageClass & (STCconst | STCin)) 
    3404         { 
    3405         if (!arg->type->isInvariant()) 
    3406             arg->type = arg->type->constOf(); 
    3407         } 
    3408         else if (arg->storageClass & STCinvariant) 
    3409         arg->type = arg->type->invariantOf(); 
     3974        arg->type = arg->type->addStorageClass(arg->storageClass); 
    34103975 
    34113976        if (arg->storageClass & (STCauto | STCalias | STCstatic)) 
    34123977        { 
     
    40504615    //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars()); 
    40514616    s = sc->search(loc, ident, &scopesym); 
    40524617    resolveHelper(loc, sc, s, scopesym, pe, pt, ps); 
    4053     if (*pt && mod) 
    4054     { 
    4055     if (mod & MODconst) 
    4056         *pt = (*pt)->constOf(); 
    4057     else if (mod & MODinvariant) 
    4058         *pt = (*pt)->invariantOf(); 
    4059     } 
     4618    if (*pt) 
     4619    (*pt) = (*pt)->addMod(mod); 
    40604620} 
    40614621 
    40624622/***************************************** 
     
    41064666        if (tt->sym->sem == 1) 
    41074667        error(loc, "circular reference of typedef %s", tt->toChars()); 
    41084668    } 
    4109     if (isConst()) 
    4110         t = t->constOf(); 
    4111     else if (isInvariant()) 
    4112         t = t->invariantOf(); 
     4669    t = t->addMod(mod); 
    41134670    } 
    41144671    else 
    41154672    { 
     
    42004757    if (s) 
    42014758    s->semantic(sc); 
    42024759    resolveHelper(loc, sc, s, NULL, pe, pt, ps); 
    4203     if (*pt && mod) 
    4204     { 
    4205     if (mod & MODconst) 
    4206         *pt = (*pt)->constOf(); 
    4207     else if (mod & MODinvariant) 
    4208         *pt = (*pt)->invariantOf(); 
    4209     } 
     4760    if (*pt) 
     4761    *pt = (*pt)->addMod(mod); 
    42104762    //printf("pt = '%s'\n", (*pt)->toChars()); 
    42114763} 
    42124764 
     
    42464798    return t; 
    42474799} 
    42484800 
     4801Dsymbol *TypeInstance::toDsymbol(Scope *sc) 
     4802{ 
     4803    Type *t; 
     4804    Expression *e; 
     4805    Dsymbol *s; 
     4806 
     4807    //printf("TypeInstance::semantic(%s)\n", toChars()); 
     4808 
     4809    if (sc->parameterSpecialization) 
     4810    { 
     4811    unsigned errors = global.errors; 
     4812    global.gag++; 
     4813 
     4814    resolve(loc, sc, &e, &t, &s); 
     4815 
     4816    global.gag--; 
     4817    if (errors != global.errors) 
     4818    {   if (global.gag == 0) 
     4819        global.errors = errors; 
     4820        return NULL; 
     4821    } 
     4822    } 
     4823    else 
     4824    resolve(loc, sc, &e, &t, &s); 
     4825 
     4826    return s; 
     4827} 
     4828 
    42494829 
    42504830/***************************** TypeTypeof *****************************/ 
    42514831 
     
    42574837 
    42584838Type *TypeTypeof::syntaxCopy() 
    42594839{ 
     4840    //printf("TypeTypeof::syntaxCopy() %s\n", toChars()); 
    42604841    TypeTypeof *t; 
    42614842 
    42624843    t = new TypeTypeof(loc, exp->syntaxCopy()); 
     
    44345015    goto Lerr; 
    44355016    } 
    44365017    t = sc->func->type->nextOf(); 
    4437  
    4438     if (mod & MODinvariant) 
    4439     t = t->invariantOf(); 
    4440     else if (mod & MODconst) 
    4441     t = t->constOf(); 
     5018    t = t->addMod(mod); 
    44425019 
    44435020    if (idents.dim) 
    44445021    { 
     
    45725149    Dsymbol *s = sym->search(e->loc, ident, 0); 
    45735150    if (!s) 
    45745151    { 
    4575     return getProperty(e->loc, ident); 
     5152    if (ident == Id::max || 
     5153        ident == Id::min || 
     5154        ident == Id::init || 
     5155        ident == Id::stringof || 
     5156        !sym->memtype 
     5157       ) 
     5158    { 
     5159        return getProperty(e->loc, ident); 
     5160    } 
     5161    return sym->memtype->dotExp(sc, e, ident); 
    45765162    } 
    45775163    EnumMember *m = s->isEnumMember(); 
    45785164    Expression *em = m->value->copy(); 
     
    48395425    sym->inuse = 1; 
    48405426    Type *t = sym->basetype->toBasetype(); 
    48415427    sym->inuse = 0; 
    4842     if (mod == MODconst && !t->isInvariant()) 
    4843     t = t->constOf(); 
    4844     else if (mod == MODinvariant) 
    4845     t = t->invariantOf(); 
     5428    t = t->addMod(mod); 
    48465429    return t; 
    48475430} 
    48485431 
     
    50085591Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident) 
    50095592{   unsigned offset; 
    50105593 
    5011     Expression *b; 
    50125594    VarDeclaration *v; 
    50135595    Dsymbol *s; 
    50145596    DotVarExp *de; 
     
    51435725    return de; 
    51445726    } 
    51455727 
     5728    Import *timp = s->isImport(); 
     5729    if (timp) 
     5730    { 
     5731    e = new DsymbolExp(e->loc, s, 0); 
     5732    e = e->semantic(sc); 
     5733    return e; 
     5734    } 
     5735 
     5736    OverloadSet *o = s->isOverloadSet(); 
     5737    if (o) 
     5738    {   /* We really should allow this, triggered by: 
     5739     *   template c() 
     5740     *   { 
     5741     *  void a(); 
     5742     *  void b () { this.a(); } 
     5743     *   } 
     5744     *   struct S 
     5745     *   { 
     5746     *  mixin c; 
     5747     *  mixin c; 
     5748     *  } 
     5749     *  alias S e; 
     5750     */ 
     5751    error(e->loc, "overload set for %s.%s not allowed in struct declaration", e->toChars(), ident->toChars()); 
     5752    return new IntegerExp(0); 
     5753    } 
     5754 
    51465755    d = s->isDeclaration(); 
    51475756#ifdef DEBUG 
    51485757    if (!d) 
     
    51895798    accessCheck(e->loc, sc, e, d); 
    51905799 
    51915800// LDC we don't want dot exprs turned into pointer arithmetic. it complicates things for no apparent gain 
    5192 #ifndef IN_LLVM 
    5193     b = new AddrExp(e->loc, e); 
     5801#if 0 
     5802    Expression *b = new AddrExp(e->loc, e); 
    51945803    b->type = e->type->pointerTo(); 
    51955804    b = new AddExp(e->loc, b, new IntegerExp(e->loc, v->offset, Type::tint32)); 
    51965805    b->type = v->type->pointerTo(); 
    51975806    b = new PtrExp(e->loc, b); 
    5198     b->type = v->type; 
    5199     if (e->type->isConst()) 
    5200         b->type = b->type->constOf(); 
    5201     else if (e->type->isInvariant()) 
    5202         b->type = b->type->invariantOf(); 
     5807    b->type = v->type->addMod(e->type->mod); 
    52035808    return b; 
    52045809#endif 
    52055810    } 
     
    52575862    for (size_t i = 0; i < s->fields.dim; i++) 
    52585863    { 
    52595864    Dsymbol *sm = (Dsymbol *)s->fields.data[i]; 
    5260     if (sm->hasPointers()) 
     5865    Declaration *d = sm->isDeclaration(); 
     5866    if (d->storage_class & STCref || d->hasPointers()) 
    52615867        return TRUE; 
    52625868    } 
    52635869    return FALSE; 
     
    52835889            assert(v && v->storage_class & STCfield); 
    52845890 
    52855891            // 'from' type 
    5286             Type *tvf = v->type; 
    5287             if (mod == MODconst) 
    5288             tvf = tvf->constOf(); 
    5289             else if (mod == MODinvariant) 
    5290             tvf = tvf->invariantOf(); 
     5892            Type *tvf = v->type->addMod(mod); 
    52915893 
    52925894            // 'to' type 
    5293             Type *tv = v->type; 
    5294             if (to->mod == 0) 
    5295             tv = tv->mutableOf(); 
    5296             else 
    5297             {   assert(to->mod == MODinvariant); 
    5298             tv = tv->invariantOf(); 
    5299             } 
     5895            Type *tv = v->type->castMod(to->mod); 
    53005896 
    53015897            //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), tvf->implicitConvTo(tv)); 
    53025898            if (tvf->implicitConvTo(tv) < MATCHconst) 
     
    56416237    return de; 
    56426238    } 
    56436239 
     6240    OverloadSet *o = s->isOverloadSet(); 
     6241    if (o) 
     6242    {   /* We really should allow this 
     6243     */ 
     6244    error(e->loc, "overload set for %s.%s not allowed in struct declaration", e->toChars(), ident->toChars()); 
     6245    return new IntegerExp(0); 
     6246    } 
     6247 
    56446248    Declaration *d = s->isDeclaration(); 
    56456249    if (!d) 
    56466250    { 
     
    59906594{ 
    59916595    //printf("TypeSlice::semantic() %s\n", toChars()); 
    59926596    next = next->semantic(loc, sc); 
    5993     if (mod == MODconst && !next->isInvariant()) 
    5994     next = next->constOf(); 
    5995     else if (mod == MODinvariant) 
    5996     next = next->invariantOf(); 
     6597    transitive(); 
    59976598    //printf("next: %s\n", next->toChars()); 
    59986599 
    59996600    Type *tbn = next->toBasetype(); 
     
    62046805        if (arg->storageClass & STCconst) 
    62056806        buf->writestring("const "); 
    62066807        if (arg->storageClass & STCinvariant) 
    6207         buf->writestring("invariant "); 
     6808        buf->writestring("immutable "); 
    62086809        if (arg->storageClass & STCshared) 
    62096810        buf->writestring("shared "); 
    62106811 
  • a/dmd2/mtype.h

    old new  
    2323 
    2424// llvm 
    2525#include "../ir/irtype.h" 
     26#include "../ir/irfuncty.h" 
    2627namespace llvm { class Type; } 
    27 struct IrFuncTy; 
    2828 
    2929struct Scope; 
    3030struct Identifier; 
     
    116116{ 
    117117    TY ty; 
    118118    unsigned char mod;  // modifiers MODxxxx 
     119    /* pick this order of numbers so switch statements work better 
     120     */ 
    119121    #define MODconst     1  // type is const 
    120     #define MODinvariant 2    // type is invariant 
    121     #define MODshared    4    // type is shared 
     122    #define MODinvariant 4    // type is invariant 
     123    #define MODshared    2    // type is shared 
    122124    char *deco; 
     125 
     126    /* Note that there is no "shared immutable", because that is just immutable 
     127     */ 
     128 
    123129    Type *cto;      // MODconst ? mutable version of this type : const version 
    124130    Type *ito;      // MODinvariant ? mutable version of this type : invariant version 
     131    Type *sto;      // MODshared ? mutable version of this type : shared mutable version 
     132    Type *scto;     // MODshared|MODconst ? mutable version of this type : shared const version 
     133 
    125134    Type *pto;      // merged pointer to this type 
    126135    Type *rto;      // reference to this type 
    127136    Type *arrayof;  // array of this type 
     
    183192    static ClassDeclaration *typeinfotypelist; 
    184193    static ClassDeclaration *typeinfoconst; 
    185194    static ClassDeclaration *typeinfoinvariant; 
     195    static ClassDeclaration *typeinfoshared; 
    186196 
    187197    static Type *basic[TMAX]; 
    188198    static unsigned char mangleChar[TMAX]; 
     
    215225    virtual void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); 
    216226    virtual void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 
    217227    void toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod); 
    218 #if TARGET_LINUX 
     228#if TARGET_LINUX || TARGET_OSX 
    219229    virtual void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    220230#endif 
    221231    virtual int isintegral(); 
     
    234244    int isInvariant()   { return mod & MODinvariant; } 
    235245    int isMutable() { return !(mod & (MODconst | MODinvariant)); } 
    236246    int isShared()  { return mod & MODshared; } 
     247    int isSharedConst() { return mod == (MODshared | MODconst); } 
    237248    Type *constOf(); 
    238249    Type *invariantOf(); 
    239250    Type *mutableOf(); 
     251    Type *sharedOf(); 
     252    Type *sharedConstOf(); 
     253    void fixTo(Type *t); 
     254    void check(); 
     255    Type *castMod(unsigned mod); 
     256    Type *addMod(unsigned mod); 
     257    Type *addStorageClass(unsigned stc); 
    240258    Type *pointerTo(); 
    241259    Type *referenceTo(); 
    242260    Type *arrayOf(); 
    243261    virtual Type *makeConst(); 
    244262    virtual Type *makeInvariant(); 
     263    virtual Type *makeShared(); 
     264    virtual Type *makeSharedConst(); 
    245265    virtual Dsymbol *toDsymbol(Scope *sc); 
    246266    virtual Type *toBasetype(); 
    247267    virtual Type *toHeadMutable(); 
     
    268288    virtual Type *nextOf(); 
    269289 
    270290    static void error(Loc loc, const char *format, ...); 
     291    static void warning(Loc loc, const char *format, ...); 
    271292 
    272293    // For backend 
    273294    virtual unsigned totym(); 
     
    293314    Type *nextOf(); 
    294315    Type *makeConst(); 
    295316    Type *makeInvariant(); 
     317    Type *makeShared(); 
     318    Type *makeSharedConst(); 
    296319    MATCH constConv(Type *to); 
     320    void transitive(); 
    297321}; 
    298322 
    299323struct TypeBasic : Type 
     
    309333    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 
    310334    char *toChars(); 
    311335    void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 
    312 #if TARGET_LINUX 
     336#if TARGET_LINUX || TARGET_OSX 
    313337    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    314338#endif 
    315339    int isintegral(); 
     
    361385    TypeInfoDeclaration *getTypeInfoDeclaration(); 
    362386    Expression *toExpression(); 
    363387    int hasPointers(); 
    364 #if TARGET_LINUX 
     388#if TARGET_LINUX || TARGET_OSX 
    365389    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    366390#endif 
    367391 
     
    386410    MATCH implicitConvTo(Type *to); 
    387411    Expression *defaultInit(Loc loc); 
    388412    int builtinTypeInfo(); 
     413    MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 
    389414    TypeInfoDeclaration *getTypeInfoDeclaration(); 
    390415    int hasPointers(); 
    391 #if TARGET_LINUX 
     416#if TARGET_LINUX || TARGET_OSX 
    392417    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    393418#endif 
    394419 
     
    415440    int hasPointers(); 
    416441    MATCH implicitConvTo(Type *to); 
    417442    MATCH constConv(Type *to); 
    418 #if TARGET_LINUX 
     443#if TARGET_LINUX || TARGET_OSX 
    419444    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    420445#endif 
    421446 
     
    440465    int isZeroInit(); 
    441466    TypeInfoDeclaration *getTypeInfoDeclaration(); 
    442467    int hasPointers(); 
    443 #if TARGET_LINUX 
     468#if TARGET_LINUX || TARGET_OSX 
    444469    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    445470#endif 
    446471 
     
    457482    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 
    458483    Expression *defaultInit(Loc loc); 
    459484    int isZeroInit(); 
    460 #if TARGET_LINUX 
     485#if TARGET_LINUX || TARGET_OSX 
    461486    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    462487#endif 
    463488}; 
     
    491516    MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 
    492517    TypeInfoDeclaration *getTypeInfoDeclaration(); 
    493518    Type *reliesOnTident(); 
    494 #if TARGET_LINUX 
     519#if TARGET_LINUX || TARGET_OSX 
    495520    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    496521#endif 
    497522    bool parameterEscapes(Argument *p); 
     
    503528    unsigned totym(); 
    504529 
    505530    // LDC 
    506     IrFuncTy* fty; 
     531    IrFuncTy fty; 
    507532}; 
    508533 
    509534struct TypeDelegate : TypeNext 
     
    522547    TypeInfoDeclaration *getTypeInfoDeclaration(); 
    523548    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 
    524549    int hasPointers(); 
    525 #if TARGET_LINUX 
     550#if TARGET_LINUX || TARGET_OSX 
    526551    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    527552#endif 
    528553 
     
    573598    void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 
    574599    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); 
    575600    Type *semantic(Loc loc, Scope *sc); 
     601    Dsymbol *toDsymbol(Scope *sc); 
    576602    MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 
    577603}; 
    578604 
     
    623649    MATCH implicitConvTo(Type *to); 
    624650    MATCH constConv(Type *to); 
    625651    Type *toHeadMutable(); 
    626 #if TARGET_LINUX 
     652#if TARGET_LINUX || TARGET_OSX 
    627653    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    628654#endif 
    629655 
     
    662688    MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 
    663689    TypeInfoDeclaration *getTypeInfoDeclaration(); 
    664690    int hasPointers(); 
    665 #if TARGET_LINUX 
     691#if TARGET_LINUX || TARGET_OSX 
    666692    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    667693#endif 
    668694 
     
    704730    TypeInfoDeclaration *getTypeInfoDeclaration(); 
    705731    int hasPointers(); 
    706732    Type *toHeadMutable(); 
    707 #if TARGET_LINUX 
     733#if TARGET_LINUX || TARGET_OSX 
    708734    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    709735#endif 
    710736 
     
    737763    int hasPointers(); 
    738764    Type *toHeadMutable(); 
    739765    MATCH constConv(Type *to); 
    740 #if TARGET_LINUX 
     766#if TARGET_LINUX || TARGET_OSX 
    741767    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    742768#endif 
    743769 
     
    806832extern int Tsize_t; 
    807833extern int Tptrdiff_t; 
    808834 
     835int arrayTypeCompatible(Loc loc, Type *t1, Type *t2); 
     836 
    809837#endif /* DMD_MTYPE_H */ 
  • a/dmd2/opover.c

    old new  
    2121#define integer_t dmd_integer_t 
    2222#endif 
    2323 
    24 #if IN_GCC || IN_LLVM 
    2524#include "mem.h" 
    26 #elif POSIX 
    27 #include "../root/mem.h" 
    28 #elif _WIN32 
    29 #include "..\root\mem.h" 
    30 #endif 
    3125 
    3226//#include "port.h" 
    3327#include "mtype.h" 
  • a/dmd2/parse.c

    old new  
    7777    { 
    7878        nextToken(); 
    7979        if (token.value != TOKidentifier) 
    80         {   error("module (safe) identifier expected"); 
     80        {   error("module (system) identifier expected"); 
    8181        goto Lerr; 
    8282        } 
    8383        Identifier *id = token.ident; 
     
    307307        stc = STCinvariant; 
    308308        goto Lstc; 
    309309 
     310        case TOKshared: 
     311        if (peek(&token)->value == TOKlparen) 
     312            goto Ldeclaration; 
     313        stc = STCshared; 
     314        goto Lstc; 
     315 
    310316        case TOKfinal:    stc = STCfinal;    goto Lstc; 
    311317        case TOKauto:     stc = STCauto;     goto Lstc; 
    312318        case TOKscope:    stc = STCscope;    goto Lstc; 
     
    337343            case TOKconst: 
    338344            case TOKinvariant: 
    339345            case TOKimmutable: 
     346            case TOKshared: 
    340347            // If followed by a (, it is not a storage class 
    341348            if (peek(&token)->value == TOKlparen) 
    342349                break; 
    343350            if (token.value == TOKconst) 
    344351                stc = STCconst; 
     352            else if (token.value == TOKshared) 
     353                stc = STCshared; 
    345354            else 
    346355                stc = STCinvariant; 
    347356            goto Lstc; 
     
    378387        if (token.value == TOKidentifier && 
    379388            (tk = peek(&token))->value == TOKlparen && 
    380389            skipParens(tk, &tk) && 
    381             peek(tk)->value == TOKlparen) 
     390            (peek(tk)->value == TOKlparen || 
     391             peek(tk)->value == TOKlcurly) 
     392           ) 
    382393        { 
    383394            a = parseDeclarations(storageClass); 
    384395            decldefs->append(a); 
     
    10371048            stc = STCinvariant; 
    10381049            goto L2; 
    10391050 
     1051        case TOKshared: 
     1052            if (peek(&token)->value == TOKlparen) 
     1053            goto Ldefault; 
     1054            stc = STCshared; 
     1055            goto L2; 
     1056 
    10401057        case TOKin:    stc = STCin;     goto L2; 
    10411058        case TOKout:       stc = STCout;    goto L2; 
    10421059        case TOKinout: 
     
    10931110            if ((storageClass & (STCconst | STCout)) == (STCconst | STCout)) 
    10941111            error("out cannot be const"); 
    10951112            if ((storageClass & (STCinvariant | STCout)) == (STCinvariant | STCout)) 
    1096             error("out cannot be invariant"); 
     1113            error("out cannot be immutable"); 
    10971114            if ((storageClass & STCscope) && 
    10981115            (storageClass & (STCref | STCout))) 
    10991116            error("scope cannot be ref or out"); 
     
    17361753 
    17371754Objects *Parser::parseTemplateArgumentList2() 
    17381755{ 
     1756    //printf("Parser::parseTemplateArgumentList2()\n"); 
    17391757    Objects *tiargs = new Objects(); 
    17401758    enum TOK endtok = TOKrparen; 
    17411759    nextToken(); 
     
    19181936Type *Parser::parseType(Identifier **pident, TemplateParameters **tpl) 
    19191937{   Type *t; 
    19201938 
    1921     if (token.value == TOKconst && peek(&token)->value != TOKlparen) 
     1939    /* Take care of the storage class prefixes that 
     1940     * serve as type attributes: 
     1941     *  const shared, shared const, const, invariant, shared 
     1942     */ 
     1943    if (token.value == TOKconst && peekNext() == TOKshared && peekNext2() != TOKlparen || 
     1944    token.value == TOKshared && peekNext() == TOKconst && peekNext2() != TOKlparen) 
     1945    { 
     1946    nextToken(); 
     1947    nextToken(); 
     1948    /* shared const type 
     1949     */ 
     1950    t = parseType(pident, tpl); 
     1951    t = t->makeSharedConst(); 
     1952    return t; 
     1953    } 
     1954    else if (token.value == TOKconst && peekNext() != TOKlparen) 
    19221955    { 
    19231956    nextToken(); 
    19241957    /* const type 
     
    19281961    return t; 
    19291962    } 
    19301963    else if ((token.value == TOKinvariant || token.value == TOKimmutable) && 
    1931              peek(&token)->value != TOKlparen) 
     1964             peekNext() != TOKlparen) 
    19321965    { 
    19331966    nextToken(); 
    19341967    /* invariant type 
     
    19371970    t = t->makeInvariant(); 
    19381971    return t; 
    19391972    } 
     1973    else if (token.value == TOKshared && peekNext() != TOKlparen) 
     1974    { 
     1975    nextToken(); 
     1976    /* shared type 
     1977     */ 
     1978    t = parseType(pident, tpl); 
     1979    t = t->makeShared(); 
     1980    return t; 
     1981    } 
    19401982    else 
    19411983    t = parseBasicType(); 
    19421984    t = parseDeclarator(t, pident, tpl); 
     
    20162058        check(TOKlparen); 
    20172059        t = parseType(); 
    20182060        check(TOKrparen); 
    2019         t = t->makeConst(); 
     2061        if (t->isShared()) 
     2062        t = t->makeSharedConst(); 
     2063        else 
     2064        t = t->makeConst(); 
    20202065        break; 
    20212066 
    20222067    case TOKinvariant: 
     
    20292074        t = t->makeInvariant(); 
    20302075        break; 
    20312076 
     2077    case TOKshared: 
     2078        // shared(type) 
     2079        nextToken(); 
     2080        check(TOKlparen); 
     2081        t = parseType(); 
     2082        check(TOKrparen); 
     2083        if (t->isConst()) 
     2084        t = t->makeSharedConst(); 
     2085        else 
     2086        t = t->makeShared(); 
     2087        break; 
     2088 
    20322089    default: 
    20332090        error("basic type expected, not %s", token.toChars()); 
    20342091        t = Type::tint32; 
     
    22472304            switch (token.value) 
    22482305            { 
    22492306            case TOKconst: 
    2250                 tf = tf->makeConst(); 
     2307                if (tf->isShared()) 
     2308                tf = tf->makeSharedConst(); 
     2309                else 
     2310                tf = tf->makeConst(); 
    22512311                nextToken(); 
    22522312                continue; 
    22532313 
     
    22572317                nextToken(); 
    22582318                continue; 
    22592319 
     2320            case TOKshared: 
     2321                if (tf->isConst()) 
     2322                tf = tf->makeSharedConst(); 
     2323                else 
     2324                tf = tf->makeShared(); 
     2325                nextToken(); 
     2326                continue; 
     2327 
    22602328            case TOKnothrow: 
    22612329                ((TypeFunction *)tf)->isnothrow = 1; 
    22622330                nextToken(); 
     
    30723140    case TOKfinal: 
    30733141    case TOKinvariant: 
    30743142    case TOKimmutable: 
     3143    case TOKshared: 
    30753144//  case TOKtypeof: 
    30763145    Ldeclaration: 
    30773146    {   Array *a; 
     
    38433912    int haveId = 0; 
    38443913 
    38453914#if DMDV2 
    3846     if ((t->value == TOKconst || t->value == TOKinvariant || token.value == TOKimmutable) && 
     3915    if ((t->value == TOKconst || 
     3916     t->value == TOKinvariant || 
     3917     t->value == TOKimmutable || 
     3918     t->value == TOKshared) && 
    38473919    peek(t)->value != TOKlparen) 
    38483920    {   /* const type 
    3849      * invariant type 
     3921     * immutable type 
     3922     * shared type 
    38503923     */ 
    38513924    t = peek(t); 
    38523925    } 
    38533926#endif 
    38543927 
    38553928    if (!isBasicType(&t)) 
     3929    { 
    38563930    goto Lisnot; 
     3931    } 
    38573932    if (!isDeclarator(&t, &haveId, endtok)) 
    38583933    goto Lisnot; 
    38593934    if ( needId == 1 || 
     
    39704045    case TOKconst: 
    39714046    case TOKinvariant: 
    39724047    case TOKimmutable: 
    3973         // const(type)  or  invariant(type) 
     4048    case TOKshared: 
     4049        // const(type)  or  immutable(type)  or  shared(type) 
    39744050        t = peek(t); 
    39754051        if (t->value != TOKlparen) 
    39764052        goto Lfalse; 
    39774053        t = peek(t); 
    39784054        if (!isDeclaration(t, 0, TOKrparen, &t)) 
     4055        { 
    39794056        goto Lfalse; 
     4057        } 
    39804058        t = peek(t); 
    39814059        break; 
    39824060 
     
    41204198            case TOKconst: 
    41214199            case TOKinvariant: 
    41224200            case TOKimmutable: 
     4201            case TOKshared: 
    41234202            case TOKpure: 
    41244203            case TOKnothrow: 
    41254204                t = peek(t); 
     
    41824261        case TOKconst: 
    41834262        case TOKinvariant: 
    41844263        case TOKimmutable: 
     4264        case TOKshared: 
    41854265        case TOKfinal: 
    41864266        continue; 
    41874267 
     
    46934773             token.value == TOKconst && peek(&token)->value == TOKrparen || 
    46944774             token.value == TOKinvariant && peek(&token)->value == TOKrparen || 
    46954775             token.value == TOKimmutable && peek(&token)->value == TOKrparen || 
     4776             token.value == TOKshared && peek(&token)->value == TOKrparen || 
    46964777             token.value == TOKfunction || 
    46974778             token.value == TOKdelegate || 
    46984779             token.value == TOKreturn)) 
     
    50585139        break; 
    50595140 
    50605141    case TOKcast:               // cast(type) expression 
    5061     {   Type *t; 
    5062  
    5063         nextToken(); 
    5064         check(TOKlparen); 
    5065         /* Look for cast(const) and cast(invariant) 
    5066          */ 
    5067         if ((token.value == TOKconst || token.value == TOKinvariant || token.value == TOKimmutable) && 
    5068         peek(&token)->value == TOKrparen) 
    5069         {   enum TOK tok = token.value; 
    5070         nextToken(); 
     5142    { 
     5143        nextToken(); 
     5144        check(TOKlparen); 
     5145        /* Look for cast(), cast(const), cast(immutable), 
     5146         * cast(shared), cast(shared const) 
     5147         */ 
     5148        unsigned m; 
     5149        if (token.value == TOKrparen) 
     5150        { 
     5151        m = 0; 
     5152        goto Lmod1; 
     5153        } 
     5154        else if (token.value == TOKconst && peekNext() == TOKrparen) 
     5155        { 
     5156        m = MODconst; 
     5157        goto Lmod2; 
     5158        } 
     5159        else if ((token.value == TOKimmutable || token.value == TOKinvariant) && peekNext() == TOKrparen) 
     5160        { 
     5161        m = MODinvariant; 
     5162        goto Lmod2; 
     5163        } 
     5164        else if (token.value == TOKshared && peekNext() == TOKrparen) 
     5165        { 
     5166        m = MODshared; 
     5167        goto Lmod2; 
     5168        } 
     5169        else if (token.value == TOKconst && peekNext() == TOKshared && peekNext2() == TOKrparen || 
     5170             token.value == TOKshared && peekNext() == TOKconst && peekNext2() == TOKrparen) 
     5171        { 
     5172        m = MODshared | MODconst; 
     5173        nextToken(); 
     5174          Lmod2: 
     5175        nextToken(); 
     5176          Lmod1: 
    50715177        nextToken(); 
    50725178        e = parseUnaryExp(); 
    5073         e = new CastExp(loc, e, tok); 
    5074         } 
    5075         else 
    5076         { 
    5077         t = parseType();      // ( type ) 
     5179        e = new CastExp(loc, e, m); 
     5180        } 
     5181        else 
     5182        { 
     5183        Type *t = parseType();        // ( type ) 
    50785184        check(TOKrparen); 
    50795185        e = parseUnaryExp(); 
    50805186        e = new CastExp(loc, e, t); 
  • a/dmd2/readme.txt

    old new  
    11 
    22        The D Programming Language 
    33        Compiler Front End Source 
    4         Copyright (c) 1999-2002, by Digital Mars 
    5         www.digitalmars.com 
     4        Copyright (c) 1999-2009, by Digital Mars 
     5        http://www.digitalmars.com 
    66        All Rights Reserved 
    77 
    88 
    99This is the source code to the front end Digital Mars D compiler. 
    1010It covers the lexical analysis, parsing, and semantic analysis 
    1111of the D Programming Language defined in the documents at 
    12 www.digitalmars.com/d/ 
    13  
    14 The optimizer, code generator, and object file generator are not part 
    15 of this source, hence the source does not currently constitute a complete, 
    16 compilable program. However, many people have expressed a strong interested 
    17 in producing a D compiler with the GNU compiler sources. This release should 
    18 enable that. 
     12http://www.digitalmars.com/d/ 
    1913 
    2014These sources are free, they are redistributable and modifiable 
    2115under the terms of the GNU General Public License (attached as gpl.txt), 
    2216or the Artistic License (attached as artistic.txt). 
    2317 
     18The optimizer and code generator sources are  
     19covered under a separate license, backendlicense.txt. 
     20 
    2421It does not apply to anything else distributed by Digital Mars, 
    2522including D compiler executables. 
    2623 
  • a/dmd2/root.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// www.digitalmars.com 
  • a/dmd2/root.h

    old new  
    3737#define TYPEDEFS 
    3838 
    3939#if _MSC_VER 
     40#include <float.h>  // for _isnan 
    4041#include <malloc.h> // for alloca 
    4142// According to VC 8.0 docs, long double is the same as double 
    4243#define strtold strtod 
  • a/dmd2/scope.c

    old new  
    257257            sc->enclosing && 
    258258            sc->enclosing->search(loc, ident, NULL)) 
    259259        { 
    260             // WTF ? 
    261260            if (global.params.warnings) 
    262             fprintf(stdmsg, "warning - "); 
    263             error(s->loc, "array 'length' hides other 'length' name in outer scope"); 
     261                warning(s->loc, "array 'length' hides other 'length' name in outer scope"); 
    264262        } 
    265263 
    266264        //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind()); 
  • a/dmd2/statement.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 
     
    9696    va_end( ap ); 
    9797} 
    9898 
     99void Statement::warning(const char *format, ...) 
     100{ 
     101    if (global.params.warnings && !global.gag) 
     102    { 
     103    fprintf(stdmsg, "warning - "); 
     104    va_list ap; 
     105    va_start(ap, format); 
     106    ::verror(loc, format, ap); 
     107    va_end( ap ); 
     108    } 
     109} 
     110 
    99111int Statement::hasBreak() 
    100112{ 
    101113    //printf("Statement::hasBreak()\n"); 
     
    124136    return BEany; 
    125137} 
    126138 
    127 // TRUE if statement may fall off the end without a throw or return 
    128  
    129 int Statement::fallOffEnd() 
    130 { 
    131     return TRUE; 
    132 } 
    133  
    134139// TRUE if statement 'comes from' somewhere else, like a goto 
    135140 
    136141int Statement::comeFrom() 
     
    231236    return result; 
    232237} 
    233238 
    234 int ExpStatement::fallOffEnd() 
    235 { 
    236     if (exp) 
    237     { 
    238     if (exp->op == TOKassert) 
    239     {   AssertExp *a = (AssertExp *)exp; 
    240  
    241         if (a->e1->isBool(FALSE))   // if it's an assert(0) 
    242         return FALSE; 
    243     } 
    244     else if (exp->op == TOKhalt) 
    245         return FALSE; 
    246     } 
    247     return TRUE; 
    248 } 
    249239 
    250240/******************************** CompileStatement ***************************/ 
    251241 
     
    565555//printf("%s\n", s->toChars()); 
    566556        if (!(result & BEfallthru) && !s->comeFrom()) 
    567557        { 
    568         if (global.params.warnings) 
    569         {   fprintf(stdmsg, "warning - "); 
    570             s->error("statement is not reachable"); 
    571         } 
     558        s->warning("statement is not reachable"); 
    572559        } 
    573560 
    574561        result &= ~BEfallthru; 
     
    578565    return result; 
    579566} 
    580567 
    581 int CompoundStatement::fallOffEnd() 
    582 {   int falloff = TRUE; 
    583  
    584     //printf("CompoundStatement::fallOffEnd() %s\n", toChars()); 
    585     for (int i = 0; i < statements->dim; i++) 
    586     {   Statement *s = (Statement *)statements->data[i]; 
    587  
    588     if (!s) 
    589         continue; 
    590  
    591 #if 0 
    592     if (!falloff && global.params.warnings && !s->comeFrom()) 
    593     { 
    594         warning("%s: statement is not reachable", s->loc.toChars()); 
    595     } 
    596 #endif 
    597     falloff = s->fallOffEnd(); 
    598     } 
    599     return falloff; 
    600 } 
    601568 
    602569int CompoundStatement::comeFrom() 
    603570{   int comefrom = FALSE; 
     
    716683    return result; 
    717684} 
    718685 
    719 int UnrolledLoopStatement::fallOffEnd() 
    720 { 
    721     //printf("UnrolledLoopStatement::fallOffEnd()\n"); 
    722     for (size_t i = 0; i < statements->dim; i++) 
    723     {   Statement *s = (Statement *)statements->data[i]; 
    724  
    725     if (s) 
    726         s->fallOffEnd(); 
    727     } 
    728     return TRUE; 
    729 } 
    730686 
    731687int UnrolledLoopStatement::comeFrom() 
    732688{   int comefrom = FALSE; 
     
    821777    return statement ? statement->blockExit() : BEfallthru; 
    822778} 
    823779 
    824 int ScopeStatement::fallOffEnd() 
    825 { 
    826     return statement ? statement->fallOffEnd() : TRUE; 
    827 } 
    828780 
    829781int ScopeStatement::comeFrom() 
    830782{ 
     
    951903    return result; 
    952904} 
    953905 
    954 int WhileStatement::fallOffEnd() 
    955 { 
    956     if (body) 
    957     body->fallOffEnd(); 
    958     return TRUE; 
    959 } 
    960906 
    961907int WhileStatement::comeFrom() 
    962908{ 
     
    1046992    return result; 
    1047993} 
    1048994 
    1049 int DoStatement::fallOffEnd() 
    1050 { 
    1051     if (body) 
    1052     body->fallOffEnd(); 
    1053     return TRUE; 
    1054 } 
    1055995 
    1056996int DoStatement::comeFrom() 
    1057997{ 
     
    11711111    result &= ~BEfallthru;  // the body must do the exiting 
    11721112    if (body) 
    11731113    {   int r = body->blockExit(); 
    1174     if (r & BEbreak
    1175         result |= BEfallthru; 
    1176     result |= r & ~(BEbreak | BEcontinue); 
     1114    if (r & (BEbreak | BEgoto)
     1115        result |= BEfallthru; 
     1116    result |= r & ~(BEfallthru | BEbreak | BEcontinue); 
    11771117    } 
    11781118    if (increment && increment->canThrow()) 
    11791119    result |= BEthrow; 
    11801120    return result; 
    11811121} 
    11821122 
    1183 int ForStatement::fallOffEnd() 
    1184 { 
    1185     if (body) 
    1186     body->fallOffEnd(); 
    1187     return TRUE; 
    1188 } 
    11891123 
    11901124int ForStatement::comeFrom() 
    11911125{ 
     
    15511485         */ 
    15521486        Identifier *id = Identifier::generateId("__r"); 
    15531487        VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, aggr)); 
    1554         r->semantic(sc); 
     1488//      r->semantic(sc); 
     1489//printf("r: %s, init: %s\n", r->toChars(), r->init->toChars()); 
    15551490        Statement *init = new DeclarationStatement(loc, r); 
     1491//printf("init: %s\n", init->toChars()); 
    15561492 
    15571493        // !__r.empty 
    15581494        Expression *e = new VarExp(loc, r); 
     
    15681504         */ 
    15691505        e = new VarExp(loc, r); 
    15701506        Expression *einit = new DotIdExp(loc, e, idhead); 
    1571       einit = einit->semantic(sc); 
     1507//        einit = einit->semantic(sc); 
    15721508        Argument *arg = (Argument *)arguments->data[0]; 
    15731509        VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit)); 
    15741510        ve->storage_class |= STCforeach; 
     
    19231859    return result; 
    19241860} 
    19251861 
    1926 int ForeachStatement::fallOffEnd() 
    1927 { 
    1928     if (body) 
    1929     body->fallOffEnd(); 
    1930     return TRUE; 
    1931 } 
    19321862 
    19331863int ForeachStatement::comeFrom() 
    19341864{ 
     
    20231953 
    20241954    if (arg->type) 
    20251955    { 
     1956    arg->type = arg->type->semantic(loc, sc); 
    20261957    lwr = lwr->implicitCastTo(sc, arg->type); 
    20271958    upr = upr->implicitCastTo(sc, arg->type); 
    20281959    } 
     
    20912022    return result; 
    20922023} 
    20932024 
    2094 int ForeachRangeStatement::fallOffEnd() 
    2095 { 
    2096     if (body) 
    2097     body->fallOffEnd(); 
    2098     return TRUE; 
    2099 } 
    21002025 
    21012026int ForeachRangeStatement::comeFrom() 
    21022027{ 
     
    22532178    return result; 
    22542179} 
    22552180 
    2256 int IfStatement::fallOffEnd() 
    2257 { 
    2258     if (!ifbody || ifbody->fallOffEnd() || 
    2259     !elsebody || elsebody->fallOffEnd()) 
    2260     return TRUE; 
    2261     return FALSE; 
    2262 } 
    2263  
    22642181 
    22652182void IfStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    22662183{ 
     
    25062423    return result; 
    25072424} 
    25082425 
    2509 int PragmaStatement::fallOffEnd() 
    2510 { 
    2511     if (body) 
    2512     return body->fallOffEnd(); 
    2513     return TRUE; 
    2514 } 
    25152426 
    25162427void PragmaStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    25172428{ 
     
    27172628    return result; 
    27182629} 
    27192630 
    2720 int SwitchStatement::fallOffEnd() 
    2721 { 
    2722     if (body) 
    2723     body->fallOffEnd(); 
    2724     return TRUE;    // need to do this better 
    2725 } 
    27262631 
    27272632void SwitchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    27282633{ 
     
    28492754    return statement->blockExit(); 
    28502755} 
    28512756 
    2852 int CaseStatement::fallOffEnd() 
    2853 { 
    2854     return statement->fallOffEnd(); 
    2855 } 
    28562757 
    28572758int CaseStatement::comeFrom() 
    28582759{ 
     
    29162817    return statement->blockExit(); 
    29172818} 
    29182819 
    2919 int DefaultStatement::fallOffEnd() 
    2920 { 
    2921     return statement->fallOffEnd(); 
    2922 } 
    29232820 
    29242821int DefaultStatement::comeFrom() 
    29252822{ 
     
    29612858    return BEgoto; 
    29622859} 
    29632860 
    2964 int GotoDefaultStatement::fallOffEnd() 
    2965 { 
    2966     return FALSE; 
    2967 } 
    29682861 
    29692862void GotoDefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    29702863{ 
     
    30152908    return BEgoto; 
    30162909} 
    30172910 
    3018 int GotoCaseStatement::fallOffEnd() 
    3019 { 
    3020     return FALSE; 
    3021 } 
    30222911 
    30232912void GotoCaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    30242913{ 
     
    30432932    return BEthrow; 
    30442933} 
    30452934 
    3046 int SwitchErrorStatement::fallOffEnd() 
    3047 { 
    3048     return FALSE; 
    3049 } 
    30502935 
    30512936void SwitchErrorStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    30522937{ 
     
    32733158        exp = exp->semantic(sc); 
    32743159    } 
    32753160 
    3276     if (((TypeFunction *)fd->type)->isref
     3161    if (((TypeFunction *)fd->type)->isref && !fd->isCtorDeclaration()
    32773162    {   // Function returns a reference 
    32783163        if (tbret->isMutable()) 
    32793164        exp = exp->modifiableLvalue(sc, exp); 
     
    33463231    return result; 
    33473232} 
    33483233 
    3349 int ReturnStatement::fallOffEnd() 
    3350 { 
    3351     return FALSE; 
    3352 } 
    33533234 
    33543235void ReturnStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    33553236{ 
     
    34453326    return ident ? BEgoto : BEbreak; 
    34463327} 
    34473328 
    3448 int BreakStatement::fallOffEnd() 
    3449 { 
    3450     return FALSE; 
    3451 } 
    34523329 
    34533330void BreakStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    34543331{ 
     
    35533430    return ident ? BEgoto : BEcontinue; 
    35543431} 
    35553432 
    3556 int ContinueStatement::fallOffEnd() 
    3557 { 
    3558     return FALSE; 
    3559 } 
    35603433 
    35613434void ContinueStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    35623435{ 
     
    36483521    return body ? body->blockExit() : BEfallthru; 
    36493522} 
    36503523 
    3651 int SynchronizedStatement::fallOffEnd() 
    3652 { 
    3653     return body ? body->fallOffEnd() : TRUE; 
    3654 } 
    36553524 
    36563525void SynchronizedStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    36573526{ 
     
    37703639    return result; 
    37713640} 
    37723641 
    3773 int WithStatement::fallOffEnd() 
    3774 { 
    3775     return body ? body->fallOffEnd() : TRUE; 
    3776 } 
    37773642 
    37783643/******************************** TryCatchStatement ***************************/ 
    37793644 
     
    38373702} 
    38383703 
    38393704int TryCatchStatement::blockExit() 
    3840 {   int result; 
    3841  
     3705
    38423706    assert(body); 
    3843     result = body->blockExit(); 
    3844  
     3707    int result = body->blockExit(); 
     3708 
     3709    int catchresult = 0; 
    38453710    for (size_t i = 0; i < catches->dim; i++) 
    38463711    { 
    38473712        Catch *c = (Catch *)catches->data[i]; 
    3848         result |= c->blockExit(); 
    3849     } 
    3850     return result; 
    3851 
    3852  
    3853 int TryCatchStatement::fallOffEnd() 
    3854 
    3855     int result = FALSE; 
    3856  
    3857     if (body) 
    3858     result = body->fallOffEnd(); 
    3859     for (int i = 0; i < catches->dim; i++) 
    3860     {   Catch *c; 
    3861  
    3862     c = (Catch *)catches->data[i]; 
    3863     if (c->handler) 
    3864         result |= c->handler->fallOffEnd(); 
    3865     } 
    3866     return result; 
    3867 
     3713        catchresult |= c->blockExit(); 
     3714 
     3715    /* If we're catching Object, then there is no throwing 
     3716     */ 
     3717    Identifier *id = c->type->toBasetype()->isClassHandle()->ident; 
     3718    if (i == 0 && 
     3719        (id == Id::Object || id == Id::Throwable || id == Id::Exception)) 
     3720    { 
     3721        result &= ~BEthrow; 
     3722    } 
     3723    } 
     3724    return result | catchresult; 
     3725
     3726 
    38683727 
    38693728void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    38703729{ 
     
    40303889 
    40313890int TryFinallyStatement::blockExit() 
    40323891{ 
    4033     int result = body->blockExit(); 
    4034     return result; 
    4035 
    4036  
    4037 int TryFinallyStatement::fallOffEnd() 
    4038 {   int result; 
    4039  
    4040     result = body->fallOffEnd(); 
    4041 //    if (finalbody) 
    4042 //  result = finalbody->fallOffEnd(); 
    4043     return result; 
    4044 
     3892    if (body) 
     3893    return body->blockExit(); 
     3894    return BEfallthru; 
     3895
     3896 
    40453897 
    40463898/****************************** OnScopeStatement ***************************/ 
    40473899 
     
    41634015    return BEthrow;  // obviously 
    41644016} 
    41654017 
    4166 int ThrowStatement::fallOffEnd() 
    4167 { 
    4168     return FALSE; 
    4169 } 
    41704018 
    41714019void ThrowStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    41724020{ 
     
    42264074    return statement ? statement->blockExit() : BEfallthru; 
    42274075} 
    42284076 
    4229 int VolatileStatement::fallOffEnd() 
    4230 { 
    4231     return statement ? statement->fallOffEnd() : TRUE; 
    4232 } 
    42334077 
    42344078void VolatileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    42354079{ 
     
    42954139    return BEgoto; 
    42964140} 
    42974141 
    4298 int GotoStatement::fallOffEnd() 
    4299 { 
    4300     return FALSE; 
    4301 } 
    43024142 
    43034143void GotoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    43044144{ 
     
    43894229    return statement ? statement->blockExit() : BEfallthru; 
    43904230} 
    43914231 
    4392 int LabelStatement::fallOffEnd() 
    4393 { 
    4394     return statement ? statement->fallOffEnd() : TRUE; 
    4395 } 
    43964232 
    43974233int LabelStatement::comeFrom() 
    43984234{ 
  • a/dmd2/statement.h

    old new  
    7979#endif 
    8080struct code; 
    8181 
    82 /* How a statement exits 
     82/* How a statement exits; this is returned by blockExit() 
    8383 */ 
    8484enum BE 
    8585{ 
     
    134134    char *toChars(); 
    135135 
    136136    void error(const char *format, ...); 
     137    void warning(const char *format, ...); 
    137138    virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    138139    virtual TryCatchStatement *isTryCatchStatement() { return NULL; } 
    139140    virtual GotoStatement *isGotoStatement() { return NULL; } 
     
    148149    virtual int hasBreak(); 
    149150    virtual int hasContinue(); 
    150151    virtual int usesEH(); 
    151     virtual int fallOffEnd(); 
    152152    virtual int blockExit(); 
    153153    virtual int comeFrom(); 
    154154    virtual void scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); 
     
    183183    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    184184    Statement *semantic(Scope *sc); 
    185185    Expression *interpret(InterState *istate); 
    186     int fallOffEnd(); 
    187186    int blockExit(); 
    188187 
    189188    int inlineCost(InlineCostState *ics); 
     
    232231    virtual Statement *semantic(Scope *sc); 
    233232    int usesEH(); 
    234233    int blockExit(); 
    235     int fallOffEnd(); 
    236234    int comeFrom(); 
    237235    virtual Statements *flatten(Scope *sc); 
    238236    ReturnStatement *isReturnStatement(); 
     
    266264    int hasContinue(); 
    267265    int usesEH(); 
    268266    int blockExit(); 
    269     int fallOffEnd(); 
    270267    int comeFrom(); 
    271268    Expression *interpret(InterState *istate); 
    272269    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    291288    int hasContinue(); 
    292289    int usesEH(); 
    293290    int blockExit(); 
    294     int fallOffEnd(); 
    295291    int comeFrom(); 
    296292    Expression *interpret(InterState *istate); 
    297293 
     
    313309    int hasContinue(); 
    314310    int usesEH(); 
    315311    int blockExit(); 
    316     int fallOffEnd(); 
    317312    int comeFrom(); 
    318313    Expression *interpret(InterState *istate); 
    319314    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    336331    int hasContinue(); 
    337332    int usesEH(); 
    338333    int blockExit(); 
    339     int fallOffEnd(); 
    340334    int comeFrom(); 
    341335    Expression *interpret(InterState *istate); 
    342336    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    362356    int hasContinue(); 
    363357    int usesEH(); 
    364358    int blockExit(); 
    365     int fallOffEnd(); 
    366359    int comeFrom(); 
    367360    Expression *interpret(InterState *istate); 
    368361    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    396389    int hasContinue(); 
    397390    int usesEH(); 
    398391    int blockExit(); 
    399     int fallOffEnd(); 
    400392    int comeFrom(); 
    401393    Expression *interpret(InterState *istate); 
    402394    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    426418    int hasContinue(); 
    427419    int usesEH(); 
    428420    int blockExit(); 
    429     int fallOffEnd(); 
    430421    int comeFrom(); 
    431422    Expression *interpret(InterState *istate); 
    432423    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    453444    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    454445    int usesEH(); 
    455446    int blockExit(); 
    456     int fallOffEnd(); 
    457447    IfStatement *isIfStatement() { return this; } 
    458448 
    459449    int inlineCost(InlineCostState *ics); 
     
    490480    Statement *semantic(Scope *sc); 
    491481    int usesEH(); 
    492482    int blockExit(); 
    493     int fallOffEnd(); 
    494483 
    495484    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    496485 
     
    528517    int hasBreak(); 
    529518    int usesEH(); 
    530519    int blockExit(); 
    531     int fallOffEnd(); 
    532520    Expression *interpret(InterState *istate); 
    533521    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    534522 
     
    550538    int compare(Object *obj); 
    551539    int usesEH(); 
    552540    int blockExit(); 
    553     int fallOffEnd(); 
    554541    int comeFrom(); 
    555542    Expression *interpret(InterState *istate); 
    556543    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    578565    Statement *semantic(Scope *sc); 
    579566    int usesEH(); 
    580567    int blockExit(); 
    581     int fallOffEnd(); 
    582568    int comeFrom(); 
    583569    Expression *interpret(InterState *istate); 
    584570    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
     
    601587    Statement *semantic(Scope *sc); 
    602588    Expression *interpret(InterState *istate); 
    603589    int blockExit(); 
    604     int fallOffEnd(); 
    605590    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    606591 
    607592    void toIR(IRState *irs); 
     
    619604    Statement *semantic(Scope *sc); 
    620605    Expression *interpret(InterState *istate); 
    621606    int blockExit(); 
    622     int fallOffEnd(); 
    623607    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    624608 
    625609    void toIR(IRState *irs); 
     
    629613{ 
    630614    SwitchErrorStatement(Loc loc); 
    631615    int blockExit(); 
    632     int fallOffEnd(); 
    633616    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    634617 
    635618    void toIR(IRState *irs); 
     
    645628    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    646629    Statement *semantic(Scope *sc); 
    647630    int blockExit(); 
    648     int fallOffEnd(); 
    649631    Expression *interpret(InterState *istate); 
    650632 
    651633    int inlineCost(InlineCostState *ics); 
     
    667649    Statement *semantic(Scope *sc); 
    668650    Expression *interpret(InterState *istate); 
    669651    int blockExit(); 
    670     int fallOffEnd(); 
    671652    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    672653 
    673654    void toIR(IRState *irs); 
     
    686667    Statement *semantic(Scope *sc); 
    687668    Expression *interpret(InterState *istate); 
    688669    int blockExit(); 
    689     int fallOffEnd(); 
    690670    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    691671 
    692672    void toIR(IRState *irs); 
     
    708688    int hasContinue(); 
    709689    int usesEH(); 
    710690    int blockExit(); 
    711     int fallOffEnd(); 
    712691    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    713692 
    714693    Statement *inlineScan(InlineScanState *iss); 
     
    732711    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    733712    int usesEH(); 
    734713    int blockExit(); 
    735     int fallOffEnd(); 
    736714 
    737715    Statement *inlineScan(InlineScanState *iss); 
    738716 
     
    750728    int hasBreak(); 
    751729    int usesEH(); 
    752730    int blockExit(); 
    753     int fallOffEnd(); 
    754731 
    755732    Statement *inlineScan(InlineScanState *iss); 
    756733 
     
    788765    int hasContinue(); 
    789766    int usesEH(); 
    790767    int blockExit(); 
    791     int fallOffEnd(); 
    792768 
    793769    Statement *inlineScan(InlineScanState *iss); 
    794770 
     
    820796    Statement *semantic(Scope *sc); 
    821797    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    822798    int blockExit(); 
    823     int fallOffEnd(); 
    824799 
    825800    Statement *inlineScan(InlineScanState *iss); 
    826801 
     
    837812    Statement *semantic(Scope *sc); 
    838813    Statements *flatten(Scope *sc); 
    839814    int blockExit(); 
    840     int fallOffEnd(); 
    841815    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    842816 
    843817    Statement *inlineScan(InlineScanState *iss); 
     
    856830    Statement *syntaxCopy(); 
    857831    Statement *semantic(Scope *sc); 
    858832    int blockExit(); 
    859     int fallOffEnd(); 
    860833    Expression *interpret(InterState *istate); 
    861834 
    862835    void toIR(IRState *irs); 
     
    879852    Statements *flatten(Scope *sc); 
    880853    int usesEH(); 
    881854    int blockExit(); 
    882     int fallOffEnd(); 
    883855    int comeFrom(); 
    884856    Expression *interpret(InterState *istate); 
    885857    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
  • a/dmd2/struct.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 
     
    1919#include "module.h" 
    2020#include "id.h" 
    2121#include "statement.h" 
     22#include "template.h" 
    2223 
    2324/********************************* AggregateDeclaration ****************************/ 
    2425 
     
    4445    stag = NULL; 
    4546    sinit = NULL; 
    4647    scope = NULL; 
    47     dtor = NULL; 
     48    isnested = 0; 
     49    vthis = NULL; 
    4850 
     51#if DMDV2 
    4952    ctor = NULL; 
    5053    defaultCtor = NULL; 
     54#endif 
     55    dtor = NULL; 
    5156} 
    5257 
    5358enum PROT AggregateDeclaration::prot() 
     
    132137 * Align sizes of 0, as we may not know array sizes yet. 
    133138 */ 
    134139 
    135 void AggregateDeclaration::alignmember(unsigned salign, unsigned size, unsigned *poffset) 
     140void AggregateDeclaration::alignmember( 
     141    unsigned salign,    // struct alignment that is in effect 
     142    unsigned size,      // alignment requirement of field 
     143    unsigned *poffset) 
    136144{ 
    137145    //printf("salign = %d, size = %d, offset = %d\n",salign,size,*poffset); 
    138146    if (salign > 1) 
    139     {   int sa; 
    140  
    141     switch (size) 
    142     {   case 1: 
    143         break; 
    144         case 2: 
    145         case_2: 
    146         *poffset = (*poffset + 1) & ~1; // align to word 
    147         break; 
    148         case 3: 
    149         case 4: 
    150         if (salign == 2) 
    151             goto case_2; 
    152         *poffset = (*poffset + 3) & ~3; // align to dword 
    153         break; 
    154         default: 
    155         *poffset = (*poffset + size - 1) & ~(size - 1); 
    156         break; 
    157     } 
     147    { 
     148    assert(size != 3); 
     149    int sa = size; 
     150    if (sa == 0 || salign < sa) 
     151        sa = salign; 
     152    *poffset = (*poffset + sa - 1) & ~(sa - 1); 
    158153    } 
    159154    //printf("result = %d\n",*poffset); 
    160155} 
     
    171166 
    172167    // Check for forward referenced types which will fail the size() call 
    173168    Type *t = v->type->toBasetype(); 
     169    if (v->storage_class & STCref) 
     170    {   // References are the size of a pointer 
     171    t = Type::tvoidptr; 
     172    } 
    174173    if (t->ty == Tstruct /*&& isStructDeclaration()*/) 
    175174    {   TypeStruct *ts = (TypeStruct *)t; 
    176  
     175#if DMDV2 
    177176    if (ts->sym == this) 
    178177    { 
    179178        error("cannot have field %s with same struct type", v->toChars()); 
    180179    } 
     180#endif 
    181181 
    182182    if (ts->sym->sizeok != 1) 
    183183    { 
     
    191191    return; 
    192192    } 
    193193 
    194     memsize = v->type->size(loc); 
    195     memalignsize = v->type->alignsize(); 
    196     xalign = v->type->memalign(sc->structalign); 
     194    memsize = t->size(loc); 
     195    memalignsize = t->alignsize(); 
     196    xalign = t->memalign(sc->structalign); 
    197197    alignmember(xalign, memalignsize, &sc->offset); 
    198198    v->offset = sc->offset; 
    199199    sc->offset += memsize; 
     
    211211} 
    212212 
    213213 
     214/**************************************** 
     215 * Returns !=0 if there's an extra member which is the 'this' 
     216 * pointer to the enclosing context (enclosing aggregate or function) 
     217 */ 
     218 
     219int AggregateDeclaration::isNested() 
     220{ 
     221    return isnested; 
     222} 
     223 
     224 
    214225/********************************* StructDeclaration ****************************/ 
    215226 
    216227StructDeclaration::StructDeclaration(Loc loc, Identifier *id) 
    217228    : AggregateDeclaration(loc, id) 
    218229{ 
    219230    zeroInit = 0;   // assume false until we do semantic processing 
     231#if DMDV2 
    220232    hasIdentityAssign = 0; 
    221233    cpctor = NULL; 
    222234    postblit = NULL; 
     235#endif 
    223236 
    224237    // For forward references 
    225238    type = new TypeStruct(this); 
     
    267280#if STRUCTTHISREF 
    268281    handle = type; 
    269282#else 
     283    assert(0); 
    270284    handle = type->pointerTo(); 
    271285#endif 
    272286    structalign = sc->structalign; 
     
    277291    assert(!isAnonymous()); 
    278292    if (sc->stc & STCabstract) 
    279293    error("structs, unions cannot be abstract"); 
     294#if DMDV2 
    280295    if (storage_class & STCinvariant) 
    281296        type = type->invariantOf(); 
    282297    else if (storage_class & STCconst) 
    283298        type = type->constOf(); 
     299#endif 
    284300 
    285301    if (sizeok == 0)        // if not already done the addMember step 
    286302    { 
     303    int hasfunctions = 0; 
    287304    for (i = 0; i < members->dim; i++) 
    288305    { 
    289306        Dsymbol *s = (Dsymbol *)members->data[i]; 
    290307        //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars()); 
    291308        s->addMember(sc, this, 1); 
     309        if (s->isFuncDeclaration()) 
     310        hasfunctions = 1; 
    292311    } 
     312 
     313    // If nested struct, add in hidden 'this' pointer to outer scope 
     314    if (hasfunctions && !(storage_class & STCstatic)) 
     315        {   Dsymbol *s = toParent2(); 
     316            if (s) 
     317            { 
     318                AggregateDeclaration *ad = s->isAggregateDeclaration(); 
     319                FuncDeclaration *fd = s->isFuncDeclaration(); 
     320 
     321        TemplateInstance *ti; 
     322                if (ad && (ti = ad->parent->isTemplateInstance()) != NULL && ti->isnested || fd) 
     323                {   isnested = 1; 
     324                    Type *t; 
     325                    if (ad) 
     326                        t = ad->handle; 
     327                    else if (fd) 
     328                    {   AggregateDeclaration *ad = fd->isMember2(); 
     329                        if (ad) 
     330                            t = ad->handle; 
     331                        else 
     332                t = Type::tvoidptr; 
     333                    } 
     334                    else 
     335                        assert(0); 
     336            if (t->ty == Tstruct) 
     337            t = Type::tvoidptr; // t should not be a ref type 
     338                    assert(!vthis); 
     339                    vthis = new ThisDeclaration(t); 
     340            //vthis->storage_class |= STCref; 
     341                    members->push(vthis); 
     342                } 
     343            } 
     344        } 
    293345    } 
    294346 
    295347    sizeok = 0; 
     
    314366        break; 
    315367    } 
    316368#endif 
     369    Type *t; 
     370    if (s->isDeclaration() && 
     371        (t = s->isDeclaration()->type) != NULL && 
     372        t->toBasetype()->ty == Tstruct) 
     373    {   StructDeclaration *sd = (StructDeclaration *)t->toDsymbol(sc); 
     374        if (sd->isnested) 
     375        error("inner struct %s cannot be a field", sd->toChars()); 
     376    } 
    317377    } 
    318378 
    319379    /* The TypeInfo_Struct is expecting an opEquals and opCmp with 
     
    373433 
    374434    id = Id::cmp; 
    375435    } 
    376  
     436#if DMDV2 
    377437    dtor = buildDtor(sc2); 
    378438    postblit = buildPostBlit(sc2); 
    379439    cpctor = buildCpCtor(sc2); 
    380440    buildOpAssign(sc2); 
     441#endif 
    381442 
    382443    sc2->pop(); 
    383444 
     
    440501 
    441502    /* Look for special member functions. 
    442503     */ 
     504#if DMDV2 
    443505    ctor =   (CtorDeclaration *)search(0, Id::ctor, 0); 
     506#endif 
    444507    inv =    (InvariantDeclaration *)search(0, Id::classInvariant, 0); 
    445508    aggNew =       (NewDeclaration *)search(0, Id::classNew,       0); 
    446509    aggDelete = (DeleteDeclaration *)search(0, Id::classDelete,    0); 
  • a/dmd2/template.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 
     
    187187    { 
    188188        goto Lnomatch; 
    189189    } 
     190#if DMDV2 
    190191    VarDeclaration *v1 = s1->isVarDeclaration(); 
    191192    VarDeclaration *v2 = s2->isVarDeclaration(); 
    192193    if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) 
     
    195196        if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) 
    196197        goto Lnomatch; 
    197198    } 
     199#endif 
    198200    } 
    199201    else if (v1) 
    200202    { 
     
    262264    } 
    263265} 
    264266 
     267#if DMDV2 
    265268Object *objectSyntaxCopy(Object *o) 
    266269{ 
    267270    if (!o) 
     
    274277    return e->syntaxCopy(); 
    275278    return o; 
    276279} 
     280#endif 
    277281 
    278282 
    279283/* ======================== TemplateDeclaration ============================= */ 
     
    301305    this->loc = loc; 
    302306    this->parameters = parameters; 
    303307    this->origParameters = parameters; 
     308#if DMDV2 
    304309    this->constraint = constraint; 
     310#endif 
    305311    this->members = decldefs; 
    306312    this->overnext = NULL; 
    307313    this->overroot = NULL; 
     
    326332        p->data[i] = (void *)tp->syntaxCopy(); 
    327333    } 
    328334    } 
     335#if DMDV2 
    329336    Expression *e = NULL; 
    330337    if (constraint) 
    331338    e = constraint->syntaxCopy(); 
     339#endif 
    332340    d = Dsymbol::arraySyntaxCopy(members); 
    333341    td = new TemplateDeclaration(loc, ident, p, e, d); 
    334342     
     
    348356 
    349357    if (sc->func) 
    350358    { 
    351 //  error("cannot declare template at function scope %s", sc->func->toChars()); 
     359#if V1 
     360    error("cannot declare template at function scope %s", sc->func->toChars()); 
     361#endif 
    352362    } 
    353363 
    354364    if (/*global.params.useArrayBounds &&*/ sc->module) 
     
    376386    paramsym->parent = sc->parent; 
    377387    Scope *paramscope = sc->push(paramsym); 
    378388    paramscope->parameterSpecialization = 1; 
     389    paramscope->stc = 0; 
    379390 
    380391    if (global.params.doDocComments) 
    381392    { 
     
    536547    ScopeDsymbol *paramsym = new ScopeDsymbol(); 
    537548    paramsym->parent = scope->parent; 
    538549    Scope *paramscope = scope->push(paramsym); 
     550    paramscope->stc = 0; 
    539551 
    540552    // Attempt type deduction 
    541553    m = MATCHexact; 
     
    591603    } 
    592604    } 
    593605 
     606#if DMDV2 
    594607    if (m && constraint && !(flag & 1)) 
    595608    {   /* Check to see if constraint is satisfied. 
    596609     */ 
     
    607620            e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); 
    608621        } 
    609622    } 
     623#endif 
    610624 
    611625#if LOGM 
    612626    // Print out the results 
     
    823837        Tuple *t = new Tuple(); 
    824838        //printf("t = %p\n", t); 
    825839        dedargs->data[parameters->dim - 1] = (void *)t; 
     840        declareParameter(paramscope, tp, t); 
    826841        goto L2; 
    827842    } 
    828843    else if (nfargs < nfparams - 1) 
     
    858873        {   Expression *farg = (Expression *)fargs->data[fptupindex + i]; 
    859874            t->objects.data[i] = (void *)farg->type; 
    860875        } 
     876        declareParameter(paramscope, tp, t); 
    861877        goto L2; 
    862878        } 
    863879        fptupindex = -1; 
     
    875891    } 
    876892 
    877893L2: 
     894#if DMDV2 
    878895    // Match 'ethis' to any TemplateThisParameter's 
    879896    if (ethis) 
    880897    { 
     
    893910        } 
    894911    } 
    895912    } 
     913#endif 
    896914 
    897915    // Loop through the function parameters 
    898916    for (i = 0; i < nfparams; i++) 
     
    924942        printf("\tfarg->type   = %s\n", farg->type->toChars()); 
    925943        printf("\tfparam->type = %s\n", fparam->type->toChars()); 
    926944#endif 
     945        Type *argtype = farg->type; 
     946 
     947#if DMDV2 
     948        /* Allow string literals which are type [] to match with [dim] 
     949         */ 
     950        if (farg->op == TOKstring) 
     951        {   StringExp *se = (StringExp *)farg; 
     952        if (!se->committed && argtype->ty == Tarray && 
     953            fparam->type->toBasetype()->ty == Tsarray) 
     954        { 
     955            argtype = new TypeSArray(argtype->nextOf(), new IntegerExp(se->loc, se->len, Type::tindex)); 
     956            argtype = argtype->semantic(se->loc, NULL); 
     957            argtype = argtype->invariantOf(); 
     958        } 
     959        } 
     960#endif 
     961 
    927962        MATCH m; 
    928         //m = farg->type->toHeadMutable()->deduceType(scope, fparam->type, parameters, &dedtypes); 
    929         m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes); 
     963        //m = argtype->toHeadMutable()->deduceType(scope, fparam->type, parameters, &dedtypes); 
     964        m = argtype->deduceType(scope, fparam->type, parameters, &dedtypes); 
    930965        //printf("\tdeduceType m = %d\n", m); 
    931966 
    932967        /* If no match, see if there's a conversion to a delegate 
     
    10611096    } 
    10621097    } 
    10631098 
     1099#if DMDV2 
    10641100    if (constraint) 
    10651101    {   /* Check to see if constraint is satisfied. 
    10661102     */ 
     
    10771113            e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); 
    10781114        } 
    10791115    } 
    1080  
     1116#endif 
    10811117 
    10821118#if 0 
    10831119    for (i = 0; i < dedargs->dim; i++) 
     
    13431379    tp->toCBuffer(buf, hgs); 
    13441380    } 
    13451381    buf->writeByte(')'); 
    1346  
     1382#if DMDV2 
    13471383    if (constraint) 
    13481384    {   buf->writestring(" if ("); 
    13491385    constraint->toCBuffer(buf, hgs); 
    13501386    buf->writeByte(')'); 
    13511387    } 
     1388#endif 
    13521389 
    13531390    if (hgs->hdrgen) 
    13541391    { 
     
    13831420    tp->toCBuffer(&buf, &hgs); 
    13841421    } 
    13851422    buf.writeByte(')'); 
    1386  
     1423#if DMDV2 
    13871424    if (constraint) 
    13881425    {   buf.writestring(" if ("); 
    13891426    constraint->toCBuffer(&buf, &hgs); 
    13901427    buf.writeByte(')'); 
    13911428    } 
    1392  
     1429#endif 
    13931430    buf.writeByte(0); 
    13941431    return (char *)buf.extractData(); 
    13951432} 
     
    15541591    return MATCHconst; 
    15551592} 
    15561593 
     1594MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, 
     1595    Objects *dedtypes) 
     1596{ 
     1597#if 0 
     1598    printf("TypeDArray::deduceType()\n"); 
     1599    printf("\tthis   = %d, ", ty); print(); 
     1600    printf("\ttparam = %d, ", tparam->ty); tparam->print(); 
     1601#endif 
     1602    return Type::deduceType(sc, tparam, parameters, dedtypes); 
     1603 
     1604  Lnomatch: 
     1605    return MATCHnomatch; 
     1606} 
     1607 
    15571608MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, 
    15581609    Objects *dedtypes) 
    15591610{ 
     
    18521903        Expression *e1 = isExpression(o1); 
    18531904        Expression *e2 = isExpression(o2); 
    18541905 
     1906        Dsymbol *s1 = isDsymbol(o1); 
     1907        Dsymbol *s2 = isDsymbol(o2); 
     1908 
     1909        Tuple *v1 = isTuple(o1); 
     1910        Tuple *v2 = isTuple(o2); 
    18551911#if 0 
    18561912        if (t1) printf("t1 = %s\n", t1->toChars()); 
    18571913        if (t2) printf("t2 = %s\n", t2->toChars()); 
    18581914        if (e1) printf("e1 = %s\n", e1->toChars()); 
    18591915        if (e2) printf("e2 = %s\n", e2->toChars()); 
     1916        if (s1) printf("s1 = %s\n", s1->toChars()); 
     1917        if (s2) printf("s2 = %s\n", s2->toChars()); 
     1918        if (v1) printf("v1 = %s\n", v1->toChars()); 
     1919        if (v2) printf("v2 = %s\n", v2->toChars()); 
    18601920#endif 
    18611921 
    18621922        if (t1 && t2) 
     
    19031963            dedtypes->data[j] = e1; 
    19041964        } 
    19051965        } 
    1906         // BUG: Need to handle alias and tuple parameters 
     1966        else if (s1 && t2 && t2->ty == Tident) 
     1967        { 
     1968        j = templateParameterLookup(t2, parameters); 
     1969        if (j == -1) 
     1970            goto Lnomatch; 
     1971        TemplateParameter *tp = (TemplateParameter *)parameters->data[j]; 
     1972        // BUG: use tp->matchArg() instead of the following 
     1973        TemplateAliasParameter *ta = tp->isTemplateAliasParameter(); 
     1974        if (!ta) 
     1975            goto Lnomatch; 
     1976        Dsymbol *s = (Dsymbol *)dedtypes->data[j]; 
     1977        if (s) 
     1978        { 
     1979            if (!s1->equals(s)) 
     1980            goto Lnomatch; 
     1981        } 
     1982        else 
     1983        { 
     1984            dedtypes->data[j] = s1; 
     1985        } 
     1986        } 
     1987        else if (s1 && s2) 
     1988        { 
     1989        if (!s1->equals(s2)) 
     1990            goto Lnomatch; 
     1991        } 
     1992        // BUG: Need to handle tuple parameters 
    19071993        else 
    19081994        goto Lnomatch; 
    19091995    } 
     
    25372623 
    25382624Lnomatch: 
    25392625    *psparam = NULL; 
     2626    //printf("\tm = %d\n", MATCHnomatch); 
    25402627    return MATCHnomatch; 
    25412628} 
    25422629 
     
    31573244    } 
    31583245    } 
    31593246 
    3160     isNested(tiargs); 
     3247    hasNestedArgs(tiargs); 
    31613248 
    31623249    /* See if there is an existing TemplateInstantiation that already 
    31633250     * implements the typeargs. If so, just refer to that one instead. 
     
    32313318#endif 
    32323319 
    32333320    //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); 
    3234     if (scx && scx->scopesym && scx->scopesym->members && !scx->scopesym->isTemplateMixin()) 
     3321    if (scx && scx->scopesym && 
     3322        scx->scopesym->members && !scx->scopesym->isTemplateMixin() 
     3323#if 0 // removed because it bloated compile times 
     3324        /* The problem is if A imports B, and B imports A, and both A 
     3325         * and B instantiate the same template, does the compilation of A 
     3326         * or the compilation of B do the actual instantiation? 
     3327         * 
     3328         * see bugzilla 2500. 
     3329         */ 
     3330        && !scx->module->selfImports() 
     3331#endif 
     3332       ) 
    32353333    { 
    32363334        //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); 
    32373335        a = scx->scopesym->members; 
     
    32733371    argsym = new ScopeDsymbol(); 
    32743372    argsym->parent = scope->parent; 
    32753373    scope = scope->push(argsym); 
     3374//    scope->stc = 0; 
    32763375 
    32773376    // Declare each template parameter as an alias for the argument type 
    3278     declareParameters(scope); 
     3377    Scope *paramscope = scope->push(); 
     3378    paramscope->stc = 0; 
     3379    declareParameters(paramscope); 
     3380    paramscope->pop(); 
    32793381 
    32803382    // Add members of template instance to template instance symbol table 
    32813383//    parent = scope->scopesym; 
     
    37523854 * generation of the TemplateDeclaration. 
    37533855 */ 
    37543856 
    3755 int TemplateInstance::isNested(Objects *args) 
     3857int TemplateInstance::hasNestedArgs(Objects *args) 
    37563858{   int nested = 0; 
    3757     //printf("TemplateInstance::isNested('%s')\n", tempdecl->ident->toChars()); 
     3859    //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars()); 
    37583860 
    37593861    /* A nested instance happens when an argument references a local 
    37603862     * symbol that is on the stack. 
     
    38033905                if (p == dparent) 
    38043906                goto L1;    // isnested is most nested 
    38053907            } 
    3806             for (Dsymbol *p = dparent; 1; p = p->parent) 
     3908            for (Dsymbol *p = dparent; p; p = p->parent) 
    38073909            { 
    38083910                if (p == isnested) 
    38093911                {   isnested = dparent; 
    38103912                goto L1;    // dparent is most nested 
    38113913                } 
    38123914            } 
    3813             error("is nested in both %s and %s", isnested->toChars(), dparent->toChars()); 
     3915            error("%s is nested in both %s and %s", 
     3916                toChars(), isnested->toChars(), dparent->toChars()); 
    38143917            } 
    38153918          L1: 
    38163919            //printf("\tnested inside %s\n", isnested->toChars()); 
     
    38223925    } 
    38233926    else if (va) 
    38243927    { 
    3825         nested |= isNested(&va->objects); 
     3928        nested |= hasNestedArgs(&va->objects); 
    38263929    } 
    38273930    } 
    38283931    return nested; 
  • a/dmd2/template.h

    old new  
    5454    TemplateParameters *parameters; // array of TemplateParameter's 
    5555 
    5656    TemplateParameters *origParameters; // originals for Ddoc 
    57  
     57#if DMDV2 
    5858    Expression *constraint; 
    59  
     59#endif 
    6060    Array instances;            // array of TemplateInstance's 
    6161 
    6262    TemplateDeclaration *overnext;  // next overloaded TemplateDeclaration 
     
    6666    Dsymbol *onemember;     // if !=NULL then one member of this template 
    6767 
    6868    TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, 
    69     Expression *constraint, Array *decldefs); 
     69#if DMDV2 
     70    Expression *constraint, 
     71#endif 
     72    Array *decldefs); 
    7073    Dsymbol *syntaxCopy(Dsymbol *); 
    7174    void semantic(Scope *sc); 
    7275    int overloadInsert(Dsymbol *s); 
     
    117120    virtual TemplateTypeParameter  *isTemplateTypeParameter(); 
    118121    virtual TemplateValueParameter *isTemplateValueParameter(); 
    119122    virtual TemplateAliasParameter *isTemplateAliasParameter(); 
     123#if DMDV2 
    120124    virtual TemplateThisParameter *isTemplateThisParameter(); 
     125#endif 
    121126    virtual TemplateTupleParameter *isTemplateTupleParameter(); 
    122127 
    123128    virtual TemplateParameter *syntaxCopy() = 0; 
     
    314319    TemplateDeclaration *findTemplateDeclaration(Scope *sc); 
    315320    TemplateDeclaration *findBestMatch(Scope *sc); 
    316321    void declareParameters(Scope *sc); 
    317     int isNested(Objects *tiargs); 
     322    int hasNestedArgs(Objects *tiargs); 
    318323    Identifier *genIdent(); 
    319324 
    320325    TemplateInstance *isTemplateInstance() { return this; } 
  • a/dmd2/traits.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 
     
    1212#include <stdlib.h> 
    1313#include <ctype.h> 
    1414#include <assert.h> 
     15#if _MSC_VER 
     16#include <complex> 
     17#else 
    1518#include <complex.h> 
     19#endif 
    1620#include <math.h> 
    1721 
    1822#if IN_GCC 
     
    2428#define integer_t dmd_integer_t 
    2529#endif 
    2630 
    27 #if IN_GCC || IN_LLVM 
    2831#include "mem.h" 
    29 #elif _WIN32 
    30 #include "..\root\mem.h" 
    31 #elif linux 
    32 #include "../root/mem.h" 
    33 #endif 
    3432 
    3533//#include "port.h" 
    3634#include "mtype.h" 
     
    5351 
    5452#define LOGSEMANTIC 0 
    5553 
     54#if DMDV2 
     55 
    5656/************************************************ 
    5757 * Delegate to be passed to overloadApply() that looks 
    5858 * for virtual functions. 
     
    438438} 
    439439 
    440440 
     441#endif 
  • a/gen/dvalue.cpp

    old new  
    3333 
    3434LLValue* DVarValue::getRVal() 
    3535{ 
    36     assert(val); 
    3736    Type* bt = type->toBasetype(); 
    3837    if (DtoIsPassedByRef(bt)) 
    3938        return val; 
  • a/gen/linker.cpp

    old new  
    1414#include "gen/logger.h" 
    1515#include "gen/cl_options.h" 
    1616 
     17#include <sys/types.h>  
     18 #include <sys/wait.h>  
     19 
    1720////////////////////////////////////////////////////////////////////////////// 
    1821 
    1922// Is this useful? 
     
    172175        break; 
    173176 
    174177    case OSWindows: 
    175         // FIXME: I'd assume kernel32 etc 
     178        // FIXME: Id assume kernel32 etc 
    176179        break; 
    177180    } 
    178181 
     
    313316        break; 
    314317 
    315318    case OSWindows: 
    316         // FIXME: I'd assume kernel32 etc 
     319        // FIXME: Id assume kernel32 etc 
    317320        break; 
    318321    } 
    319322 
     
    339342    llvm::OStream logstr = Logger::cout(); 
    340343    for (; I != E; ++I) 
    341344        if (*I) 
    342             logstr << "'" << *I << "'" << " "; 
     345            logstr << "" << *I << "" << " "; 
    343346    logstr << "\n" << std::flush; 
    344347 
    345348 
    346349    // terminate args list 
    347350    args.push_back(NULL); 
    348351 
     352    const char** Cargs = new const char* [args.size()]; 
     353    for (unsigned i = 0, e = args.size(); i != e; ++i) 
     354            Cargs[i] = args[i]; 
    349355    // try to call linker!!! 
    350     if (int status = llvm::sys::Program::ExecuteAndWait(gcc, &args[0], NULL, NULL, 0,0, &errstr)) 
     356    int pid = fork(); 
     357    if( pid == 0 ) execv( gcc.c_str(), (char* const *)Cargs ); 
     358    int status; waitpid(pid, &status, 0); 
     359    status = WEXITSTATUS( status ); 
     360    if ( status) // llvm::sys::Program::ExecuteAndWait(gcc, &args[0], NULL, NULL, 0,0, &errstr)) 
    351361    { 
    352362        error("linking failed:\nstatus: %d", status); 
    353363        if (!errstr.empty()) 
     
    379389    std::vector<const char*> args; 
    380390    // args[0] should be the name of the executable 
    381391    args.push_back(gExePath.toString().c_str()); 
    382     // Skip first argument to -run; it's a D source file. 
     392    // Skip first argument to -run; its a D source file. 
    383393    for (size_t i = 1, length = opts::runargs.size(); i < length; i++) 
    384394    { 
    385395        args.push_back(opts::runargs[i].c_str()); 
  • a/gen/llvmhelpers.cpp

    old new  
    396396 
    397397void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs) 
    398398{ 
    399     Logger::println("DtoAssign(...);\n"); 
     399    Logger::println("DtoAssign( %s <- %s );\n", lhs->toChars(), rhs->toChars() ); 
    400400    LOG_SCOPE; 
    401401 
    402402    Type* t = lhs->getType()->toBasetype(); 
    403403    Type* t2 = rhs->getType()->toBasetype(); 
    404404 
     405     Logger::println("type: %s <- %s );\n", t->toChars(), t2->toChars() ); 
     406 
    405407    if (t->ty == Tstruct) { 
    406408        if (!t->equals(t2)) { 
    407409            // FIXME: use 'rhs' for something !?! 
    408410            DtoAggrZeroInit(lhs->getLVal()); 
    409411        } 
    410412        else { 
     413        Logger::cout() << "struct copy: " << *lhs->getLVal() << " <- " << *rhs->getRVal() << " );\n"; 
    411414            DtoAggrCopy(lhs->getLVal(), rhs->getRVal()); 
    412415        } 
    413416    } 
     
    15721575{ 
    15731576    t = t->toBasetype(); 
    15741577    if (t->ty == Tsarray) { 
    1575         assert(t->next->size() % t->next->alignsize() == 0); 
    1576         return hasUnalignedFields(t->next); 
     1578    assert( 0 && "'struct Type' has no member named 'next'"); 
     1579        /*assert(t->next->size() % t->next->alignsize() == 0); 
     1580        return hasUnalignedFields(t->next);*/ 
    15771581    } else if (t->ty != Tstruct) 
    15781582        return false; 
    15791583 
  • a/gen/todebug.cpp

    old new  
    3333 */ 
    3434static LLGlobalVariable* emitDwarfGlobalDecl(const LLStructType* type, const char* name, bool linkonce=false) 
    3535{ 
    36     LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceLinkage : LLGlobalValue::InternalLinkage; 
     36    LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceAnyLinkage : LLGlobalValue::InternalLinkage; 
    3737    LLGlobalVariable* gv = new LLGlobalVariable(type, true, linkage, NULL, name, gIR->module); 
    3838    gv->setSection("llvm.metadata"); 
    3939    return gv; 
  • a/gen/toir.cpp

    old new  
    10671067    if (VarDeclaration* vd = var->isVarDeclaration()) { 
    10681068        LLValue* arrptr; 
    10691069        // indexing struct pointer 
    1070         if (e1type->ty == Tpointer) { 
     1070        if (e1type->ty == Tpointer ) { 
     1071        Logger::cout() << "indexing struct pointer: " << '\n'; 
    10711072            assert(e1type->nextOf()->ty == Tstruct); 
    10721073            TypeStruct* ts = (TypeStruct*)e1type->nextOf(); 
    10731074            arrptr = DtoIndexStruct(l->getRVal(), ts->sym, vd); 
    10741075        } 
    10751076        // indexing normal struct 
    10761077        else if (e1type->ty == Tstruct) { 
     1078        Logger::cout() << "indexing normal struct: " << '\n'; 
    10771079            TypeStruct* ts = (TypeStruct*)e1type; 
    10781080            arrptr = DtoIndexStruct(l->getRVal(), ts->sym, vd); 
    10791081        } 
    10801082        // indexing class 
    10811083        else if (e1type->ty == Tclass) { 
     1084        Logger::cout() << "indexing indexing class: " << '\n'; 
    10821085            TypeClass* tc = (TypeClass*)e1type; 
    10831086            arrptr = DtoIndexClass(l->getRVal(), tc->sym, vd); 
    10841087        } 
     
    11721175        else { 
    11731176            Logger::println("normal this exp"); 
    11741177            v = p->func()->thisArg; 
     1178        if( type->toBasetype()->ty == Tstruct ) v = DtoLoad(v); 
    11751179        } 
    11761180        return new DVarValue(type, vd, v); 
    11771181    } 
  • a/gen/toobj.cpp

    old new  
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
     10#include <sys/types.h>  
     11 #include <sys/wait.h>  
     12 
    1013#include <cstddef> 
    1114#include <fstream> 
    1215 
     
    357360    } 
    358361 
    359362    // Run the compiler to assembly the program. 
    360     std::string ErrMsg; 
    361     int R = sys::Program::ExecuteAndWait( 
    362         gcc, &Args[0], 0, 0, 0, 0, &ErrMsg); 
     363   std::string ErrMsg; 
     364    const char** Cargs = new const char* [args.size()+1]; 
     365    for (unsigned i = 0, e = args.size(); i != e; ++i) 
     366            Cargs[i] = args[i].c_str(); 
     367    Cargs[args.size()] = 0; 
     368    int pid = fork(); 
     369    if( pid == 0 ) execv( gcc.c_str(), (char* const *)Cargs ); 
     370    int R; waitpid(pid, &R, 0); 
     371    R = WEXITSTATUS( R ); 
     372    /*int R = sys::Program::ExecuteAndWait( 
     373        gcc, &Args[0], 0, 0, 0, 0, &ErrMsg);*/ 
     374    //int R = system("/usr/bin/gcc -fno-strict-aliasing -O3 -c -xassembler test.s -o test.o -fpic -m64"); 
    363375    if (R) 
    364376    { 
    365377        error("Failed to invoke gcc. %s", ErrMsg.c_str()); 
  • a/gen/typinf.cpp

    old new  
    11 
    22 
    3 // Copyright (c) 1999-2004 by Digital Mars 
     3// Copyright (c) 1999-2009 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// www.digitalmars.com 
     
    116116    if (!t->vtinfo) 
    117117    { 
    118118#if DMDV2 
    119     if (t->isConst()) 
     119    if (t->isShared())  // does both 'shared' and 'shared const' 
     120        t->vtinfo = new TypeInfoSharedDeclaration(t); 
     121    else if (t->isConst()) 
    120122        t->vtinfo = new TypeInfoConstDeclaration(t); 
    121123    else if (t->isInvariant()) 
    122124        t->vtinfo = new TypeInfoInvariantDeclaration(t); 
     
    366368    assert(0 && "TypeInfoDeclaration::llvmDeclare"); 
    367369} 
    368370 
     371void TypeInfoSharedDeclaration::toDt(dt_t **pdt) 
     372{ 
     373    assert(0 && "TypeInfoSharedDeclaration::toDt"); 
     374} 
    369375/* ========================================================================= */ 
    370376 
    371377void TypeInfoTypedefDeclaration::llvmDeclare() 
  • a/ir/irfuncty.h

    old new  
    22#define LDC_IR_IRFUNCTY_H 
    33 
    44#include "ir/ir.h" 
    5 #include "llvm/ADT/SmallVector.h" 
     5//#include "llvm/ADT/SmallVector.h" 
    66 
    77#include <vector> 
    88 
  • a/ldc2.conf.in

    old new  
    11[Environment] 
    2 DFLAGS=-I@RUNTIME_DIR@/import -L-L%@P%/../lib 
     2DFLAGS=-I@RUNTIME_DIR@/import -L-L%@P%/../lib -defaultlib=@RUNTIME_AIO@ -debuglib=@RUNTIME_AIO@ 
Copyright © 2008, LDC Development Team.