Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 639

Show
Ignore:
Timestamp:
08/28/10 07:15:45 (14 years ago)
Author:
walter
Message:

Issue 2716 - Confusion of auto and scope as the class attribute

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/aggregate.h

    r638 r639  
    203203    CtorDeclaration *defaultCtor;       // default constructor 
    204204#endif 
    205205    FuncDeclaration *staticCtor; 
    206206    FuncDeclaration *staticDtor; 
    207207    Array vtbl;                         // Array of FuncDeclaration's making up the vtbl[] 
    208208    Array vtblFinal;                    // More FuncDeclaration's that aren't in vtbl[] 
    209209 
    210210    BaseClasses *baseclasses;           // Array of BaseClass's; first is super, 
    211211                                        // rest are Interface's 
    212212 
    213213    int interfaces_dim; 
    214214    BaseClass **interfaces;             // interfaces[interfaces_dim] for this class 
    215215                                        // (does not include baseClass) 
    216216 
    217217    BaseClasses *vtblInterfaces;        // array of base interfaces that have 
    218218                                        // their own vtbl[] 
    219219 
    220220    ClassInfoDeclaration *vclassinfo;   // the ClassInfo object for this ClassDeclaration 
    221221    int com;                            // !=0 if this is a COM class (meaning 
    222222                                        // it derives from IUnknown) 
    223     int isauto;                         // !=0 if this is an auto class 
     223    int isscope;                        // !=0 if this is an auto class 
    224224    int isabstract;                     // !=0 if abstract class 
    225225#if DMDV1 
    226226    int isnested;                       // !=0 if is nested 
    227227    VarDeclaration *vthis;              // 'this' parameter if this class is nested 
    228228#endif 
    229229    int inuse;                          // to prevent recursive attempts 
    230230 
    231231    ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 
    232232    Dsymbol *syntaxCopy(Dsymbol *s); 
    233233    void semantic(Scope *sc); 
    234234    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    235235    int isBaseOf2(ClassDeclaration *cd); 
    236236 
    237237    #define OFFSET_RUNTIME 0x76543210 
    238238    virtual int isBaseOf(ClassDeclaration *cd, int *poffset); 
    239239 
    240240    virtual int isBaseInfoComplete(); 
    241241    Dsymbol *search(Loc, Identifier *ident, int flags); 
    242242#if DMDV2 
    243243    int isFuncHidden(FuncDeclaration *fd); 
  • branches/dmd-1.x/src/class.c

    r638 r639  
    174174        if (id == Id::Object) 
    175175        {   if (object) 
    176176                object->error("%s", msg); 
    177177            object = this; 
    178178        } 
    179179 
    180180        if (id == Id::ClassInfo) 
    181181        {   if (classinfo) 
    182182                classinfo->error("%s", msg); 
    183183            classinfo = this; 
    184184        } 
    185185 
    186186        if (id == Id::ModuleInfo) 
    187187        {   if (Module::moduleinfo) 
    188188                Module::moduleinfo->error("%s", msg); 
    189189            Module::moduleinfo = this; 
    190190        } 
    191191    } 
    192192 
    193193    com = 0; 
    194     isauto = 0; 
     194    isscope = 0; 
    195195    isabstract = 0; 
    196196    isnested = 0; 
    197197    vthis = NULL; 
    198198    inuse = 0; 
    199199} 
    200200 
    201201Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s) 
    202202{ 
    203203    ClassDeclaration *cd; 
    204204 
    205205    //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars()); 
    206206    if (s) 
    207207        cd = (ClassDeclaration *)s; 
    208208    else 
    209209        cd = new ClassDeclaration(loc, ident, NULL); 
    210210 
    211211    cd->storage_class |= storage_class; 
    212212 
    213213    cd->baseclasses->setDim(this->baseclasses->dim); 
    214214    for (int i = 0; i < cd->baseclasses->dim; i++) 
     
    454454    } 
    455455 
    456456    interfaces_dim = baseclasses->dim; 
    457457    interfaces = (BaseClass **)baseclasses->data; 
    458458 
    459459 
    460460    if (baseClass) 
    461461    { 
    462462        if (baseClass->storage_class & STCfinal) 
    463463            error("cannot inherit from final class %s", baseClass->toChars()); 
    464464 
    465465        interfaces_dim--; 
    466466        interfaces++; 
    467467 
    468468        // Copy vtbl[] from base class 
    469469        vtbl.setDim(baseClass->vtbl.dim); 
    470470        memcpy(vtbl.data, baseClass->vtbl.data, sizeof(void *) * vtbl.dim); 
    471471 
    472472        // Inherit properties from base class 
    473473        com = baseClass->isCOMclass(); 
    474         isauto = baseClass->isauto
     474        isscope = baseClass->isscope
    475475        vthis = baseClass->vthis; 
    476476    } 
    477477    else 
    478478    { 
    479479        // No base class, so this is the root of the class hierarchy 
    480480        vtbl.setDim(0); 
    481481        vtbl.push(this);                // leave room for classinfo as first member 
    482482    } 
    483483 
    484484    protection = sc->protection; 
    485485    storage_class |= sc->stc; 
    486486 
    487487    if (sizeok == 0) 
    488488    { 
    489489        interfaceSemantic(sc); 
    490490 
    491491        for (i = 0; i < members->dim; i++) 
    492492        { 
    493493            Dsymbol *s = (Dsymbol *)members->data[i]; 
    494494            s->addMember(sc, this, 1); 
     
    536536                    else if (fd) 
    537537                    {   AggregateDeclaration *ad = fd->isMember2(); 
    538538                        if (ad) 
    539539                            t = ad->handle; 
    540540                        else 
    541541                        { 
    542542                            t = new TypePointer(Type::tvoid); 
    543543                            t = t->semantic(0, sc); 
    544544                        } 
    545545                    } 
    546546                    else 
    547547                        assert(0); 
    548548                    assert(!vthis); 
    549549                    vthis = new ThisDeclaration(loc, t); 
    550550                    members->push(vthis); 
    551551                } 
    552552            } 
    553553        } 
    554554    } 
    555555 
    556     if (storage_class & (STCauto | STCscope)) 
    557         isauto = 1; 
     556    if (storage_class & STCauto) 
     557        error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?"); 
     558    if (storage_class & STCscope) 
     559        isscope = 1; 
    558560    if (storage_class & STCabstract) 
    559561        isabstract = 1; 
    560562 
    561563    sc = sc->push(this); 
    562564    sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 
    563565                 STCabstract | STCdeprecated); 
    564566    sc->parent = this; 
    565567    sc->inunion = 0; 
    566568 
    567569    if (isCOMclass()) 
    568570    { 
    569571#if _WIN32 
    570572        sc->linkage = LINKwindows; 
    571573#else 
    572574        /* This enables us to use COM objects under Linux and 
    573575         * work with things like XPCOM 
    574576         */ 
    575577        sc->linkage = LINKc; 
    576578#endif 
    577579    } 
  • branches/dmd-1.x/src/declaration.c

    r608 r639  
    657657 
    658658VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) 
    659659    : Declaration(id) 
    660660{ 
    661661    //printf("VarDeclaration('%s')\n", id->toChars()); 
    662662#ifdef DEBUG 
    663663    if (!type && !init) 
    664664    {   printf("VarDeclaration('%s')\n", id->toChars()); 
    665665        //*(char*)0=0; 
    666666    } 
    667667#endif 
    668668    assert(type || init); 
    669669    this->type = type; 
    670670    this->init = init; 
    671671#ifdef _DH 
    672672    this->htype = NULL; 
    673673    this->hinit = NULL; 
    674674#endif 
    675675    this->loc = loc; 
    676676    offset = 0; 
    677     noauto = 0; 
     677    noscope = 0; 
    678678#if DMDV2 
    679679    isargptr = FALSE; 
    680680#endif 
    681681#if DMDV1 
    682682    nestedref = 0; 
    683683#endif 
    684684    ctorinit = 0; 
    685685    aliassym = NULL; 
    686686    onstack = 0; 
    687687    canassign = 0; 
    688688    value = NULL; 
    689689} 
    690690 
    691691Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) 
    692692{ 
    693693    //printf("VarDeclaration::syntaxCopy(%s)\n", toChars()); 
    694694 
    695695    VarDeclaration *sv; 
    696696    if (s) 
    697697    {   sv = (VarDeclaration *)s; 
     
    787787 
    788788    Type *tb = type->toBasetype(); 
    789789    if (tb->ty == Tvoid && !(storage_class & STClazy)) 
    790790    {   error("voids have no value"); 
    791791        type = Type::terror; 
    792792        tb = type; 
    793793    } 
    794794    if (tb->ty == Tfunction) 
    795795    {   error("cannot be declared to be a function"); 
    796796        type = Type::terror; 
    797797        tb = type; 
    798798    } 
    799799    if (tb->ty == Tstruct) 
    800800    {   TypeStruct *ts = (TypeStruct *)tb; 
    801801 
    802802        if (!ts->sym->members) 
    803803        { 
    804804            error("no definition of struct %s", ts->toChars()); 
    805805        } 
    806806    } 
     807    if ((storage_class & STCauto) && !inferred) 
     808       error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?"); 
    807809 
    808810    if (tb->ty == Ttuple) 
    809811    {   /* Instead, declare variables for each of the tuple elements 
    810812         * and add those. 
    811813         */ 
    812814        TypeTuple *tt = (TypeTuple *)tb; 
    813815        size_t nelems = Parameter::dim(tt->arguments); 
    814816        Objects *exps = new Objects(); 
    815817        exps->setDim(nelems); 
    816818        Expression *ie = init ? init->toExpression() : NULL; 
    817819 
    818820        for (size_t i = 0; i < nelems; i++) 
    819821        {   Parameter *arg = Parameter::getNth(tt->arguments, i); 
    820822 
    821823            OutBuffer buf; 
    822824            buf.printf("_%s_field_%zu", ident->toChars(), i); 
    823825            buf.writeByte(0); 
    824826            const char *name = (const char *)buf.extractData(); 
    825827            Identifier *id = Lexer::idPool(name); 
    826828 
     
    920922                ti = ti2; 
    921923            } 
    922924 
    923925            // If it's a member template 
    924926            AggregateDeclaration *ad = ti->tempdecl->isMember(); 
    925927            if (ad && storage_class != STCundefined) 
    926928            { 
    927929                error("cannot use template to add field to aggregate '%s'", ad->toChars()); 
    928930            } 
    929931        } 
    930932    } 
    931933 
    932934#if DMDV2 
    933935    if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 
    934936        ident != Id::This) 
    935937    { 
    936938        error("only parameters or foreach declarations can be ref"); 
    937939    } 
    938940#endif 
    939941 
    940     if (type->isauto() && !noauto
     942    if (type->isscope() && !noscope
    941943    { 
    942944        if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) 
    943945        { 
    944946            error("globals, statics, fields, ref and out parameters cannot be auto"); 
    945947        } 
    946948 
    947         if (!(storage_class & (STCauto | STCscope))) 
     949        if (!(storage_class & STCscope)) 
    948950        { 
    949951            if (!(storage_class & STCparameter) && ident != Id::withSym) 
    950952                error("reference to scope class must be scope"); 
    951953        } 
    952954    } 
    953955 
    954956    enum TOK op = TOKconstruct; 
    955957    if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 
    956958        !(storage_class & (STCfield | STCin | STCforeach)) && 
    957959        type->size() != 0) 
    958960    { 
    959961        // Provide a default initializer 
    960962        //printf("Providing default initializer for '%s'\n", toChars()); 
    961963        if (type->ty == Tstruct && 
    962964            ((TypeStruct *)type)->sym->zeroInit == 1) 
    963965        {   /* If a struct is all zeros, as a special case 
    964966             * set it's initializer to the integer 0. 
    965967             * In AssignExp::toElem(), we check for this and issue 
    966968             * a memset() to initialize the struct. 
    967969             * Must do same check in interpreter. 
     
    13611363} 
    13621364 
    13631365/******************************************** 
    13641366 * Can variable be read and written by CTFE? 
    13651367 */ 
    13661368 
    13671369int VarDeclaration::isCTFE() 
    13681370{ 
    13691371    //printf("VarDeclaration::isCTFE(%p, '%s')\n", this, toChars()); 
    13701372    //printf("%llx\n", storage_class); 
    13711373    return (storage_class & STCctfe) != 0; // || !isDataseg(); 
    13721374} 
    13731375 
    13741376int VarDeclaration::hasPointers() 
    13751377{ 
    13761378    //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); 
    13771379    return (!isDataseg() && type->hasPointers()); 
    13781380} 
    13791381 
    13801382/****************************************** 
    1381  * If a variable has an auto destructor call, return call for it. 
     1383 * If a variable has a scope destructor call, return call for it. 
    13821384 * Otherwise, return NULL. 
    13831385 */ 
    13841386 
    1385 Expression *VarDeclaration::callAutoDtor(Scope *sc) 
     1387Expression *VarDeclaration::callScopeDtor(Scope *sc) 
    13861388{   Expression *e = NULL; 
    13871389 
    1388     //printf("VarDeclaration::callAutoDtor() %s\n", toChars()); 
    1389     if (storage_class & (STCauto | STCscope) && !noauto
     1390    //printf("VarDeclaration::callScopeDtor() %s\n", toChars()); 
     1391    if (storage_class & (STCauto | STCscope) && !noscope
    13901392    { 
    13911393        for (ClassDeclaration *cd = type->isClassHandle(); 
    13921394             cd; 
    13931395             cd = cd->baseClass) 
    13941396        { 
    13951397            /* We can do better if there's a way with onstack 
    13961398             * classes to determine if there's no way the monitor 
    13971399             * could be set. 
    13981400             */ 
    13991401            //if (cd->isInterfaceDeclaration()) 
    14001402                //error("interface %s cannot be scope", cd->toChars()); 
    14011403            if (1 || onstack || cd->dtors.dim)  // if any destructors 
    14021404            { 
    14031405                // delete this; 
    14041406                Expression *ec; 
    14051407 
    14061408                ec = new VarExp(loc, this); 
    14071409                e = new DeleteExp(loc, ec); 
    14081410                e->type = Type::tvoid; 
    14091411                break; 
     
    15751577 
    15761578TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo) 
    15771579    : TypeInfoDeclaration(tinfo, 0) 
    15781580{ 
    15791581} 
    15801582 
    15811583/***************************** TypeInfoTupleDeclaration **********************/ 
    15821584 
    15831585TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) 
    15841586    : TypeInfoDeclaration(tinfo, 0) 
    15851587{ 
    15861588} 
    15871589 
    15881590/********************************* ThisDeclaration ****************************/ 
    15891591 
    15901592// For the "this" parameter to member functions 
    15911593 
    15921594ThisDeclaration::ThisDeclaration(Loc loc, Type *t) 
    15931595   : VarDeclaration(loc, t, Id::This, NULL) 
    15941596{ 
    1595     noauto = 1; 
     1597    noscope = 1; 
    15961598} 
    15971599 
    15981600Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) 
    15991601{ 
    16001602    assert(0);          // should never be produced by syntax 
    16011603    return NULL; 
    16021604} 
    16031605 
  • branches/dmd-1.x/src/declaration.h

    r591 r639  
    124124    void checkModify(Loc loc, Scope *sc, Type *t); 
    125125 
    126126    void emitComment(Scope *sc); 
    127127    void toJsonBuffer(OutBuffer *buf); 
    128128    void toDocBuffer(OutBuffer *buf); 
    129129 
    130130    char *mangle(); 
    131131    int isStatic() { return storage_class & STCstatic; } 
    132132    virtual int isStaticConstructor(); 
    133133    virtual int isStaticDestructor(); 
    134134    virtual int isDelete(); 
    135135    virtual int isDataseg(); 
    136136    virtual int isThreadlocal(); 
    137137    virtual int isCodeseg(); 
    138138    int isCtorinit()     { return storage_class & STCctorinit; } 
    139139    int isFinal()        { return storage_class & STCfinal; } 
    140140    int isAbstract()     { return storage_class & STCabstract; } 
    141141    int isConst()        { return storage_class & STCconst; } 
    142142    int isImmutable()    { return storage_class & STCimmutable; } 
    143143    int isAuto()         { return storage_class & STCauto; } 
    144     int isScope()        { return storage_class & (STCscope | STCauto); } 
     144    int isScope()        { return storage_class & STCscope; } 
    145145    int isSynchronized() { return storage_class & STCsynchronized; } 
    146146    int isParameter()    { return storage_class & STCparameter; } 
    147147    int isDeprecated()   { return storage_class & STCdeprecated; } 
    148148    int isOverride()     { return storage_class & STCoverride; } 
    149149 
    150150    int isIn()    { return storage_class & STCin; } 
    151151    int isOut()   { return storage_class & STCout; } 
    152152    int isRef()   { return storage_class & STCref; } 
    153153 
    154154    enum PROT prot(); 
    155155 
    156156    Declaration *isDeclaration() { return this; } 
    157157}; 
    158158 
    159159/**************************************************************/ 
    160160 
    161161struct TupleDeclaration : Declaration 
    162162{ 
    163163    Objects *objects; 
    164164    int isexp;                  // 1: expression tuple 
     
    226226    const char *kind(); 
    227227    Type *getType(); 
    228228    Dsymbol *toAlias(); 
    229229    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    230230#ifdef _DH 
    231231    Type *htype; 
    232232    Dsymbol *haliassym; 
    233233#endif 
    234234 
    235235    void toDocBuffer(OutBuffer *buf); 
    236236 
    237237    AliasDeclaration *isAliasDeclaration() { return this; } 
    238238}; 
    239239 
    240240/**************************************************************/ 
    241241 
    242242struct VarDeclaration : Declaration 
    243243{ 
    244244    Initializer *init; 
    245245    unsigned offset; 
    246     int noauto;                 // no auto semantics 
     246    int noscope;                 // no auto semantics 
    247247#if DMDV2 
    248248    FuncDeclarations nestedrefs; // referenced by these lexically nested functions 
    249249    bool isargptr;              // if parameter that _argptr points to 
    250250#else 
    251251    int nestedref;              // referenced by a lexically nested function 
    252252#endif 
    253253    int ctorinit;               // it has been initialized in a ctor 
    254254    int onstack;                // 1: it has been allocated on the stack 
    255255                                // 2: on stack, run destructor anyway 
    256256    int canassign;              // it can be assigned to 
    257257    Dsymbol *aliassym;          // if redone as alias to another symbol 
    258258    Expression *value;          // when interpreting, this is the value 
    259259                                // (NULL if value not determinable) 
    260260#if DMDV2 
    261261    VarDeclaration *rundtor;    // if !NULL, rundtor is tested at runtime to see 
    262262                                // if the destructor should be run. Used to prevent 
    263263                                // dtor calls on postblitted vars 
    264264#endif 
    265265 
    266266    VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init); 
    267267    Dsymbol *syntaxCopy(Dsymbol *); 
    268268    void semantic(Scope *sc); 
    269269    void semantic2(Scope *sc); 
    270270    const char *kind(); 
    271271    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    272272#ifdef _DH 
    273273    Type *htype; 
    274274    Initializer *hinit; 
    275275#endif 
    276276    int needThis(); 
    277277    int isImportedSymbol(); 
    278278    int isDataseg(); 
    279279    int isThreadlocal(); 
    280280    int isCTFE(); 
    281281    int hasPointers(); 
    282282#if DMDV2 
    283283    int canTakeAddressOf(); 
    284284    int needsAutoDtor(); 
    285285#endif 
    286     Expression *callAutoDtor(Scope *sc); 
     286    Expression *callScopeDtor(Scope *sc); 
    287287    ExpInitializer *getExpInitializer(); 
    288288    Expression *getConstInitializer(); 
    289289    void checkCtorConstInit(); 
    290290    void checkNestedReference(Scope *sc, Loc loc); 
    291291    Dsymbol *toAlias(); 
    292292 
    293293    Symbol *toSymbol(); 
    294294    void toObjFile(int multiobj);                       // compile to .obj file 
    295295    int cvMember(unsigned char *p); 
    296296 
    297297    // Eliminate need for dynamic_cast 
    298298    VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } 
    299299}; 
    300300 
    301301/**************************************************************/ 
    302302 
    303303// This is a shell around a back end symbol 
    304304 
    305305struct SymbolDeclaration : Declaration 
    306306{ 
  • branches/dmd-1.x/src/expression.c

    r637 r639  
    39903990} 
    39913991 
    39923992char *VarExp::toChars() 
    39933993{ 
    39943994    return var->toChars(); 
    39953995} 
    39963996 
    39973997void VarExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    39983998{ 
    39993999    buf->writestring(var->toChars()); 
    40004000} 
    40014001 
    40024002void VarExp::checkEscape() 
    40034003{ 
    40044004    VarDeclaration *v = var->isVarDeclaration(); 
    40054005    if (v) 
    40064006    {   Type *tb = v->type->toBasetype(); 
    40074007        // if reference type 
    40084008        if (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tclass) 
    40094009        { 
    4010             if ((v->isAuto() || v->isScope()) && !v->noauto
     4010            if (v->isScope() && !v->noscope
    40114011                error("escaping reference to auto local %s", v->toChars()); 
    40124012            else if (v->storage_class & STCvariadic) 
    40134013                error("escaping reference to variadic parameter %s", v->toChars()); 
    40144014        } 
    40154015    } 
    40164016} 
    40174017 
    40184018void VarExp::checkEscapeRef() 
    40194019{ 
    40204020    VarDeclaration *v = var->isVarDeclaration(); 
    40214021    if (v) 
    40224022    { 
    40234023        if (!v->isDataseg() && !(v->storage_class & (STCref | STCout))) 
    40244024            error("escaping reference to local variable %s", v->toChars()); 
    40254025    } 
    40264026} 
    40274027 
    40284028#if DMDV2 
    40294029int VarExp::isLvalue() 
    40304030{ 
  • branches/dmd-1.x/src/func.c

    r603 r639  
    940940            if (type->nextOf()->ty == Tvoid) 
    941941            { 
    942942                if (outId) 
    943943                    error("void functions have no result"); 
    944944            } 
    945945            else 
    946946            { 
    947947                if (!outId) 
    948948                    outId = Id::result;         // provide a default 
    949949            } 
    950950 
    951951            if (outId) 
    952952            {   // Declare result variable 
    953953                VarDeclaration *v; 
    954954                Loc loc = this->loc; 
    955955 
    956956                if (fensure) 
    957957                    loc = fensure->loc; 
    958958 
    959959                v = new VarDeclaration(loc, type->nextOf(), outId, NULL); 
    960                 v->noauto = 1; 
     960                v->noscope = 1; 
    961961#if DMDV2 
    962962                if (!isVirtual()) 
    963963                    v->storage_class |= STCconst; 
    964964                if (f->isref) 
    965965                { 
    966966                    v->storage_class |= STCref | STCforeach; 
    967967                } 
    968968#endif 
    969969                sc2->incontract--; 
    970970                v->semantic(sc2); 
    971971                sc2->incontract++; 
    972972                if (!sc2->insert(v)) 
    973973                    error("out result %s is already defined", v->toChars()); 
    974974                v->parent = this; 
    975975                vresult = v; 
    976976 
    977977                // vresult gets initialized with the function return value 
    978978                // in ReturnStatement::semantic() 
    979979            } 
    980980 
     
    13501350 
    13511351            fbody = new CompoundStatement(0, a); 
    13521352#if DMDV2 
    13531353            /* Append destructor calls for parameters as finally blocks. 
    13541354             */ 
    13551355            if (parameters) 
    13561356            {   for (size_t i = 0; i < parameters->dim; i++) 
    13571357                { 
    13581358                    VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 
    13591359 
    13601360                    if (v->storage_class & (STCref | STCout)) 
    13611361                        continue; 
    13621362 
    13631363                    /* Don't do this for static arrays, since static 
    13641364                     * arrays are called by reference. Remove this 
    13651365                     * when we change them to call by value. 
    13661366                     */ 
    13671367                    if (v->type->toBasetype()->ty == Tsarray) 
    13681368                        continue; 
    13691369 
    1370                     Expression *e = v->callAutoDtor(sc); 
     1370                    Expression *e = v->callScopeDtor(sc); 
    13711371                    if (e) 
    13721372                    {   Statement *s = new ExpStatement(0, e); 
    13731373                        s = s->semantic(sc); 
    13741374                        if (fbody->blockExit() == BEfallthru) 
    13751375                            fbody = new CompoundStatement(0, fbody, s); 
    13761376                        else 
    13771377                            fbody = new TryFinallyStatement(0, fbody, s); 
    13781378                    } 
    13791379                } 
    13801380            } 
    13811381#endif 
    13821382 
    13831383#if 1 
    13841384            if (isSynchronized()) 
    13851385            {   /* Wrap the entire function body in a synchronized statement 
    13861386                 */ 
    13871387                ClassDeclaration *cd = parent->isClassDeclaration(); 
    13881388                if (cd) 
    13891389                { 
    13901390#if TARGET_WINDOS 
  • branches/dmd-1.x/src/mtype.c

    r619 r639  
    487487int Type::iscomplex() 
    488488{ 
    489489    return FALSE; 
    490490} 
    491491 
    492492int Type::isscalar() 
    493493{ 
    494494    return FALSE; 
    495495} 
    496496 
    497497int Type::isunsigned() 
    498498{ 
    499499    return FALSE; 
    500500} 
    501501 
    502502ClassDeclaration *Type::isClassHandle() 
    503503{ 
    504504    return NULL; 
    505505} 
    506506 
    507 int Type::isauto() 
     507int Type::isscope() 
    508508{ 
    509509    return FALSE; 
    510510} 
    511511 
    512512int Type::isString() 
    513513{ 
    514514    return FALSE; 
    515515} 
    516516 
    517517int Type::checkBoolean() 
    518518{ 
    519519    return isscalar(); 
    520520} 
    521521 
    522522/********************************* 
    523523 * Check type to see if it is based on a deprecated symbol. 
    524524 */ 
    525525 
    526526void Type::checkDeprecated(Loc loc, Scope *sc) 
    527527{ 
     
    19101910    { 
    19111911        case Ttuple: 
    19121912        {   // Index the tuple to get the type 
    19131913            assert(dim); 
    19141914            TypeTuple *tt = (TypeTuple *)tbn; 
    19151915            uinteger_t d = dim->toUInteger(); 
    19161916 
    19171917            if (d >= tt->arguments->dim) 
    19181918            {   error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); 
    19191919                return Type::terror; 
    19201920            } 
    19211921            Parameter *arg = (Parameter *)tt->arguments->data[(size_t)d]; 
    19221922            return arg->type; 
    19231923        } 
    19241924        case Tfunction: 
    19251925        case Tnone: 
    19261926            error(loc, "can't have array of %s", tbn->toChars()); 
    19271927            tbn = next = tint32; 
    19281928            break; 
    19291929    } 
    1930     if (tbn->isauto()) 
     1930    if (tbn->isscope()) 
    19311931        error(loc, "cannot have array of auto %s", tbn->toChars()); 
    19321932    return merge(); 
    19331933} 
    19341934 
    19351935void TypeSArray::toDecoBuffer(OutBuffer *buf) 
    19361936{ 
    19371937    buf->writeByte(mangleChar[ty]); 
    19381938    if (dim) 
    19391939        buf->printf("%ju", dim->toInteger()); 
    19401940    if (next) 
    19411941        next->toDecoBuffer(buf); 
    19421942} 
    19431943 
    19441944void TypeSArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 
    19451945{ 
    19461946    if (mod != this->mod) 
    19471947    {   toCBuffer3(buf, hgs, mod); 
    19481948        return; 
    19491949    } 
    19501950    next->toCBuffer2(buf, hgs, this->mod); 
     
    20882088{ 
    20892089    // A DArray consists of two ptr-sized values, so align it on pointer size 
    20902090    // boundary 
    20912091    return PTRSIZE; 
    20922092} 
    20932093 
    20942094Type *TypeDArray::semantic(Loc loc, Scope *sc) 
    20952095{   Type *tn = next; 
    20962096 
    20972097    tn = next->semantic(loc,sc); 
    20982098    Type *tbn = tn->toBasetype(); 
    20992099    switch (tbn->ty) 
    21002100    { 
    21012101        case Tfunction: 
    21022102        case Tnone: 
    21032103        case Ttuple: 
    21042104            error(loc, "can't have array of %s", tbn->toChars()); 
    21052105            tn = next = tint32; 
    21062106            break; 
    21072107    } 
    2108     if (tn->isauto()) 
    2109         error(loc, "cannot have array of auto %s", tn->toChars()); 
     2108    if (tn->isscope()) 
     2109        error(loc, "cannot have array of scope %s", tn->toChars()); 
    21102110    if (next != tn) 
    21112111        //deco = NULL;                  // redo 
    21122112        return tn->arrayOf(); 
    21132113    return merge(); 
    21142114} 
    21152115 
    21162116void TypeDArray::toDecoBuffer(OutBuffer *buf) 
    21172117{ 
    21182118    buf->writeByte(mangleChar[ty]); 
    21192119    if (next) 
    21202120        next->toDecoBuffer(buf); 
    21212121} 
    21222122 
    21232123void TypeDArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 
    21242124{ 
    21252125    if (mod != this->mod) 
    21262126    {   toCBuffer3(buf, hgs, mod); 
    21272127        return; 
    21282128    } 
    21292129    next->toCBuffer2(buf, hgs, this->mod); 
     
    22852285            key = key->next->arrayOf(); 
    22862286#endif 
    22872287            break; 
    22882288        case Tbit: 
    22892289        case Tbool: 
    22902290        case Tfunction: 
    22912291        case Tvoid: 
    22922292        case Tnone: 
    22932293        case Ttuple: 
    22942294            error(loc, "can't have associative array key of %s", key->toChars()); 
    22952295            break; 
    22962296    } 
    22972297    next = next->semantic(loc,sc); 
    22982298    switch (next->toBasetype()->ty) 
    22992299    { 
    23002300        case Tfunction: 
    23012301        case Tnone: 
    23022302            error(loc, "can't have associative array of %s", next->toChars()); 
    23032303            break; 
    23042304    } 
    2305     if (next->isauto()) 
     2305    if (next->isscope()) 
    23062306        error(loc, "cannot have array of auto %s", next->toChars()); 
    23072307 
    23082308    return merge(); 
    23092309} 
    23102310 
    23112311void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) 
    23122312{ 
    23132313    //printf("TypeAArray::resolve() %s\n", toChars()); 
    23142314 
    23152315    // Deal with the case where we thought the index was a type, but 
    23162316    // in reality it was an expression. 
    23172317    if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray) 
    23182318    { 
    23192319        Expression *e; 
    23202320        Type *t; 
    23212321        Dsymbol *s; 
    23222322 
    23232323        index->resolve(loc, sc, &e, &t, &s); 
    23242324        if (e) 
    23252325        {   // It was an expression - 
     
    28552855    } 
    28562856 
    28572857    tf->linkage = sc->linkage; 
    28582858    if (tf->next) 
    28592859    { 
    28602860        tf->next = tf->next->semantic(loc,sc); 
    28612861#if !SARRAYVALUE 
    28622862        if (tf->next->toBasetype()->ty == Tsarray) 
    28632863        {   error(loc, "functions cannot return static array %s", tf->next->toChars()); 
    28642864            tf->next = Type::terror; 
    28652865        } 
    28662866#endif 
    28672867        if (tf->next->toBasetype()->ty == Tfunction) 
    28682868        {   error(loc, "functions cannot return a function"); 
    28692869            tf->next = Type::terror; 
    28702870        } 
    28712871        if (tf->next->toBasetype()->ty == Ttuple) 
    28722872        {   error(loc, "functions cannot return a tuple"); 
    28732873            tf->next = Type::terror; 
    28742874        } 
    2875         if (tf->next->isauto() && !(sc->flags & SCOPEctor)) 
    2876             error(loc, "functions cannot return auto %s", tf->next->toChars()); 
     2875        if (tf->next->isscope() && !(sc->flags & SCOPEctor)) 
     2876            error(loc, "functions cannot return scope %s", tf->next->toChars()); 
    28772877    } 
    28782878 
    28792879    if (tf->parameters) 
    28802880    { 
    28812881        /* Create a scope for evaluating the default arguments for the parameters 
    28822882         */ 
    28832883        Scope *argsc = sc->push(); 
    28842884        argsc->stc = 0;                 // don't inherit storage class 
    28852885        argsc->protection = PROTpublic; 
    28862886 
    28872887        size_t dim = Parameter::dim(tf->parameters); 
    28882888        for (size_t i = 0; i < dim; i++) 
    28892889        {   Parameter *fparam = Parameter::getNth(tf->parameters, i); 
    28902890 
    28912891            tf->inuse++; 
    28922892            fparam->type = fparam->type->semantic(loc, argsc); 
    28932893            if (tf->inuse == 1) tf->inuse--; 
    28942894 
    28952895            Type *t = fparam->type->toBasetype(); 
    28962896 
     
    49954995    if (d->parent && d->toParent()->isModule()) 
    49964996    { 
    49974997        // (e, d) 
    49984998        VarExp *ve; 
    49994999 
    50005000        ve = new VarExp(e->loc, d); 
    50015001        e = new CommaExp(e->loc, e, ve); 
    50025002        e->type = d->type; 
    50035003        return e; 
    50045004    } 
    50055005 
    50065006    de = new DotVarExp(e->loc, e, d); 
    50075007    return de->semantic(sc); 
    50085008} 
    50095009 
    50105010ClassDeclaration *TypeClass::isClassHandle() 
    50115011{ 
    50125012    return sym; 
    50135013} 
    50145014 
    5015 int TypeClass::isauto() 
    5016 { 
    5017     return sym->isauto
     5015int TypeClass::isscope() 
     5016{ 
     5017    return sym->isscope
    50185018} 
    50195019 
    50205020int TypeClass::isBaseOf(Type *t, int *poffset) 
    50215021{ 
    50225022    if (t->ty == Tclass) 
    50235023    {   ClassDeclaration *cd; 
    50245024 
    50255025        cd   = ((TypeClass *)t)->sym; 
    50265026        if (sym->isBaseOf(cd, poffset)) 
    50275027            return 1; 
    50285028    } 
    50295029    return 0; 
    50305030} 
    50315031 
    50325032MATCH TypeClass::implicitConvTo(Type *to) 
    50335033{ 
    50345034    //printf("TypeClass::implicitConvTo('%s')\n", to->toChars()); 
    50355035    if (this == to) 
    50365036        return MATCHexact; 
    50375037 
  • branches/dmd-1.x/src/mtype.h

    r619 r639  
    200200    static char needThisPrefix(); 
    201201    static void init(); 
    202202    d_uns64 size(); 
    203203    virtual d_uns64 size(Loc loc); 
    204204    virtual unsigned alignsize(); 
    205205    virtual Type *semantic(Loc loc, Scope *sc); 
    206206    virtual void toDecoBuffer(OutBuffer *buf); 
    207207    Type *merge(); 
    208208    Type *merge2(); 
    209209    virtual void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); 
    210210    virtual void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 
    211211    void toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod); 
    212212    virtual int isbit(); 
    213213    virtual int isintegral(); 
    214214    virtual int isfloating();   // real, imaginary, or complex 
    215215    virtual int isreal(); 
    216216    virtual int isimaginary(); 
    217217    virtual int iscomplex(); 
    218218    virtual int isscalar(); 
    219219    virtual int isunsigned(); 
    220     virtual int isauto(); 
     220    virtual int isscope(); 
    221221    virtual int isString(); 
    222222    virtual int checkBoolean(); // if can be converted to boolean value 
    223223    void checkDeprecated(Loc loc, Scope *sc); 
    224224    Type *pointerTo(); 
    225225    Type *referenceTo(); 
    226226    Type *arrayOf(); 
    227227    virtual Dsymbol *toDsymbol(Scope *sc); 
    228228    virtual Type *toBasetype(); 
    229229    virtual int isBaseOf(Type *t, int *poffset); 
    230230    virtual MATCH implicitConvTo(Type *to); 
    231231    virtual ClassDeclaration *isClassHandle(); 
    232232    virtual Expression *getProperty(Loc loc, Identifier *ident); 
    233233    virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 
    234234    virtual unsigned memalign(unsigned salign); 
    235235    virtual Expression *defaultInit(Loc loc = 0); 
    236236    virtual Expression *defaultInitLiteral(Loc loc = 0); 
    237237    virtual int isZeroInit(Loc loc = 0);                // if initializer is 0 
    238238    virtual dt_t **toDt(dt_t **pdt); 
    239239    Identifier *getTypeInfoIdent(int internal); 
    240240    virtual MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 
     
    654654 
    655655struct TypeClass : Type 
    656656{ 
    657657    ClassDeclaration *sym; 
    658658 
    659659    TypeClass(ClassDeclaration *sym); 
    660660    d_uns64 size(Loc loc); 
    661661    char *toChars(); 
    662662    Type *syntaxCopy(); 
    663663    Type *semantic(Loc loc, Scope *sc); 
    664664    Dsymbol *toDsymbol(Scope *sc); 
    665665    void toDecoBuffer(OutBuffer *buf); 
    666666    void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 
    667667    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 
    668668    ClassDeclaration *isClassHandle(); 
    669669    int isBaseOf(Type *t, int *poffset); 
    670670    MATCH implicitConvTo(Type *to); 
    671671    Expression *defaultInit(Loc loc); 
    672672    int isZeroInit(Loc loc); 
    673673    MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 
    674     int isauto(); 
     674    int isscope(); 
    675675    int checkBoolean(); 
    676676    TypeInfoDeclaration *getTypeInfoDeclaration(); 
    677677    int hasPointers(); 
    678678    int builtinTypeInfo(); 
    679679#if DMDV2 
    680680    Type *toHeadMutable(); 
    681681    MATCH constConv(Type *to); 
    682682#if CPP_MANGLE 
    683683    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    684684#endif 
    685685#endif 
    686686 
    687687    type *toCtype(); 
    688688 
    689689    Symbol *toSymbol(); 
    690690}; 
    691691 
    692692struct TypeTuple : Type 
    693693{ 
    694694    Parameters *arguments;      // types making up the tuple 
  • branches/dmd-1.x/src/statement.c

    r586 r639  
    353353} 
    354354 
    355355void DeclarationStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally) 
    356356{ 
    357357    //printf("DeclarationStatement::scopeCode()\n"); 
    358358    //print(); 
    359359 
    360360    *sentry = NULL; 
    361361    *sexception = NULL; 
    362362    *sfinally = NULL; 
    363363 
    364364    if (exp) 
    365365    { 
    366366        if (exp->op == TOKdeclaration) 
    367367        { 
    368368            DeclarationExp *de = (DeclarationExp *)(exp); 
    369369            VarDeclaration *v = de->declaration->isVarDeclaration(); 
    370370            if (v) 
    371371            {   Expression *e; 
    372372 
    373                 e = v->callAutoDtor(sc); 
     373                e = v->callScopeDtor(sc); 
    374374                if (e) 
    375375                { 
    376376                    //printf("dtor is: "); e->print(); 
    377377                    *sfinally = new ExpStatement(loc, e); 
    378378                } 
    379379            } 
    380380        } 
    381381    } 
    382382} 
    383383 
    384384void DeclarationStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    385385{ 
    386386    exp->toCBuffer(buf, hgs); 
    387387} 
    388388 
    389389 
    390390/******************************** CompoundStatement ***************************/ 
    391391 
    392392CompoundStatement::CompoundStatement(Loc loc, Statements *s) 
    393393    : Statement(loc) 
     
    16781678            printf("increment: %s\n", increment->toChars()); 
    16791679            printf("body: %s\n", body->toChars()); 
    16801680#endif 
    16811681            s = s->semantic(sc); 
    16821682            break; 
    16831683        } 
    16841684#endif 
    16851685        case Tdelegate: 
    16861686        Lapply: 
    16871687        { 
    16881688            Expression *ec; 
    16891689            Expression *e; 
    16901690            Parameter *a; 
    16911691 
    16921692            Type *tret = func->type->nextOf(); 
    16931693 
    16941694            // Need a variable to hold value from any return statements in body. 
    16951695            if (!sc->func->vresult && tret && tret != Type::tvoid) 
    16961696            { 
    16971697                VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); 
    1698                 v->noauto = 1; 
     1698                v->noscope = 1; 
    16991699                v->semantic(sc); 
    17001700                if (!sc->insert(v)) 
    17011701                    assert(0); 
    17021702                v->parent = sc->func; 
    17031703                sc->func->vresult = v; 
    17041704            } 
    17051705 
    17061706            /* Turn body into the function literal: 
    17071707             *  int delegate(ref T arg) { body } 
    17081708             */ 
    17091709            Parameters *args = new Parameters(); 
    17101710            for (size_t i = 0; i < dim; i++) 
    17111711            {   Parameter *arg = (Parameter *)arguments->data[i]; 
    17121712                Identifier *id; 
    17131713 
    17141714                arg->type = arg->type->semantic(loc, sc); 
    17151715                if (arg->storageClass & STCref) 
    17161716                    id = arg->ident; 
    17171717                else 
    17181718                {   // Make a copy of the ref argument so it isn't 
     
    22062206    // If we can short-circuit evaluate the if statement, don't do the 
    22072207    // semantic analysis of the skipped code. 
    22082208    // This feature allows a limited form of conditional compilation. 
    22092209    condition = condition->optimize(WANTflags); 
    22102210 
    22112211    // Evaluate at runtime 
    22122212    unsigned cs0 = sc->callSuper; 
    22132213    unsigned cs1; 
    22142214 
    22152215    Scope *scd; 
    22162216    if (arg) 
    22172217    {   /* Declare arg, which we will set to be the 
    22182218         * result of condition. 
    22192219         */ 
    22202220        ScopeDsymbol *sym = new ScopeDsymbol(); 
    22212221        sym->parent = sc->scopesym; 
    22222222        scd = sc->push(sym); 
    22232223 
    22242224        Type *t = arg->type ? arg->type : condition->type; 
    22252225        match = new VarDeclaration(loc, t, arg->ident, NULL); 
    2226         match->noauto = 1; 
     2226        match->noscope = 1; 
    22272227        match->semantic(scd); 
    22282228        if (!scd->insert(match)) 
    22292229            assert(0); 
    22302230        match->parent = sc->func; 
    22312231 
    22322232        /* Generate: 
    22332233         *  (arg = condition) 
    22342234         */ 
    22352235        VarExp *v = new VarExp(0, match); 
    22362236        condition = new AssignExp(loc, v, condition); 
    22372237        condition = condition->semantic(scd); 
    22382238    } 
    22392239    else 
    22402240        scd = sc->push(); 
    22412241    ifbody = ifbody->semanticNoScope(scd); 
    22422242    scd->pop(); 
    22432243 
    22442244    cs1 = sc->callSuper; 
    22452245    sc->callSuper = cs0; 
    22462246    if (elsebody) 
     
    32803280            sc->fes->cases->push(this); 
    32813281            // Construct: return cases->dim+1; 
    32823282            s = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 
    32833283        } 
    32843284        else if (fd->type->nextOf()->toBasetype() == Type::tvoid) 
    32853285        { 
    32863286            s = new ReturnStatement(0, NULL); 
    32873287            sc->fes->cases->push(s); 
    32883288 
    32893289            // Construct: { exp; return cases->dim + 1; } 
    32903290            Statement *s1 = new ExpStatement(loc, exp); 
    32913291            Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 
    32923292            s = new CompoundStatement(loc, s1, s2); 
    32933293        } 
    32943294        else 
    32953295        { 
    32963296            // Construct: return vresult; 
    32973297            if (!fd->vresult) 
    32983298            {   // Declare vresult 
    32993299                VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); 
    3300                 v->noauto = 1; 
     3300                v->noscope = 1; 
    33013301                v->semantic(scx); 
    33023302                if (!scx->insert(v)) 
    33033303                    assert(0); 
    33043304                v->parent = fd; 
    33053305                fd->vresult = v; 
    33063306            } 
    33073307 
    33083308            s = new ReturnStatement(0, new VarExp(0, fd->vresult)); 
    33093309            sc->fes->cases->push(s); 
    33103310 
    33113311            // Construct: { vresult = exp; return cases->dim + 1; } 
    33123312            exp = new ConstructExp(loc, new VarExp(0, fd->vresult), exp); 
    33133313            exp = exp->semantic(sc); 
    33143314            Statement *s1 = new ExpStatement(loc, exp); 
    33153315            Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 
    33163316            s = new CompoundStatement(loc, s1, s2); 
    33173317        } 
    33183318        return s; 
    33193319    } 
    33203320 
  • trunk/src/aggregate.h

    r638 r639  
    206206    CtorDeclaration *defaultCtor;       // default constructor 
    207207#endif 
    208208    FuncDeclaration *staticCtor; 
    209209    FuncDeclaration *staticDtor; 
    210210    Array vtbl;                         // Array of FuncDeclaration's making up the vtbl[] 
    211211    Array vtblFinal;                    // More FuncDeclaration's that aren't in vtbl[] 
    212212 
    213213    BaseClasses *baseclasses;           // Array of BaseClass's; first is super, 
    214214                                        // rest are Interface's 
    215215 
    216216    int interfaces_dim; 
    217217    BaseClass **interfaces;             // interfaces[interfaces_dim] for this class 
    218218                                        // (does not include baseClass) 
    219219 
    220220    BaseClasses *vtblInterfaces;        // array of base interfaces that have 
    221221                                        // their own vtbl[] 
    222222 
    223223    TypeInfoClassDeclaration *vclassinfo;       // the ClassInfo object for this ClassDeclaration 
    224224    int com;                            // !=0 if this is a COM class (meaning 
    225225                                        // it derives from IUnknown) 
    226     int isauto;                         // !=0 if this is an auto class 
     226    int isscope;                         // !=0 if this is an auto class 
    227227    int isabstract;                     // !=0 if abstract class 
    228228#if DMDV1 
    229229    int isnested;                       // !=0 if is nested 
    230230    VarDeclaration *vthis;              // 'this' parameter if this class is nested 
    231231#endif 
    232232    int inuse;                          // to prevent recursive attempts 
    233233 
    234234    ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 
    235235    Dsymbol *syntaxCopy(Dsymbol *s); 
    236236    void semantic(Scope *sc); 
    237237    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    238238    int isBaseOf2(ClassDeclaration *cd); 
    239239 
    240240    #define OFFSET_RUNTIME 0x76543210 
    241241    virtual int isBaseOf(ClassDeclaration *cd, int *poffset); 
    242242 
    243243    virtual int isBaseInfoComplete(); 
    244244    Dsymbol *search(Loc, Identifier *ident, int flags); 
    245245#if DMDV2 
    246246    int isFuncHidden(FuncDeclaration *fd); 
  • trunk/src/class.c

    r638 r639  
    179179        {   if (object) 
    180180                object->error("%s", msg); 
    181181            object = this; 
    182182        } 
    183183 
    184184        //if (id == Id::ClassInfo) 
    185185        if (id == Id::TypeInfo_Class) 
    186186        {   if (classinfo) 
    187187                classinfo->error("%s", msg); 
    188188            classinfo = this; 
    189189        } 
    190190 
    191191        if (id == Id::ModuleInfo) 
    192192        {   if (Module::moduleinfo) 
    193193                Module::moduleinfo->error("%s", msg); 
    194194            Module::moduleinfo = this; 
    195195        } 
    196196    } 
    197197 
    198198    com = 0; 
    199     isauto = 0; 
     199    isscope = 0; 
    200200    isabstract = 0; 
    201201    inuse = 0; 
    202202} 
    203203 
    204204Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s) 
    205205{ 
    206206    ClassDeclaration *cd; 
    207207 
    208208    //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars()); 
    209209    if (s) 
    210210        cd = (ClassDeclaration *)s; 
    211211    else 
    212212        cd = new ClassDeclaration(loc, ident, NULL); 
    213213 
    214214    cd->storage_class |= storage_class; 
    215215 
    216216    cd->baseclasses->setDim(this->baseclasses->dim); 
    217217    for (int i = 0; i < cd->baseclasses->dim; i++) 
    218218    { 
    219219        BaseClass *b = (BaseClass *)this->baseclasses->data[i]; 
     
    462462    } 
    463463 
    464464    interfaces_dim = baseclasses->dim; 
    465465    interfaces = (BaseClass **)baseclasses->data; 
    466466 
    467467 
    468468    if (baseClass) 
    469469    { 
    470470        if (baseClass->storage_class & STCfinal) 
    471471            error("cannot inherit from final class %s", baseClass->toChars()); 
    472472 
    473473        interfaces_dim--; 
    474474        interfaces++; 
    475475 
    476476        // Copy vtbl[] from base class 
    477477        vtbl.setDim(baseClass->vtbl.dim); 
    478478        memcpy(vtbl.data, baseClass->vtbl.data, sizeof(void *) * vtbl.dim); 
    479479 
    480480        // Inherit properties from base class 
    481481        com = baseClass->isCOMclass(); 
    482         isauto = baseClass->isauto
     482        isscope = baseClass->isscope
    483483        vthis = baseClass->vthis; 
    484484        storage_class |= baseClass->storage_class & STC_TYPECTOR; 
    485485    } 
    486486    else 
    487487    { 
    488488        // No base class, so this is the root of the class hierarchy 
    489489        vtbl.setDim(0); 
    490490        vtbl.push(this);                // leave room for classinfo as first member 
    491491    } 
    492492 
    493493    protection = sc->protection; 
    494494    storage_class |= sc->stc; 
    495495 
    496496    if (sizeok == 0) 
    497497    { 
    498498        interfaceSemantic(sc); 
    499499 
    500500        for (i = 0; i < members->dim; i++) 
    501501        { 
    502502            Dsymbol *s = (Dsymbol *)members->data[i]; 
     
    546546                    {   AggregateDeclaration *ad = fd->isMember2(); 
    547547                        if (ad) 
    548548                            t = ad->handle; 
    549549                        else 
    550550                        { 
    551551                            t = Type::tvoidptr; 
    552552                        } 
    553553                    } 
    554554                    else 
    555555                        assert(0); 
    556556                    if (t->ty == Tstruct)       // ref to struct 
    557557                        t = Type::tvoidptr; 
    558558                    assert(!vthis); 
    559559                    vthis = new ThisDeclaration(loc, t); 
    560560                    members->push(vthis); 
    561561                } 
    562562            } 
    563563        } 
    564564    } 
    565565 
    566     if (storage_class & (STCauto | STCscope)) 
    567         isauto = 1; 
     566    if (storage_class & STCauto) 
     567        error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?"); 
     568    if (storage_class & STCscope) 
     569        isscope = 1; 
    568570    if (storage_class & STCabstract) 
    569571        isabstract = 1; 
    570572    if (storage_class & STCimmutable) 
    571573        type = type->invariantOf(); 
    572574    else if (storage_class & STCconst) 
    573575        type = type->constOf(); 
    574576    else if (storage_class & STCshared) 
    575577        type = type->sharedOf(); 
    576578 
    577579    sc = sc->push(this); 
    578580    sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 
    579581                 STCabstract | STCdeprecated | STC_TYPECTOR | STCtls | STCgshared); 
    580582    sc->stc |= storage_class & STC_TYPECTOR; 
    581583    sc->parent = this; 
    582584    sc->inunion = 0; 
    583585 
    584586    if (isCOMclass()) 
    585587    { 
    586588#if _WIN32 
    587589        sc->linkage = LINKwindows; 
  • trunk/src/clone.c

    r581 r639  
    140140    fparams->push(param); 
    141141    Type *ftype = new TypeFunction(fparams, handle, FALSE, LINKd); 
    142142#if STRUCTTHISREF 
    143143    ((TypeFunction *)ftype)->isref = 1; 
    144144#endif 
    145145 
    146146    fop = new FuncDeclaration(0, 0, Id::assign, STCundefined, ftype); 
    147147 
    148148    Expression *e = NULL; 
    149149    if (postblit) 
    150150    {   /* Swap: 
    151151         *    tmp = *this; *this = s; tmp.dtor(); 
    152152         */ 
    153153        //printf("\tswap copy\n"); 
    154154        Identifier *idtmp = Lexer::uniqueId("__tmp"); 
    155155        VarDeclaration *tmp; 
    156156        AssignExp *ec = NULL; 
    157157        if (dtor) 
    158158        { 
    159159            tmp = new VarDeclaration(0, type, idtmp, new VoidInitializer(0)); 
    160             tmp->noauto = 1; 
     160            tmp->noscope = 1; 
    161161            tmp->storage_class |= STCctfe; 
    162162            e = new DeclarationExp(0, tmp); 
    163163            ec = new AssignExp(0, 
    164164                new VarExp(0, tmp), 
    165165#if STRUCTTHISREF 
    166166                new ThisExp(0) 
    167167#else 
    168168                new PtrExp(0, new ThisExp(0)) 
    169169#endif 
    170170                ); 
    171171            ec->op = TOKblit; 
    172172            e = Expression::combine(e, ec); 
    173173        } 
    174174        ec = new AssignExp(0, 
    175175#if STRUCTTHISREF 
    176176                new ThisExp(0), 
    177177#else 
    178178                new PtrExp(0, new ThisExp(0)), 
    179179#endif 
    180180                new IdentifierExp(0, Id::p)); 
  • trunk/src/declaration.c

    r610 r639  
    635635 
    636636VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) 
    637637    : Declaration(id) 
    638638{ 
    639639    //printf("VarDeclaration('%s')\n", id->toChars()); 
    640640#ifdef DEBUG 
    641641    if (!type && !init) 
    642642    {   printf("VarDeclaration('%s')\n", id->toChars()); 
    643643        //*(char*)0=0; 
    644644    } 
    645645#endif 
    646646    assert(type || init); 
    647647    this->type = type; 
    648648    this->init = init; 
    649649#ifdef _DH 
    650650    this->htype = NULL; 
    651651    this->hinit = NULL; 
    652652#endif 
    653653    this->loc = loc; 
    654654    offset = 0; 
    655     noauto = 0; 
     655    noscope = 0; 
    656656#if DMDV2 
    657657    isargptr = FALSE; 
    658658#endif 
    659659#if DMDV1 
    660660    nestedref = 0; 
    661661#endif 
    662662    ctorinit = 0; 
    663663    aliassym = NULL; 
    664664    onstack = 0; 
    665665    canassign = 0; 
    666666    value = NULL; 
    667667    rundtor = NULL; 
    668668} 
    669669 
    670670Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) 
    671671{ 
    672672    //printf("VarDeclaration::syntaxCopy(%s)\n", toChars()); 
    673673 
    674674    VarDeclaration *sv; 
    675675    if (s) 
     
    807807 
    808808    Type *tb = type->toBasetype(); 
    809809    if (tb->ty == Tvoid && !(storage_class & STClazy)) 
    810810    {   error("voids have no value"); 
    811811        type = Type::terror; 
    812812        tb = type; 
    813813    } 
    814814    if (tb->ty == Tfunction) 
    815815    {   error("cannot be declared to be a function"); 
    816816        type = Type::terror; 
    817817        tb = type; 
    818818    } 
    819819    if (tb->ty == Tstruct) 
    820820    {   TypeStruct *ts = (TypeStruct *)tb; 
    821821 
    822822        if (!ts->sym->members) 
    823823        { 
    824824            error("no definition of struct %s", ts->toChars()); 
    825825        } 
    826826    } 
     827    if ((storage_class & STCauto) && !inferred) 
     828       error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?"); 
    827829 
    828830    if (tb->ty == Ttuple) 
    829831    {   /* Instead, declare variables for each of the tuple elements 
    830832         * and add those. 
    831833         */ 
    832834        TypeTuple *tt = (TypeTuple *)tb; 
    833835        size_t nelems = Parameter::dim(tt->arguments); 
    834836        Objects *exps = new Objects(); 
    835837        exps->setDim(nelems); 
    836838        Expression *ie = init ? init->toExpression() : NULL; 
    837839 
    838840        for (size_t i = 0; i < nelems; i++) 
    839841        {   Parameter *arg = Parameter::getNth(tt->arguments, i); 
    840842 
    841843            OutBuffer buf; 
    842844            buf.printf("_%s_field_%zu", ident->toChars(), i); 
    843845            buf.writeByte(0); 
    844846            const char *name = (const char *)buf.extractData(); 
    845847            Identifier *id = Lexer::idPool(name); 
    846848 
     
    958960                error("cannot use template to add field to aggregate '%s'", ad->toChars()); 
    959961            } 
    960962        } 
    961963    } 
    962964 
    963965#if DMDV2 
    964966    if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 
    965967        ident != Id::This) 
    966968    { 
    967969        error("only parameters or foreach declarations can be ref"); 
    968970    } 
    969971 
    970972    if ((storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest) || 
    971973        isDataseg()) && 
    972974        type->hasWild()) 
    973975    { 
    974976        error("only fields, parameters or stack based variables can be inout"); 
    975977    } 
    976978#endif 
    977979 
    978     if (type->isauto() && !noauto
     980    if (type->isscope() && !noscope
    979981    { 
    980982        if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd) 
    981983        { 
    982984            error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope"); 
    983985        } 
    984986 
    985         if (!(storage_class & (STCauto | STCscope))) 
     987        if (!(storage_class & STCscope)) 
    986988        { 
    987989            if (!(storage_class & STCparameter) && ident != Id::withSym) 
    988990                error("reference to scope class must be scope"); 
    989991        } 
    990992    } 
    991993 
    992994    if (!init && !fd) 
    993995    {   // If not mutable, initializable by constructor only 
    994996        storage_class |= STCctorinit; 
    995997    } 
    996998 
    997999    if (init) 
    9981000        storage_class |= STCinit;     // remember we had an explicit initializer 
    9991001    else if (storage_class & STCmanifest) 
    10001002        error("manifest constants must have initializers"); 
    10011003 
    10021004    enum TOK op = TOKconstruct; 
    10031005    if (!init && !sc->inunion && !isStatic() && fd && 
    10041006        (!(storage_class & (STCfield | STCin | STCforeach | STCparameter | STCresult)) 
    10051007         || (storage_class & STCout)) && 
     
    15731575 
    15741576int VarDeclaration::isCTFE() 
    15751577{ 
    15761578    return (storage_class & STCctfe) != 0; // || !isDataseg(); 
    15771579} 
    15781580 
    15791581int VarDeclaration::hasPointers() 
    15801582{ 
    15811583    //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); 
    15821584    return (!isDataseg() && type->hasPointers()); 
    15831585} 
    15841586 
    15851587/****************************************** 
    15861588 * Return TRUE if variable needs to call the destructor. 
    15871589 */ 
    15881590 
    15891591int VarDeclaration::needsAutoDtor() 
    15901592{ 
    15911593    //printf("VarDeclaration::needsAutoDtor() %s\n", toChars()); 
    15921594 
    1593     if (noauto || storage_class & STCnodtor) 
     1595    if (noscope || storage_class & STCnodtor) 
    15941596        return FALSE; 
    15951597 
    15961598    // Destructors for structs and arrays of structs 
    15971599    Type *tv = type->toBasetype(); 
    15981600    while (tv->ty == Tsarray) 
    15991601    {   TypeSArray *ta = (TypeSArray *)tv; 
    16001602        tv = tv->nextOf()->toBasetype(); 
    16011603    } 
    16021604    if (tv->ty == Tstruct) 
    16031605    {   TypeStruct *ts = (TypeStruct *)tv; 
    16041606        StructDeclaration *sd = ts->sym; 
    16051607        if (sd->dtor) 
    16061608            return TRUE; 
    16071609    } 
    16081610 
    16091611    // Destructors for classes 
    16101612    if (storage_class & (STCauto | STCscope)) 
    16111613    { 
    16121614        if (type->isClassHandle()) 
    16131615            return TRUE; 
    16141616    } 
    16151617    return FALSE; 
    16161618} 
    16171619 
    16181620 
    16191621/****************************************** 
    1620  * If a variable has an auto destructor call, return call for it. 
     1622 * If a variable has a scope destructor call, return call for it. 
    16211623 * Otherwise, return NULL. 
    16221624 */ 
    16231625 
    1624 Expression *VarDeclaration::callAutoDtor(Scope *sc) 
     1626Expression *VarDeclaration::callScopeDtor(Scope *sc) 
    16251627{   Expression *e = NULL; 
    16261628 
    1627     //printf("VarDeclaration::callAutoDtor() %s\n", toChars()); 
    1628  
    1629     if (noauto || storage_class & STCnodtor) 
     1629    //printf("VarDeclaration::callScopeDtor() %s\n", toChars()); 
     1630 
     1631    if (noscope || storage_class & STCnodtor) 
    16301632        return NULL; 
    16311633 
    16321634    // Destructors for structs and arrays of structs 
    16331635    bool array = false; 
    16341636    Type *tv = type->toBasetype(); 
    16351637    while (tv->ty == Tsarray) 
    16361638    {   TypeSArray *ta = (TypeSArray *)tv; 
    16371639        array = true; 
    16381640        tv = tv->nextOf()->toBasetype(); 
    16391641    } 
    16401642    if (tv->ty == Tstruct) 
    16411643    {   TypeStruct *ts = (TypeStruct *)tv; 
    16421644        StructDeclaration *sd = ts->sym; 
    16431645        if (sd->dtor) 
    16441646        { 
    16451647            if (array) 
    16461648            { 
    16471649                // Typeinfo.destroy(cast(void*)&v); 
    16481650                Expression *ea = new SymOffExp(loc, this, 0, 0); 
    16491651                ea = new CastExp(loc, ea, Type::tvoid->pointerTo()); 
     
    18801882    : TypeInfoDeclaration(tinfo, 0) 
    18811883{ 
    18821884    type = Type::typeinfodelegate->type; 
    18831885} 
    18841886 
    18851887/***************************** TypeInfoTupleDeclaration **********************/ 
    18861888 
    18871889TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) 
    18881890    : TypeInfoDeclaration(tinfo, 0) 
    18891891{ 
    18901892    type = Type::typeinfotypelist->type; 
    18911893} 
    18921894 
    18931895/********************************* ThisDeclaration ****************************/ 
    18941896 
    18951897// For the "this" parameter to member functions 
    18961898 
    18971899ThisDeclaration::ThisDeclaration(Loc loc, Type *t) 
    18981900   : VarDeclaration(loc, t, Id::This, NULL) 
    18991901{ 
    1900     noauto = 1; 
     1902    noscope = 1; 
    19011903} 
    19021904 
    19031905Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) 
    19041906{ 
    19051907    assert(0);          // should never be produced by syntax 
    19061908    return NULL; 
    19071909} 
    19081910 
  • trunk/src/declaration.h

    r591 r639  
    123123    const char *kind(); 
    124124    unsigned size(Loc loc); 
    125125    void checkModify(Loc loc, Scope *sc, Type *t); 
    126126 
    127127    void emitComment(Scope *sc); 
    128128    void toJsonBuffer(OutBuffer *buf); 
    129129    void toDocBuffer(OutBuffer *buf); 
    130130 
    131131    char *mangle(); 
    132132    int isStatic() { return storage_class & STCstatic; } 
    133133    virtual int isDelete(); 
    134134    virtual int isDataseg(); 
    135135    virtual int isThreadlocal(); 
    136136    virtual int isCodeseg(); 
    137137    int isCtorinit()     { return storage_class & STCctorinit; } 
    138138    int isFinal()        { return storage_class & STCfinal; } 
    139139    int isAbstract()     { return storage_class & STCabstract; } 
    140140    int isConst()        { return storage_class & STCconst; } 
    141141    int isImmutable()    { return storage_class & STCimmutable; } 
    142142    int isAuto()         { return storage_class & STCauto; } 
    143     int isScope()        { return storage_class & (STCscope | STCauto); } 
     143    int isScope()        { return storage_class & STCscope; } 
    144144    int isSynchronized() { return storage_class & STCsynchronized; } 
    145145    int isParameter()    { return storage_class & STCparameter; } 
    146146    int isDeprecated()   { return storage_class & STCdeprecated; } 
    147147    int isOverride()     { return storage_class & STCoverride; } 
    148148    int isResult()       { return storage_class & STCresult; } 
    149149 
    150150    int isIn()    { return storage_class & STCin; } 
    151151    int isOut()   { return storage_class & STCout; } 
    152152    int isRef()   { return storage_class & STCref; } 
    153153 
    154154    enum PROT prot(); 
    155155 
    156156    Declaration *isDeclaration() { return this; } 
    157157}; 
    158158 
    159159/**************************************************************/ 
    160160 
    161161struct TupleDeclaration : Declaration 
    162162{ 
    163163    Objects *objects; 
     
    222222    const char *kind(); 
    223223    Type *getType(); 
    224224    Dsymbol *toAlias(); 
    225225    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    226226#ifdef _DH 
    227227    Type *htype; 
    228228    Dsymbol *haliassym; 
    229229#endif 
    230230 
    231231    void toDocBuffer(OutBuffer *buf); 
    232232 
    233233    AliasDeclaration *isAliasDeclaration() { return this; } 
    234234}; 
    235235 
    236236/**************************************************************/ 
    237237 
    238238struct VarDeclaration : Declaration 
    239239{ 
    240240    Initializer *init; 
    241241    unsigned offset; 
    242     int noauto;                 // no auto semantics 
     242    int noscope;                 // no auto semantics 
    243243#if DMDV2 
    244244    FuncDeclarations nestedrefs; // referenced by these lexically nested functions 
    245245    bool isargptr;              // if parameter that _argptr points to 
    246246#else 
    247247    int nestedref;              // referenced by a lexically nested function 
    248248#endif 
    249249    int ctorinit;               // it has been initialized in a ctor 
    250250    int onstack;                // 1: it has been allocated on the stack 
    251251                                // 2: on stack, run destructor anyway 
    252252    int canassign;              // it can be assigned to 
    253253    Dsymbol *aliassym;          // if redone as alias to another symbol 
    254254    Expression *value;          // when interpreting, this is the value 
    255255                                // (NULL if value not determinable) 
    256256#if DMDV2 
    257257    VarDeclaration *rundtor;    // if !NULL, rundtor is tested at runtime to see 
    258258                                // if the destructor should be run. Used to prevent 
    259259                                // dtor calls on postblitted vars 
    260260#endif 
    261261 
    262262    VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init); 
    263263    Dsymbol *syntaxCopy(Dsymbol *); 
    264264    void semantic(Scope *sc); 
    265265    void semantic2(Scope *sc); 
    266266    const char *kind(); 
    267267    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    268268#ifdef _DH 
    269269    Type *htype; 
    270270    Initializer *hinit; 
    271271#endif 
    272272    int needThis(); 
    273273    int isImportedSymbol(); 
    274274    int isDataseg(); 
    275275    int isThreadlocal(); 
    276276    int isCTFE(); 
    277277    int hasPointers(); 
    278278#if DMDV2 
    279279    int canTakeAddressOf(); 
    280280    int needsAutoDtor(); 
    281281#endif 
    282     Expression *callAutoDtor(Scope *sc); 
     282    Expression *callScopeDtor(Scope *sc); 
    283283    ExpInitializer *getExpInitializer(); 
    284284    Expression *getConstInitializer(); 
    285285    void checkCtorConstInit(); 
    286286    void checkNestedReference(Scope *sc, Loc loc); 
    287287    Dsymbol *toAlias(); 
    288288 
    289289    Symbol *toSymbol(); 
    290290    void toObjFile(int multiobj);                       // compile to .obj file 
    291291    int cvMember(unsigned char *p); 
    292292 
    293293    // Eliminate need for dynamic_cast 
    294294    VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } 
    295295}; 
    296296 
    297297/**************************************************************/ 
    298298 
    299299// This is a shell around a back end symbol 
    300300 
    301301struct SymbolDeclaration : Declaration 
    302302{ 
  • trunk/src/expression.c

    r634 r639  
    43244324} 
    43254325 
    43264326char *VarExp::toChars() 
    43274327{ 
    43284328    return var->toChars(); 
    43294329} 
    43304330 
    43314331void VarExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 
    43324332{ 
    43334333    buf->writestring(var->toChars()); 
    43344334} 
    43354335 
    43364336void VarExp::checkEscape() 
    43374337{ 
    43384338    VarDeclaration *v = var->isVarDeclaration(); 
    43394339    if (v) 
    43404340    {   Type *tb = v->type->toBasetype(); 
    43414341        // if reference type 
    43424342        if (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tclass) 
    43434343        { 
    4344             if ((v->isAuto() || v->isScope()) && !v->noauto
     4344            if (v->isScope() && !v->noscope
    43454345                error("escaping reference to scope local %s", v->toChars()); 
    43464346            else if (v->storage_class & STCvariadic) 
    43474347                error("escaping reference to variadic parameter %s", v->toChars()); 
    43484348        } 
    43494349    } 
    43504350} 
    43514351 
    43524352void VarExp::checkEscapeRef() 
    43534353{ 
    43544354    VarDeclaration *v = var->isVarDeclaration(); 
    43554355    if (v) 
    43564356    { 
    43574357        if (!v->isDataseg() && !(v->storage_class & (STCref | STCout))) 
    43584358            error("escaping reference to local variable %s", v->toChars()); 
    43594359    } 
    43604360} 
    43614361 
    43624362#if DMDV2 
    43634363int VarExp::isLvalue() 
    43644364{ 
  • trunk/src/func.c

    r611 r639  
    10901090            assert(type->nextOf()); 
    10911091            if (type->nextOf()->ty == Tvoid) 
    10921092            { 
    10931093                if (outId) 
    10941094                    error("void functions have no result"); 
    10951095            } 
    10961096            else 
    10971097            { 
    10981098                if (!outId) 
    10991099                    outId = Id::result;         // provide a default 
    11001100            } 
    11011101 
    11021102            if (outId) 
    11031103            {   // Declare result variable 
    11041104                Loc loc = this->loc; 
    11051105 
    11061106                if (fensure) 
    11071107                    loc = fensure->loc; 
    11081108 
    11091109                VarDeclaration *v = new VarDeclaration(loc, type->nextOf(), outId, NULL); 
    1110                 v->noauto = 1; 
     1110                v->noscope = 1; 
    11111111                v->storage_class |= STCresult; 
    11121112#if DMDV2 
    11131113                if (!isVirtual()) 
    11141114                    v->storage_class |= STCconst; 
    11151115                if (f->isref) 
    11161116                { 
    11171117                    v->storage_class |= STCref | STCforeach; 
    11181118                } 
    11191119#endif 
    11201120                sc2->incontract--; 
    11211121                v->semantic(sc2); 
    11221122                sc2->incontract++; 
    11231123                if (!sc2->insert(v)) 
    11241124                    error("out result %s is already defined", v->toChars()); 
    11251125                v->parent = this; 
    11261126                vresult = v; 
    11271127 
    11281128                // vresult gets initialized with the function return value 
    11291129                // in ReturnStatement::semantic() 
    11301130            } 
     
    15011501 
    15021502            fbody = new CompoundStatement(0, a); 
    15031503#if DMDV2 
    15041504            /* Append destructor calls for parameters as finally blocks. 
    15051505             */ 
    15061506            if (parameters) 
    15071507            {   for (size_t i = 0; i < parameters->dim; i++) 
    15081508                { 
    15091509                    VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 
    15101510 
    15111511                    if (v->storage_class & (STCref | STCout)) 
    15121512                        continue; 
    15131513 
    15141514                    /* Don't do this for static arrays, since static 
    15151515                     * arrays are called by reference. Remove this 
    15161516                     * when we change them to call by value. 
    15171517                     */ 
    15181518                    if (v->type->toBasetype()->ty == Tsarray) 
    15191519                        continue; 
    15201520 
    1521                     Expression *e = v->callAutoDtor(sc2); 
     1521                    Expression *e = v->callScopeDtor(sc2); 
    15221522                    if (e) 
    15231523                    {   Statement *s = new ExpStatement(0, e); 
    15241524                        s = s->semantic(sc2); 
    15251525                        if (fbody->blockExit() == BEfallthru) 
    15261526                            fbody = new CompoundStatement(0, fbody, s); 
    15271527                        else 
    15281528                            fbody = new TryFinallyStatement(0, fbody, s); 
    15291529                    } 
    15301530                } 
    15311531            } 
    15321532#endif 
    15331533 
    15341534#if 1 
    15351535            if (isSynchronized()) 
    15361536            {   /* Wrap the entire function body in a synchronized statement 
    15371537                 */ 
    15381538                ClassDeclaration *cd = parent->isClassDeclaration(); 
    15391539                if (cd) 
    15401540                { 
    15411541#if TARGET_WINDOS 
  • trunk/src/mtype.c

    r638 r639  
    15591559int Type::iscomplex() 
    15601560{ 
    15611561    return FALSE; 
    15621562} 
    15631563 
    15641564int Type::isscalar() 
    15651565{ 
    15661566    return FALSE; 
    15671567} 
    15681568 
    15691569int Type::isunsigned() 
    15701570{ 
    15711571    return FALSE; 
    15721572} 
    15731573 
    15741574ClassDeclaration *Type::isClassHandle() 
    15751575{ 
    15761576    return NULL; 
    15771577} 
    15781578 
    1579 int Type::isauto() 
     1579int Type::isscope() 
    15801580{ 
    15811581    return FALSE; 
    15821582} 
    15831583 
    15841584int Type::isString() 
    15851585{ 
    15861586    return FALSE; 
    15871587} 
    15881588 
    15891589/************************** 
    15901590 * Given: 
    15911591 *      T a, b; 
    15921592 * Can we assign: 
    15931593 *      a = b; 
    15941594 * ? 
    15951595 */ 
    15961596int Type::isAssignable() 
    15971597{ 
    15981598    return TRUE; 
    15991599} 
     
    33803380 
    33813381            if (d >= tt->arguments->dim) 
    33823382            {   error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); 
    33833383                return Type::terror; 
    33843384            } 
    33853385            Parameter *arg = (Parameter *)tt->arguments->data[(size_t)d]; 
    33863386            return arg->type; 
    33873387        } 
    33883388        case Tstruct: 
    33893389        {   TypeStruct *ts = (TypeStruct *)tbn; 
    33903390            if (ts->sym->isnested) 
    33913391                error(loc, "cannot have array of inner structs %s", ts->toChars()); 
    33923392            break; 
    33933393        } 
    33943394        case Tfunction: 
    33953395        case Tnone: 
    33963396            error(loc, "can't have array of %s", tbn->toChars()); 
    33973397            tbn = next = tint32; 
    33983398            break; 
    33993399    } 
    3400     if (tbn->isauto()) 
    3401         error(loc, "cannot have array of auto %s", tbn->toChars()); 
     3400    if (tbn->isscope()) 
     3401        error(loc, "cannot have array of scope %s", tbn->toChars()); 
    34023402    return merge(); 
    34033403} 
    34043404 
    34053405void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag) 
    34063406{ 
    34073407    Type::toDecoBuffer(buf, flag); 
    34083408    if (dim) 
    34093409        buf->printf("%ju", dim->toInteger()); 
    34103410    if (next) 
    34113411        /* Note that static arrays are value types, so 
    34123412         * for a parameter, propagate the 0x100 to the next 
    34133413         * level, since for T[4][3], any const should apply to the T, 
    34143414         * not the [4]. 
    34153415         */ 
    34163416        next->toDecoBuffer(buf,  (flag & 0x100) ? flag : mod); 
    34173417} 
    34183418 
    34193419void TypeSArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 
    34203420{ 
    34213421    if (mod != this->mod) 
     
    36093609Type *TypeDArray::semantic(Loc loc, Scope *sc) 
    36103610{   Type *tn = next; 
    36113611 
    36123612    tn = next->semantic(loc,sc); 
    36133613    Type *tbn = tn->toBasetype(); 
    36143614    switch (tbn->ty) 
    36153615    { 
    36163616        case Tfunction: 
    36173617        case Tnone: 
    36183618        case Ttuple: 
    36193619            error(loc, "can't have array of %s", tbn->toChars()); 
    36203620            tn = next = tint32; 
    36213621            break; 
    36223622        case Tstruct: 
    36233623        {   TypeStruct *ts = (TypeStruct *)tbn; 
    36243624            if (ts->sym->isnested) 
    36253625                error(loc, "cannot have array of inner structs %s", ts->toChars()); 
    36263626            break; 
    36273627        } 
    36283628    } 
    3629     if (tn->isauto()) 
    3630         error(loc, "cannot have array of auto %s", tn->toChars()); 
     3629    if (tn->isscope()) 
     3630        error(loc, "cannot have array of scope %s", tn->toChars()); 
    36313631 
    36323632    next = tn; 
    36333633    transitive(); 
    36343634    return merge(); 
    36353635} 
    36363636 
    36373637void TypeDArray::toDecoBuffer(OutBuffer *buf, int flag) 
    36383638{ 
    36393639    Type::toDecoBuffer(buf, flag); 
    36403640    if (next) 
    36413641        next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); 
    36423642} 
    36433643 
    36443644void TypeDArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 
    36453645{ 
    36463646    if (mod != this->mod) 
    36473647    {   toCBuffer3(buf, hgs, mod); 
    36483648        return; 
    36493649    } 
    36503650    if (equals(tstring)) 
     
    38123812Type *TypeNewArray::semantic(Loc loc, Scope *sc) 
    38133813{   Type *tn = next; 
    38143814 
    38153815    tn = next->semantic(loc,sc); 
    38163816    Type *tbn = tn->toBasetype(); 
    38173817    switch (tbn->ty) 
    38183818    { 
    38193819        case Tfunction: 
    38203820        case Tnone: 
    38213821        case Ttuple: 
    38223822            error(loc, "can't have array of %s", tbn->toChars()); 
    38233823            tn = next = tint32; 
    38243824            break; 
    38253825        case Tstruct: 
    38263826        {   TypeStruct *ts = (TypeStruct *)tbn; 
    38273827            if (ts->sym->isnested) 
    38283828                error(loc, "cannot have array of inner structs %s", ts->toChars()); 
    38293829            break; 
    38303830        } 
    38313831    } 
    3832     if (tn->isauto()) 
    3833         error(loc, "cannot have array of auto %s", tn->toChars()); 
     3832    if (tn->isscope()) 
     3833        error(loc, "cannot have array of scope %s", tn->toChars()); 
    38343834 
    38353835    next = tn; 
    38363836    transitive(); 
    38373837    return merge(); 
    38383838} 
    38393839 
    38403840void TypeNewArray::toDecoBuffer(OutBuffer *buf, int flag) 
    38413841{ 
    38423842    Type::toDecoBuffer(buf, flag); 
    38433843    buf->writeByte('e'); 
    38443844    if (next) 
    38453845        next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); 
    38463846} 
    38473847 
    38483848void TypeNewArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 
    38493849{ 
    38503850    if (mod != this->mod) 
    38513851    {   toCBuffer3(buf, hgs, mod); 
    38523852        return; 
    38533853    } 
     
    39403940    switch (index->toBasetype()->ty) 
    39413941    { 
    39423942        case Tbool: 
    39433943        case Tfunction: 
    39443944        case Tvoid: 
    39453945        case Tnone: 
    39463946        case Ttuple: 
    39473947            error(loc, "can't have associative array key of %s", index->toBasetype()->toChars()); 
    39483948            return Type::terror; 
    39493949    } 
    39503950    next = next->semantic(loc,sc); 
    39513951    transitive(); 
    39523952 
    39533953    switch (next->toBasetype()->ty) 
    39543954    { 
    39553955        case Tfunction: 
    39563956        case Tnone: 
    39573957            error(loc, "can't have associative array of %s", next->toChars()); 
    39583958            return Type::terror; 
    39593959    } 
    3960     if (next->isauto()) 
    3961     {   error(loc, "cannot have array of auto %s", next->toChars()); 
     3960    if (next->isscope()) 
     3961    {   error(loc, "cannot have array of scope %s", next->toChars()); 
    39623962        return Type::terror; 
    39633963    } 
    39643964    return merge(); 
    39653965} 
    39663966 
    39673967StructDeclaration *TypeAArray::getImpl() 
    39683968{ 
    39693969    // Do it lazily 
    39703970    if (!impl) 
    39713971    { 
    39723972        Type *index = this->index; 
    39733973        Type *next = this->next; 
    39743974        if (index->reliesOnTident() || next->reliesOnTident()) 
    39753975        { 
    39763976            error(loc, "cannot create associative array %s", toChars()); 
    39773977            index = terror; 
    39783978            next = terror; 
    39793979        } 
    39803980        /* This is really a proxy for the template instance AssocArray!(index, next) 
    39813981         * But the instantiation can fail if it is a template specialization field 
     
    48404840        } 
    48414841 
    48424842    bool wildreturn = FALSE; 
    48434843    if (tf->next) 
    48444844    { 
    48454845        tf->next = tf->next->semantic(loc,sc); 
    48464846#if !SARRAYVALUE 
    48474847        if (tf->next->toBasetype()->ty == Tsarray) 
    48484848        {   error(loc, "functions cannot return static array %s", tf->next->toChars()); 
    48494849            tf->next = Type::terror; 
    48504850        } 
    48514851#endif 
    48524852        if (tf->next->toBasetype()->ty == Tfunction) 
    48534853        {   error(loc, "functions cannot return a function"); 
    48544854            tf->next = Type::terror; 
    48554855        } 
    48564856        if (tf->next->toBasetype()->ty == Ttuple) 
    48574857        {   error(loc, "functions cannot return a tuple"); 
    48584858            tf->next = Type::terror; 
    48594859        } 
    4860         if (tf->next->isauto() && !(sc->flags & SCOPEctor)) 
     4860        if (tf->next->isscope() && !(sc->flags & SCOPEctor)) 
    48614861            error(loc, "functions cannot return scope %s", tf->next->toChars()); 
    48624862        if (tf->next->toBasetype()->ty == Tvoid) 
    48634863            tf->isref = FALSE;                  // rewrite "ref void" as just "void" 
    48644864        if (tf->next->isWild()) 
    48654865            wildreturn = TRUE; 
    48664866    } 
    48674867 
    48684868    bool wildparams = FALSE; 
    48694869    bool wildsubparams = FALSE; 
    48704870    if (tf->parameters) 
    48714871    { 
    48724872        /* Create a scope for evaluating the default arguments for the parameters 
    48734873         */ 
    48744874        Scope *argsc = sc->push(); 
    48754875        argsc->stc = 0;                 // don't inherit storage class 
    48764876        argsc->protection = PROTpublic; 
    48774877 
    48784878        size_t dim = Parameter::dim(tf->parameters); 
    48794879        for (size_t i = 0; i < dim; i++) 
    48804880        {   Parameter *fparam = Parameter::getNth(tf->parameters, i); 
     
    74027402 
    74037403    if (d->parent && d->toParent()->isModule()) 
    74047404    { 
    74057405        // (e, d) 
    74067406 
    74077407        VarExp *ve = new VarExp(e->loc, d, 1); 
    74087408        e = new CommaExp(e->loc, e, ve); 
    74097409        e->type = d->type; 
    74107410        return e; 
    74117411    } 
    74127412 
    74137413    DotVarExp *de = new DotVarExp(e->loc, e, d); 
    74147414    return de->semantic(sc); 
    74157415} 
    74167416 
    74177417ClassDeclaration *TypeClass::isClassHandle() 
    74187418{ 
    74197419    return sym; 
    74207420} 
    74217421 
    7422 int TypeClass::isauto() 
    7423 { 
    7424     return sym->isauto
     7422int TypeClass::isscope() 
     7423{ 
     7424    return sym->isscope
    74257425} 
    74267426 
    74277427int TypeClass::isBaseOf(Type *t, int *poffset) 
    74287428{ 
    74297429    if (t->ty == Tclass) 
    74307430    {   ClassDeclaration *cd; 
    74317431 
    74327432        cd   = ((TypeClass *)t)->sym; 
    74337433        if (sym->isBaseOf(cd, poffset)) 
    74347434            return 1; 
    74357435    } 
    74367436    return 0; 
    74377437} 
    74387438 
    74397439MATCH TypeClass::implicitConvTo(Type *to) 
    74407440{ 
    74417441    //printf("TypeClass::implicitConvTo(to = '%s') %s\n", to->toChars(), toChars()); 
    74427442    MATCH m = constConv(to); 
    74437443    if (m != MATCHnomatch) 
    74447444        return m; 
  • trunk/src/mtype.h

    r619 r639  
    229229    virtual unsigned alignsize(); 
    230230    virtual Type *semantic(Loc loc, Scope *sc); 
    231231    Type *trySemantic(Loc loc, Scope *sc); 
    232232    virtual void toDecoBuffer(OutBuffer *buf, int flag = 0); 
    233233    Type *merge(); 
    234234    Type *merge2(); 
    235235    virtual void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); 
    236236    virtual void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 
    237237    void toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod); 
    238238    void modToBuffer(OutBuffer *buf); 
    239239#if CPP_MANGLE 
    240240    virtual void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    241241#endif 
    242242    virtual int isintegral(); 
    243243    virtual int isfloating();   // real, imaginary, or complex 
    244244    virtual int isreal(); 
    245245    virtual int isimaginary(); 
    246246    virtual int iscomplex(); 
    247247    virtual int isscalar(); 
    248248    virtual int isunsigned(); 
    249     virtual int isauto(); 
     249    virtual int isscope(); 
    250250    virtual int isString(); 
    251251    virtual int isAssignable(); 
    252252    virtual int checkBoolean(); // if can be converted to boolean value 
    253253    virtual void checkDeprecated(Loc loc, Scope *sc); 
    254254    int isConst()       { return mod & MODconst; } 
    255255    int isImmutable()   { return mod & MODimmutable; } 
    256256    int isMutable()     { return !(mod & (MODconst | MODimmutable | MODwild)); } 
    257257    int isShared()      { return mod & MODshared; } 
    258258    int isSharedConst() { return mod == (MODshared | MODconst); } 
    259259    int isWild()        { return mod & MODwild; } 
    260260    int isSharedWild()  { return mod == (MODshared | MODwild); } 
    261261    int isNaked()       { return mod == 0; } 
    262262    Type *constOf(); 
    263263    Type *invariantOf(); 
    264264    Type *mutableOf(); 
    265265    Type *sharedOf(); 
    266266    Type *sharedConstOf(); 
    267267    Type *unSharedOf(); 
    268268    Type *wildOf(); 
    269269    Type *sharedWildOf(); 
     
    797797 
    798798struct TypeClass : Type 
    799799{ 
    800800    ClassDeclaration *sym; 
    801801 
    802802    TypeClass(ClassDeclaration *sym); 
    803803    d_uns64 size(Loc loc); 
    804804    char *toChars(); 
    805805    Type *syntaxCopy(); 
    806806    Type *semantic(Loc loc, Scope *sc); 
    807807    Dsymbol *toDsymbol(Scope *sc); 
    808808    void toDecoBuffer(OutBuffer *buf, int flag); 
    809809    void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 
    810810    Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 
    811811    ClassDeclaration *isClassHandle(); 
    812812    int isBaseOf(Type *t, int *poffset); 
    813813    MATCH implicitConvTo(Type *to); 
    814814    Expression *defaultInit(Loc loc); 
    815815    int isZeroInit(Loc loc); 
    816816    MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 
    817     int isauto(); 
     817    int isscope(); 
    818818    int checkBoolean(); 
    819819    TypeInfoDeclaration *getTypeInfoDeclaration(); 
    820820    int hasPointers(); 
    821821    int builtinTypeInfo(); 
    822822#if DMDV2 
    823823    Type *toHeadMutable(); 
    824824    MATCH constConv(Type *to); 
    825825#if CPP_MANGLE 
    826826    void toCppMangle(OutBuffer *buf, CppMangleState *cms); 
    827827#endif 
    828828#endif 
    829829 
    830830    type *toCtype(); 
    831831 
    832832    Symbol *toSymbol(); 
    833833}; 
    834834 
    835835struct TypeTuple : Type 
    836836{ 
    837837    Parameters *arguments;      // types making up the tuple 
  • trunk/src/statement.c

    r636 r639  
    369369} 
    370370 
    371371void DeclarationStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally) 
    372372{ 
    373373    //printf("DeclarationStatement::scopeCode()\n"); 
    374374    //print(); 
    375375 
    376376    *sentry = NULL; 
    377377    *sexception = NULL; 
    378378    *sfinally = NULL; 
    379379 
    380380    if (exp) 
    381381    { 
    382382        if (exp->op == TOKdeclaration) 
    383383        { 
    384384            DeclarationExp *de = (DeclarationExp *)(exp); 
    385385            VarDeclaration *v = de->declaration->isVarDeclaration(); 
    386386            if (v) 
    387387            {   Expression *e; 
    388388 
    389                 e = v->callAutoDtor(sc); 
     389                e = v->callScopeDtor(sc); 
    390390                if (e) 
    391391                { 
    392392                    //printf("dtor is: "); e->print(); 
    393393#if 0 
    394394                    if (v->type->toBasetype()->ty == Tstruct) 
    395395                    {   /* Need a 'gate' to turn on/off destruction, 
    396396                         * in case v gets moved elsewhere. 
    397397                         */ 
    398398                        Identifier *id = Lexer::uniqueId("__runDtor"); 
    399399                        ExpInitializer *ie = new ExpInitializer(loc, new IntegerExp(1)); 
    400400                        VarDeclaration *rd = new VarDeclaration(loc, Type::tint32, id, ie); 
    401401                        *sentry = new DeclarationStatement(loc, rd); 
    402402                        v->rundtor = rd; 
    403403 
    404404                        /* Rewrite e as: 
    405405                         *  rundtor && e 
    406406                         */ 
    407407                        Expression *ve = new VarExp(loc, v->rundtor); 
    408408                        e = new AndAndExp(loc, ve, e); 
    409409                        e->type = Type::tbool; 
     
    17431743        } 
    17441744#endif 
    17451745        case Tdelegate: 
    17461746        Lapply: 
    17471747        { 
    17481748            Expression *ec; 
    17491749            Expression *e; 
    17501750            Parameter *a; 
    17511751 
    17521752            if (!checkForArgTypes()) 
    17531753            {   body = body->semanticNoScope(sc); 
    17541754                return this; 
    17551755            } 
    17561756 
    17571757            Type *tret = func->type->nextOf(); 
    17581758 
    17591759            // Need a variable to hold value from any return statements in body. 
    17601760            if (!sc->func->vresult && tret && tret != Type::tvoid) 
    17611761            { 
    17621762                VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); 
    1763                 v->noauto = 1; 
     1763                v->noscope = 1; 
    17641764                v->semantic(sc); 
    17651765                if (!sc->insert(v)) 
    17661766                    assert(0); 
    17671767                v->parent = sc->func; 
    17681768                sc->func->vresult = v; 
    17691769            } 
    17701770 
    17711771            /* Turn body into the function literal: 
    17721772             *  int delegate(ref T arg) { body } 
    17731773             */ 
    17741774            Parameters *args = new Parameters(); 
    17751775            for (size_t i = 0; i < dim; i++) 
    17761776            {   Parameter *arg = (Parameter *)arguments->data[i]; 
    17771777                Identifier *id; 
    17781778 
    17791779                arg->type = arg->type->semantic(loc, sc); 
    17801780                if (arg->storageClass & STCref) 
    17811781                    id = arg->ident; 
    17821782                else 
    17831783                {   // Make a copy of the ref argument so it isn't 
     
    23232323    // If we can short-circuit evaluate the if statement, don't do the 
    23242324    // semantic analysis of the skipped code. 
    23252325    // This feature allows a limited form of conditional compilation. 
    23262326    condition = condition->optimize(WANTflags); 
    23272327 
    23282328    // Evaluate at runtime 
    23292329    unsigned cs0 = sc->callSuper; 
    23302330    unsigned cs1; 
    23312331 
    23322332    Scope *scd; 
    23332333    if (arg) 
    23342334    {   /* Declare arg, which we will set to be the 
    23352335         * result of condition. 
    23362336         */ 
    23372337        ScopeDsymbol *sym = new ScopeDsymbol(); 
    23382338        sym->parent = sc->scopesym; 
    23392339        scd = sc->push(sym); 
    23402340 
    23412341        Type *t = arg->type ? arg->type : condition->type; 
    23422342        match = new VarDeclaration(loc, t, arg->ident, NULL); 
    2343         match->noauto = 1; 
     2343        match->noscope = 1; 
    23442344        match->semantic(scd); 
    23452345        if (!scd->insert(match)) 
    23462346            assert(0); 
    23472347        match->parent = sc->func; 
    23482348 
    23492349        /* Generate: 
    23502350         *  (arg = condition) 
    23512351         */ 
    23522352        VarExp *v = new VarExp(0, match); 
    23532353        condition = new AssignExp(loc, v, condition); 
    23542354        condition = condition->semantic(scd); 
    23552355    } 
    23562356    else 
    23572357        scd = sc->push(); 
    23582358 
    23592359    ifbody = ifbody->semanticNoScope(scd); 
    23602360    scd->pop(); 
    23612361 
    23622362    cs1 = sc->callSuper; 
    23632363    sc->callSuper = cs0; 
     
    34793479            sc->fes->cases->push(this); 
    34803480            // Construct: return cases->dim+1; 
    34813481            s = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 
    34823482        } 
    34833483        else if (fd->type->nextOf()->toBasetype() == Type::tvoid) 
    34843484        { 
    34853485            s = new ReturnStatement(0, NULL); 
    34863486            sc->fes->cases->push(s); 
    34873487 
    34883488            // Construct: { exp; return cases->dim + 1; } 
    34893489            Statement *s1 = new ExpStatement(loc, exp); 
    34903490            Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 
    34913491            s = new CompoundStatement(loc, s1, s2); 
    34923492        } 
    34933493        else 
    34943494        { 
    34953495            // Construct: return vresult; 
    34963496            if (!fd->vresult) 
    34973497            {   // Declare vresult 
    34983498                VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); 
    3499                 v->noauto = 1; 
     3499                v->noscope = 1; 
    35003500                v->storage_class |= STCresult; 
    35013501                v->semantic(scx); 
    35023502                if (!scx->insert(v)) 
    35033503                    assert(0); 
    35043504                v->parent = fd; 
    35053505                fd->vresult = v; 
    35063506            } 
    35073507 
    35083508            s = new ReturnStatement(0, new VarExp(0, fd->vresult)); 
    35093509            sc->fes->cases->push(s); 
    35103510 
    35113511            // Construct: { vresult = exp; return cases->dim + 1; } 
    35123512            exp = new ConstructExp(loc, new VarExp(0, fd->vresult), exp); 
    35133513            exp = exp->semantic(sc); 
    35143514            Statement *s1 = new ExpStatement(loc, exp); 
    35153515            Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 
    35163516            s = new CompoundStatement(loc, s1, s2); 
    35173517        } 
    35183518        return s; 
    35193519    }