Expression *CallExp::optimize(int result) { //printf("CallExp::optimize(result = %d) %s\n", result, toChars()); Expression *e = this; e1 = e1->optimize(result); if (e1->op == TOKvar) { FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration(); if (fd) { enum BUILTIN b = fd->isBuiltin(); if (b) { e = eval_builtin(b, arguments); if (!e) // failed e = this; // evaluate at runtime } else if (result & WANTinterpret) { Expression *eresult = fd->interpret(NULL, arguments); if (eresult && eresult != EXP_VOID_INTERPRET) e = eresult; else error("cannot evaluate %s at compile time", toChars()); } } } return e; }
Expression *CallExp::optimize(int result) { //printf("CallExp::optimize(result = %d) %s\n", result, toChars()); Expression *e = this; // Optimize parameters if (arguments) { for (size_t i = 0; i < arguments->dim; i++) { Expression *e = (*arguments)[i]; e = e->optimize(WANTvalue); (*arguments)[i] = e; } } e1 = e1->optimize(result); #if 1 if (result & WANTinterpret) { Expression *eresult = interpret(NULL); if (eresult == EXP_CANT_INTERPRET) return e; if (eresult && eresult != EXP_VOID_INTERPRET) e = eresult; else error("cannot evaluate %s at compile time", toChars()); } #else if (e1->op == TOKvar) { FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration(); if (fd) { enum BUILTIN b = fd->isBuiltin(); if (b) { e = eval_builtin(b, arguments); if (!e) // failed e = this; // evaluate at runtime } else if (result & WANTinterpret) { Expression *eresult = fd->interpret(NULL, arguments); if (eresult && eresult != EXP_VOID_INTERPRET) e = eresult; else error("cannot evaluate %s at compile time", toChars()); } } } else if (e1->op == TOKdotvar && result & WANTinterpret) { DotVarExp *dve = (DotVarExp *)e1; FuncDeclaration *fd = dve->var->isFuncDeclaration(); if (fd) { Expression *eresult = fd->interpret(NULL, arguments, dve->e1); if (eresult && eresult != EXP_VOID_INTERPRET) e = eresult; else error("cannot evaluate %s at compile time", toChars()); } } #endif return e; }
Expression *CallExp::optimize(int result, bool keepLvalue) { //printf("CallExp::optimize(result = %d) %s\n", result, toChars()); Expression *e = this; // Optimize parameters with keeping lvalue-ness if (arguments) { Type *t1 = e1->type->toBasetype(); if (t1->ty == Tdelegate) t1 = t1->nextOf(); assert(t1->ty == Tfunction); TypeFunction *tf = (TypeFunction *)t1; size_t pdim = Parameter::dim(tf->parameters) - (tf->varargs == 2 ? 1 : 0); for (size_t i = 0; i < arguments->dim; i++) { bool keepLvalue = false; if (i < pdim) { Parameter *p = Parameter::getNth(tf->parameters, i); keepLvalue = ((p->storageClass & (STCref | STCout)) != 0); } Expression *e = (*arguments)[i]; e = e->optimize(WANTvalue, keepLvalue); (*arguments)[i] = e; } } e1 = e1->optimize(result); if (keepLvalue) return this; #if 1 if (result & WANTinterpret) { Expression *eresult = interpret(NULL); if (eresult == EXP_CANT_INTERPRET) return e; if (eresult && eresult != EXP_VOID_INTERPRET) e = eresult; else error("cannot evaluate %s at compile time", toChars()); } #else if (e1->op == TOKvar) { FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration(); if (fd) { enum BUILTIN b = fd->isBuiltin(); if (b) { e = eval_builtin(b, arguments); if (!e) // failed e = this; // evaluate at runtime } else if (result & WANTinterpret) { Expression *eresult = fd->interpret(NULL, arguments); if (eresult && eresult != EXP_VOID_INTERPRET) e = eresult; else error("cannot evaluate %s at compile time", toChars()); } } } else if (e1->op == TOKdotvar && result & WANTinterpret) { DotVarExp *dve = (DotVarExp *)e1; FuncDeclaration *fd = dve->var->isFuncDeclaration(); if (fd) { Expression *eresult = fd->interpret(NULL, arguments, dve->e1); if (eresult && eresult != EXP_VOID_INTERPRET) e = eresult; else error("cannot evaluate %s at compile time", toChars()); } } #endif return e; }