mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
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:
@@ -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
|
||||
|
||||
10
dmd/class.c
10
dmd/class.c
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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++;
|
||||
|
||||
22
dmd/mtype.c
22
dmd/mtype.c
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user