mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-18 09:49:02 +02:00
Merge branch 'dmd-2.060' into master.
Conflicts: dmd2/func.c dmd2/mars.c
This commit is contained in:
@@ -122,6 +122,18 @@ void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
|
||||
}
|
||||
#endif
|
||||
|
||||
Dsymbol *Declaration::search(Loc loc, Identifier *ident, int flags)
|
||||
{
|
||||
Dsymbol *s = Dsymbol::search(loc, ident, flags);
|
||||
if (!s && type)
|
||||
{
|
||||
s = type->toDsymbol(NULL);
|
||||
if (s)
|
||||
s = s->search(loc, ident, flags);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/********************************* TupleDeclaration ****************************/
|
||||
|
||||
@@ -159,7 +171,7 @@ Type *TupleDeclaration::getType()
|
||||
/* It's only a type tuple if all the Object's are types
|
||||
*/
|
||||
for (size_t i = 0; i < objects->dim; i++)
|
||||
{ Object *o = objects->tdata()[i];
|
||||
{ Object *o = (*objects)[i];
|
||||
|
||||
if (o->dyncast() != DYNCAST_TYPE)
|
||||
{
|
||||
@@ -176,7 +188,7 @@ Type *TupleDeclaration::getType()
|
||||
OutBuffer buf;
|
||||
int hasdeco = 1;
|
||||
for (size_t i = 0; i < types->dim; i++)
|
||||
{ Type *t = types->tdata()[i];
|
||||
{ Type *t = (*types)[i];
|
||||
|
||||
//printf("type = %s\n", t->toChars());
|
||||
#if 0
|
||||
@@ -187,7 +199,7 @@ Type *TupleDeclaration::getType()
|
||||
#else
|
||||
Parameter *arg = new Parameter(0, t, NULL, NULL);
|
||||
#endif
|
||||
args->tdata()[i] = arg;
|
||||
(*args)[i] = arg;
|
||||
if (!t->deco)
|
||||
hasdeco = 0;
|
||||
}
|
||||
@@ -204,7 +216,7 @@ int TupleDeclaration::needThis()
|
||||
{
|
||||
//printf("TupleDeclaration::needThis(%s)\n", toChars());
|
||||
for (size_t i = 0; i < objects->dim; i++)
|
||||
{ Object *o = objects->tdata()[i];
|
||||
{ Object *o = (*objects)[i];
|
||||
if (o->dyncast() == DYNCAST_EXPRESSION)
|
||||
{ Expression *e = (Expression *)o;
|
||||
if (e->op == TOKdsymbol)
|
||||
@@ -336,7 +348,7 @@ void TypedefDeclaration::semantic2(Scope *sc)
|
||||
{
|
||||
Initializer *savedinit = init;
|
||||
int errors = global.errors;
|
||||
init = init->semantic(sc, basetype, WANTinterpret);
|
||||
init = init->semantic(sc, basetype, INITinterpret);
|
||||
if (errors != global.errors)
|
||||
{
|
||||
init = savedinit;
|
||||
@@ -557,6 +569,17 @@ void AliasDeclaration::semantic(Scope *sc)
|
||||
s->parent = sc->parent;
|
||||
}
|
||||
}
|
||||
OverloadSet *o = s->toAlias()->isOverloadSet();
|
||||
if (o)
|
||||
{
|
||||
if (overnext)
|
||||
{
|
||||
o->push(overnext);
|
||||
overnext = NULL;
|
||||
s = o;
|
||||
s->parent = sc->parent;
|
||||
}
|
||||
}
|
||||
if (overnext)
|
||||
ScopeDsymbol::multiplyDefined(0, this, overnext);
|
||||
if (s == this)
|
||||
@@ -619,7 +642,9 @@ const char *AliasDeclaration::kind()
|
||||
|
||||
Type *AliasDeclaration::getType()
|
||||
{
|
||||
return type;
|
||||
if (type)
|
||||
return type;
|
||||
return toAlias()->getType();
|
||||
}
|
||||
|
||||
Dsymbol *AliasDeclaration::toAlias()
|
||||
@@ -632,7 +657,9 @@ Dsymbol *AliasDeclaration::toAlias()
|
||||
aliassym = new AliasDeclaration(loc, ident, Type::terror);
|
||||
type = Type::terror;
|
||||
}
|
||||
else if (!aliassym && scope)
|
||||
else if (aliassym || type->deco)
|
||||
; // semantic is already done.
|
||||
else if (scope)
|
||||
semantic(scope);
|
||||
Dsymbol *s = aliassym ? aliassym->toAlias() : this;
|
||||
return s;
|
||||
@@ -845,6 +872,14 @@ void VarDeclaration::semantic(Scope *sc)
|
||||
this->parent = sc->parent;
|
||||
//printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
|
||||
protection = sc->protection;
|
||||
|
||||
/* If scope's alignment is the default, use the type's alignment,
|
||||
* otherwise the scope overrrides.
|
||||
*/
|
||||
alignment = sc->structalign;
|
||||
if (alignment == STRUCTALIGN_DEFAULT)
|
||||
alignment = type->alignment(); // use type's alignment
|
||||
|
||||
//printf("sc->stc = %x\n", sc->stc);
|
||||
//printf("storage_class = x%x\n", storage_class);
|
||||
|
||||
@@ -931,7 +966,7 @@ void VarDeclaration::semantic(Scope *sc)
|
||||
for (size_t pos = 0; pos < iexps->dim; pos++)
|
||||
{
|
||||
Lexpand1:
|
||||
Expression *e = iexps->tdata()[pos];
|
||||
Expression *e = (*iexps)[pos];
|
||||
Parameter *arg = Parameter::getNth(tt->arguments, pos);
|
||||
arg->type = arg->type->semantic(loc, sc);
|
||||
//printf("[%d] iexps->dim = %d, ", pos, iexps->dim);
|
||||
@@ -1028,7 +1063,7 @@ Lnomatch:
|
||||
|
||||
Expression *einit = ie;
|
||||
if (ie && ie->op == TOKtuple)
|
||||
{ einit = ((TupleExp *)ie)->exps->tdata()[i];
|
||||
{ einit = (*((TupleExp *)ie)->exps)[i];
|
||||
}
|
||||
Initializer *ti = init;
|
||||
if (einit)
|
||||
@@ -1051,7 +1086,7 @@ Lnomatch:
|
||||
}
|
||||
#endif
|
||||
Expression *e = new DsymbolExp(loc, v);
|
||||
exps->tdata()[i] = e;
|
||||
(*exps)[i] = e;
|
||||
}
|
||||
TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
|
||||
v2->isexp = 1;
|
||||
@@ -1091,7 +1126,7 @@ Lnomatch:
|
||||
}
|
||||
else if (storage_class & STCfinal)
|
||||
{
|
||||
error("final cannot be applied to variable");
|
||||
error("final cannot be applied to variable, perhaps you meant const?");
|
||||
}
|
||||
|
||||
if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared | STCctfe))
|
||||
@@ -1114,7 +1149,6 @@ Lnomatch:
|
||||
#endif
|
||||
{
|
||||
storage_class |= STCfield;
|
||||
alignment = sc->structalign;
|
||||
#if DMDV2
|
||||
if (tb->ty == Tstruct && ((TypeStruct *)tb)->sym->noDefaultCtor ||
|
||||
tb->ty == Tclass && ((TypeClass *)tb)->sym->noDefaultCtor)
|
||||
@@ -1244,6 +1278,19 @@ Lnomatch:
|
||||
init = new ExpInitializer(loc, e);
|
||||
goto Ldtor;
|
||||
}
|
||||
else if (type->ty == Tstruct &&
|
||||
(((TypeStruct *)type)->sym->isnested))
|
||||
{
|
||||
/* Nested struct requires valid enclosing frame pointer.
|
||||
* In StructLiteralExp::toElem(), it's calculated.
|
||||
*/
|
||||
Expression *e = type->defaultInitLiteral(loc);
|
||||
Expression *e1 = new VarExp(loc, this);
|
||||
e = new ConstructExp(loc, e1, e);
|
||||
e = e->semantic(sc);
|
||||
init = new ExpInitializer(loc, e);
|
||||
goto Ldtor;
|
||||
}
|
||||
else if (type->ty == Ttypedef)
|
||||
{ TypeTypedef *td = (TypeTypedef *)type;
|
||||
if (td->sym->init)
|
||||
@@ -1313,7 +1360,8 @@ Lnomatch:
|
||||
Expression *e = init->toExpression();
|
||||
if (!e)
|
||||
{
|
||||
init = init->semantic(sc, type, 0); // Don't need to interpret
|
||||
// Run semantic, but don't need to interpret
|
||||
init = init->semantic(sc, type, INITnointerpret);
|
||||
e = init->toExpression();
|
||||
if (!e)
|
||||
{ error("is not a static and cannot have static initializer");
|
||||
@@ -1395,16 +1443,26 @@ Lnomatch:
|
||||
{
|
||||
e = new ConstructExp(loc, new VarExp(loc, this), new IntegerExp(loc, 0, Type::tint32));
|
||||
}
|
||||
else if (sd->isNested())
|
||||
{ e = new AssignExp(loc, new VarExp(loc, this), t->defaultInitLiteral(loc));
|
||||
e->op = TOKblit;
|
||||
}
|
||||
else
|
||||
{ e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc));
|
||||
e->op = TOKblit;
|
||||
}
|
||||
e->type = t;
|
||||
(*pinit) = new CommaExp(loc, e, (*pinit));
|
||||
|
||||
/* Replace __ctmp being constructed with e1
|
||||
/* Replace __ctmp being constructed with e1.
|
||||
* We need to copy constructor call expression,
|
||||
* because it may be used in other place.
|
||||
*/
|
||||
dve->e1 = e1;
|
||||
DotVarExp *dvx = (DotVarExp *)dve->copy();
|
||||
dvx->e1 = e1;
|
||||
CallExp *cx = (CallExp *)ce->copy();
|
||||
cx->e1 = dvx;
|
||||
|
||||
(*pinit) = new CommaExp(loc, e, cx);
|
||||
(*pinit) = (*pinit)->semantic(sc);
|
||||
goto Ldtor;
|
||||
}
|
||||
@@ -1466,7 +1524,7 @@ Lnomatch:
|
||||
}
|
||||
else
|
||||
{
|
||||
init = init->semantic(sc, type, WANTinterpret);
|
||||
init = init->semantic(sc, type, INITinterpret);
|
||||
}
|
||||
}
|
||||
else if (storage_class & (STCconst | STCimmutable | STCmanifest) ||
|
||||
@@ -1537,7 +1595,7 @@ Lnomatch:
|
||||
}
|
||||
else if (si || ai)
|
||||
{ i2 = init->syntaxCopy();
|
||||
i2 = i2->semantic(sc, type, WANTinterpret);
|
||||
i2 = i2->semantic(sc, type, INITinterpret);
|
||||
}
|
||||
inuse--;
|
||||
if (global.endGagging(errors)) // if errors happened
|
||||
@@ -1552,7 +1610,7 @@ Lnomatch:
|
||||
else if (ei)
|
||||
{
|
||||
if (isDataseg() || (storage_class & STCmanifest))
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
e = e->ctfeInterpret();
|
||||
else
|
||||
e = e->optimize(WANTvalue);
|
||||
switch (e->op)
|
||||
@@ -1639,7 +1697,7 @@ void VarDeclaration::semantic2(Scope *sc)
|
||||
printf("type = %p\n", ei->exp->type);
|
||||
}
|
||||
#endif
|
||||
init = init->semantic(sc, type, WANTinterpret);
|
||||
init = init->semantic(sc, type, INITinterpret);
|
||||
inuse--;
|
||||
}
|
||||
sem = Semantic2Done;
|
||||
@@ -1710,9 +1768,8 @@ void VarDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset,
|
||||
|
||||
unsigned memsize = t->size(loc); // size of member
|
||||
unsigned memalignsize = t->alignsize(); // size of member for alignment purposes
|
||||
unsigned memalign = t->memalign(alignment); // alignment boundaries
|
||||
|
||||
offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, memalign,
|
||||
offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, alignment,
|
||||
&ad->structsize, &ad->alignsize, isunion);
|
||||
|
||||
//printf("\t%s: alignsize = %d\n", toChars(), alignsize);
|
||||
@@ -1831,28 +1888,8 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
|
||||
// The current function
|
||||
FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
|
||||
|
||||
if (fdv && fdthis && fdv != fdthis && fdthis->ident != Id::ensure && fdthis->ident != Id::require)
|
||||
if (fdv && fdthis && fdv != fdthis)
|
||||
{
|
||||
/* __ensure is always called directly,
|
||||
* so it never becomes closure.
|
||||
*/
|
||||
|
||||
//printf("\tfdv = %s\n", fdv->toChars());
|
||||
//printf("\tfdthis = %s\n", fdthis->toChars());
|
||||
|
||||
if (loc.filename)
|
||||
fdthis->getLevel(loc, sc, fdv);
|
||||
|
||||
// Function literals from fdthis to fdv must be delegates
|
||||
for (Dsymbol *s = fdthis; s && s != fdv; s = s->toParent2())
|
||||
{
|
||||
// function literal has reference to enclosing scope is delegate
|
||||
if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
|
||||
{
|
||||
fld->tok = TOKdelegate;
|
||||
}
|
||||
}
|
||||
|
||||
// Add fdthis to nestedrefs[] if not already there
|
||||
for (size_t i = 0; 1; i++)
|
||||
{
|
||||
@@ -1865,23 +1902,46 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
|
||||
break;
|
||||
}
|
||||
|
||||
// Add this to fdv->closureVars[] if not already there
|
||||
for (size_t i = 0; 1; i++)
|
||||
if (fdthis->ident != Id::ensure)
|
||||
{
|
||||
if (i == fdv->closureVars.dim)
|
||||
{
|
||||
fdv->closureVars.push(this);
|
||||
break;
|
||||
}
|
||||
if (fdv->closureVars[i] == this)
|
||||
break;
|
||||
}
|
||||
/* __ensure is always called directly,
|
||||
* so it never becomes closure.
|
||||
*/
|
||||
|
||||
//printf("fdthis is %s\n", fdthis->toChars());
|
||||
//printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
|
||||
// __dollar creates problems because it isn't a real variable Bugzilla 3326
|
||||
if (ident == Id::dollar)
|
||||
::error(loc, "cannnot use $ inside a function literal");
|
||||
//printf("\tfdv = %s\n", fdv->toChars());
|
||||
//printf("\tfdthis = %s\n", fdthis->toChars());
|
||||
|
||||
if (loc.filename)
|
||||
fdthis->getLevel(loc, sc, fdv);
|
||||
|
||||
// Function literals from fdthis to fdv must be delegates
|
||||
for (Dsymbol *s = fdthis; s && s != fdv; s = s->toParent2())
|
||||
{
|
||||
// function literal has reference to enclosing scope is delegate
|
||||
if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
|
||||
{
|
||||
fld->tok = TOKdelegate;
|
||||
}
|
||||
}
|
||||
|
||||
// Add this to fdv->closureVars[] if not already there
|
||||
for (size_t i = 0; 1; i++)
|
||||
{
|
||||
if (i == fdv->closureVars.dim)
|
||||
{
|
||||
fdv->closureVars.push(this);
|
||||
break;
|
||||
}
|
||||
if (fdv->closureVars[i] == this)
|
||||
break;
|
||||
}
|
||||
|
||||
//printf("fdthis is %s\n", fdthis->toChars());
|
||||
//printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
|
||||
// __dollar creates problems because it isn't a real variable Bugzilla 3326
|
||||
if (ident == Id::dollar)
|
||||
::error(loc, "cannnot use $ inside a function literal");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2353,7 +2413,7 @@ TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *t
|
||||
TypeInfoVectorDeclaration::TypeInfoVectorDeclaration(Type *tinfo)
|
||||
: TypeInfoDeclaration(tinfo, 0)
|
||||
{
|
||||
if (!Type::typeinfoarray)
|
||||
if (!Type::typeinfovector)
|
||||
{
|
||||
ObjectNotFound(Id::TypeInfo_Vector);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user