Infer function literal kind (TOKdelegate or TOKfunction).

This commit is contained in:
Alexey Prokhin
2012-04-21 16:59:40 +04:00
parent 0e54278c5a
commit 7e23eb5047
3 changed files with 32 additions and 8 deletions

View File

@@ -1621,6 +1621,7 @@ Expression *CommaExp::castTo(Scope *sc, Type *t)
/****************************************
* Set type inference target
* flag 1: don't put an error when inference fails
* 2: ldc specific: allow to infer function literal kind (TOKdelegate or TOKfunction)
*/
Expression *Expression::inferType(Type *t, int flag, TemplateParameters *tparams)
@@ -1770,9 +1771,27 @@ Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams)
}
else
e = this;
#if IN_LLVM
if (flag == 2 && e)
{ FuncExp *fe = (FuncExp *)e;
if (fe->fd && fe->fd->tok == TOKreserved)
{
if (fe->type->ty == Tpointer)
{
fe->fd->vthis = NULL;
fe->fd->tok = TOKfunction;
}
else
{
fe->fd->tok = TOKdelegate;
}
}
}
#endif
}
L1:
if (!flag && !e)
if (flag != 1 && !e)
{ error("cannot infer function literal type from %s", to->toChars());
e = new ErrorExp();
}

View File

@@ -891,7 +891,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
Type *pt = p->type;
if (tf->varargs == 2 && i + 1 == nparams && pt->nextOf())
pt = pt->nextOf();
arg = arg->inferType(pt);
arg = arg->inferType(pt, 2);
arguments->tdata()[i] = arg;
}
@@ -10464,7 +10464,7 @@ Ltupleassign:
}
}
e2 = e2->inferType(t1);
e2 = e2->inferType(t1, 2);
if (!e2->rvalue())
return new ErrorExp();

View File

@@ -5404,12 +5404,17 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
}
if (FuncLiteralDeclaration *literal = funcdecl->isFuncLiteralDeclaration()) {
// Never merge types of function literals of different kind
if (literal->tok == TOKreserved)
buf->writeByte('L');
else if (literal->tok == TOKfunction)
buf->writeByte('F');
else if (literal->tok == TOKdelegate)
if (literal->tok == TOKdelegate) {
buf->writeByte('D');
} else if (literal->tok == TOKfunction) {
buf->writeByte('F');
} else if (literal->tok == TOKreserved) {
static int counter = 0;
buf->writeByte('L');
// And never merge types of lambdas, because we don't know whether
// they need a nested context argument or not.
buf->printf("%i", counter++);
}
}
/* BUG This causes problems with delegate types
On the other hand, the llvm type for nested functions *is* different