From 7e23eb50471905a6dfc8c517cd728ae1f98ec5d7 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Sat, 21 Apr 2012 16:59:40 +0400 Subject: [PATCH] Infer function literal kind (TOKdelegate or TOKfunction). --- dmd2/cast.c | 21 ++++++++++++++++++++- dmd2/expression.c | 4 ++-- dmd2/mtype.c | 15 ++++++++++----- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/dmd2/cast.c b/dmd2/cast.c index fded2ecc..7aaf2517 100644 --- a/dmd2/cast.c +++ b/dmd2/cast.c @@ -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(); } diff --git a/dmd2/expression.c b/dmd2/expression.c index c2a4a3b3..4363d935 100644 --- a/dmd2/expression.c +++ b/dmd2/expression.c @@ -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(); diff --git a/dmd2/mtype.c b/dmd2/mtype.c index 8dc23d7e..1eaf106b 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -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