Merge the 2.063 frontend.

This commit is contained in:
David Nadlinger
2013-06-12 20:16:37 +02:00
parent 981a6af17e
commit 292caa1438
90 changed files with 10179 additions and 8105 deletions
+83 -24
View File
@@ -40,9 +40,9 @@ Expression *ClassReferenceExp::interpret(InterState *istate, CtfeGoal goal)
return this;
}
char *ClassReferenceExp::toChars()
void ClassReferenceExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
return value->toChars();
buf->writestring(value->toChars());
}
ClassDeclaration *ClassReferenceExp::originalClass()
@@ -306,6 +306,7 @@ Expression *copyLiteral(Expression *e)
#endif
r->type = e->type;
r->ownedByCtfe = true;
r->origin = ((StructLiteralExp*)e)->origin;
return r;
}
else if (e->op == TOKfunction || e->op == TOKdelegate
@@ -379,13 +380,13 @@ Expression *paintTypeOntoLiteral(Type *type, Expression *lit)
else if (lit->op == TOKarrayliteral)
{
e = new SliceExp(lit->loc, lit,
new IntegerExp(0, 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit));
new IntegerExp(Loc(), 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit));
}
else if (lit->op == TOKstring)
{
// For strings, we need to introduce another level of indirection
e = new SliceExp(lit->loc, lit,
new IntegerExp(0, 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit));
new IntegerExp(Loc(), 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit));
}
else if (lit->op == TOKassocarrayliteral)
{
@@ -532,6 +533,16 @@ TypeAArray *toBuiltinAAType(Type *t)
#endif
}
/************** TypeInfo operations ************************************/
// Return true if type is TypeInfo_Class
bool isTypeInfo_Class(Type *type)
{
return type->ty == Tclass &&
(( Type::typeinfo == ((TypeClass*)type)->sym)
|| Type::typeinfo->isBaseOf(((TypeClass*)type)->sym, NULL));
}
/************** Pointer operations ************************************/
// Return true if t is a pointer (not a function pointer)
@@ -574,6 +585,8 @@ Expression *getAggregateFromPointer(Expression *e, dinteger_t *ofs)
*ofs = 0;
if (e->op == TOKaddress)
e = ((AddrExp *)e)->e1;
if (e->op == TOKsymoff)
*ofs = ((SymOffExp *)e)->offset;
if (e->op == TOKdotvar)
{
Expression *ex = ((DotVarExp *)e)->e1;
@@ -607,11 +620,19 @@ Expression *getAggregateFromPointer(Expression *e, dinteger_t *ofs)
*/
bool pointToSameMemoryBlock(Expression *agg1, Expression *agg2)
{
// For integers cast to pointers, we regard them as non-comparable
// unless they are identical. (This may be overly strict).
if (agg1->op == TOKint64 && agg2->op == TOKint64
&& agg1->toInteger() == agg2->toInteger())
return true;
// Note that type painting can occur with VarExp, so we
// must compare the variables being pointed to.
return agg1 == agg2 ||
(agg1->op == TOKvar && agg2->op == TOKvar &&
((VarExp *)agg1)->var == ((VarExp *)agg2)->var);
((VarExp *)agg1)->var == ((VarExp *)agg2)->var) ||
(agg1->op == TOKsymoff && agg2->op == TOKsymoff &&
((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var);
}
// return e1 - e2 as an integer, or error if not possible
@@ -630,11 +651,16 @@ Expression *pointerDifference(Loc loc, Type *type, Expression *e1, Expression *e
{
if (((StringExp *)agg1)->string == ((StringExp *)agg2)->string)
{
Type *pointee = ((TypePointer *)agg1->type)->next;
dinteger_t sz = pointee->size();
return new IntegerExp(loc, (ofs1-ofs2)*sz, type);
Type *pointee = ((TypePointer *)agg1->type)->next;
dinteger_t sz = pointee->size();
return new IntegerExp(loc, (ofs1-ofs2)*sz, type);
}
}
else if (agg1->op == TOKsymoff && agg2->op == TOKsymoff &&
((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var)
{
return new IntegerExp(loc, ofs1-ofs2, type);
}
error(loc, "%s - %s cannot be interpreted at compile time: cannot subtract "
"pointers to two different memory blocks",
e1->toChars(), e2->toChars());
@@ -655,21 +681,36 @@ Expression *pointerArithmetic(Loc loc, enum TOK op, Type *type,
if (eptr->op == TOKaddress)
eptr = ((AddrExp *)eptr)->e1;
Expression *agg1 = getAggregateFromPointer(eptr, &ofs1);
if (agg1->op != TOKstring && agg1->op != TOKarrayliteral)
if (agg1->op == TOKsymoff)
{
if (((SymOffExp *)agg1)->var->type->ty != Tsarray)
{
error(loc, "cannot perform pointer arithmetic on arrays of unknown length at compile time");
return EXP_CANT_INTERPRET;
}
}
else if (agg1->op != TOKstring && agg1->op != TOKarrayliteral)
{
error(loc, "cannot perform pointer arithmetic on non-arrays at compile time");
return EXP_CANT_INTERPRET;
}
ofs2 = e2->toInteger();
Type *pointee = ((TypePointer *)agg1->type)->next;
sinteger_t indx = ofs1;
dinteger_t sz = pointee->size();
Expression *dollar = ArrayLength(Type::tsize_t, agg1);
assert(dollar != EXP_CANT_INTERPRET);
Expression *dollar;
if (agg1->op == TOKsymoff)
{
dollar = ((TypeSArray *)(((SymOffExp *)agg1)->var->type))->dim;
indx = ofs1/sz;
}
else
{
dollar = ArrayLength(Type::tsize_t, agg1);
assert(dollar != EXP_CANT_INTERPRET);
}
dinteger_t len = dollar->toInteger();
Expression *val = agg1;
TypeArray *tar = (TypeArray *)val->type;
sinteger_t indx = ofs1;
if (op == TOKadd || op == TOKaddass || op == TOKplusplus)
indx = indx + ofs2/sz;
else if (op == TOKmin || op == TOKminass || op == TOKminusminus)
@@ -679,17 +720,27 @@ Expression *pointerArithmetic(Loc loc, enum TOK op, Type *type,
error(loc, "CTFE Internal compiler error: bad pointer operation");
return EXP_CANT_INTERPRET;
}
if (val->op != TOKarrayliteral && val->op != TOKstring)
{
error(loc, "CTFE Internal compiler error: pointer arithmetic %s", val->toChars());
return EXP_CANT_INTERPRET;
}
if (indx < 0 || indx > len)
{
error(loc, "cannot assign pointer to index %lld inside memory block [0..%lld]", indx, len);
return EXP_CANT_INTERPRET;
}
if (agg1->op == TOKsymoff)
{
SymOffExp *se = new SymOffExp(loc, ((SymOffExp *)agg1)->var, indx*sz);
se->type = type;
return se;
}
Expression *val = agg1;
if (val->op != TOKarrayliteral && val->op != TOKstring)
{
error(loc, "CTFE Internal compiler error: pointer arithmetic %s", val->toChars());
return EXP_CANT_INTERPRET;
}
IntegerExp *ofs = new IntegerExp(loc, indx, Type::tsize_t);
IndexExp *ie = new IndexExp(loc, val, ofs);
ie->type = type;
@@ -1408,7 +1459,9 @@ int ctfeIdentity(Loc loc, enum TOK op, Expression *e1, Expression *e2)
int ctfeCmp(Loc loc, enum TOK op, Expression *e1, Expression *e2)
{
int n;
if (e1->type->isString() && e2->type->isString())
Type *t1 = e1->type->toBasetype();
Type *t2 = e2->type->toBasetype();
if (t1->isString() && t2->isString())
{
int cmp = ctfeRawCmp(loc, e1, e2);
switch (op)
@@ -1431,15 +1484,15 @@ int ctfeCmp(Loc loc, enum TOK op, Expression *e1, Expression *e2)
assert(0);
}
}
else if (e1->type->isreal())
else if (t1->isreal())
{
n = realCmp(op, e1->toReal(), e2->toReal());
}
else if (e1->type->isimaginary())
else if (t1->isimaginary())
{
n = realCmp(op, e1->toImaginary(), e2->toImaginary());
}
else if (e1->type->isunsigned() || e2->type->isunsigned())
else if (t1->isunsigned() || t2->isunsigned())
{
n = intUnsignedCmp(op, e1->toInteger(), e2->toInteger());
}
@@ -1598,6 +1651,10 @@ Expression *ctfeCast(Loc loc, Type *type, Type *to, Expression *e)
else
return new NullExp(loc, to);
}
// Allow TypeInfo type painting
if (isTypeInfo_Class(e->type) && e->type->implicitConvTo(to))
return paintTypeOntoLiteral(to, e);
Expression *r = Cast(type, to, e);
if (r == EXP_CANT_INTERPRET)
error(loc, "cannot cast %s to %s at compile time", e->toChars(), to->toChars());
@@ -1765,7 +1822,7 @@ Expression *assignAssocArrayElement(Loc loc, AssocArrayLiteralExp *aae,
Expression *changeArrayLiteralLength(Loc loc, TypeArray *arrayType,
Expression *oldval, size_t oldlen, size_t newlen)
{
Type *elemType = elemType = arrayType->next;
Type *elemType = arrayType->next;
assert(elemType);
Expression *defaultElem = elemType->defaultInitLiteral(loc);
Expressions *elements = new Expressions();
@@ -1895,6 +1952,8 @@ bool isCtfeValueValid(Expression *newval)
{
if (((SymOffExp *)newval)->var->isFuncDeclaration())
return true;
if (((SymOffExp *)newval)->var->isDataseg())
return true; // pointer to static variable
}
if (newval->op == TOKint64 || newval->op == TOKfloat64 ||