Make the auto storage class never have the same meaning as scope.

This changes the meaning of
auto class MyClass {} and
auto MyClass ident;
Both have been made an error to prevent accidents.
This commit is contained in:
Christian Kamm
2009-07-12 16:15:21 +02:00
parent 756a2cb2a1
commit 72d1f1e6dd
9 changed files with 42 additions and 38 deletions

View File

@@ -222,7 +222,7 @@ struct ClassDeclaration : AggregateDeclaration
ClassInfoDeclaration *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
int isnested; // !=0 if is nested

View File

@@ -184,7 +184,7 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
}
com = 0;
isauto = 0;
isscope = 0;
isabstract = 0;
isnested = 0;
vthis = NULL;
@@ -447,7 +447,7 @@ void ClassDeclaration::semantic(Scope *sc)
// Inherit properties from base class
com = baseClass->isCOMclass();
isauto = baseClass->isauto;
isscope = baseClass->isscope;
vthis = baseClass->vthis;
}
else
@@ -529,8 +529,10 @@ void ClassDeclaration::semantic(Scope *sc)
}
}
if (storage_class & (STCauto | STCscope))
isauto = 1;
if (storage_class & STCauto)
error("storage class has no effect: auto");
if (storage_class & STCscope)
isscope = 1;
if (storage_class & STCabstract)
isabstract = 1;

View File

@@ -619,7 +619,7 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
#endif
this->loc = loc;
offset = 0;
noauto = 0;
noscope = 0;
nestedref = 0;
ctorinit = 0;
aliassym = NULL;
@@ -747,6 +747,8 @@ void VarDeclaration::semantic(Scope *sc)
error("no definition of struct %s", ts->toChars());
}
}
if ((storage_class & STCauto) && !inferred)
error("storage class has no effect: auto");
if (tb->ty == Ttuple)
{ /* Instead, declare variables for each of the tuple elements
@@ -862,14 +864,14 @@ void VarDeclaration::semantic(Scope *sc)
}
}
if (type->isauto() && !noauto)
if (type->isscope() && !noscope)
{
if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd)
{
error("globals, statics, fields, ref and out parameters cannot be auto");
error("globals, statics, fields, 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");
@@ -1222,15 +1224,15 @@ int VarDeclaration::isSameAsInitializer()
}
/******************************************
* If a variable has an auto destructor call, return call for it.
* If a variable has an scope destructor call, return call for it.
* Otherwise, return NULL.
*/
Expression *VarDeclaration::callAutoDtor()
Expression *VarDeclaration::callScopeDtor()
{ Expression *e = NULL;
//printf("VarDeclaration::callAutoDtor() %s\n", toChars());
if (storage_class & (STCauto | STCscope) && !noauto)
//printf("VarDeclaration::callScopeDtor() %s\n", toChars());
if (storage_class & STCscope && !noscope)
{
for (ClassDeclaration *cd = type->isClassHandle();
cd;
@@ -1430,7 +1432,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)

View File

@@ -130,7 +130,7 @@ struct Declaration : Dsymbol
int isConst() { return storage_class & STCconst; }
int isInvariant() { return 0; }
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; }
@@ -254,7 +254,7 @@ struct VarDeclaration : Declaration
{
Initializer *init;
unsigned offset;
int noauto; // no auto semantics
int noscope; // no scope semantics
int nestedref; // referenced by a lexically nested function
int ctorinit; // it has been initialized in a ctor
int onstack; // 1: it has been allocated on the stack
@@ -279,7 +279,7 @@ struct VarDeclaration : Declaration
int isImportedSymbol();
int isDataseg();
int hasPointers();
Expression *callAutoDtor();
Expression *callScopeDtor();
ExpInitializer *getExpInitializer();
void checkCtorConstInit();
void checkNestedReference(Scope *sc, Loc loc);

View File

@@ -3993,8 +3993,8 @@ void VarExp::checkEscape()
// if reference type
if (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tclass)
{
if ((v->isAuto() || v->isScope()) && !v->noauto)
error("escaping reference to auto local %s", v->toChars());
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());
}

View File

@@ -184,7 +184,7 @@ void FuncDeclaration::semantic(Scope *sc)
error("_ctor is reserved for constructors");
if (isConst() || isAuto() || isScope())
error("functions cannot be const or auto");
error("functions cannot be const, auto or scope");
if (isAbstract() && !isVirtual())
error("non-virtual functions cannot be abstract");
@@ -960,7 +960,7 @@ void FuncDeclaration::semantic3(Scope *sc)
loc = fensure->loc;
v = new VarDeclaration(loc, type->nextOf(), outId, NULL);
v->noauto = 1;
v->noscope = 1;
sc2->incontract--;
v->semantic(sc2);
sc2->incontract++;

View File

@@ -548,7 +548,7 @@ ClassDeclaration *Type::isClassHandle()
return NULL;
}
int Type::isauto()
int Type::isscope()
{
return FALSE;
}
@@ -1996,8 +1996,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();
}
@@ -2159,8 +2159,8 @@ Type *TypeDArray::semantic(Loc loc, Scope *sc)
tn = next = tint32;
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());
if (next != tn)
//deco = NULL; // redo
return tn->arrayOf();
@@ -2358,8 +2358,8 @@ Type *TypeAArray::semantic(Loc loc, Scope *sc)
error(loc, "can't have associative array of %s", next->toChars());
break;
}
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 merge();
}
@@ -2996,8 +2996,8 @@ 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))
error(loc, "functions cannot return auto %s", tf->next->toChars());
if (tf->next->isscope() && !(sc->flags & SCOPEctor))
error(loc, "functions cannot return scope %s", tf->next->toChars());
if (tf->parameters)
{ size_t dim = Argument::dim(tf->parameters);
@@ -5068,9 +5068,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)

View File

@@ -234,7 +234,7 @@ struct Type : Object
virtual int iscomplex();
virtual int isscalar();
virtual int isunsigned();
virtual int isauto();
virtual int isscope();
virtual int isString();
virtual int checkBoolean(); // if can be converted to boolean value
void checkDeprecated(Loc loc, Scope *sc);
@@ -692,7 +692,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();

View File

@@ -333,7 +333,7 @@ void DeclarationStatement::scopeCode(Statement **sentry, Statement **sexception,
if (v)
{ Expression *e;
e = v->callAutoDtor();
e = v->callScopeDtor();
if (e)
{
//printf("dtor is: "); e->print();
@@ -1590,7 +1590,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
{ VarDeclaration *v;
v = new VarDeclaration(loc, tret, Id::result, NULL);
v->noauto = 1;
v->noscope = 1;
v->semantic(sc);
if (!sc->insert(v))
assert(0);
@@ -1961,7 +1961,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);
@@ -2931,7 +2931,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->semantic(scx);
if (!scx->insert(v))
assert(0);