mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-10-22 02:37:26 +02:00
Merge the 2.063 frontend.
This commit is contained in:
+83
-24
@@ -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 ||
|
||||
|
||||
Reference in New Issue
Block a user