Skip to content

Commit

Permalink
Merge pull request #4166 from WalterBright/paintliteral
Browse files Browse the repository at this point in the history
CTFE: paintTypeOntoLiteral() to UnionExp
  • Loading branch information
9rnsr committed Nov 25, 2014
2 parents c0e8143 + 886755d commit 330cede
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/ctfe.h
Expand Up @@ -136,6 +136,7 @@ UnionExp copyLiteral(Expression *e);

/// Set this literal to the given type, copying it if necessary
Expression *paintTypeOntoLiteral(Type *type, Expression *lit);
UnionExp paintTypeOntoLiteralCopy(Type *type, Expression *lit);

/// Convert from a CTFE-internal slice, into a normal Expression
Expression *resolveSlice(Expression *e);
Expand Down
43 changes: 28 additions & 15 deletions src/ctfeexpr.c
Expand Up @@ -366,35 +366,46 @@ Expression *paintTypeOntoLiteral(Type *type, Expression *lit)
{
if (lit->type->equals(type))
return lit;
return paintTypeOntoLiteralCopy(type, lit).copy();
}

UnionExp paintTypeOntoLiteralCopy(Type *type, Expression *lit)
{
UnionExp ue;

if (lit->type->equals(type))
{
memcpy(&ue, lit, lit->size);
return ue;
}

// If it is a cast to inout, retain the original type of the referenced part.
if (type->hasWild() && type->hasPointers())
{
lit = lit->copy();
lit->type = type;
return lit;
memcpy(&ue, lit, lit->size);
ue.exp()->type = type;
return ue;
}

Expression *e;
if (lit->op == TOKslice)
{
SliceExp *se = (SliceExp *)lit;
e = new SliceExp(lit->loc, se->e1, se->lwr, se->upr);
new(&ue) SliceExp(lit->loc, se->e1, se->lwr, se->upr);
}
else if (lit->op == TOKindex)
{
IndexExp *ie = (IndexExp *)lit;
e = new IndexExp(lit->loc, ie->e1, ie->e2);
new(&ue) IndexExp(lit->loc, ie->e1, ie->e2);
}
else if (lit->op == TOKarrayliteral)
{
e = new SliceExp(lit->loc, lit,
new(&ue) SliceExp(lit->loc, lit,
new IntegerExp(Loc(), 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit).copy());
}
else if (lit->op == TOKstring)
{
// For strings, we need to introduce another level of indirection
e = new SliceExp(lit->loc, lit,
new(&ue) SliceExp(lit->loc, lit,
new IntegerExp(Loc(), 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit).copy());
}
else if (lit->op == TOKassocarrayliteral)
Expand All @@ -403,20 +414,20 @@ Expression *paintTypeOntoLiteral(Type *type, Expression *lit)
// TODO: we should be creating a reference to this AAExp, not
// just a ref to the keys and values.
bool wasOwned = aae->ownedByCtfe;
aae = new AssocArrayLiteralExp(lit->loc, aae->keys, aae->values);
new(&ue) AssocArrayLiteralExp(lit->loc, aae->keys, aae->values);
aae = (AssocArrayLiteralExp *)ue.exp();
aae->ownedByCtfe = wasOwned;
e = aae;
}
else
{
// Can't type paint from struct to struct*; this needs another
// level of indirection
if (lit->op == TOKstructliteral && isPointer(type))
lit->error("CTFE internal error painting %s", type->toChars());
e = copyLiteral(lit).copy();
ue = copyLiteral(lit);
}
e->type = type;
return e;
ue.exp()->type = type;
return ue;
}

Expression *resolveSlice(Expression *e)
Expand Down Expand Up @@ -1675,13 +1686,15 @@ UnionExp ctfeCat(Type *type, Expression *e1, Expression *e2)
t1->nextOf()->equals(t2->nextOf()))
{
// [ e1 ] ~ null ----> [ e1 ].dup
e = paintTypeOntoLiteral(type, copyLiteral(e1).copy());
ue = paintTypeOntoLiteralCopy(type, copyLiteral(e1).exp());
return ue;
}
else if (e1->op == TOKnull && e2->op == TOKarrayliteral &&
t1->nextOf()->equals(t2->nextOf()))
{
// null ~ [ e2 ] ----> [ e2 ].dup
e = paintTypeOntoLiteral(type, copyLiteral(e2).copy());
ue = paintTypeOntoLiteralCopy(type, copyLiteral(e2).exp());
return ue;
}
else
{
Expand Down

0 comments on commit 330cede

Please sign in to comment.