144 changes: 78 additions & 66 deletions src/cast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1317,28 +1317,29 @@ Expression *BinExp::scaleFactor(Scope *sc)
return this;
}

/************************************
* Bring leaves to common type.
/**************************************
* Combine types.
* Output:
* *pt merged type, if *pt is not NULL
* *pe1 rewritten e1
* *pe2 rewritten e2
* Returns:
* !=0 success
* 0 failed
*/

Expression *BinExp::typeCombine(Scope *sc)
int typeMerge(Scope *sc, Type **pt, Expression **pe1, Expression **pe2)
{
Type *t1;
Type *t2;
Type *t;
TY ty;

//printf("BinExp::typeCombine() %s\n", toChars());
//printf("typeMerge() %s\n", toChars());
//dump(0);

e1 = e1->integralPromotions(sc);
e2 = e2->integralPromotions(sc);
Expression *e1 = (*pe1)->integralPromotions(sc);
Expression *e2 = (*pe2)->integralPromotions(sc);

// BUG: do toBasetype()
t1 = e1->type;
t2 = e2->type;
Type *t1 = e1->type;
Type *t2 = e2->type;
assert(t1);
t = t1;
Type *t = t1;

//if (t1) printf("\tt1 = %s\n", t1->toChars());
//if (t2) printf("\tt2 = %s\n", t2->toChars());
Expand All @@ -1350,7 +1351,7 @@ Expression *BinExp::typeCombine(Scope *sc)
Type *t1b = t1->toBasetype();
Type *t2b = t2->toBasetype();

ty = (TY)Type::impcnvResult[t1b->ty][t2b->ty];
TY ty = (TY)Type::impcnvResult[t1b->ty][t2b->ty];
if (ty != Terror)
{ TY ty1;
TY ty2;
Expand All @@ -1362,73 +1363,35 @@ Expression *BinExp::typeCombine(Scope *sc)
{
if (t1 == t2)
{
if (!type)
type = t1;
return this;
t = t1;
goto Lret;
}

if (t1b == t2b)
{
if (!type)
type = t1b;
return this;
t = t1b;
goto Lret;
}
}

if (!type)
type = Type::basic[ty];
t = Type::basic[ty];

t1 = Type::basic[ty1];
t2 = Type::basic[ty2];
e1 = e1->castTo(sc, t1);
e2 = e2->castTo(sc, t2);
#if 0
if (type != Type::basic[ty])
{ t = type;
type = Type::basic[ty];
return castTo(sc, t);
}
#endif
//printf("after typeCombine():\n");
//dump(0);
//printf("ty = %d, ty1 = %d, ty2 = %d\n", ty, ty1, ty2);
return this;
goto Lret;
}

t1 = t1b;
t2 = t2b;

if (op == TOKcat)
{
if ((t1->ty == Tsarray || t1->ty == Tarray) &&
(t2->ty == Tsarray || t2->ty == Tarray) &&
(t1->nextOf()->mod || t2->nextOf()->mod) &&
(t1->nextOf()->mod != t2->nextOf()->mod)
)
{
t1 = t1->nextOf()->mutableOf()->constOf()->arrayOf();
t2 = t2->nextOf()->mutableOf()->constOf()->arrayOf();
//t1 = t1->constOf();
//t2 = t2->constOf();
if (e1->op == TOKstring && !((StringExp *)e1)->committed)
e1->type = t1;
else
e1 = e1->castTo(sc, t1);
if (e2->op == TOKstring && !((StringExp *)e2)->committed)
e2->type = t2;
else
e2 = e2->castTo(sc, t2);
t = t1;
goto Lagain;
}
}

Lagain:
if (t1 == t2)
{
if ((t1->ty == Tstruct || t1->ty == Tclass) &&
(op == TOKmin || op == TOKadd))
goto Lincompatible;
}
else if (t1->ty == Tpointer && t2->ty == Tpointer)
{
Expand Down Expand Up @@ -1544,7 +1507,7 @@ Expression *BinExp::typeCombine(Scope *sc)
/* Pick 'tightest' type
*/
ClassDeclaration *cd1 = tc1->sym->baseClass;
ClassDeclaration *cd2 = tc1->sym->baseClass;
ClassDeclaration *cd2 = tc2->sym->baseClass;

if (cd1 && cd2)
{ t1 = cd1->type;
Expand Down Expand Up @@ -1597,19 +1560,21 @@ Expression *BinExp::typeCombine(Scope *sc)
else
{
Lincompatible:
incompatibleTypes();
return 0;
}
Lret:
if (!type)
type = t;
if (!*pt)
*pt = t;
*pe1 = e1;
*pe2 = e2;
#if 0
printf("-BinExp::typeCombine() %s\n", toChars());
printf("-typeMerge() %s\n", toChars());
if (e1->type) printf("\tt1 = %s\n", e1->type->toChars());
if (e2->type) printf("\tt2 = %s\n", e2->type->toChars());
printf("\ttype = %s\n", type->toChars());
#endif
//dump(0);
return this;
return 1;


Lt1:
Expand All @@ -1623,6 +1588,53 @@ Expression *BinExp::typeCombine(Scope *sc)
goto Lret;
}

/************************************
* Bring leaves to common type.
*/

Expression *BinExp::typeCombine(Scope *sc)
{
Type *t1 = e1->type->toBasetype();
Type *t2 = e2->type->toBasetype();

if (op == TOKcat)
{
if ((t1->ty == Tsarray || t1->ty == Tarray) &&
(t2->ty == Tsarray || t2->ty == Tarray) &&
(t1->nextOf()->mod || t2->nextOf()->mod) &&
(t1->nextOf()->mod != t2->nextOf()->mod)
)
{
t1 = t1->nextOf()->mutableOf()->constOf()->arrayOf();
t2 = t2->nextOf()->mutableOf()->constOf()->arrayOf();
//t1 = t1->constOf();
//t2 = t2->constOf();
if (e1->op == TOKstring && !((StringExp *)e1)->committed)
e1->type = t1;
else
e1 = e1->castTo(sc, t1);
if (e2->op == TOKstring && !((StringExp *)e2)->committed)
e2->type = t2;
else
e2 = e2->castTo(sc, t2);
}
}
else if (op == TOKmin || op == TOKadd)
{
if (t1 == t2 && (t1->ty == Tstruct || t1->ty == Tclass))
goto Lerror;
}

if (!typeMerge(sc, &type, &e1, &e2))
goto Lerror;
return this;

Lerror:
incompatibleTypes();
type = Type::terror;
return this;
}

/***********************************
* Do integral promotions (convertchk).
* Don't convert <array of> to <pointer to>
Expand Down
2 changes: 1 addition & 1 deletion src/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ int isf(void *param, FuncDeclaration *fd)

int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
{
//printf("ClassDeclaration::isFuncHidden(%s)\n", fd->toChars());
//printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars());
Dsymbol *s = search(0, fd->ident, 4|2);
if (!s)
{ //printf("not found\n");
Expand Down
31 changes: 24 additions & 7 deletions src/constfold.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,10 +1078,21 @@ Expression *Cast(Type *type, Type *to, Expression *e1)
to->implicitConvTo(e1->type) >= MATCHconst)
return expType(to, e1);

Type *tb = to->toBasetype();
Type *typeb = type->toBasetype();

if (e1->op == TOKstring)
{
if (tb->ty == Tarray && typeb->ty == Tarray &&
tb->nextOf()->size() == typeb->nextOf()->size())
{
return expType(to, e1);
}
}

if (e1->isConst() != 1)
return EXP_CANT_INTERPRET;

Type *tb = to->toBasetype();
if (tb->ty == Tbool)
e = new IntegerExp(loc, e1->toInteger() != 0, type);
else if (type->isintegral())
Expand All @@ -1090,7 +1101,7 @@ Expression *Cast(Type *type, Type *to, Expression *e1)
{ integer_t result;
real_t r = e1->toReal();

switch (type->toBasetype()->ty)
switch (typeb->ty)
{
case Tint8: result = (d_int8)r; break;
case Tchar:
Expand Down Expand Up @@ -1467,13 +1478,19 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
else
e->type = type;
}
else if (e1->op == TOKarrayliteral &&
else if ((e1->op == TOKarrayliteral || e1->op == TOKnull) &&
e1->type->toBasetype()->nextOf()->equals(e2->type))
{
ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;

es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy());
es1->elements->push(e2);
ArrayLiteralExp *es1;
if (e1->op == TOKarrayliteral)
{ es1 = (ArrayLiteralExp *)e1;
es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy());
es1->elements->push(e2);
}
else
{
es1 = new ArrayLiteralExp(e1->loc, e2);
}
e = es1;

if (type->toBasetype()->ty == Tsarray)
Expand Down
30 changes: 19 additions & 11 deletions src/declaration.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ enum PROT Declaration::prot()
* Issue error if not.
*/

#if V2
void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
{
if (sc->incontract && isParameter())
Expand Down Expand Up @@ -146,6 +147,7 @@ void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
}
}
}
#endif


/********************************* TupleDeclaration ****************************/
Expand Down Expand Up @@ -658,12 +660,14 @@ Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)

void VarDeclaration::semantic(Scope *sc)
{
//printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
//printf(" type = %s\n", type ? type->toChars() : "null");
//printf(" stc = x%x\n", sc->stc);
//printf(" storage_class = x%x\n", storage_class);
//printf("linkage = %d\n", sc->linkage);
#if 0
printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
printf(" type = %s\n", type ? type->toChars() : "null");
printf(" stc = x%x\n", sc->stc);
printf(" storage_class = x%x\n", storage_class);
printf("linkage = %d\n", sc->linkage);
//if (strcmp(toChars(), "mul") == 0) halt();
#endif

storage_class |= sc->stc;
if (storage_class & STCextern && init)
Expand Down Expand Up @@ -1107,16 +1111,20 @@ Dsymbol *VarDeclaration::toAlias()

void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (storage_class & STCmanifest)
buf->writestring("manifest ");
if (storage_class & STCstatic)
buf->writestring("static ");
if (storage_class & STCtls)
buf->writestring("__tls ");
if (storage_class & STCconst)
buf->writestring("const ");
if (storage_class & STCstatic)
buf->writestring("static ");
if (storage_class & STCauto)
buf->writestring("auto ");
#if V2
if (storage_class & STCmanifest)
buf->writestring("manifest ");
if (storage_class & STCinvariant)
buf->writestring("invariant ");
if (storage_class & STCtls)
buf->writestring("__thread ");
#endif

if (type)
type->toCBuffer(buf, ident, hgs);
Expand Down
7 changes: 5 additions & 2 deletions src/declaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ enum STC
STCnothrow = 0x2000000, // never throws exceptions
STCpure = 0x4000000, // pure function
STCtls = 0x8000000, // thread local
STCalias = 0x10000000, // alias parameter
};

struct Match
Expand Down Expand Up @@ -264,7 +265,6 @@ struct VarDeclaration : Declaration
VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
};


/**************************************************************/

// This is a shell around a back end symbol
Expand Down Expand Up @@ -618,6 +618,7 @@ struct CtorDeclaration : FuncDeclaration
CtorDeclaration *isCtorDeclaration() { return this; }
};

#if V2
struct PostBlitDeclaration : FuncDeclaration
{
PostBlitDeclaration(Loc loc, Loc endloc);
Expand All @@ -633,6 +634,7 @@ struct PostBlitDeclaration : FuncDeclaration

PostBlitDeclaration *isPostBlitDeclaration() { return this; }
};
#endif

struct DtorDeclaration : FuncDeclaration
{
Expand Down Expand Up @@ -667,7 +669,8 @@ struct StaticCtorDeclaration : FuncDeclaration
};

struct StaticDtorDeclaration : FuncDeclaration
{
{ VarDeclaration *vgate; // 'gate' variable

StaticDtorDeclaration(Loc loc, Loc endloc);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
Expand Down
14 changes: 11 additions & 3 deletions src/doc.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ void Dsymbol::emitDitto(Scope *sc)

void ScopeDsymbol::emitMemberComments(Scope *sc)
{
//printf("ScopeDsymbol::emitMemberComments()\n");
//printf("ScopeDsymbol::emitMemberComments() %s\n", toChars());
OutBuffer *buf = sc->docbuf;

if (members)
Expand Down Expand Up @@ -743,7 +743,9 @@ void FuncDeclaration::toDocBuffer(OutBuffer *buf)
if (parent &&
(td = parent->isTemplateDeclaration()) != NULL &&
td->onemember == this)
{ HdrGenState hgs;
{ /* It's a function template
*/
HdrGenState hgs;
unsigned o = buf->offset;
TypeFunction *tf = (TypeFunction *)type;

Expand Down Expand Up @@ -1581,7 +1583,13 @@ Argument *isFunctionParameter(Dsymbol *s, unsigned char *p, unsigned len)
*/
if (f && f->type)
{
TypeFunction *tf = (TypeFunction *)f->type;
TypeFunction *tf;
if (f->originalType)
{
tf = (TypeFunction *)f->originalType;
}
else
tf = (TypeFunction *)f->type;

if (tf->parameters)
{
Expand Down
10 changes: 10 additions & 0 deletions src/dsymbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,16 @@ Dsymbol *Dsymbol::toParent2()
return s;
}

TemplateInstance *Dsymbol::inTemplateInstance()
{
for (Dsymbol *parent = this->parent; parent; parent = parent->parent)
{
TemplateInstance *ti = parent->isTemplateInstance();
if (ti)
return ti;
}
return NULL;
}

int Dsymbol::isAnonymous()
{
Expand Down
2 changes: 1 addition & 1 deletion src/dsymbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ struct Type;
struct TypeTuple;
struct WithStatement;
struct LabelDsymbol;
struct ScopeDsymbol;
struct TemplateDeclaration;
struct TemplateInstance;
struct TemplateMixin;
Expand Down Expand Up @@ -115,6 +114,7 @@ struct Dsymbol : Object
Dsymbol *pastMixin();
Dsymbol *toParent();
Dsymbol *toParent2();
TemplateInstance *inTemplateInstance();

int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()

Expand Down
157 changes: 132 additions & 25 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ void initPrecedence()
precedence[TOKassert] = PREC_primary;
precedence[TOKfunction] = PREC_primary;
precedence[TOKvar] = PREC_primary;
#if V2
precedence[TOKdefault] = PREC_primary;
#endif

// post
precedence[TOKdotti] = PREC_primary;
Expand Down Expand Up @@ -234,26 +236,32 @@ Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
*/

e1 = new DotVarExp(loc, e1, tcd->vthis);
e1 = e1->semantic(sc);
e1->type = tcd->vthis->type;
// Do not call checkNestedRef()
//e1 = e1->semantic(sc);

// Skip up over nested functions, and get the enclosing
// class type.
int n = 0;
Dsymbol *s;
for (s = tcd->toParent();
s && s->isFuncDeclaration();
s = s->toParent())
{ FuncDeclaration *f = s->isFuncDeclaration();
if (f->vthis)
{
{ n++;
e1 = new VarExp(loc, f->vthis);
}
}
if (s && s->isClassDeclaration())
e1->type = s->isClassDeclaration()->type;
e1 = e1->semantic(sc);
{ e1->type = s->isClassDeclaration()->type;
if (n > 1)
e1 = e1->semantic(sc);
}
else
e1 = e1->semantic(sc);
goto L1;
}

/* Can't find a path from e1 to ad
*/
error("this for %s needs to be type %s not type %s",
Expand Down Expand Up @@ -474,7 +482,7 @@ void preFunctionArguments(Loc loc, Scope *sc, Expressions *exps)
/*********************************************
* Call copy constructor for struct value argument.
*/

#if V2
Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
{
Type *tb = e->type->toBasetype();
Expand All @@ -496,6 +504,7 @@ Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
}
return e;
}
#endif

/****************************************
* Now that we know the exact type of the function we're calling,
Expand Down Expand Up @@ -546,11 +555,13 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
break;
}
arg = p->defaultArg;
#if V2
if (arg->op == TOKdefault)
{ DefaultInitExp *de = (DefaultInitExp *)arg;
arg = de->resolve(loc, sc);
}
else
#endif
arg = arg->copy();
arguments->push(arg);
nargs++;
Expand Down Expand Up @@ -708,7 +719,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
else
arg = arg->castTo(sc, ta);
}

#if V2
if (tb->ty == Tstruct)
{
arg = callCpCtor(loc, sc, arg);
Expand All @@ -720,9 +731,9 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique())
arg->error("function %s is overloaded", arg->toChars());
}
#endif
arg->rvalue();
}

arg = arg->optimize(WANTvalue);
arguments->data[i] = (void *) arg;
if (done)
Expand Down Expand Up @@ -950,6 +961,15 @@ void Expression::toMangleBuffer(OutBuffer *buf)
error("expression %s is not a valid template value argument", toChars());
}

/***************************************
* Return !=0 if expression is an lvalue.
*/

int Expression::isLvalue()
{
return 0;
}

/*******************************
* Give error if we're not an lvalue.
* If we can, convert expression to be an lvalue.
Expand Down Expand Up @@ -1848,6 +1868,11 @@ void IdentifierExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring(ident->toChars());
}

int IdentifierExp::isLvalue()
{
return 1;
}

Expression *IdentifierExp::toLvalue(Scope *sc, Expression *e)
{
#if 0
Expand Down Expand Up @@ -2048,6 +2073,11 @@ void DsymbolExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring(s->toChars());
}

int DsymbolExp::isLvalue()
{
return 1;
}

Expression *DsymbolExp::toLvalue(Scope *sc, Expression *e)
{
#if 0
Expand Down Expand Up @@ -2122,7 +2152,8 @@ Expression *ThisExp::semantic(Scope *sc)
assert(var->parent);
type = var->type;
var->isVarDeclaration()->checkNestedReference(sc, loc);
sc->callSuper |= CSXthis;
if (!sc->intypeof)
sc->callSuper |= CSXthis;
return this;

Lerr:
Expand All @@ -2141,6 +2172,11 @@ void ThisExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring("this");
}

int ThisExp::isLvalue()
{
return 1;
}

Expression *ThisExp::toLvalue(Scope *sc, Expression *e)
{
return this;
Expand Down Expand Up @@ -2223,7 +2259,8 @@ Expression *SuperExp::semantic(Scope *sc)

var->isVarDeclaration()->checkNestedReference(sc, loc);

sc->callSuper |= CSXsuper;
if (!sc->intypeof)
sc->callSuper |= CSXsuper;
return this;


Expand Down Expand Up @@ -3004,6 +3041,10 @@ int StructLiteralExp::getFieldIndex(Type *type, unsigned offset)
return -1;
}

int StructLiteralExp::isLvalue()
{
return 1;
}

Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e)
{
Expand Down Expand Up @@ -3760,6 +3801,13 @@ void VarExp::checkEscape()
}
}

int VarExp::isLvalue()
{
if (var->storage_class & STClazy)
return 0;
return 1;
}

Expression *VarExp::toLvalue(Scope *sc, Expression *e)
{
#if 0
Expand Down Expand Up @@ -3797,6 +3845,11 @@ OverExp::OverExp(OverloadSet *s)
type = Type::tvoid;
}

int OverExp::isLvalue()
{
return 1;
}

Expression *OverExp::toLvalue(Scope *sc, Expression *e)
{
return this;
Expand Down Expand Up @@ -5259,7 +5312,6 @@ Expression *DotVarExp::semantic(Scope *sc)
}

e1 = e1->semantic(sc);

type = var->type;
if (!type && global.errors)
{ // var is goofed up, just return 0
Expand Down Expand Up @@ -5287,6 +5339,11 @@ Expression *DotVarExp::semantic(Scope *sc)
return this;
}

int DotVarExp::isLvalue()
{
return 1;
}

Expression *DotVarExp::toLvalue(Scope *sc, Expression *e)
{
//printf("DotVarExp::toLvalue(%s)\n", toChars());
Expand Down Expand Up @@ -5687,12 +5744,15 @@ e1->dump(0);
/* Attempt to instantiate ti. If that works, go with it.
* If not, go with partial explicit specialization.
*/
ti->semanticTiargs(sc);
unsigned errors = global.errors;
global.gag++;
ti->semantic(sc);
global.gag--;
if (errors != global.errors)
{
/* Didn't work, go with partial explicit specialization
*/
global.errors = errors;
targsi = ti->tiargs;
e1 = new IdentifierExp(loc, ti->name);
Expand All @@ -5711,6 +5771,7 @@ e1->dump(0);
/* Attempt to instantiate ti. If that works, go with it.
* If not, go with partial explicit specialization.
*/
ti->semanticTiargs(sc);
Expression *etmp;
unsigned errors = global.errors;
global.gag++;
Expand Down Expand Up @@ -5950,15 +6011,18 @@ e1->dump(0);
}
else
{
if (!sc->intypeof)
{
#if 0
if (sc->callSuper & (CSXthis | CSXsuper))
error("reference to this before super()");
if (sc->callSuper & (CSXthis | CSXsuper))
error("reference to this before super()");
#endif
if (sc->noctor || sc->callSuper & CSXlabel)
error("constructor calls not allowed in loops or after labels");
if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
error("multiple constructor calls");
sc->callSuper |= CSXany_ctor | CSXsuper_ctor;
if (sc->noctor || sc->callSuper & CSXlabel)
error("constructor calls not allowed in loops or after labels");
if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
error("multiple constructor calls");
sc->callSuper |= CSXany_ctor | CSXsuper_ctor;
}

f = f->overloadResolve(loc, NULL, arguments);
checkDeprecated(sc, f);
Expand All @@ -5983,15 +6047,18 @@ e1->dump(0);
}
else
{
if (!sc->intypeof)
{
#if 0
if (sc->callSuper & (CSXthis | CSXsuper))
error("reference to this before super()");
if (sc->callSuper & (CSXthis | CSXsuper))
error("reference to this before super()");
#endif
if (sc->noctor || sc->callSuper & CSXlabel)
error("constructor calls not allowed in loops or after labels");
if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
error("multiple constructor calls");
sc->callSuper |= CSXany_ctor | CSXthis_ctor;
if (sc->noctor || sc->callSuper & CSXlabel)
error("constructor calls not allowed in loops or after labels");
if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
error("multiple constructor calls");
sc->callSuper |= CSXany_ctor | CSXthis_ctor;
}

f = cd->ctor;
f = f->overloadResolve(loc, NULL, arguments);
Expand Down Expand Up @@ -6156,6 +6223,14 @@ int CallExp::canThrow()
return 1;
}

int CallExp::isLvalue()
{
if (type->toBasetype()->ty == Tstruct)
return 1;
else
return 0;
}

Expression *CallExp::toLvalue(Scope *sc, Expression *e)
{
if (type->toBasetype()->ty == Tstruct)
Expand Down Expand Up @@ -6304,6 +6379,11 @@ Expression *PtrExp::semantic(Scope *sc)
return this;
}

int PtrExp::isLvalue()
{
return 1;
}

Expression *PtrExp::toLvalue(Scope *sc, Expression *e)
{
#if 0
Expand Down Expand Up @@ -6902,6 +6982,11 @@ void SliceExp::checkEscape()
e1->checkEscape();
}

int SliceExp::isLvalue()
{
return 1;
}

Expression *SliceExp::toLvalue(Scope *sc, Expression *e)
{
return this;
Expand Down Expand Up @@ -7017,6 +7102,13 @@ Expression *ArrayExp::semantic(Scope *sc)
}


int ArrayExp::isLvalue()
{
if (type && type->toBasetype()->ty == Tvoid)
return 0;
return 1;
}

Expression *ArrayExp::toLvalue(Scope *sc, Expression *e)
{
if (type && type->toBasetype()->ty == Tvoid)
Expand Down Expand Up @@ -7086,6 +7178,11 @@ void CommaExp::checkEscape()
e2->checkEscape();
}

int CommaExp::isLvalue()
{
return e2->isLvalue();
}

Expression *CommaExp::toLvalue(Scope *sc, Expression *e)
{
e2 = e2->toLvalue(sc, NULL);
Expand Down Expand Up @@ -7251,6 +7348,11 @@ Expression *IndexExp::semantic(Scope *sc)
return e;
}

int IndexExp::isLvalue()
{
return 1;
}

Expression *IndexExp::toLvalue(Scope *sc, Expression *e)
{
// if (type && type->toBasetype()->ty == Tvoid)
Expand Down Expand Up @@ -9126,6 +9228,11 @@ Expression *CondExp::semantic(Scope *sc)
return this;
}

int CondExp::isLvalue()
{
return e1->isLvalue() && e2->isLvalue();
}

Expression *CondExp::toLvalue(Scope *sc, Expression *ex)
{
PtrExp *e;
Expand Down
15 changes: 15 additions & 0 deletions src/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ struct Expression : Object
virtual complex_t toComplex();
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
virtual void toMangleBuffer(OutBuffer *buf);
virtual int isLvalue();
virtual Expression *toLvalue(Scope *sc, Expression *e);
virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
Expression *implicitCastTo(Scope *sc, Type *t);
Expand Down Expand Up @@ -233,6 +234,7 @@ struct IdentifierExp : Expression
char *toChars();
void dump(int indent);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
};

Expand All @@ -251,6 +253,7 @@ struct DsymbolExp : Expression
char *toChars();
void dump(int indent);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
};

Expand All @@ -262,6 +265,7 @@ struct ThisExp : Expression
Expression *semantic(Scope *sc);
int isBool(int result);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
void scanForNestedRef(Scope *sc);

Expand Down Expand Up @@ -431,6 +435,7 @@ struct StructLiteralExp : Expression
Expression *optimize(int result);
Expression *interpret(InterState *istate);
dt_t **toDt(dt_t **pdt);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
int canThrow();
MATCH implicitConvTo(Type *t);
Expand Down Expand Up @@ -569,6 +574,7 @@ struct VarExp : SymbolExp
char *toChars();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void checkEscape();
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
dt_t **toDt(dt_t **pdt);
Expand All @@ -586,6 +592,7 @@ struct OverExp : Expression
OverloadSet *vars;

OverExp(OverloadSet *s);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
};

Expand Down Expand Up @@ -803,6 +810,7 @@ struct DotVarExp : UnaExp

DotVarExp(Loc loc, Expression *e, Declaration *var, int hasOverloads = 0);
Expression *semantic(Scope *sc);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Expand Down Expand Up @@ -865,6 +873,7 @@ struct CallExp : UnaExp
void dump(int indent);
elem *toElem(IRState *irs);
void scanForNestedRef(Scope *sc);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
int canThrow();

Expand All @@ -888,6 +897,7 @@ struct PtrExp : UnaExp
PtrExp(Loc loc, Expression *e);
PtrExp(Loc loc, Expression *e, Type *t);
Expression *semantic(Scope *sc);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Expand Down Expand Up @@ -996,6 +1006,7 @@ struct SliceExp : UnaExp
Expression *syntaxCopy();
Expression *semantic(Scope *sc);
void checkEscape();
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Expand Down Expand Up @@ -1029,6 +1040,7 @@ struct ArrayExp : UnaExp
ArrayExp(Loc loc, Expression *e1, Expressions *arguments);
Expression *syntaxCopy();
Expression *semantic(Scope *sc);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void scanForNestedRef(Scope *sc);
Expand All @@ -1054,6 +1066,7 @@ struct CommaExp : BinExp
CommaExp(Loc loc, Expression *e1, Expression *e2);
Expression *semantic(Scope *sc);
void checkEscape();
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
int isBool(int result);
Expand All @@ -1070,6 +1083,7 @@ struct IndexExp : BinExp

IndexExp(Loc loc, Expression *e1, Expression *e2);
Expression *semantic(Scope *sc);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Expand Down Expand Up @@ -1403,6 +1417,7 @@ struct CondExp : BinExp
Expression *optimize(int result);
Expression *interpret(InterState *istate);
void checkEscape();
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
Expression *checkToBoolean();
Expand Down
86 changes: 78 additions & 8 deletions src/func.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
Expand Down Expand Up @@ -67,6 +66,9 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC s
fes = NULL;
introducing = 0;
tintro = NULL;
/* The type given for "infer the return type" is a TypeFunction with
* NULL for the return type.
*/
inferRetType = (type && type->nextOf() == NULL);
scope = NULL;
hasReturnExp = 0;
Expand Down Expand Up @@ -172,8 +174,8 @@ void FuncDeclaration::semantic(Scope *sc)
protection = sc->protection;
Dsymbol *parent = toParent();

if (isAuto() || isScope())
error("functions cannot be scope or auto");
if (storage_class & STCscope)
error("functions cannot be scope");

if (isAbstract() && !isVirtual())
error("non-virtual functions cannot be abstract");
Expand Down Expand Up @@ -600,9 +602,8 @@ void FuncDeclaration::semantic3(Scope *sc)

// Check the 'throws' clause
if (fthrows)
{ int i;

for (i = 0; i < fthrows->dim; i++)
{
for (int i = 0; i < fthrows->dim; i++)
{
Type *t = (Type *)fthrows->data[i];

Expand Down Expand Up @@ -1606,6 +1607,7 @@ int fp2(void *param, FuncDeclaration *f)
{
MATCH c1 = f->leastAsSpecialized(m->lastf);
MATCH c2 = m->lastf->leastAsSpecialized(f);
//printf("c1 = %d, c2 = %d\n", c1, c2);
if (c1 > c2)
goto LfIsBetter;
if (c1 < c2)
Expand Down Expand Up @@ -1763,14 +1765,21 @@ MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
for (int u = 0; u < nfparams; u++)
{
Argument *p = Argument::getNth(tf->parameters, u);
Expression *e = p->type->defaultInit();
Expression *e;
if (p->storageClass & (STCref | STCout))
{
e = new IdentifierExp(0, p->ident);
e->type = p->type;
}
else
e = p->type->defaultInit();
args.data[u] = e;
}

MATCH m = (MATCH) tg->callMatch(NULL, &args);
if (m)
{
/* A variadic template is less specialized than a
/* A variadic parameter list is less specialized than a
* non-variadic one.
*/
if (tf->varargs && !tg->varargs)
Expand Down Expand Up @@ -2279,6 +2288,8 @@ void CtorDeclaration::semantic(Scope *sc)
else
tret = cd->type; //->referenceTo();
type = new TypeFunction(arguments, tret, varargs, LINKd);
if (!originalType)
originalType = type;

sc->flags |= SCOPEctor;
type = type->semantic(loc, sc);
Expand Down Expand Up @@ -2513,6 +2524,34 @@ void StaticCtorDeclaration::semantic(Scope *sc)

type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);

/* If the static ctor appears within a template instantiation,
* it could get called multiple times by the module constructors
* for different modules. Thus, protect it with a gate.
*/
if (inTemplateInstance())
{
/* Add this prefix to the function:
* static int gate;
* if (++gate != 1) return;
* Note that this is not thread safe; should not have threads
* during static construction.
*/
Identifier *id = Lexer::idPool("__gate");
VarDeclaration *v = new VarDeclaration(0, Type::tint32, id, NULL);
v->storage_class = STCstatic;
Statements *sa = new Statements();
Statement *s = new DeclarationStatement(0, v);
sa->push(s);
Expression *e = new IdentifierExp(0, id);
e = new AddAssignExp(0, e, new IntegerExp(1));
e = new EqualExp(TOKnotequal, 0, e, new IntegerExp(1));
s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL);
sa->push(s);
if (fbody)
sa->push(fbody);
fbody = new CompoundStatement(0, sa);
}

FuncDeclaration::semantic(sc);

// We're going to need ModuleInfo
Expand Down Expand Up @@ -2568,6 +2607,7 @@ StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc)
: FuncDeclaration(loc, endloc,
Identifier::generateId("_staticDtor"), STCstatic, NULL)
{
vgate = NULL;
}

Dsymbol *StaticDtorDeclaration::syntaxCopy(Dsymbol *s)
Expand All @@ -2591,6 +2631,36 @@ void StaticDtorDeclaration::semantic(Scope *sc)
}
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);

/* If the static ctor appears within a template instantiation,
* it could get called multiple times by the module constructors
* for different modules. Thus, protect it with a gate.
*/
if (inTemplateInstance())
{
/* Add this prefix to the function:
* static int gate;
* if (--gate != 0) return;
* Increment gate during constructor execution.
* Note that this is not thread safe; should not have threads
* during static destruction.
*/
Identifier *id = Lexer::idPool("__gate");
VarDeclaration *v = new VarDeclaration(0, Type::tint32, id, NULL);
v->storage_class = STCstatic;
Statements *sa = new Statements();
Statement *s = new DeclarationStatement(0, v);
sa->push(s);
Expression *e = new IdentifierExp(0, id);
e = new AddAssignExp(0, e, new IntegerExp(-1));
e = new EqualExp(TOKnotequal, 0, e, new IntegerExp(1));
s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL);
sa->push(s);
if (fbody)
sa->push(fbody);
fbody = new CompoundStatement(0, sa);
vgate = v;
}

FuncDeclaration::semantic(sc);

// We're going to need ModuleInfo
Expand Down
1 change: 0 additions & 1 deletion src/interpret.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
return NULL;
}

//printf("test2 %d, %p\n", semanticRun, scope);
if (semanticRun == 0 && scope)
{
semantic3(scope);
Expand Down
2 changes: 1 addition & 1 deletion src/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ void Lexer::scan(Token *t)
sprintf(timestamp, "%.24s", p);
}

#if !V2
#if V1
if (mod && id == Id::FILE)
{
t->ustring = (unsigned char *)(loc.filename ? loc.filename : mod->ident->toChars());
Expand Down
6 changes: 5 additions & 1 deletion src/mars.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Global::Global()

copyright = "Copyright (c) 1999-2008 by Digital Mars";
written = "written by Walter Bright";
version = "v2.014";
version = "v2.015";
global.structalign = 8;

memset(&params, 0, sizeof(Param));
Expand Down Expand Up @@ -320,8 +320,10 @@ int main(int argc, char *argv[])
global.params.link = 0;
else if (strcmp(p + 1, "cov") == 0)
global.params.cov = 1;
#if TARGET_LINUX
else if (strcmp(p + 1, "fPIC") == 0)
global.params.pic = 1;
#endif
else if (strcmp(p + 1, "multiobj") == 0)
global.params.multiobj = 1;
else if (strcmp(p + 1, "g") == 0)
Expand Down Expand Up @@ -664,6 +666,8 @@ int main(int argc, char *argv[])
}
if (global.params.cov)
VersionCondition::addPredefinedGlobalIdent("D_Coverage");
if (global.params.pic)
VersionCondition::addPredefinedGlobalIdent("D_PIC");
#if V2
if (global.params.useUnitTests)
VersionCondition::addPredefinedGlobalIdent("unittest");
Expand Down
82 changes: 63 additions & 19 deletions src/mtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -2895,8 +2895,7 @@ Expression *TypeReference::defaultInit(Loc loc)
#if LOGDEFAULTINIT
printf("TypeReference::defaultInit() '%s'\n", toChars());
#endif
Expression *e;
e = new NullExp(loc);
Expression *e = new NullExp(loc);
e->type = this;
return e;
}
Expand All @@ -2914,6 +2913,7 @@ TypeFunction::TypeFunction(Arguments *parameters, Type *treturn, int varargs, en
{
//if (!treturn) *(char*)0=0;
// assert(treturn);
assert(0 <= varargs && varargs <= 2);
this->parameters = parameters;
this->varargs = varargs;
this->linkage = linkage;
Expand Down Expand Up @@ -3241,7 +3241,6 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)

for (size_t i = 0; i < dim; i++)
{ Argument *arg = Argument::getNth(tf->parameters, i);
Type *t;

tf->inuse++;
arg->type = arg->type->semantic(loc,sc);
Expand All @@ -3255,7 +3254,13 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
else if (arg->storageClass & STCinvariant)
arg->type = arg->type->invariantOf();

t = arg->type->toBasetype();
if (arg->storageClass & (STCauto | STCalias | STCstatic))
{
if (!arg->type)
continue;
}

Type *t = arg->type->toBasetype();

if (arg->storageClass & (STCout | STCref | STClazy))
{
Expand Down Expand Up @@ -3355,6 +3360,11 @@ int TypeFunction::callMatch(Expression *ethis, Expressions *args)
}
arg = (Expression *)args->data[u];
assert(arg);

// Non-lvalues do not match ref or out parameters
if (p->storageClass & (STCref | STCout) && !arg->isLvalue())
goto Nomatch;

if (p->storageClass & STClazy && p->type->ty == Tvoid &&
arg->type->ty != Tvoid)
m = MATCHconvert;
Expand Down Expand Up @@ -5855,22 +5865,22 @@ Arguments *Argument::arraySyntaxCopy(Arguments *args)
}

char *Argument::argsTypesToChars(Arguments *args, int varargs)
{ OutBuffer *buf;

buf = new OutBuffer();
{
OutBuffer *buf = new OutBuffer();

#if 1
HdrGenState hgs;
argsToCBuffer(buf, &hgs, args, varargs);
#else
buf->writeByte('(');
if (args)
{ int i;
OutBuffer argbuf;
{ OutBuffer argbuf;
HdrGenState hgs;

for (i = 0; i < args->dim; i++)
{ Argument *arg;

if (i)
for (int i = 0; i < args->dim; i++)
{ if (i)
buf->writeByte(',');
arg = (Argument *)args->data[i];
Argument *arg = (Argument *)args->data[i];
argbuf.reset();
arg->type->toCBuffer2(&argbuf, &hgs, 0);
buf->write(&argbuf);
Expand All @@ -5883,7 +5893,7 @@ char *Argument::argsTypesToChars(Arguments *args, int varargs)
}
}
buf->writeByte(')');

#endif
return buf->toChars();
}

Expand All @@ -5895,11 +5905,11 @@ void Argument::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Arguments *argume
OutBuffer argbuf;

for (i = 0; i < arguments->dim; i++)
{ Argument *arg;

{
if (i)
buf->writestring(", ");
arg = (Argument *)arguments->data[i];
Argument *arg = (Argument *)arguments->data[i];

if (arg->storageClass & STCout)
buf->writestring("out ");
else if (arg->storageClass & STCref)
Expand All @@ -5909,12 +5919,23 @@ void Argument::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Arguments *argume
buf->writestring("in ");
else if (arg->storageClass & STClazy)
buf->writestring("lazy ");
else if (arg->storageClass & STCalias)
buf->writestring("alias ");
else if (arg->storageClass & STCauto)
buf->writestring("auto ");

if (arg->storageClass & STCconst)
buf->writestring("const ");
if (arg->storageClass & STCinvariant)
buf->writestring("invariant ");

argbuf.reset();
arg->type->toCBuffer(&argbuf, arg->ident, hgs);
if (arg->storageClass & STCalias)
{ if (arg->ident)
argbuf.writestring(arg->ident->toChars());
}
else
arg->type->toCBuffer(&argbuf, arg->ident, hgs);
if (arg->defaultArg)
{
argbuf.writestring(" = ");
Expand Down Expand Up @@ -5949,6 +5970,29 @@ void Argument::argsToDecoBuffer(OutBuffer *buf, Arguments *arguments)
}
}


/****************************************
* Determine if parameter list is really a template parameter list
* (i.e. it has auto or alias parameters)
*/

int Argument::isTPL(Arguments *arguments)
{
//printf("Argument::isTPL()\n");

if (arguments)
{
size_t dim = Argument::dim(arguments);
for (size_t i = 0; i < dim; i++)
{
Argument *arg = Argument::getNth(arguments, i);
if (arg->storageClass & (STCalias | STCauto | STCstatic))
return 1;
}
}
return 0;
}

/****************************************************
* Determine if parameter is a lazy array of delegates.
* If so, return the return type of those delegates.
Expand Down
1 change: 1 addition & 0 deletions src/mtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ struct Argument : Object
static void argsCppMangle(OutBuffer *buf, CppMangleState *cms, Arguments *arguments, int varargs);
static void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Arguments *arguments, int varargs);
static void argsToDecoBuffer(OutBuffer *buf, Arguments *arguments);
static int isTPL(Arguments *arguments);
static size_t dim(Arguments *arguments);
static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL);
};
Expand Down
95 changes: 46 additions & 49 deletions src/opover.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "template.h"

static void inferApplyArgTypesX(FuncDeclaration *fstart, Arguments *arguments);
static void inferApplyArgTypesZ(TemplateDeclaration *tstart, Arguments *arguments);
static int inferApplyArgTypesY(TypeFunction *tf, Arguments *arguments);
static void templateResolve(Match *m, TemplateDeclaration *td, Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *arguments);

Expand Down Expand Up @@ -503,7 +504,6 @@ void inferApplyArgTypes(enum TOK op, Arguments *arguments, Expression *aggr)
}

AggregateDeclaration *ad;
FuncDeclaration *fd;

Argument *arg = (Argument *)arguments->data[0];
Type *taggr = aggr->type;
Expand Down Expand Up @@ -574,9 +574,18 @@ void inferApplyArgTypes(enum TOK op, Arguments *arguments, Expression *aggr)
: Id::apply);
if (s)
{
fd = s->isFuncDeclaration();
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
inferApplyArgTypesX(fd, arguments);
{ inferApplyArgTypesX(fd, arguments);
break;
}
#if 0
TemplateDeclaration *td = s->isTemplateDeclaration();
if (td)
{ inferApplyArgTypesZ(td, arguments);
break;
}
#endif
}
break;
}
Expand All @@ -586,7 +595,7 @@ void inferApplyArgTypes(enum TOK op, Arguments *arguments, Expression *aggr)
if (0 && aggr->op == TOKdelegate)
{ DelegateExp *de = (DelegateExp *)aggr;

fd = de->func->isFuncDeclaration();
FuncDeclaration *fd = de->func->isFuncDeclaration();
if (fd)
inferApplyArgTypesX(fd, arguments);
}
Expand Down Expand Up @@ -623,51 +632,6 @@ static void inferApplyArgTypesX(FuncDeclaration *fstart, Arguments *arguments)
overloadApply(fstart, &fp3, arguments);
}

#if 0
static void inferApplyArgTypesX(FuncDeclaration *fstart, Arguments *arguments)
{
Declaration *d;
Declaration *next;

for (d = fstart; d; d = next)
{
FuncDeclaration *f;
FuncAliasDeclaration *fa;
AliasDeclaration *a;

fa = d->isFuncAliasDeclaration();
if (fa)
{
inferApplyArgTypesX(fa->funcalias, arguments);
next = fa->overnext;
}
else if ((f = d->isFuncDeclaration()) != NULL)
{
next = f->overnext;

TypeFunction *tf = (TypeFunction *)f->type;
if (inferApplyArgTypesY(tf, arguments) == 1)
continue;
if (arguments->dim == 0)
return;
}
else if ((a = d->isAliasDeclaration()) != NULL)
{
Dsymbol *s = a->toAlias();
next = s->isDeclaration();
if (next == a)
break;
if (next == fstart)
break;
}
else
{ d->error("is aliased to a function");
break;
}
}
}
#endif

/******************************
* Infer arguments from type of function.
* Returns:
Expand Down Expand Up @@ -720,6 +684,39 @@ static int inferApplyArgTypesY(TypeFunction *tf, Arguments *arguments)
return 1;
}

/*******************************************
* Infer foreach arg types from a template function opApply which looks like:
* int opApply(alias int func(ref uint))() { ... }
*/

#if 0
void inferApplyArgTypesZ(TemplateDeclaration *tstart, Arguments *arguments)
{
for (TemplateDeclaration *td = tstart; td; td = td->overnext)
{
if (!td->scope)
{
error("forward reference to template %s", td->toChars());
return;
}
if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration())
{
error("is not a function template");
return;
}
if (!td->parameters || td->parameters->dim != 1)
continue;
TemplateParameter *tp = (TemplateParameter *)td->parameters->data[0];
TemplateAliasParameter *tap = tp->isTemplateAliasParameter();
if (!tap || !tap->specType || tap->specType->ty != Tfunction)
continue;
TypeFunction *tf = (TypeFunction *)tap->specType;
if (inferApplyArgTypesY(tf, arguments) == 0) // found it
return;
}
}
#endif

/**************************************
*/

Expand Down
445 changes: 293 additions & 152 deletions src/parse.c

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/parse.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
Expand Down Expand Up @@ -68,7 +68,9 @@ struct Parser : Lexer

Array *parseModule();
Array *parseDeclDefs(int once);
Array *parseAutoDeclarations(unsigned storageClass, unsigned char *comment);
Array *parseBlock();
Expression *parseConstraint();
TemplateDeclaration *parseTemplateDeclaration();
TemplateParameters *parseTemplateParameterList(int flag = 0);
Dsymbol *parseMixin();
Expand Down Expand Up @@ -98,7 +100,7 @@ struct Parser : Lexer
Type *parseBasicType();
Type *parseBasicType2(Type *t);
Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL);
Array *parseDeclarations();
Array *parseDeclarations(unsigned storage_class);
void parseContracts(FuncDeclaration *f);
Statement *parseStatement(int flags);
Initializer *parseInitializer();
Expand Down
143 changes: 88 additions & 55 deletions src/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ Statement *ExpStatement::semantic(Scope *sc)
exp = resolveProperties(sc, exp);
exp->checkSideEffect(0);
exp = exp->optimize(0);
if (exp->op == TOKdeclaration && !isDeclarationStatement())
{ Statement *s = new DeclarationStatement(loc, exp);
return s;
}
//exp = exp->optimize(isDeclarationStatement() ? WANTvalue : 0);
}
return this;
Expand Down Expand Up @@ -267,31 +271,40 @@ void CompileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
}

Statement *CompileStatement::semantic(Scope *sc)
Statements *CompileStatement::flatten(Scope *sc)
{
//printf("CompileStatement::semantic() %s\n", exp->toChars());
//printf("CompileStatement::flatten() %s\n", exp->toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);
if (exp->op != TOKstring)
{ error("argument to mixin must be a string, not (%s)", exp->toChars());
return this;
return NULL;
}
StringExp *se = (StringExp *)exp;
se = se->toUTF8(sc);
Parser p(sc->module, (unsigned char *)se->string, se->len, 0);
p.loc = loc;
p.nextToken();

Statements *statements = new Statements();
Statements *a = new Statements();
while (p.token.value != TOKeof)
{
Statement *s = p.parseStatement(PSsemi | PScurlyscope);
statements->push(s);
a->push(s);
}
return a;
}

Statement *s = new CompoundStatement(loc, statements);
return s->semantic(sc);
Statement *CompileStatement::semantic(Scope *sc)
{
//printf("CompileStatement::semantic() %s\n", exp->toChars());
/* Shouldn't happen unless errors, as CompileStatement::flatten()
* should have replaced it.
* Return NULL so no further errors happen.
*/
assert(global.errors);
return NULL;
}


Expand Down Expand Up @@ -495,7 +508,9 @@ Statement *CompoundStatement::semantic(Scope *sc)
i++;
}
if (statements->dim == 1)
return s;
{
return (Statement *)statements->data[0];
}
return this;
}

Expand All @@ -505,13 +520,11 @@ Statements *CompoundStatement::flatten(Scope *sc)
}

ReturnStatement *CompoundStatement::isReturnStatement()
{ int i;
{
ReturnStatement *rs = NULL;

for (i = 0; i < statements->dim; i++)
{ Statement *s;

s = (Statement *) statements->data[i];
for (int i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
{
rs = s->isReturnStatement();
Expand All @@ -523,12 +536,9 @@ ReturnStatement *CompoundStatement::isReturnStatement()
}

void CompoundStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ int i;

for (i = 0; i < statements->dim; i++)
{ Statement *s;

s = (Statement *) statements->data[i];
{
for (int i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
s->toCBuffer(buf, hgs);
}
Expand All @@ -537,9 +547,7 @@ void CompoundStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
int CompoundStatement::usesEH()
{
for (int i = 0; i < statements->dim; i++)
{ Statement *s;

s = (Statement *) statements->data[i];
{ Statement *s = (Statement *) statements->data[i];
if (s && s->usesEH())
return TRUE;
}
Expand Down Expand Up @@ -1635,14 +1643,33 @@ Statement *ForeachStatement::semantic(Scope *sc)
}
else
{
/* Call:
* aggr.apply(flde)
*/
ec = new DotIdExp(loc, aggr,
(op == TOKforeach_reverse) ? Id::applyReverse
: Id::apply);
Expressions *exps = new Expressions();
exps->push(flde);
assert(tab->ty == Tstruct || tab->ty == Tclass);
Identifier *idapply = (op == TOKforeach_reverse)
? Id::applyReverse : Id::apply;
Dsymbol *sapply = search_function((AggregateDeclaration *)tab->toDsymbol(sc), idapply);
Expressions *exps = new Expressions();
#if 0
TemplateDeclaration *td;
if (sapply &&
(td = sapply->isTemplateDeclaration()) != NULL)
{ /* Call:
* aggr.apply!(fld)()
*/
TemplateInstance *ti = new TemplateInstance(loc, idapply);
Objects *tiargs = new Objects();
tiargs->push(fld);
ti->tiargs = tiargs;
ec = new DotTemplateInstanceExp(loc, aggr, ti);
}
else
#endif
{
/* Call:
* aggr.apply(flde)
*/
ec = new DotIdExp(loc, aggr, idapply);
exps->push(flde);
}
e = new CallExp(loc, ec, exps);
e = e->semantic(sc);
if (e->type != Type::tint32)
Expand Down Expand Up @@ -1817,7 +1844,7 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
*/
AddExp ea(loc, lwr, upr);
ea.typeCombine(sc);
arg->type = ea.type;
arg->type = ea.type->mutableOf();
lwr = ea.e1;
upr = ea.e2;
}
Expand Down Expand Up @@ -2112,13 +2139,21 @@ void ConditionalStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
condition->toCBuffer(buf, hgs);
buf->writenl();
buf->writeByte('{');
buf->writenl();
if (ifbody)
ifbody->toCBuffer(buf, hgs);
buf->writeByte('}');
buf->writenl();
if (elsebody)
{
buf->writestring("else");
buf->writenl();
buf->writeByte('{');
buf->writenl();
elsebody->toCBuffer(buf, hgs);
buf->writeByte('}');
buf->writenl();
}
buf->writenl();
}
Expand Down Expand Up @@ -2817,6 +2852,8 @@ Statement *ReturnStatement::semantic(Scope *sc)

Type *tret = fd->type->nextOf();
if (fd->tintro)
/* We'll be implicitly casting the return expression to tintro
*/
tret = fd->tintro->nextOf();
Type *tbret = NULL;

Expand Down Expand Up @@ -2938,32 +2975,25 @@ Statement *ReturnStatement::semantic(Scope *sc)
exp->op == TOKstring)
{
sc->fes->cases.push(this);
// Construct: return cases.dim+1;
s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
}
else if (fd->type->nextOf()->toBasetype() == Type::tvoid)
{
Statement *s1;
Statement *s2;

s = new ReturnStatement(0, NULL);
sc->fes->cases.push(s);

// Construct: { exp; return cases.dim + 1; }
s1 = new ExpStatement(loc, exp);
s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
Statement *s1 = new ExpStatement(loc, exp);
Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
s = new CompoundStatement(loc, s1, s2);
}
else
{
VarExp *v;
Statement *s1;
Statement *s2;

// Construct: return vresult;
if (!fd->vresult)
{ VarDeclaration *v;

v = new VarDeclaration(loc, tret, Id::result, NULL);
{ // Declare vresult
VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL);
v->noauto = 1;
v->semantic(scx);
if (!scx->insert(v))
Expand All @@ -2972,16 +3002,14 @@ Statement *ReturnStatement::semantic(Scope *sc)
fd->vresult = v;
}

v = new VarExp(0, fd->vresult);
s = new ReturnStatement(0, v);
s = new ReturnStatement(0, new VarExp(0, fd->vresult));
sc->fes->cases.push(s);

// Construct: { vresult = exp; return cases.dim + 1; }
v = new VarExp(0, fd->vresult);
exp = new AssignExp(loc, v, exp);
exp = new AssignExp(loc, new VarExp(0, fd->vresult), exp);
exp = exp->semantic(sc);
s1 = new ExpStatement(loc, exp);
s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
Statement *s1 = new ExpStatement(loc, exp);
Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
s = new CompoundStatement(loc, s1, s2);
}
return s;
Expand Down Expand Up @@ -3022,18 +3050,23 @@ Statement *ReturnStatement::semantic(Scope *sc)

gs->label = fd->returnLabel;
if (exp)
{ Statement *s;

s = new ExpStatement(0, exp);
{ /* Replace: return exp;
* with: exp; goto returnLabel;
*/
Statement *s = new ExpStatement(0, exp);
return new CompoundStatement(loc, s, gs);
}
return gs;
}

if (exp && tbret->ty == Tvoid && !fd->isMain())
{ Statement *s;

s = new ExpStatement(loc, exp);
{
/* Replace:
* return exp;
* with:
* exp; return;
*/
Statement *s = new ExpStatement(loc, exp);
loc = 0;
exp = NULL;
return new CompoundStatement(loc, s, this);
Expand Down
1 change: 1 addition & 0 deletions src/statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ struct CompileStatement : Statement
CompileStatement(Loc loc, Expression *exp);
Statement *syntaxCopy();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Statements *flatten(Scope *sc);
Statement *semantic(Scope *sc);
};

Expand Down
362 changes: 286 additions & 76 deletions src/template.c

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions src/template.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
Expand Down Expand Up @@ -52,6 +52,8 @@ struct TemplateDeclaration : ScopeDsymbol

TemplateParameters *origParameters; // originals for Ddoc

Expression *constraint;

Array instances; // array of TemplateInstance's

TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
Expand All @@ -60,7 +62,8 @@ struct TemplateDeclaration : ScopeDsymbol
Scope *scope;
Dsymbol *onemember; // if !=NULL then one member of this template

TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs);
TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters,
Expression *constraint, Array *decldefs);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
int overloadInsert(Dsymbol *s);
Expand Down Expand Up @@ -202,17 +205,16 @@ struct TemplateValueParameter : TemplateParameter
struct TemplateAliasParameter : TemplateParameter
{
/* Syntax:
* ident : specAlias = defaultAlias
* specType ident : specAlias = defaultAlias
*/

Type *specAliasT;
Dsymbol *specAlias;

Type *defaultAlias;
Type *specType;
Object *specAlias;
Object *defaultAlias;

static Dsymbol *sdummy;

TemplateAliasParameter(Loc loc, Identifier *ident, Type *specAliasT, Type *defaultAlias);
TemplateAliasParameter(Loc loc, Identifier *ident, Type *specType, Object *specAlias, Object *defaultAlias);

TemplateAliasParameter *isTemplateAliasParameter();
TemplateParameter *syntaxCopy();
Expand Down Expand Up @@ -271,6 +273,7 @@ struct TemplateInstance : ScopeDsymbol
// sole member
WithScopeSymbol *withsym; // if a member of a with statement
int semanticdone; // has semantic() been done?
int semantictiargsdone; // has semanticTiargs() been done?
int nest; // for recursion detection
int havetempdecl; // 1 if used second constructor
Dsymbol *isnested; // if referencing local symbols, this is the context
Expand Down
57 changes: 55 additions & 2 deletions src/toir.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,11 @@ int intrinsic_op(char *name)
"4math5ldexpFeiZe",
"4math6rndtolFeZl",

#if V1
"9intrinsic2btFPkkZi",
#else
"9intrinsic2btFxPkkZi",
#endif
"9intrinsic3bsfFkZi",
"9intrinsic3bsrFkZi",
"9intrinsic3btcFPkkZi",
Expand Down Expand Up @@ -406,6 +410,7 @@ void FuncDeclaration::buildClosure(IRState *irs)
{ // Generate closure on the heap
// BUG: doesn't capture variadic arguments passed to this function

#if V2
/* BUG: doesn't handle destructors for the local variables.
* The way to do it is to make the closure variables the fields
* of a class object:
Expand All @@ -418,7 +423,7 @@ void FuncDeclaration::buildClosure(IRState *irs)
* ~this() { call destructor }
* }
*/

#endif
//printf("FuncDeclaration::buildClosure()\n");
Symbol *sclosure;
sclosure = symbol_name("__closptr",SCauto,Type::tvoidptr->toCtype());
Expand All @@ -431,9 +436,10 @@ void FuncDeclaration::buildClosure(IRState *irs)
{ VarDeclaration *v = (VarDeclaration *)closureVars.data[i];
assert(v->isVarDeclaration());

#if V2
if (v->needsAutoDtor())
v->error("has scoped destruction, cannot build closure");

#endif
/* Align and allocate space for v in the closure
* just like AggregateDeclaration::addField() does.
*/
Expand Down Expand Up @@ -502,3 +508,50 @@ void FuncDeclaration::buildClosure(IRState *irs)

#endif

/***************************
* Determine return style of function - whether in registers or
* through a hidden pointer to the caller's stack.
*/

enum RET TypeFunction::retStyle()
{
//printf("TypeFunction::retStyle() %s\n", toChars());
Type *tn = next->toBasetype();

if (tn->ty == Tstruct)
{ StructDeclaration *sd = ((TypeStruct *)tn)->sym;
if (global.params.isLinux && linkage != LINKd)
;
#if V2
else if (sd->dtor || sd->cpctor)
;
#endif
else
{
switch ((int)tn->size())
{ case 1:
case 2:
case 4:
case 8:
return RETregs; // return small structs in regs
// (not 3 byte structs!)
default:
break;
}
}
return RETstack;
}
else if (global.params.isLinux &&
linkage == LINKc &&
tn->iscomplex())
{
if (tn->ty == Tcomplex32)
return RETregs; // in EDX:EAX, not ST1:ST0
else
return RETstack;
}
else
return RETregs;
}


104 changes: 61 additions & 43 deletions src/toobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,12 @@ void Module::genmoduleinfo()
else
dtdword(&dt, 0);

#if V2
FuncDeclaration *sgetmembers = findGetMembers();
if (sgetmembers)
dtxoff(&dt, sgetmembers->toSymbol(), 0, TYnptr);
else
#endif
dtdword(&dt, 0); // xgetMembers

if (sictor)
Expand Down Expand Up @@ -204,14 +206,8 @@ void ClassDeclaration::toObjFile(int multiobj)
assert(!scope); // semantic() should have been run to completion

scclass = SCglobal;
for (Dsymbol *parent = this->parent; parent; parent = parent->parent)
{
if (parent->isTemplateInstance())
{
scclass = SCcomdat;
break;
}
}
if (inTemplateInstance())
scclass = SCcomdat;

// Put out the members
for (i = 0; i < members->dim; i++)
Expand Down Expand Up @@ -382,7 +378,10 @@ void ClassDeclaration::toObjFile(int multiobj)
dtdword(&dt, 0);

// flags
int flags = 16 | 4 | isCOMclass();
int flags = 4 | isCOMclass();
#if V2
flags |= 16;
#endif
if (ctor)
flags |= 8;
for (ClassDeclaration *cd = this; cd; cd = cd->baseClass)
Expand Down Expand Up @@ -419,11 +418,13 @@ void ClassDeclaration::toObjFile(int multiobj)
else
dtdword(&dt, 0);

#if V2
FuncDeclaration *sgetmembers = findGetMembers();
if (sgetmembers)
dtxoff(&dt, sgetmembers->toSymbol(), 0, TYnptr);
else
dtdword(&dt, 0); // module getMembers() function
#endif

//////////////////////////////////////////////

Expand Down Expand Up @@ -618,17 +619,37 @@ void ClassDeclaration::toObjFile(int multiobj)

//printf("\tvtbl[%d] = %p\n", i, fd);
if (fd && (fd->fbody || !isAbstract()))
{
{ Symbol *s = fd->toSymbol();

#if V2
if (isFuncHidden(fd))
{
if (global.params.warnings)
{ fprintf(stdmsg, "warning - ");
error("%s %s is hidden in %s\n", fd->toParent()->toChars(), fd->toChars(), toChars());
{ /* fd is hidden from the view of this class.
* If fd overlaps with any function in the vtbl[], then
* issue 'hidden' error.
*/
for (int j = 1; j < vtbl.dim; j++)
{ if (j == i)
continue;
FuncDeclaration *fd2 = ((Dsymbol *)vtbl.data[j])->isFuncDeclaration();
if (!fd2->ident->equals(fd->ident))
continue;
if (fd->leastAsSpecialized(fd2) || fd2->leastAsSpecialized(fd))
{
if (global.params.warnings)
{ fprintf(stdmsg, "warning - ");
TypeFunction *tf = (TypeFunction *)fd->type;
if (tf->ty == Tfunction)
error("%s%s is hidden by %s\n", fd->toPrettyChars(), Argument::argsTypesToChars(tf->parameters, tf->varargs), toChars());
else
error("%s is hidden by %s\n", fd->toPrettyChars(), toChars());
}
s = rtlsym[RTLSYM_DHIDDENFUNC];
break;
}
}
dtxoff(&dt, rtlsym[RTLSYM_DHIDDENFUNC], 0, TYnptr);
}
else
dtxoff(&dt, fd->toSymbol(), 0, TYnptr);
#endif
dtxoff(&dt, s, 0, TYnptr);
}
else
dtdword(&dt, 0);
Expand Down Expand Up @@ -732,14 +753,8 @@ void InterfaceDeclaration::toObjFile(int multiobj)
toDebug();

scclass = SCglobal;
for (Dsymbol *parent = this->parent; parent; parent = parent->parent)
{
if (parent->isTemplateInstance())
{
scclass = SCcomdat;
break;
}
}
if (inTemplateInstance())
scclass = SCcomdat;

// Put out the members
for (i = 0; i < members->dim; i++)
Expand Down Expand Up @@ -775,7 +790,9 @@ void InterfaceDeclaration::toObjFile(int multiobj)
void *deallocator;
OffsetTypeInfo[] offTi;
void *defaultConstructor;
#if V2
const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function
#endif
}
*/
dt_t *dt = NULL;
Expand Down Expand Up @@ -835,8 +852,10 @@ void InterfaceDeclaration::toObjFile(int multiobj)
// defaultConstructor
dtdword(&dt, 0);

#if V2
// xgetMembers
dtdword(&dt, 0);
#endif

//////////////////////////////////////////////

Expand Down Expand Up @@ -951,19 +970,21 @@ void VarDeclaration::toObjFile(int multiobj)
return;
}

#if V2
// Do not store variables we cannot take the address of
if (!canTakeAddressOf())
{
return;
}
#endif

if (isDataseg() && !(storage_class & STCextern))
{
s = toSymbol();
sz = type->size();

parent = this->toParent();
#if 0 /* private statics should still get a global symbol, in case
#if V1 /* private statics should still get a global symbol, in case
* another module inlines a function that references it.
*/
if (/*protection == PROTprivate ||*/
Expand All @@ -987,7 +1008,7 @@ void VarDeclaration::toObjFile(int multiobj)
*/
if (parent->isTemplateInstance() && !parent->isTemplateMixin())
{
#if 0
#if V1
/* These symbol constants have already been copied,
* so no reason to output them.
* Note that currently there is no way to take
Expand Down Expand Up @@ -1085,14 +1106,8 @@ void TypedefDeclaration::toObjFile(int multiobj)
else
{
enum_SC scclass = SCglobal;
for (Dsymbol *parent = this->parent; parent; parent = parent->parent)
{
if (parent->isTemplateInstance())
{
scclass = SCcomdat;
break;
}
}
if (inTemplateInstance())
scclass = SCcomdat;

// Generate static initializer
toInitializer();
Expand All @@ -1112,8 +1127,10 @@ void EnumDeclaration::toObjFile(int multiobj)
{
//printf("EnumDeclaration::toObjFile('%s')\n", toChars());

#if V2
if (isAnonymous())
return;
#endif

if (global.params.symdebug)
toDebug();
Expand All @@ -1126,14 +1143,8 @@ void EnumDeclaration::toObjFile(int multiobj)
else
{
enum_SC scclass = SCglobal;
for (Dsymbol *parent = this->parent; parent; parent = parent->parent)
{
if (parent->isTemplateInstance())
{
scclass = SCcomdat;
break;
}
}
if (inTemplateInstance())
scclass = SCcomdat;

// Generate static initializer
toInitializer();
Expand All @@ -1142,9 +1153,16 @@ void EnumDeclaration::toObjFile(int multiobj)
#if ELFOBJ // Burton
sinit->Sseg = CDATA;
#endif /* ELFOBJ */
#if V1
dtnbytes(&sinit->Sdt, tc->size(0), (char *)&tc->sym->defaultval);
//sinit->Sdt = tc->sym->init->toDt();
#endif
#if V2
tc->sym->defaultval->toDt(&sinit->Sdt);
#endif
outdata(sinit);
}
}