diff --git a/src/aggregate.h b/src/aggregate.h --- a/src/aggregate.h +++ b/src/aggregate.h @@ -222,7 +222,7 @@ struct ClassDeclaration : AggregateDeclaration TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration int com; // !=0 if this is a COM class (meaning // it derives from IUnknown) - int isauto; // !=0 if this is an auto class + int isscope; // !=0 if this is a scope class int isabstract; // !=0 if abstract class #if DMDV1 int isnested; // !=0 if is nested diff --git a/src/class.c b/src/class.c --- a/src/class.c +++ b/src/class.c @@ -193,7 +193,7 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla } com = 0; - isauto = 0; + isscope = 0; isabstract = 0; inuse = 0; } @@ -476,7 +476,7 @@ void ClassDeclaration::semantic(Scope *sc) // Inherit properties from base class com = baseClass->isCOMclass(); - isauto = baseClass->isauto; + isscope = baseClass->isscope; vthis = baseClass->vthis; storage_class |= baseClass->storage_class & STC_TYPECTOR; } @@ -560,8 +560,10 @@ void ClassDeclaration::semantic(Scope *sc) } } - if (storage_class & (STCauto | STCscope)) - isauto = 1; + if (storage_class & STCauto) + error("storage class 'auto' has no effect when declaring a class, did you mean to use 'scope'"); + if (storage_class & STCscope) + isscope = 1; if (storage_class & STCabstract) isabstract = 1; if (storage_class & STCimmutable) diff --git a/src/clone.c b/src/clone.c --- a/src/clone.c +++ b/src/clone.c @@ -150,7 +150,7 @@ FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc) if (dtor) { tmp = new VarDeclaration(0, type, idtmp, new VoidInitializer(0)); - tmp->noauto = 1; + tmp->noscope = 1; tmp->storage_class |= STCctfe; e = new DeclarationExp(0, tmp); ec = new AssignExp(0, diff --git a/src/declaration.c b/src/declaration.c --- a/src/declaration.c +++ b/src/declaration.c @@ -645,7 +645,7 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer #endif this->loc = loc; offset = 0; - noauto = 0; + noscope = 0; #if DMDV2 isargptr = FALSE; #endif @@ -805,6 +805,8 @@ void VarDeclaration::semantic(Scope *sc) error("no definition of struct %s", ts->toChars()); } } + if ((storage_class & STCauto) && !inferred) + error("storage class 'auto' has no effect, did you mean 'scope'?"); if (tb->ty == Ttuple) { /* Instead, declare variables for each of the tuple elements @@ -956,14 +958,14 @@ Lagain: } #endif - if (type->isauto() && !noauto) + if (type->isscope() && !noscope) { if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd) { error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope"); } - if (!(storage_class & (STCauto | STCscope))) + if (!(storage_class & STCscope)) { if (!(storage_class & STCparameter) && ident != Id::withSym) error("reference to scope class must be scope"); @@ -1566,7 +1568,7 @@ int VarDeclaration::needsAutoDtor() { //printf("VarDeclaration::needsAutoDtor() %s\n", toChars()); - if (noauto || storage_class & STCnodtor) + if (noscope || storage_class & STCnodtor) return FALSE; // Destructors for structs and arrays of structs @@ -1593,16 +1595,16 @@ int VarDeclaration::needsAutoDtor() /****************************************** - * If a variable has an auto destructor call, return call for it. + * If a variable has a scope destructor call, return call for it. * Otherwise, return NULL. */ -Expression *VarDeclaration::callAutoDtor(Scope *sc) +Expression *VarDeclaration::callScopeDtor(Scope *sc) { Expression *e = NULL; - //printf("VarDeclaration::callAutoDtor() %s\n", toChars()); + //printf("VarDeclaration::callScopeDtor() %s\n", toChars()); - if (noauto || storage_class & STCnodtor) + if (noscope || storage_class & STCnodtor) return NULL; // Destructors for structs and arrays of structs @@ -1873,7 +1875,7 @@ TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) ThisDeclaration::ThisDeclaration(Loc loc, Type *t) : VarDeclaration(loc, t, Id::This, NULL) { - noauto = 1; + noscope = 1; } Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) diff --git a/src/declaration.h b/src/declaration.h --- a/src/declaration.h +++ b/src/declaration.h @@ -130,7 +130,7 @@ struct Declaration : Dsymbol int isConst() { return storage_class & STCconst; } int isImmutable() { return storage_class & STCimmutable; } int isAuto() { return storage_class & STCauto; } - int isScope() { return storage_class & (STCscope | STCauto); } + int isScope() { return storage_class & STCscope; } int isSynchronized() { return storage_class & STCsynchronized; } int isParameter() { return storage_class & STCparameter; } int isDeprecated() { return storage_class & STCdeprecated; } @@ -233,7 +233,7 @@ struct VarDeclaration : Declaration { Initializer *init; unsigned offset; - int noauto; // no auto semantics + int noscope; // no scope semantics #if DMDV2 FuncDeclarations nestedrefs; // referenced by these lexically nested functions bool isargptr; // if parameter that _argptr points to @@ -273,7 +273,7 @@ struct VarDeclaration : Declaration int canTakeAddressOf(); int needsAutoDtor(); #endif - Expression *callAutoDtor(Scope *sc); + Expression *callScopeDtor(Scope *sc); ExpInitializer *getExpInitializer(); Expression *getConstInitializer(); void checkCtorConstInit(); diff --git a/src/expression.c b/src/expression.c --- a/src/expression.c +++ b/src/expression.c @@ -4460,7 +4460,7 @@ void VarExp::checkEscape() // if reference type if (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tclass) { - if ((v->isAuto() || v->isScope()) && !v->noauto) + if (v->isScope() && !v->noscope) error("escaping reference to scope local %s", v->toChars()); else if (v->storage_class & STCvariadic) error("escaping reference to variadic parameter %s", v->toChars()); diff --git a/src/func.c b/src/func.c --- a/src/func.c +++ b/src/func.c @@ -1105,7 +1105,7 @@ void FuncDeclaration::semantic3(Scope *sc) loc = fensure->loc; VarDeclaration *v = new VarDeclaration(loc, type->nextOf(), outId, NULL); - v->noauto = 1; + v->noscope = 1; v->storage_class |= STCresult; #if DMDV2 if (!isVirtual()) @@ -1497,7 +1497,7 @@ void FuncDeclaration::semantic3(Scope *sc) if (v->type->toBasetype()->ty == Tsarray) continue; - Expression *e = v->callAutoDtor(sc); + Expression *e = v->callScopeDtor(sc); if (e) { Statement *s = new ExpStatement(0, e); s = s->semantic(sc); diff --git a/src/mtype.c b/src/mtype.c --- a/src/mtype.c +++ b/src/mtype.c @@ -1572,7 +1572,7 @@ ClassDeclaration *Type::isClassHandle() return NULL; } -int Type::isauto() +int Type::isscope() { return FALSE; } @@ -3371,8 +3371,8 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) tbn = next = tint32; break; } - if (tbn->isauto()) - error(loc, "cannot have array of auto %s", tbn->toChars()); + if (tbn->isscope()) + error(loc, "cannot have array of scope %s", tbn->toChars()); return merge(); } @@ -3600,8 +3600,8 @@ Type *TypeDArray::semantic(Loc loc, Scope *sc) break; } } - if (tn->isauto()) - error(loc, "cannot have array of auto %s", tn->toChars()); + if (tn->isscope()) + error(loc, "cannot have array of scope %s", tn->toChars()); next = tn; transitive(); @@ -3803,8 +3803,8 @@ Type *TypeNewArray::semantic(Loc loc, Scope *sc) break; } } - if (tn->isauto()) - error(loc, "cannot have array of auto %s", tn->toChars()); + if (tn->isscope()) + error(loc, "cannot have array of scope %s", tn->toChars()); next = tn; transitive(); @@ -3931,8 +3931,8 @@ printf("index->ito->ito = x%x\n", index->ito->ito); error(loc, "can't have associative array of %s", next->toChars()); return Type::terror; } - if (next->isauto()) - { error(loc, "cannot have array of auto %s", next->toChars()); + if (next->isscope()) + { error(loc, "cannot have array of scope %s", next->toChars()); return Type::terror; } return merge(); @@ -4815,7 +4815,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) { error(loc, "functions cannot return a tuple"); tf->next = Type::terror; } - if (tf->next->isauto() && !(sc->flags & SCOPEctor)) + if (tf->next->isscope() && !(sc->flags & SCOPEctor)) error(loc, "functions cannot return scope %s", tf->next->toChars()); if (tf->next->toBasetype()->ty == Tvoid) tf->isref = FALSE; // rewrite "ref void" as just "void" @@ -7353,9 +7353,9 @@ ClassDeclaration *TypeClass::isClassHandle() return sym; } -int TypeClass::isauto() +int TypeClass::isscope() { - return sym->isauto; + return sym->isscope; } int TypeClass::isBaseOf(Type *t, int *poffset) diff --git a/src/mtype.h b/src/mtype.h --- a/src/mtype.h +++ b/src/mtype.h @@ -246,7 +246,7 @@ struct Type : Object virtual int iscomplex(); virtual int isscalar(); virtual int isunsigned(); - virtual int isauto(); + virtual int isscope(); virtual int isString(); virtual int isAssignable(); virtual int checkBoolean(); // if can be converted to boolean value @@ -799,7 +799,7 @@ struct TypeClass : Type Expression *defaultInit(Loc loc); int isZeroInit(Loc loc); MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); - int isauto(); + int isscope(); int checkBoolean(); TypeInfoDeclaration *getTypeInfoDeclaration(); int hasPointers(); diff --git a/src/statement.c b/src/statement.c --- a/src/statement.c +++ b/src/statement.c @@ -376,7 +376,7 @@ void DeclarationStatement::scopeCode(Scope *sc, Statement **sentry, Statement ** if (v) { Expression *e; - e = v->callAutoDtor(sc); + e = v->callScopeDtor(sc); if (e) { //printf("dtor is: "); e->print(); @@ -1739,7 +1739,7 @@ Lagain: if (!sc->func->vresult && tret && tret != Type::tvoid) { VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); - v->noauto = 1; + v->noscope = 1; v->semantic(sc); if (!sc->insert(v)) assert(0); @@ -2312,7 +2312,7 @@ Statement *IfStatement::semantic(Scope *sc) Type *t = arg->type ? arg->type : condition->type; match = new VarDeclaration(loc, t, arg->ident, NULL); - match->noauto = 1; + match->noscope = 1; match->semantic(scd); if (!scd->insert(match)) assert(0); @@ -3466,7 +3466,7 @@ Statement *ReturnStatement::semantic(Scope *sc) if (!fd->vresult) { // Declare vresult VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); - v->noauto = 1; + v->noscope = 1; v->storage_class |= STCresult; v->semantic(scx); if (!scx->insert(v))