Merge dmd upstream 6243fa6d2
[official-gcc.git] / gcc / d / dmd / dinterpret.c
blob2bb1aace2ca155d5fbed2cdb1df1cdabf7844464
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/interpret.c
9 */
11 #include "root/dsystem.h" // mem{cpy|set}()
12 #include "root/rmem.h"
14 #include "mars.h"
15 #include "statement.h"
16 #include "expression.h"
17 #include "cond.h"
18 #include "init.h"
19 #include "staticassert.h"
20 #include "mtype.h"
21 #include "scope.h"
22 #include "declaration.h"
23 #include "aggregate.h"
24 #include "id.h"
25 #include "utf.h"
26 #include "attrib.h" // for AttribDeclaration
28 #include "template.h"
29 #include "ctfe.h"
31 /* Interpreter: what form of return value expression is required?
33 enum CtfeGoal
35 ctfeNeedRvalue, // Must return an Rvalue (== CTFE value)
36 ctfeNeedLvalue, // Must return an Lvalue (== CTFE reference)
37 ctfeNeedNothing // The return value is not required
40 bool walkPostorder(Expression *e, StoppableVisitor *v);
41 Expression *interpret(Statement *s, InterState *istate);
42 Expression *interpret(Expression *e, InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
43 Expression *semantic(Expression *e, Scope *sc);
44 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
46 static Expression *interpret(UnionExp *pue, Expression *e, InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
47 static Expression *interpret(UnionExp *pue, Statement *s, InterState *istate);
49 #define SHOWPERFORMANCE 0
51 // Maximum allowable recursive function calls in CTFE
52 #define CTFE_RECURSION_LIMIT 1000
54 /**
55 The values of all CTFE variables
57 struct CtfeStack
59 private:
60 /* The stack. Every declaration we encounter is pushed here,
61 together with the VarDeclaration, and the previous
62 stack address of that variable, so that we can restore it
63 when we leave the stack frame.
64 Note that when a function is forward referenced, the interpreter must
65 run semantic3, and that may start CTFE again with a NULL istate. Thus
66 the stack might not be empty when CTFE begins.
68 Ctfe Stack addresses are just 0-based integers, but we save
69 them as 'void *' because Array can only do pointers.
71 Expressions values; // values on the stack
72 VarDeclarations vars; // corresponding variables
73 Array<void *> savedId; // id of the previous state of that var
75 Array<void *> frames; // all previous frame pointers
76 Expressions savedThis; // all previous values of localThis
78 /* Global constants get saved here after evaluation, so we never
79 * have to redo them. This saves a lot of time and memory.
81 Expressions globalValues; // values of global constants
83 size_t framepointer; // current frame pointer
84 size_t maxStackPointer; // most stack we've ever used
85 Expression *localThis; // value of 'this', or NULL if none
86 public:
87 CtfeStack();
89 size_t stackPointer();
91 // The current value of 'this', or NULL if none
92 Expression *getThis();
94 // Largest number of stack positions we've used
95 size_t maxStackUsage();
96 // Start a new stack frame, using the provided 'this'.
97 void startFrame(Expression *thisexp);
98 void endFrame();
99 bool isInCurrentFrame(VarDeclaration *v);
100 Expression *getValue(VarDeclaration *v);
101 void setValue(VarDeclaration *v, Expression *e);
102 void push(VarDeclaration *v);
103 void pop(VarDeclaration *v);
104 void popAll(size_t stackpointer);
105 void saveGlobalConstant(VarDeclaration *v, Expression *e);
108 struct InterState
110 InterState *caller; // calling function's InterState
111 FuncDeclaration *fd; // function being interpreted
112 Statement *start; // if !=NULL, start execution at this statement
113 /* target of CTFEExp result; also
114 * target of labelled CTFEExp or
115 * CTFEExp. (NULL if no label).
117 Statement *gotoTarget;
119 InterState();
122 /************** CtfeStack ********************************************/
124 CtfeStack ctfeStack;
126 CtfeStack::CtfeStack() : framepointer(0), maxStackPointer(0)
130 size_t CtfeStack::stackPointer()
132 return values.dim;
135 Expression *CtfeStack::getThis()
137 return localThis;
140 // Largest number of stack positions we've used
141 size_t CtfeStack::maxStackUsage()
143 return maxStackPointer;
146 void CtfeStack::startFrame(Expression *thisexp)
148 frames.push((void *)(size_t)(framepointer));
149 savedThis.push(localThis);
150 framepointer = stackPointer();
151 localThis = thisexp;
154 void CtfeStack::endFrame()
156 size_t oldframe = (size_t)(frames[frames.dim-1]);
157 localThis = savedThis[savedThis.dim-1];
158 popAll(framepointer);
159 framepointer = oldframe;
160 frames.setDim(frames.dim - 1);
161 savedThis.setDim(savedThis.dim -1);
164 bool CtfeStack::isInCurrentFrame(VarDeclaration *v)
166 if (v->isDataseg() && !v->isCTFE())
167 return false; // It's a global
168 return v->ctfeAdrOnStack >= (int)framepointer;
171 Expression *CtfeStack::getValue(VarDeclaration *v)
173 if ((v->isDataseg() || v->storage_class & STCmanifest) && !v->isCTFE())
175 assert(v->ctfeAdrOnStack >= 0 &&
176 v->ctfeAdrOnStack < (int)globalValues.dim);
177 return globalValues[v->ctfeAdrOnStack];
179 assert(v->ctfeAdrOnStack >= 0 && v->ctfeAdrOnStack < (int)stackPointer());
180 return values[v->ctfeAdrOnStack];
183 void CtfeStack::setValue(VarDeclaration *v, Expression *e)
185 assert(!v->isDataseg() || v->isCTFE());
186 assert(v->ctfeAdrOnStack >= 0 && v->ctfeAdrOnStack < (int)stackPointer());
187 values[v->ctfeAdrOnStack] = e;
190 void CtfeStack::push(VarDeclaration *v)
192 assert(!v->isDataseg() || v->isCTFE());
193 if (v->ctfeAdrOnStack != -1 &&
194 v->ctfeAdrOnStack >= (int)framepointer)
196 // Already exists in this frame, reuse it.
197 values[v->ctfeAdrOnStack] = NULL;
198 return;
200 savedId.push((void *)(size_t)(v->ctfeAdrOnStack));
201 v->ctfeAdrOnStack = (int)values.dim;
202 vars.push(v);
203 values.push(NULL);
206 void CtfeStack::pop(VarDeclaration *v)
208 assert(!v->isDataseg() || v->isCTFE());
209 assert(!(v->storage_class & (STCref | STCout)));
210 int oldid = v->ctfeAdrOnStack;
211 v->ctfeAdrOnStack = (int)(size_t)(savedId[oldid]);
212 if (v->ctfeAdrOnStack == (int)values.dim - 1)
214 values.pop();
215 vars.pop();
216 savedId.pop();
220 void CtfeStack::popAll(size_t stackpointer)
222 if (stackPointer() > maxStackPointer)
223 maxStackPointer = stackPointer();
224 assert(values.dim >= stackpointer);
225 for (size_t i = stackpointer; i < values.dim; ++i)
227 VarDeclaration *v = vars[i];
228 v->ctfeAdrOnStack = (int)(size_t)(savedId[i]);
230 values.setDim(stackpointer);
231 vars.setDim(stackpointer);
232 savedId.setDim(stackpointer);
235 void CtfeStack::saveGlobalConstant(VarDeclaration *v, Expression *e)
237 assert(v->_init && (v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) && !v->isCTFE());
238 v->ctfeAdrOnStack = (int)globalValues.dim;
239 globalValues.push(e);
242 /************** InterState ********************************************/
244 InterState::InterState()
246 memset(this, 0, sizeof(InterState));
249 /************** CtfeStatus ********************************************/
251 int CtfeStatus::callDepth = 0;
252 int CtfeStatus::stackTraceCallsToSuppress = 0;
253 int CtfeStatus::maxCallDepth = 0;
254 int CtfeStatus::numArrayAllocs = 0;
255 int CtfeStatus::numAssignments = 0;
257 // CTFE diagnostic information
258 void printCtfePerformanceStats()
260 #if SHOWPERFORMANCE
261 printf(" ---- CTFE Performance ----\n");
262 printf("max call depth = %d\tmax stack = %d\n", CtfeStatus::maxCallDepth, ctfeStack.maxStackUsage());
263 printf("array allocs = %d\tassignments = %d\n\n", CtfeStatus::numArrayAllocs, CtfeStatus::numAssignments);
264 #endif
267 VarDeclaration *findParentVar(Expression *e);
268 Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
269 FuncDeclaration *fd, Expressions *arguments, Expression *pthis);
270 Expression *evaluatePostblit(InterState *istate, Expression *e);
271 Expression *evaluateDtor(InterState *istate, Expression *e);
272 Expression *scrubReturnValue(Loc loc, Expression *e);
274 Expression *scrubCacheValue(Loc loc, Expression *e);
277 /*************************************
278 * CTFE-object code for a single function
280 * Currently only counts the number of local variables in the function
282 struct CompiledCtfeFunction
284 FuncDeclaration *func; // Function being compiled, NULL if global scope
285 int numVars; // Number of variables declared in this function
286 Loc callingloc;
288 CompiledCtfeFunction(FuncDeclaration *f)
290 func = f;
291 numVars = 0;
294 void onDeclaration(VarDeclaration *)
296 //printf("%s CTFE declare %s\n", v->loc.toChars(), v->toChars());
297 ++numVars;
300 void onExpression(Expression *e)
302 class VarWalker : public StoppableVisitor
304 public:
305 CompiledCtfeFunction *ccf;
307 VarWalker(CompiledCtfeFunction *ccf)
308 : ccf(ccf)
312 void visit(Expression *)
316 void visit(ErrorExp *e)
318 // Currently there's a front-end bug: silent errors
319 // can occur inside delegate literals inside is(typeof()).
320 // Suppress the check in this case.
321 if (global.gag && ccf->func)
323 stop = 1;
324 return;
327 ::error(e->loc, "CTFE internal error: ErrorExp in %s\n", ccf->func ? ccf->func->loc.toChars() : ccf->callingloc.toChars());
328 assert(0);
331 void visit(DeclarationExp *e)
333 VarDeclaration *v = e->declaration->isVarDeclaration();
334 if (!v)
335 return;
336 TupleDeclaration *td = v->toAlias()->isTupleDeclaration();
337 if (td)
339 if (!td->objects)
340 return;
341 for (size_t i= 0; i < td->objects->dim; ++i)
343 RootObject *o = td->objects->tdata()[i];
344 Expression *ex = isExpression(o);
345 DsymbolExp *s = (ex && ex->op == TOKdsymbol) ? (DsymbolExp *)ex : NULL;
346 assert(s);
347 VarDeclaration *v2 = s->s->isVarDeclaration();
348 assert(v2);
349 if (!v2->isDataseg() || v2->isCTFE())
350 ccf->onDeclaration(v2);
353 else if (!(v->isDataseg() || v->storage_class & STCmanifest) || v->isCTFE())
354 ccf->onDeclaration(v);
355 Dsymbol *s = v->toAlias();
356 if (s == v && !v->isStatic() && v->_init)
358 ExpInitializer *ie = v->_init->isExpInitializer();
359 if (ie)
360 ccf->onExpression(ie->exp);
364 void visit(IndexExp *e)
366 if (e->lengthVar)
367 ccf->onDeclaration(e->lengthVar);
370 void visit(SliceExp *e)
372 if (e->lengthVar)
373 ccf->onDeclaration(e->lengthVar);
377 VarWalker v(this);
378 walkPostorder(e, &v);
382 class CtfeCompiler : public Visitor
384 public:
385 CompiledCtfeFunction *ccf;
387 CtfeCompiler(CompiledCtfeFunction *ccf)
388 : ccf(ccf)
392 void visit(Statement *)
394 assert(0);
397 void visit(ExpStatement *s)
399 if (s->exp)
400 ccf->onExpression(s->exp);
403 void visit(CompoundStatement *s)
405 for (size_t i = 0; i < s->statements->dim; i++)
407 Statement *sx = (*s->statements)[i];
408 if (sx)
409 ctfeCompile(sx);
413 void visit(UnrolledLoopStatement *s)
415 for (size_t i = 0; i < s->statements->dim; i++)
417 Statement *sx = (*s->statements)[i];
418 if (sx)
419 ctfeCompile(sx);
423 void visit(IfStatement *s)
425 ccf->onExpression(s->condition);
426 if (s->ifbody)
427 ctfeCompile(s->ifbody);
428 if (s->elsebody)
429 ctfeCompile(s->elsebody);
432 void visit(ScopeStatement *s)
434 if (s->statement)
435 ctfeCompile(s->statement);
438 void visit(OnScopeStatement *)
440 // rewritten to try/catch/finally
441 assert(0);
444 void visit(DoStatement *s)
446 ccf->onExpression(s->condition);
447 if (s->_body)
448 ctfeCompile(s->_body);
451 void visit(WhileStatement *)
453 // rewritten to ForStatement
454 assert(0);
457 void visit(ForStatement *s)
459 if (s->_init)
460 ctfeCompile(s->_init);
461 if (s->condition)
462 ccf->onExpression(s->condition);
463 if (s->increment)
464 ccf->onExpression(s->increment);
465 if (s->_body)
466 ctfeCompile(s->_body);
469 void visit(ForeachStatement *)
471 // rewritten for ForStatement
472 assert(0);
475 void visit(SwitchStatement *s)
477 ccf->onExpression(s->condition);
478 // Note that the body contains the the Case and Default
479 // statements, so we only need to compile the expressions
480 for (size_t i = 0; i < s->cases->dim; i++)
482 ccf->onExpression((*s->cases)[i]->exp);
484 if (s->_body)
485 ctfeCompile(s->_body);
488 void visit(CaseStatement *s)
490 if (s->statement)
491 ctfeCompile(s->statement);
494 void visit(DefaultStatement *s)
496 if (s->statement)
497 ctfeCompile(s->statement);
500 void visit(GotoDefaultStatement *)
504 void visit(GotoCaseStatement *)
508 void visit(SwitchErrorStatement *)
512 void visit(ReturnStatement *s)
514 if (s->exp)
515 ccf->onExpression(s->exp);
518 void visit(BreakStatement *)
522 void visit(ContinueStatement *)
526 void visit(WithStatement *s)
528 // If it is with(Enum) {...}, just execute the body.
529 if (s->exp->op == TOKscope || s->exp->op == TOKtype)
532 else
534 ccf->onDeclaration(s->wthis);
535 ccf->onExpression(s->exp);
537 if (s->_body)
538 ctfeCompile(s->_body);
541 void visit(TryCatchStatement *s)
543 if (s->_body)
544 ctfeCompile(s->_body);
545 for (size_t i = 0; i < s->catches->dim; i++)
547 Catch *ca = (*s->catches)[i];
548 if (ca->var)
549 ccf->onDeclaration(ca->var);
550 if (ca->handler)
551 ctfeCompile(ca->handler);
555 void visit(TryFinallyStatement *s)
557 if (s->_body)
558 ctfeCompile(s->_body);
559 if (s->finalbody)
560 ctfeCompile(s->finalbody);
563 void visit(ThrowStatement *s)
565 ccf->onExpression(s->exp);
568 void visit(GotoStatement *)
572 void visit(LabelStatement *s)
574 if (s->statement)
575 ctfeCompile(s->statement);
578 void visit(ImportStatement *)
580 // Contains no variables or executable code
583 void visit(ForeachRangeStatement *)
585 // rewritten for ForStatement
586 assert(0);
589 void visit(AsmStatement *)
591 // we can't compile asm statements
594 void ctfeCompile(Statement *s)
596 s->accept(this);
600 /*************************************
601 * Compile this function for CTFE.
602 * At present, this merely allocates variables.
604 void ctfeCompile(FuncDeclaration *fd)
606 assert(!fd->ctfeCode);
607 assert(!fd->semantic3Errors);
608 assert(fd->semanticRun == PASSsemantic3done);
610 fd->ctfeCode = new CompiledCtfeFunction(fd);
611 if (fd->parameters)
613 Type *tb = fd->type->toBasetype();
614 assert(tb->ty == Tfunction);
615 for (size_t i = 0; i < fd->parameters->dim; i++)
617 VarDeclaration *v = (*fd->parameters)[i];
618 fd->ctfeCode->onDeclaration(v);
621 if (fd->vresult)
622 fd->ctfeCode->onDeclaration(fd->vresult);
623 CtfeCompiler v(fd->ctfeCode);
624 v.ctfeCompile(fd->fbody);
627 /*************************************
628 * Entry point for CTFE.
629 * A compile-time result is required. Give an error if not possible.
631 * `e` must be semantically valid expression. In other words, it should not
632 * contain any `ErrorExp`s in it. But, CTFE interpretation will cross over
633 * functions and may invoke a function that contains `ErrorStatement` in its body.
634 * If that, the "CTFE failed because of previous errors" error is raised.
636 Expression *ctfeInterpret(Expression *e)
638 if (e->op == TOKerror)
639 return e;
640 assert(e->type); // Bugzilla 14642
641 //assert(e->type->ty != Terror); // FIXME
642 if (e->type->ty == Terror)
643 return new ErrorExp();
645 // This code is outside a function, but still needs to be compiled
646 // (there are compiler-generated temporary variables such as __dollar).
647 // However, this will only be run once and can then be discarded.
648 CompiledCtfeFunction ctfeCodeGlobal(NULL);
649 ctfeCodeGlobal.callingloc = e->loc;
650 ctfeCodeGlobal.onExpression(e);
652 Expression *result = interpret(e, NULL);
653 if (!CTFEExp::isCantExp(result))
654 result = scrubReturnValue(e->loc, result);
655 if (CTFEExp::isCantExp(result))
656 result = new ErrorExp();
657 return result;
660 /* Run CTFE on the expression, but allow the expression to be a TypeExp
661 * or a tuple containing a TypeExp. (This is required by pragma(msg)).
663 Expression *ctfeInterpretForPragmaMsg(Expression *e)
665 if (e->op == TOKerror || e->op == TOKtype)
666 return e;
668 // It's also OK for it to be a function declaration (happens only with
669 // __traits(getOverloads))
670 if (e->op == TOKvar && ((VarExp *)e)->var->isFuncDeclaration())
672 return e;
675 if (e->op != TOKtuple)
676 return e->ctfeInterpret();
678 // Tuples need to be treated seperately, since they are
679 // allowed to contain a TypeExp in this case.
681 TupleExp *tup = (TupleExp *)e;
682 Expressions *expsx = NULL;
683 for (size_t i = 0; i < tup->exps->dim; ++i)
685 Expression *g = (*tup->exps)[i];
686 Expression *h = g;
687 h = ctfeInterpretForPragmaMsg(g);
688 if (h != g)
690 if (!expsx)
692 expsx = new Expressions();
693 expsx->setDim(tup->exps->dim);
694 for (size_t j = 0; j < tup->exps->dim; j++)
695 (*expsx)[j] = (*tup->exps)[j];
697 (*expsx)[i] = h;
700 if (expsx)
702 TupleExp *te = new TupleExp(e->loc, expsx);
703 expandTuples(te->exps);
704 te->type = new TypeTuple(te->exps);
705 return te;
707 return e;
710 /*************************************
711 * Attempt to interpret a function given the arguments.
712 * Input:
713 * istate state for calling function (NULL if none)
714 * arguments function arguments
715 * thisarg 'this', if a needThis() function, NULL if not.
717 * Return result expression if successful, TOKcantexp if not,
718 * or CTFEExp if function returned void.
721 static Expression *interpretFunction(FuncDeclaration *fd, InterState *istate, Expressions *arguments, Expression *thisarg)
723 if (fd->semanticRun == PASSsemantic3)
725 fd->error("circular dependency. Functions cannot be interpreted while being compiled");
726 return CTFEExp::cantexp;
728 if (!fd->functionSemantic3())
729 return CTFEExp::cantexp;
730 if (fd->semanticRun < PASSsemantic3done)
731 return CTFEExp::cantexp;
733 // CTFE-compile the function
734 if (!fd->ctfeCode)
735 ctfeCompile(fd);
737 Type *tb = fd->type->toBasetype();
738 assert(tb->ty == Tfunction);
739 TypeFunction *tf = (TypeFunction *)tb;
740 if (tf->varargs && arguments &&
741 ((fd->parameters && arguments->dim != fd->parameters->dim) || (!fd->parameters && arguments->dim)))
743 fd->error("C-style variadic functions are not yet implemented in CTFE");
744 return CTFEExp::cantexp;
747 // Nested functions always inherit the 'this' pointer from the parent,
748 // except for delegates. (Note that the 'this' pointer may be null).
749 // Func literals report isNested() even if they are in global scope,
750 // so we need to check that the parent is a function.
751 if (fd->isNested() && fd->toParent2()->isFuncDeclaration() && !thisarg && istate)
752 thisarg = ctfeStack.getThis();
754 if (fd->needThis() && !thisarg)
756 // error, no this. Prevent segfault.
757 // Here should be unreachable by the strict 'this' check in front-end.
758 fd->error("need 'this' to access member %s", fd->toChars());
759 return CTFEExp::cantexp;
762 // Place to hold all the arguments to the function while
763 // we are evaluating them.
764 Expressions eargs;
765 size_t dim = arguments ? arguments->dim : 0;
766 assert((fd->parameters ? fd->parameters->dim : 0) == dim);
768 /* Evaluate all the arguments to the function,
769 * store the results in eargs[]
771 eargs.setDim(dim);
772 for (size_t i = 0; i < dim; i++)
774 Expression *earg = (*arguments)[i];
775 Parameter *fparam = Parameter::getNth(tf->parameters, i);
777 if (fparam->storageClass & (STCout | STCref))
779 if (!istate && (fparam->storageClass & STCout))
781 // initializing an out parameter involves writing to it.
782 earg->error("global %s cannot be passed as an 'out' parameter at compile time", earg->toChars());
783 return CTFEExp::cantexp;
785 // Convert all reference arguments into lvalue references
786 earg = interpret(earg, istate, ctfeNeedLvalue);
787 if (CTFEExp::isCantExp(earg))
788 return earg;
790 else if (fparam->storageClass & STClazy)
793 else
795 /* Value parameters
797 Type *ta = fparam->type->toBasetype();
798 if (ta->ty == Tsarray && earg->op == TOKaddress)
800 /* Static arrays are passed by a simple pointer.
801 * Skip past this to get at the actual arg.
803 earg = ((AddrExp *)earg)->e1;
805 earg = interpret(earg, istate);
806 if (CTFEExp::isCantExp(earg))
807 return earg;
808 /* Struct literals are passed by value, but we don't need to
809 * copy them if they are passed as const
811 if (earg->op == TOKstructliteral && !(fparam->storageClass & (STCconst | STCimmutable)))
812 earg = copyLiteral(earg).copy();
814 if (earg->op == TOKthrownexception)
816 if (istate)
817 return earg;
818 ((ThrownExceptionExp *)earg)->generateUncaughtError();
819 return CTFEExp::cantexp;
821 eargs[i] = earg;
824 // Now that we've evaluated all the arguments, we can start the frame
825 // (this is the moment when the 'call' actually takes place).
826 InterState istatex;
827 istatex.caller = istate;
828 istatex.fd = fd;
829 ctfeStack.startFrame(thisarg);
830 if (fd->vthis && thisarg)
832 ctfeStack.push(fd->vthis);
833 setValue(fd->vthis, thisarg);
836 for (size_t i = 0; i < dim; i++)
838 Expression *earg = eargs[i];
839 Parameter *fparam = Parameter::getNth(tf->parameters, i);
840 VarDeclaration *v = (*fd->parameters)[i];
841 ctfeStack.push(v);
843 if ((fparam->storageClass & (STCout | STCref)) &&
844 earg->op == TOKvar && ((VarExp *)earg)->var->toParent2() == fd)
846 VarDeclaration *vx = ((VarExp *)earg)->var->isVarDeclaration();
847 if (!vx)
849 fd->error("cannot interpret %s as a ref parameter", earg->toChars());
850 return CTFEExp::cantexp;
853 /* vx is a variable that is declared in fd.
854 * It means that fd is recursively called. e.g.
856 * void fd(int n, ref int v = dummy) {
857 * int vx;
858 * if (n == 1) fd(2, vx);
860 * fd(1);
862 * The old value of vx on the stack in fd(1)
863 * should be saved at the start of fd(2, vx) call.
865 int oldadr = vx->ctfeAdrOnStack;
867 ctfeStack.push(vx);
868 assert(!hasValue(vx)); // vx is made uninitialized
870 // Bugzilla 14299: v->ctfeAdrOnStack should be saved already
871 // in the stack before the overwrite.
872 v->ctfeAdrOnStack = oldadr;
873 assert(hasValue(v)); // ref parameter v should refer existing value.
875 else
877 // Value parameters and non-trivial references
878 setValueWithoutChecking(v, earg);
882 if (fd->vresult)
883 ctfeStack.push(fd->vresult);
885 // Enter the function
886 ++CtfeStatus::callDepth;
887 if (CtfeStatus::callDepth > CtfeStatus::maxCallDepth)
888 CtfeStatus::maxCallDepth = CtfeStatus::callDepth;
890 Expression *e = NULL;
891 while (1)
893 if (CtfeStatus::callDepth > CTFE_RECURSION_LIMIT)
895 // This is a compiler error. It must not be suppressed.
896 global.gag = 0;
897 fd->error("CTFE recursion limit exceeded");
898 e = CTFEExp::cantexp;
899 break;
901 e = interpret(fd->fbody, &istatex);
903 if (istatex.start)
905 fd->error("CTFE internal error: failed to resume at statement %s", istatex.start->toChars());
906 return CTFEExp::cantexp;
909 /* This is how we deal with a recursive statement AST
910 * that has arbitrary goto statements in it.
911 * Bubble up a 'result' which is the target of the goto
912 * statement, then go recursively down the AST looking
913 * for that statement, then execute starting there.
915 if (CTFEExp::isGotoExp(e))
917 istatex.start = istatex.gotoTarget; // set starting statement
918 istatex.gotoTarget = NULL;
920 else
922 assert(!e || (e->op != TOKcontinue && e->op != TOKbreak));
923 break;
926 // If fell off the end of a void function, return void
927 if (!e && tf->next->ty == Tvoid)
928 e = CTFEExp::voidexp;
929 if (tf->isref && e->op == TOKvar && ((VarExp *)e)->var == fd->vthis)
930 e = thisarg;
931 assert(e != NULL);
933 // Leave the function
934 --CtfeStatus::callDepth;
936 ctfeStack.endFrame();
938 // If it generated an uncaught exception, report error.
939 if (!istate && e->op == TOKthrownexception)
941 ((ThrownExceptionExp *)e)->generateUncaughtError();
942 e = CTFEExp::cantexp;
945 return e;
948 class Interpreter : public Visitor
950 public:
951 InterState *istate;
952 CtfeGoal goal;
954 Expression *result;
955 UnionExp *pue; // storage for `result`
957 Interpreter(UnionExp *pue, InterState *istate, CtfeGoal goal)
958 : istate(istate), goal(goal), pue(pue)
960 result = NULL;
963 // If e is TOKthrowexception or TOKcantexp,
964 // set it to 'result' and returns true.
965 bool exceptionOrCant(Expression *e)
967 if (exceptionOrCantInterpret(e))
969 // Make sure e is not pointing to a stack temporary
970 result = (e->op == TOKcantexp) ? CTFEExp::cantexp : e;
971 return true;
973 return false;
976 static Expressions *copyArrayOnWrite(Expressions *exps, Expressions *original)
978 if (exps == original)
980 if (!original)
981 exps = new Expressions();
982 else
983 exps = original->copy();
984 ++CtfeStatus::numArrayAllocs;
986 return exps;
989 /******************************** Statement ***************************/
991 void visit(Statement *s)
993 if (istate->start)
995 if (istate->start != s)
996 return;
997 istate->start = NULL;
1000 s->error("statement %s cannot be interpreted at compile time", s->toChars());
1001 result = CTFEExp::cantexp;
1004 void visit(ExpStatement *s)
1006 if (istate->start)
1008 if (istate->start != s)
1009 return;
1010 istate->start = NULL;
1013 Expression *e = interpret(pue, s->exp, istate, ctfeNeedNothing);
1014 if (exceptionOrCant(e))
1015 return;
1018 void visit(CompoundStatement *s)
1020 if (istate->start == s)
1021 istate->start = NULL;
1023 const size_t dim = s->statements ? s->statements->dim : 0;
1024 for (size_t i = 0; i < dim; i++)
1026 Statement *sx = (*s->statements)[i];
1027 result = interpret(pue, sx, istate);
1028 if (result)
1029 break;
1033 void visit(UnrolledLoopStatement *s)
1035 if (istate->start == s)
1036 istate->start = NULL;
1038 const size_t dim = s->statements ? s->statements->dim : 0;
1039 for (size_t i = 0; i < dim; i++)
1041 Statement *sx = (*s->statements)[i];
1042 Expression *e = interpret(pue, sx, istate);
1043 if (!e) // suceeds to interpret, or goto target
1044 continue; // was not fonnd when istate->start != NULL
1045 if (exceptionOrCant(e))
1046 return;
1047 if (e->op == TOKbreak)
1049 if (istate->gotoTarget && istate->gotoTarget != s)
1051 result = e; // break at a higher level
1052 return;
1054 istate->gotoTarget = NULL;
1055 result = NULL;
1056 return;
1058 if (e->op == TOKcontinue)
1060 if (istate->gotoTarget && istate->gotoTarget != s)
1062 result = e; // continue at a higher level
1063 return;
1065 istate->gotoTarget = NULL;
1066 continue;
1069 // expression from return statement, or thrown exception
1070 result = e;
1071 break;
1075 void visit(IfStatement *s)
1077 if (istate->start == s)
1078 istate->start = NULL;
1079 if (istate->start)
1081 Expression *e = NULL;
1082 e = interpret(s->ifbody, istate);
1083 if (!e && istate->start)
1084 e = interpret(s->elsebody, istate);
1085 result = e;
1086 return;
1089 UnionExp ue;
1090 Expression *e = interpret(&ue, s->condition, istate);
1091 assert(e);
1092 if (exceptionOrCant(e))
1093 return;
1095 if (isTrueBool(e))
1096 result = interpret(pue, s->ifbody, istate);
1097 else if (e->isBool(false))
1098 result = interpret(pue, s->elsebody, istate);
1099 else
1101 // no error, or assert(0)?
1102 result = CTFEExp::cantexp;
1106 void visit(ScopeStatement *s)
1108 if (istate->start == s)
1109 istate->start = NULL;
1111 result = interpret(pue, s->statement, istate);
1115 Given an expression e which is about to be returned from the current
1116 function, generate an error if it contains pointers to local variables.
1118 Only checks expressions passed by value (pointers to local variables
1119 may already be stored in members of classes, arrays, or AAs which
1120 were passed as mutable function parameters).
1121 Returns:
1122 true if it is safe to return, false if an error was generated.
1125 static bool stopPointersEscaping(Loc loc, Expression *e)
1127 if (!e->type->hasPointers())
1128 return true;
1129 if (isPointer(e->type))
1131 Expression *x = e;
1132 if (e->op == TOKaddress)
1133 x = ((AddrExp *)e)->e1;
1134 VarDeclaration *v;
1135 while (x->op == TOKvar &&
1136 (v = ((VarExp *)x)->var->isVarDeclaration()) != NULL)
1138 if (v->storage_class & STCref)
1140 x = getValue(v);
1141 if (e->op == TOKaddress)
1142 ((AddrExp *)e)->e1 = x;
1143 continue;
1145 if (ctfeStack.isInCurrentFrame(v))
1147 error(loc, "returning a pointer to a local stack variable");
1148 return false;
1150 else
1151 break;
1153 // TODO: If it is a TOKdotvar or TOKindex, we should check that it is not
1154 // pointing to a local struct or static array.
1156 if (e->op == TOKstructliteral)
1158 StructLiteralExp *se = (StructLiteralExp *)e;
1159 return stopPointersEscapingFromArray(loc, se->elements);
1161 if (e->op == TOKarrayliteral)
1163 return stopPointersEscapingFromArray(loc, ((ArrayLiteralExp *)e)->elements);
1165 if (e->op == TOKassocarrayliteral)
1167 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
1168 if (!stopPointersEscapingFromArray(loc, aae->keys))
1169 return false;
1170 return stopPointersEscapingFromArray(loc, aae->values);
1172 return true;
1175 // Check all members of an array for escaping local variables. Return false if error
1176 static bool stopPointersEscapingFromArray(Loc loc, Expressions *elems)
1178 for (size_t i = 0; i < elems->dim; i++)
1180 Expression *m = (*elems)[i];
1181 if (!m)
1182 continue;
1183 if (!stopPointersEscaping(loc, m))
1184 return false;
1186 return true;
1189 void visit(ReturnStatement *s)
1191 if (istate->start)
1193 if (istate->start != s)
1194 return;
1195 istate->start = NULL;
1198 if (!s->exp)
1200 result = CTFEExp::voidexp;
1201 return;
1204 assert(istate && istate->fd && istate->fd->type && istate->fd->type->ty == Tfunction);
1205 TypeFunction *tf = (TypeFunction *)istate->fd->type;
1207 /* If the function returns a ref AND it's been called from an assignment,
1208 * we need to return an lvalue. Otherwise, just do an (rvalue) interpret.
1210 if (tf->isref)
1212 result = interpret(pue, s->exp, istate, ctfeNeedLvalue);
1213 return;
1215 if (tf->next && tf->next->ty == Tdelegate && istate->fd->closureVars.dim > 0)
1217 // To support this, we need to copy all the closure vars
1218 // into the delegate literal.
1219 s->error("closures are not yet supported in CTFE");
1220 result = CTFEExp::cantexp;
1221 return;
1224 // We need to treat pointers specially, because TOKsymoff can be used to
1225 // return a value OR a pointer
1226 Expression *e = interpret(pue, s->exp, istate);
1227 if (exceptionOrCant(e))
1228 return;
1230 // Disallow returning pointers to stack-allocated variables (bug 7876)
1231 if (!stopPointersEscaping(s->loc, e))
1233 result = CTFEExp::cantexp;
1234 return;
1237 if (needToCopyLiteral(e))
1238 e = copyLiteral(e).copy();
1239 result = e;
1242 static Statement *findGotoTarget(InterState *istate, Identifier *ident)
1244 Statement *target = NULL;
1245 if (ident)
1247 LabelDsymbol *label = istate->fd->searchLabel(ident);
1248 assert(label && label->statement);
1249 LabelStatement *ls = label->statement;
1250 target = ls->gotoTarget ? ls->gotoTarget : ls->statement;
1252 return target;
1255 void visit(BreakStatement *s)
1257 if (istate->start)
1259 if (istate->start != s)
1260 return;
1261 istate->start = NULL;
1264 istate->gotoTarget = findGotoTarget(istate, s->ident);
1265 result = CTFEExp::breakexp;
1268 void visit(ContinueStatement *s)
1270 if (istate->start)
1272 if (istate->start != s)
1273 return;
1274 istate->start = NULL;
1277 istate->gotoTarget = findGotoTarget(istate, s->ident);
1278 result = CTFEExp::continueexp;
1281 void visit(WhileStatement *)
1283 assert(0); // rewritten to ForStatement
1286 void visit(DoStatement *s)
1288 if (istate->start == s)
1289 istate->start = NULL;
1291 while (1)
1293 Expression *e = interpret(s->_body, istate);
1294 if (!e && istate->start) // goto target was not found
1295 return;
1296 assert(!istate->start);
1298 if (exceptionOrCant(e))
1299 return;
1300 if (e && e->op == TOKbreak)
1302 if (istate->gotoTarget && istate->gotoTarget != s)
1304 result = e; // break at a higher level
1305 return;
1307 istate->gotoTarget = NULL;
1308 break;
1310 if (e && e->op == TOKcontinue)
1312 if (istate->gotoTarget && istate->gotoTarget != s)
1314 result = e; // continue at a higher level
1315 return;
1317 istate->gotoTarget = NULL;
1318 e = NULL;
1320 if (e)
1322 result = e; // bubbled up from ReturnStatement
1323 return;
1326 UnionExp ue;
1327 e = interpret(&ue, s->condition, istate);
1328 if (exceptionOrCant(e))
1329 return;
1330 if (!e->isConst())
1332 result = CTFEExp::cantexp;
1333 return;
1335 if (e->isBool(false))
1336 break;
1337 assert(isTrueBool(e));
1339 assert(result == NULL);
1342 void visit(ForStatement *s)
1344 if (istate->start == s)
1345 istate->start = NULL;
1347 UnionExp ueinit;
1348 Expression *ei = interpret(&ueinit, s->_init, istate);
1349 if (exceptionOrCant(ei))
1350 return;
1351 assert(!ei); // s->init never returns from function, or jumps out from it
1353 while (1)
1355 if (s->condition && !istate->start)
1357 UnionExp ue;
1358 Expression *e = interpret(&ue, s->condition, istate);
1359 if (exceptionOrCant(e))
1360 return;
1361 if (e->isBool(false))
1362 break;
1363 assert(isTrueBool(e));
1366 Expression *e = interpret(pue, s->_body, istate);
1367 if (!e && istate->start) // goto target was not found
1368 return;
1369 assert(!istate->start);
1371 if (exceptionOrCant(e))
1372 return;
1373 if (e && e->op == TOKbreak)
1375 if (istate->gotoTarget && istate->gotoTarget != s)
1377 result = e; // break at a higher level
1378 return;
1380 istate->gotoTarget = NULL;
1381 break;
1383 if (e && e->op == TOKcontinue)
1385 if (istate->gotoTarget && istate->gotoTarget != s)
1387 result = e; // continue at a higher level
1388 return;
1390 istate->gotoTarget = NULL;
1391 e = NULL;
1393 if (e)
1395 result = e; // bubbled up from ReturnStatement
1396 return;
1399 UnionExp uei;
1400 e = interpret(&uei, s->increment, istate, ctfeNeedNothing);
1401 if (exceptionOrCant(e))
1402 return;
1404 assert(result == NULL);
1407 void visit(ForeachStatement *)
1409 assert(0); // rewritten to ForStatement
1412 void visit(ForeachRangeStatement *)
1414 assert(0); // rewritten to ForStatement
1417 void visit(SwitchStatement *s)
1419 if (istate->start == s)
1420 istate->start = NULL;
1421 if (istate->start)
1423 Expression *e = interpret(s->_body, istate);
1424 if (istate->start) // goto target was not found
1425 return;
1426 if (exceptionOrCant(e))
1427 return;
1428 if (e && e->op == TOKbreak)
1430 if (istate->gotoTarget && istate->gotoTarget != s)
1432 result = e; // break at a higher level
1433 return;
1435 istate->gotoTarget = NULL;
1436 e = NULL;
1438 result = e;
1439 return;
1442 UnionExp uecond;
1443 Expression *econdition = interpret(&uecond, s->condition, istate);
1444 if (exceptionOrCant(econdition))
1445 return;
1447 Statement *scase = NULL;
1448 size_t dim = s->cases ? s->cases->dim : 0;
1449 for (size_t i = 0; i < dim; i++)
1451 CaseStatement *cs = (*s->cases)[i];
1452 UnionExp uecase;
1453 Expression *ecase = interpret(&uecase, cs->exp, istate);
1454 if (exceptionOrCant(ecase))
1455 return;
1456 if (ctfeEqual(cs->exp->loc, TOKequal, econdition, ecase))
1458 scase = cs;
1459 break;
1462 if (!scase)
1464 if (s->hasNoDefault)
1465 s->error("no default or case for %s in switch statement", econdition->toChars());
1466 scase = s->sdefault;
1469 assert(scase);
1471 /* Jump to scase
1473 istate->start = scase;
1474 Expression *e = interpret(pue, s->_body, istate);
1475 assert(!istate->start); // jump must not fail
1476 if (e && e->op == TOKbreak)
1478 if (istate->gotoTarget && istate->gotoTarget != s)
1480 result = e; // break at a higher level
1481 return;
1483 istate->gotoTarget = NULL;
1484 e = NULL;
1486 result = e;
1489 void visit(CaseStatement *s)
1491 if (istate->start == s)
1492 istate->start = NULL;
1494 result = interpret(pue, s->statement, istate);
1497 void visit(DefaultStatement *s)
1499 if (istate->start == s)
1500 istate->start = NULL;
1502 result = interpret(pue, s->statement, istate);
1505 void visit(GotoStatement *s)
1507 if (istate->start)
1509 if (istate->start != s)
1510 return;
1511 istate->start = NULL;
1514 assert(s->label && s->label->statement);
1515 istate->gotoTarget = s->label->statement;
1516 result = CTFEExp::gotoexp;
1519 void visit(GotoCaseStatement *s)
1521 if (istate->start)
1523 if (istate->start != s)
1524 return;
1525 istate->start = NULL;
1528 assert(s->cs);
1529 istate->gotoTarget = s->cs;
1530 result = CTFEExp::gotoexp;
1533 void visit(GotoDefaultStatement *s)
1535 if (istate->start)
1537 if (istate->start != s)
1538 return;
1539 istate->start = NULL;
1542 assert(s->sw && s->sw->sdefault);
1543 istate->gotoTarget = s->sw->sdefault;
1544 result = CTFEExp::gotoexp;
1547 void visit(LabelStatement *s)
1549 if (istate->start == s)
1550 istate->start = NULL;
1552 result = interpret(pue, s->statement, istate);
1555 void visit(TryCatchStatement *s)
1557 if (istate->start == s)
1558 istate->start = NULL;
1559 if (istate->start)
1561 Expression *e = NULL;
1562 e = interpret(pue, s->_body, istate);
1563 for (size_t i = 0; i < s->catches->dim; i++)
1565 if (e || !istate->start) // goto target was found
1566 break;
1567 Catch *ca = (*s->catches)[i];
1568 e = interpret(ca->handler, istate);
1570 result = e;
1571 return;
1574 Expression *e = interpret(pue, s->_body, istate);
1576 // An exception was thrown
1577 if (e && e->op == TOKthrownexception)
1579 ThrownExceptionExp *ex = (ThrownExceptionExp *)e;
1580 Type *extype = ex->thrown->originalClass()->type;
1582 // Search for an appropriate catch clause.
1583 for (size_t i = 0; i < s->catches->dim; i++)
1585 Catch *ca = (*s->catches)[i];
1586 Type *catype = ca->type;
1587 if (!catype->equals(extype) && !catype->isBaseOf(extype, NULL))
1588 continue;
1590 // Execute the handler
1591 if (ca->var)
1593 ctfeStack.push(ca->var);
1594 setValue(ca->var, ex->thrown);
1596 e = interpret(ca->handler, istate);
1597 if (CTFEExp::isGotoExp(e))
1599 /* This is an optimization that relies on the locality of the jump target.
1600 * If the label is in the same catch handler, the following scan
1601 * would find it quickly and can reduce jump cost.
1602 * Otherwise, the catch block may be unnnecessary scanned again
1603 * so it would make CTFE speed slower.
1605 InterState istatex = *istate;
1606 istatex.start = istate->gotoTarget; // set starting statement
1607 istatex.gotoTarget = NULL;
1608 Expression *eh = interpret(ca->handler, &istatex);
1609 if (!istatex.start)
1611 istate->gotoTarget = NULL;
1612 e = eh;
1615 break;
1618 result = e;
1621 static bool isAnErrorException(ClassDeclaration *cd)
1623 return cd == ClassDeclaration::errorException || ClassDeclaration::errorException->isBaseOf(cd, NULL);
1626 static ThrownExceptionExp *chainExceptions(ThrownExceptionExp *oldest, ThrownExceptionExp *newest)
1628 // Little sanity check to make sure it's really a Throwable
1629 ClassReferenceExp *boss = oldest->thrown;
1630 assert((*boss->value->elements)[4]->type->ty == Tclass); // Throwable.next
1631 ClassReferenceExp *collateral = newest->thrown;
1632 if ( isAnErrorException(collateral->originalClass()) &&
1633 !isAnErrorException(boss->originalClass()))
1635 // The new exception bypass the existing chain
1636 assert((*collateral->value->elements)[5]->type->ty == Tclass);
1637 (*collateral->value->elements)[5] = boss;
1638 return newest;
1640 while ((*boss->value->elements)[4]->op == TOKclassreference)
1642 boss = (ClassReferenceExp *)(*boss->value->elements)[4];
1644 (*boss->value->elements)[4] = collateral;
1645 return oldest;
1648 void visit(TryFinallyStatement *s)
1650 if (istate->start == s)
1651 istate->start = NULL;
1652 if (istate->start)
1654 Expression *e = NULL;
1655 e = interpret(pue, s->_body, istate);
1656 // Jump into/out from finalbody is disabled in semantic analysis.
1657 // and jump inside will be handled by the ScopeStatement == finalbody.
1658 result = e;
1659 return;
1662 Expression *ex = interpret(s->_body, istate);
1663 if (CTFEExp::isCantExp(ex))
1665 result = ex;
1666 return;
1668 while (CTFEExp::isGotoExp(ex))
1670 // If the goto target is within the body, we must not interpret the finally statement,
1671 // because that will call destructors for objects within the scope, which we should not do.
1672 InterState istatex = *istate;
1673 istatex.start = istate->gotoTarget; // set starting statement
1674 istatex.gotoTarget = NULL;
1675 Expression *bex = interpret(s->_body, &istatex);
1676 if (istatex.start)
1678 // The goto target is outside the current scope.
1679 break;
1681 // The goto target was within the body.
1682 if (CTFEExp::isCantExp(bex))
1684 result = bex;
1685 return;
1687 *istate = istatex;
1688 ex = bex;
1690 Expression *ey = interpret(s->finalbody, istate);
1691 if (CTFEExp::isCantExp(ey))
1693 result = ey;
1694 return;
1696 if (ey && ey->op == TOKthrownexception)
1698 // Check for collided exceptions
1699 if (ex && ex->op == TOKthrownexception)
1700 ex = chainExceptions((ThrownExceptionExp *)ex, (ThrownExceptionExp *)ey);
1701 else
1702 ex = ey;
1704 result = ex;
1707 void visit(ThrowStatement *s)
1709 if (istate->start)
1711 if (istate->start != s)
1712 return;
1713 istate->start = NULL;
1716 Expression *e = interpret(s->exp, istate);
1717 if (exceptionOrCant(e))
1718 return;
1720 assert(e->op == TOKclassreference);
1721 result = new ThrownExceptionExp(s->loc, (ClassReferenceExp *)e);
1724 void visit(OnScopeStatement *)
1726 assert(0);
1729 void visit(WithStatement *s)
1731 if (istate->start == s)
1732 istate->start = NULL;
1733 if (istate->start)
1735 result = s->_body ? interpret(s->_body, istate) : NULL;
1736 return;
1739 // If it is with(Enum) {...}, just execute the body.
1740 if (s->exp->op == TOKscope || s->exp->op == TOKtype)
1742 result = interpret(pue, s->_body, istate);
1743 return;
1746 Expression *e = interpret(s->exp, istate);
1747 if (exceptionOrCant(e))
1748 return;
1750 if (s->wthis->type->ty == Tpointer && s->exp->type->ty != Tpointer)
1752 e = new AddrExp(s->loc, e, s->wthis->type);
1754 ctfeStack.push(s->wthis);
1755 setValue(s->wthis, e);
1756 e = interpret(s->_body, istate);
1757 if (CTFEExp::isGotoExp(e))
1759 /* This is an optimization that relies on the locality of the jump target.
1760 * If the label is in the same WithStatement, the following scan
1761 * would find it quickly and can reduce jump cost.
1762 * Otherwise, the statement body may be unnnecessary scanned again
1763 * so it would make CTFE speed slower.
1765 InterState istatex = *istate;
1766 istatex.start = istate->gotoTarget; // set starting statement
1767 istatex.gotoTarget = NULL;
1768 Expression *ex = interpret(s->_body, &istatex);
1769 if (!istatex.start)
1771 istate->gotoTarget = NULL;
1772 e = ex;
1775 ctfeStack.pop(s->wthis);
1776 result = e;
1779 void visit(AsmStatement *s)
1781 if (istate->start)
1783 if (istate->start != s)
1784 return;
1785 istate->start = NULL;
1788 s->error("asm statements cannot be interpreted at compile time");
1789 result = CTFEExp::cantexp;
1792 void visit(ImportStatement *s)
1794 if (istate->start)
1796 if (istate->start != s)
1797 return;
1798 istate->start = NULL;
1802 /******************************** Expression ***************************/
1804 void visit(Expression *e)
1806 e->error("cannot interpret %s at compile time", e->toChars());
1807 result = CTFEExp::cantexp;
1810 void visit(ThisExp *e)
1812 if (goal == ctfeNeedLvalue)
1814 // We might end up here with istate being zero (see bugzilla 16382)
1815 if (istate && istate->fd->vthis)
1817 result = new VarExp(e->loc, istate->fd->vthis);
1818 result->type = e->type;
1820 else
1821 result = e;
1822 return;
1825 result = ctfeStack.getThis();
1826 if (result)
1828 assert(result->op == TOKstructliteral ||
1829 result->op == TOKclassreference);
1830 return;
1832 e->error("value of 'this' is not known at compile time");
1833 result = CTFEExp::cantexp;
1836 void visit(NullExp *e)
1838 result = e;
1841 void visit(IntegerExp *e)
1843 result = e;
1846 void visit(RealExp *e)
1848 result = e;
1851 void visit(ComplexExp *e)
1853 result = e;
1856 void visit(StringExp *e)
1858 /* Attempts to modify string literals are prevented
1859 * in BinExp::interpretAssignCommon.
1861 result = e;
1864 void visit(FuncExp *e)
1866 result = e;
1869 void visit(SymOffExp *e)
1871 if (e->var->isFuncDeclaration() && e->offset == 0)
1873 result = e;
1874 return;
1876 if (isTypeInfo_Class(e->type) && e->offset == 0)
1878 result = e;
1879 return;
1881 if (e->type->ty != Tpointer)
1883 // Probably impossible
1884 e->error("cannot interpret %s at compile time", e->toChars());
1885 result = CTFEExp::cantexp;
1886 return;
1888 Type *pointee = ((TypePointer *)e->type)->next;
1889 if (e->var->isThreadlocal())
1891 e->error("cannot take address of thread-local variable %s at compile time", e->var->toChars());
1892 result = CTFEExp::cantexp;
1893 return;
1895 // Check for taking an address of a shared variable.
1896 // If the shared variable is an array, the offset might not be zero.
1897 Type *fromType = NULL;
1898 if (e->var->type->ty == Tarray || e->var->type->ty == Tsarray)
1900 fromType = ((TypeArray *)(e->var->type))->next;
1902 if (e->var->isDataseg() &&
1903 ((e->offset == 0 && isSafePointerCast(e->var->type, pointee)) ||
1904 (fromType && isSafePointerCast(fromType, pointee))))
1906 result = e;
1907 return;
1909 Expression *val = getVarExp(e->loc, istate, e->var, goal);
1910 if (exceptionOrCant(val))
1911 return;
1912 if (val->type->ty == Tarray || val->type->ty == Tsarray)
1914 // Check for unsupported type painting operations
1915 Type *elemtype = ((TypeArray *)(val->type))->next;
1916 d_uns64 elemsize = elemtype->size();
1918 // It's OK to cast from fixed length to dynamic array, eg &int[3] to int[]*
1919 if (val->type->ty == Tsarray && pointee->ty == Tarray &&
1920 elemsize == pointee->nextOf()->size())
1922 new(pue) AddrExp(e->loc, val, e->type);
1923 result = pue->exp();
1924 return;
1927 // It's OK to cast from fixed length to fixed length array, eg &int[n] to int[d]*.
1928 if (val->type->ty == Tsarray && pointee->ty == Tsarray &&
1929 elemsize == pointee->nextOf()->size())
1931 size_t d = (size_t)((TypeSArray *)pointee)->dim->toInteger();
1932 Expression *elwr = new IntegerExp(e->loc, e->offset / elemsize, Type::tsize_t);
1933 Expression *eupr = new IntegerExp(e->loc, e->offset / elemsize + d, Type::tsize_t);
1935 // Create a CTFE pointer &val[ofs..ofs+d]
1936 SliceExp *se = new SliceExp(e->loc, val, elwr, eupr);
1937 se->type = pointee;
1938 new(pue) AddrExp(e->loc, se, e->type);
1939 result = pue->exp();
1940 return;
1943 if (!isSafePointerCast(elemtype, pointee))
1945 // It's also OK to cast from &string to string*.
1946 if (e->offset == 0 && isSafePointerCast(e->var->type, pointee))
1948 // Create a CTFE pointer &var
1949 VarExp *ve = new VarExp(e->loc, e->var);
1950 ve->type = elemtype;
1951 new(pue) AddrExp(e->loc, ve, e->type);
1952 result = pue->exp();
1953 return;
1955 e->error("reinterpreting cast from %s to %s is not supported in CTFE",
1956 val->type->toChars(), e->type->toChars());
1957 result = CTFEExp::cantexp;
1958 return;
1961 const dinteger_t sz = pointee->size();
1962 dinteger_t indx = e->offset / sz;
1963 assert(sz * indx == e->offset);
1964 Expression *aggregate = NULL;
1965 if (val->op == TOKarrayliteral || val->op == TOKstring)
1967 aggregate = val;
1969 else if (val->op == TOKslice)
1971 aggregate = ((SliceExp *)val)->e1;
1972 UnionExp uelwr;
1973 Expression *lwr = interpret(&uelwr, ((SliceExp *)val)->lwr, istate);
1974 indx += lwr->toInteger();
1976 if (aggregate)
1978 // Create a CTFE pointer &aggregate[ofs]
1979 IntegerExp *ofs = new IntegerExp(e->loc, indx, Type::tsize_t);
1980 IndexExp *ei = new IndexExp(e->loc, aggregate, ofs);
1981 ei->type = elemtype;
1982 new(pue) AddrExp(e->loc, ei, e->type);
1983 result = pue->exp();
1984 return;
1987 else if (e->offset == 0 && isSafePointerCast(e->var->type, pointee))
1989 // Create a CTFE pointer &var
1990 VarExp *ve = new VarExp(e->loc, e->var);
1991 ve->type = e->var->type;
1992 new(pue) AddrExp(e->loc, ve, e->type);
1993 result = pue->exp();
1994 return;
1997 e->error("cannot convert &%s to %s at compile time", e->var->type->toChars(), e->type->toChars());
1998 result = CTFEExp::cantexp;
2001 void visit(AddrExp *e)
2003 if (e->e1->op == TOKvar && ((VarExp *)e->e1)->var->isDataseg())
2005 // Normally this is already done by optimize()
2006 // Do it here in case optimize(WANTvalue) wasn't run before CTFE
2007 result = new SymOffExp(e->loc, ((VarExp *)e->e1)->var, 0);
2008 result->type = e->type;
2009 return;
2011 Expression *er = interpret(e->e1, istate, ctfeNeedLvalue);
2012 if (er->op == TOKvar && ((VarExp *)er)->var == istate->fd->vthis)
2013 er = interpret(er, istate);
2014 if (exceptionOrCant(er))
2015 return;
2017 // Return a simplified address expression
2018 new(pue) AddrExp(e->loc, er, e->type);
2019 result = pue->exp();
2022 void visit(DelegateExp *e)
2024 // TODO: Really we should create a CTFE-only delegate expression
2025 // of a pointer and a funcptr.
2027 // If it is &nestedfunc, just return it
2028 // TODO: We should save the context pointer
2029 if (e->e1->op == TOKvar && ((VarExp *)e->e1)->var == e->func)
2031 result = e;
2032 return;
2035 Expression *er = interpret(e->e1, istate);
2036 if (exceptionOrCant(er))
2037 return;
2038 if (er == e->e1)
2040 // If it has already been CTFE'd, just return it
2041 result = e;
2043 else
2045 new(pue) DelegateExp(e->loc, er, e->func, false);
2046 result = pue->exp();
2047 result->type = e->type;
2051 static Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal)
2053 Expression *e = CTFEExp::cantexp;
2054 if (VarDeclaration *v = d->isVarDeclaration())
2056 /* Magic variable __ctfe always returns true when interpreting
2058 if (v->ident == Id::ctfe)
2059 return new IntegerExp(loc, 1, Type::tbool);
2061 if (!v->originalType && v->_scope) // semantic() not yet run
2063 v->semantic (v->_scope);
2064 if (v->type->ty == Terror)
2065 return CTFEExp::cantexp;
2068 if ((v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) &&
2069 !hasValue(v) &&
2070 v->_init && !v->isCTFE())
2072 if (v->inuse)
2074 error(loc, "circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
2075 return CTFEExp::cantexp;
2077 if (v->_scope)
2079 v->inuse++;
2080 v->_init = ::semantic(v->_init, v->_scope, v->type, INITinterpret); // might not be run on aggregate members
2081 v->inuse--;
2083 e = initializerToExpression(v->_init, v->type);
2084 if (!e)
2085 return CTFEExp::cantexp;
2086 assert(e->type);
2088 if (e->op == TOKconstruct || e->op == TOKblit)
2090 AssignExp *ae = (AssignExp *)e;
2091 e = ae->e2;
2094 if (e->op == TOKerror)
2096 // FIXME: Ultimately all errors should be detected in prior semantic analysis stage.
2098 else if (v->isDataseg() || (v->storage_class & STCmanifest))
2100 /* Bugzilla 14304: e is a value that is not yet owned by CTFE.
2101 * Mark as "cached", and use it directly during interpretation.
2103 e = scrubCacheValue(v->loc, e);
2104 ctfeStack.saveGlobalConstant(v, e);
2106 else
2108 v->inuse++;
2109 e = interpret(e, istate);
2110 v->inuse--;
2111 if (CTFEExp::isCantExp(e) && !global.gag && !CtfeStatus::stackTraceCallsToSuppress)
2112 errorSupplemental(loc, "while evaluating %s.init", v->toChars());
2113 if (exceptionOrCantInterpret(e))
2114 return e;
2117 else if (v->isCTFE() && !hasValue(v))
2119 if (v->_init && v->type->size() != 0)
2121 if (v->_init->isVoidInitializer())
2123 // var should have been initialized when it was created
2124 error(loc, "CTFE internal error: trying to access uninitialized var");
2125 assert(0);
2126 return CTFEExp::cantexp;
2128 e = initializerToExpression(v->_init);
2130 else
2131 e = v->type->defaultInitLiteral(e->loc);
2133 e = interpret(e, istate);
2135 else if (!(v->isDataseg() || v->storage_class & STCmanifest) && !v->isCTFE() && !istate)
2137 error(loc, "variable %s cannot be read at compile time", v->toChars());
2138 return CTFEExp::cantexp;
2140 else
2142 e = hasValue(v) ? getValue(v) : NULL;
2143 if (!e && !v->isCTFE() && v->isDataseg())
2145 error(loc, "static variable %s cannot be read at compile time", v->toChars());
2146 return CTFEExp::cantexp;
2148 if (!e)
2150 assert(!(v->_init && v->_init->isVoidInitializer()));
2151 // CTFE initiated from inside a function
2152 error(loc, "variable %s cannot be read at compile time", v->toChars());
2153 return CTFEExp::cantexp;
2155 if (e->op == TOKvoid)
2157 VoidInitExp *ve = (VoidInitExp *)e;
2158 error(loc, "cannot read uninitialized variable %s in ctfe", v->toPrettyChars());
2159 errorSupplemental(ve->var->loc, "%s was uninitialized and used before set", ve->var->toChars());
2160 return CTFEExp::cantexp;
2162 if (goal != ctfeNeedLvalue && (v->isRef() || v->isOut()))
2163 e = interpret(e, istate, goal);
2165 if (!e)
2166 e = CTFEExp::cantexp;
2168 else if (SymbolDeclaration *s = d->isSymbolDeclaration())
2170 // Struct static initializers, for example
2171 e = s->dsym->type->defaultInitLiteral(loc);
2172 if (e->op == TOKerror)
2173 error(loc, "CTFE failed because of previous errors in %s.init", s->toChars());
2174 e = ::semantic(e, NULL);
2175 if (e->op == TOKerror)
2176 e = CTFEExp::cantexp;
2177 else // Convert NULL to CTFEExp
2178 e = interpret(e, istate, goal);
2180 else
2181 error(loc, "cannot interpret declaration %s at compile time", d->toChars());
2182 return e;
2185 void visit(VarExp *e)
2187 if (e->var->isFuncDeclaration())
2189 result = e;
2190 return;
2193 if (goal == ctfeNeedLvalue)
2195 VarDeclaration *v = e->var->isVarDeclaration();
2196 if (v && !v->isDataseg() && !v->isCTFE() && !istate)
2198 e->error("variable %s cannot be read at compile time", v->toChars());
2199 result = CTFEExp::cantexp;
2200 return;
2202 if (v && !hasValue(v))
2204 if (!v->isCTFE() && v->isDataseg())
2205 e->error("static variable %s cannot be read at compile time", v->toChars());
2206 else // CTFE initiated from inside a function
2207 e->error("variable %s cannot be read at compile time", v->toChars());
2208 result = CTFEExp::cantexp;
2209 return;
2211 if (v && (v->storage_class & (STCout | STCref)) && hasValue(v))
2213 // Strip off the nest of ref variables
2214 Expression *ev = getValue(v);
2215 if (ev->op == TOKvar || ev->op == TOKindex || ev->op == TOKdotvar)
2217 result = interpret(pue, ev, istate, goal);
2218 return;
2221 result = e;
2222 return;
2224 result = getVarExp(e->loc, istate, e->var, goal);
2225 if (exceptionOrCant(result))
2226 return;
2227 if ((e->var->storage_class & (STCref | STCout)) == 0 &&
2228 e->type->baseElemOf()->ty != Tstruct)
2230 /* Ultimately, STCref|STCout check should be enough to see the
2231 * necessity of type repainting. But currently front-end paints
2232 * non-ref struct variables by the const type.
2234 * auto foo(ref const S cs);
2235 * S s;
2236 * foo(s); // VarExp('s') will have const(S)
2238 // A VarExp may include an implicit cast. It must be done explicitly.
2239 result = paintTypeOntoLiteral(e->type, result);
2243 void visit(DeclarationExp *e)
2245 Dsymbol *s = e->declaration;
2246 if (VarDeclaration *v = s->isVarDeclaration())
2248 if (TupleDeclaration *td = v->toAlias()->isTupleDeclaration())
2250 result = NULL;
2252 // Reserve stack space for all tuple members
2253 if (!td->objects)
2254 return;
2255 for (size_t i = 0; i < td->objects->dim; ++i)
2257 RootObject * o = (*td->objects)[i];
2258 Expression *ex = isExpression(o);
2259 DsymbolExp *ds = (ex && ex->op == TOKdsymbol) ? (DsymbolExp *)ex : NULL;
2260 VarDeclaration *v2 = ds ? ds->s->isVarDeclaration() : NULL;
2261 assert(v2);
2262 if (v2->isDataseg() && !v2->isCTFE())
2263 continue;
2265 ctfeStack.push(v2);
2266 if (v2->_init)
2268 Expression *einit;
2269 if (ExpInitializer *ie = v2->_init->isExpInitializer())
2271 einit = interpret(ie->exp, istate, goal);
2272 if (exceptionOrCant(einit))
2273 return;
2275 else if (v2->_init->isVoidInitializer())
2277 einit = voidInitLiteral(v2->type, v2).copy();
2279 else
2281 e->error("declaration %s is not yet implemented in CTFE", e->toChars());
2282 result = CTFEExp::cantexp;
2283 return;
2285 setValue(v2, einit);
2288 return;
2290 if (v->isStatic())
2292 // Just ignore static variables which aren't read or written yet
2293 result = NULL;
2294 return;
2296 if (!(v->isDataseg() || v->storage_class & STCmanifest) || v->isCTFE())
2297 ctfeStack.push(v);
2298 if (v->_init)
2300 if (ExpInitializer *ie = v->_init->isExpInitializer())
2302 result = interpret(ie->exp, istate, goal);
2304 else if (v->_init->isVoidInitializer())
2306 result = voidInitLiteral(v->type, v).copy();
2307 // There is no AssignExp for void initializers,
2308 // so set it here.
2309 setValue(v, result);
2311 else
2313 e->error("declaration %s is not yet implemented in CTFE", e->toChars());
2314 result = CTFEExp::cantexp;
2317 else if (v->type->size() == 0)
2319 // Zero-length arrays don't need an initializer
2320 result = v->type->defaultInitLiteral(e->loc);
2322 else
2324 e->error("variable %s cannot be modified at compile time", v->toChars());
2325 result = CTFEExp::cantexp;
2327 return;
2329 if (s->isAttribDeclaration() ||
2330 s->isTemplateMixin() ||
2331 s->isTupleDeclaration())
2333 // Check for static struct declarations, which aren't executable
2334 AttribDeclaration *ad = e->declaration->isAttribDeclaration();
2335 if (ad && ad->decl && ad->decl->dim == 1)
2337 Dsymbol *sparent = (*ad->decl)[0];
2338 if (sparent->isAggregateDeclaration() ||
2339 sparent->isTemplateDeclaration() ||
2340 sparent->isAliasDeclaration())
2342 result = NULL;
2343 return; // static (template) struct declaration. Nothing to do.
2347 // These can be made to work, too lazy now
2348 e->error("declaration %s is not yet implemented in CTFE", e->toChars());
2349 result = CTFEExp::cantexp;
2350 return;
2353 // Others should not contain executable code, so are trivial to evaluate
2354 result = NULL;
2357 void visit(TypeidExp *e)
2359 if (isType(e->obj))
2361 result = e;
2362 return;
2364 if (Expression *ex = isExpression(e->obj))
2366 result = interpret(ex, istate);
2367 if (exceptionOrCant(ex))
2368 return;
2370 if (result->op == TOKnull)
2372 e->error("null pointer dereference evaluating typeid. '%s' is null", ex->toChars());
2373 result = CTFEExp::cantexp;
2374 return;
2376 if (result->op != TOKclassreference)
2378 e->error("CTFE internal error: determining classinfo");
2379 result = CTFEExp::cantexp;
2380 return;
2383 ClassDeclaration *cd = ((ClassReferenceExp *)result)->originalClass();
2384 assert(cd);
2386 new(pue) TypeidExp(e->loc, cd->type);
2387 result = pue->exp();
2388 result->type = e->type;
2389 return;
2391 visit((Expression *)e);
2394 void visit(TupleExp *e)
2396 if (exceptionOrCant(interpret(e->e0, istate, ctfeNeedNothing)))
2397 return;
2399 Expressions *expsx = e->exps;
2400 for (size_t i = 0; i < expsx->dim; i++)
2402 Expression *exp = (*expsx)[i];
2403 Expression *ex = interpret(exp, istate);
2404 if (exceptionOrCant(ex))
2405 return;
2407 // A tuple of assignments can contain void (Bug 5676).
2408 if (goal == ctfeNeedNothing)
2409 continue;
2410 if (ex->op == TOKvoidexp)
2412 e->error("CTFE internal error: void element %s in tuple", exp->toChars());
2413 assert(0);
2416 /* If any changes, do Copy On Write
2418 if (ex != exp)
2420 expsx = copyArrayOnWrite(expsx, e->exps);
2421 (*expsx)[i] = ex;
2424 if (expsx != e->exps)
2426 expandTuples(expsx);
2427 new(pue) TupleExp(e->loc, expsx);
2428 result = pue->exp();
2429 result->type = new TypeTuple(expsx);
2431 else
2432 result = e;
2435 void visit(ArrayLiteralExp *e)
2437 if (e->ownedByCtfe >= OWNEDctfe) // We've already interpreted all the elements
2439 result = e;
2440 return;
2443 Type *tn = e->type->toBasetype()->nextOf()->toBasetype();
2444 bool wantCopy = (tn->ty == Tsarray || tn->ty == Tstruct);
2446 Expression *basis = interpret(e->basis, istate);
2447 if (exceptionOrCant(basis))
2448 return;
2450 Expressions *expsx = e->elements;
2451 size_t dim = expsx ? expsx->dim : 0;
2452 for (size_t i = 0; i < dim; i++)
2454 Expression *exp = (*expsx)[i];
2455 Expression *ex;
2456 if (!exp)
2458 ex = copyLiteral(basis).copy();
2460 else
2462 // segfault bug 6250
2463 assert(exp->op != TOKindex || ((IndexExp *)exp)->e1 != e);
2465 ex = interpret(exp, istate);
2466 if (exceptionOrCant(ex))
2467 return;
2469 /* Each elements should have distinct CFE memory.
2470 * int[1] z = 7;
2471 * int[1][] pieces = [z,z]; // here
2473 if (wantCopy)
2474 ex = copyLiteral(ex).copy();
2477 /* If any changes, do Copy On Write
2479 if (ex != exp)
2481 expsx = copyArrayOnWrite(expsx, e->elements);
2482 (*expsx)[i] = ex;
2486 if (expsx != e->elements)
2488 // todo: all tuple expansions should go in semantic phase.
2489 expandTuples(expsx);
2490 if (expsx->dim != dim)
2492 e->error("CTFE internal error: invalid array literal");
2493 result = CTFEExp::cantexp;
2494 return;
2496 new(pue) ArrayLiteralExp(e->loc, basis, expsx);
2497 ArrayLiteralExp *ale = (ArrayLiteralExp *)pue->exp();
2498 ale->type = e->type;
2499 ale->ownedByCtfe = OWNEDctfe;
2500 result = ale;
2502 else if (((TypeNext *)e->type)->next->mod & (MODconst | MODimmutable))
2504 // If it's immutable, we don't need to dup it
2505 result = e;
2507 else
2508 result = copyLiteral(e).copy();
2511 void visit(AssocArrayLiteralExp *e)
2513 if (e->ownedByCtfe >= OWNEDctfe) // We've already interpreted all the elements
2515 result = e;
2516 return;
2519 Expressions *keysx = e->keys;
2520 Expressions *valuesx = e->values;
2521 for (size_t i = 0; i < keysx->dim; i++)
2523 Expression *ekey = (*keysx)[i];
2524 Expression *evalue = (*valuesx)[i];
2526 Expression *ek = interpret(ekey, istate);
2527 if (exceptionOrCant(ek))
2528 return;
2529 Expression *ev = interpret(evalue, istate);
2530 if (exceptionOrCant(ev))
2531 return;
2533 /* If any changes, do Copy On Write
2535 if (ek != ekey ||
2536 ev != evalue)
2538 keysx = copyArrayOnWrite(keysx, e->keys);
2539 valuesx = copyArrayOnWrite(valuesx, e->values);
2540 (*keysx)[i] = ek;
2541 (*valuesx)[i] = ev;
2544 if (keysx != e->keys)
2545 expandTuples(keysx);
2546 if (valuesx != e->values)
2547 expandTuples(valuesx);
2548 if (keysx->dim != valuesx->dim)
2550 e->error("CTFE internal error: invalid AA");
2551 result = CTFEExp::cantexp;
2552 return;
2555 /* Remove duplicate keys
2557 for (size_t i = 1; i < keysx->dim; i++)
2559 Expression *ekey = (*keysx)[i - 1];
2560 for (size_t j = i; j < keysx->dim; j++)
2562 Expression *ekey2 = (*keysx)[j];
2563 if (!ctfeEqual(e->loc, TOKequal, ekey, ekey2))
2564 continue;
2566 // Remove ekey
2567 keysx = copyArrayOnWrite(keysx, e->keys);
2568 valuesx = copyArrayOnWrite(valuesx, e->values);
2569 keysx->remove(i - 1);
2570 valuesx->remove(i - 1);
2572 i -= 1; // redo the i'th iteration
2573 break;
2577 if (keysx != e->keys ||
2578 valuesx != e->values)
2580 assert(keysx != e->keys &&
2581 valuesx != e->values);
2582 AssocArrayLiteralExp *ae = new AssocArrayLiteralExp(e->loc, keysx, valuesx);
2583 ae->type = e->type;
2584 ae->ownedByCtfe = OWNEDctfe;
2585 result = ae;
2587 else
2588 result = copyLiteral(e).copy();
2591 void visit(StructLiteralExp *e)
2593 if (e->ownedByCtfe >= OWNEDctfe)
2595 result = e;
2596 return;
2599 size_t dim = e->elements ? e->elements->dim : 0;
2600 Expressions *expsx = e->elements;
2602 if (dim != e->sd->fields.dim)
2604 // guaranteed by AggregateDeclaration.fill and TypeStruct.defaultInitLiteral
2605 assert(e->sd->isNested() && dim == e->sd->fields.dim - 1);
2607 /* If a nested struct has no initialized hidden pointer,
2608 * set it to null to match the runtime behaviour.
2610 NullExp *ne = new NullExp(e->loc);
2611 ne->type = e->sd->vthis->type;
2613 expsx = copyArrayOnWrite(expsx, e->elements);
2614 expsx->push(ne);
2615 ++dim;
2617 assert(dim == e->sd->fields.dim);
2619 for (size_t i = 0; i < dim; i++)
2621 VarDeclaration *v = e->sd->fields[i];
2622 Expression *exp = (*expsx)[i];
2623 Expression *ex = NULL;
2624 if (!exp)
2626 ex = voidInitLiteral(v->type, v).copy();
2628 else
2630 ex = interpret(exp, istate);
2631 if (exceptionOrCant(ex))
2632 return;
2633 if ((v->type->ty != ex->type->ty) && v->type->ty == Tsarray)
2635 // Block assignment from inside struct literals
2636 TypeSArray *tsa = (TypeSArray *)v->type;
2637 size_t len = (size_t)tsa->dim->toInteger();
2638 ex = createBlockDuplicatedArrayLiteral(ex->loc, v->type, ex, len);
2642 /* If any changes, do Copy On Write
2644 if (ex != exp)
2646 expsx = copyArrayOnWrite(expsx, e->elements);
2647 (*expsx)[i] = ex;
2651 if (expsx != e->elements)
2653 expandTuples(expsx);
2654 if (expsx->dim != e->sd->fields.dim)
2656 e->error("CTFE internal error: invalid struct literal");
2657 result = CTFEExp::cantexp;
2658 return;
2660 new(pue) StructLiteralExp(e->loc, e->sd, expsx);
2661 StructLiteralExp *sle = (StructLiteralExp *)pue->exp();
2662 sle->type = e->type;
2663 sle->ownedByCtfe = OWNEDctfe;
2664 sle->origin = e->origin;
2665 result = sle;
2667 else
2668 result = copyLiteral(e).copy();
2671 // Create an array literal of type 'newtype' with dimensions given by
2672 // 'arguments'[argnum..$]
2673 static Expression *recursivelyCreateArrayLiteral(Loc loc, Type *newtype, InterState *istate,
2674 Expressions *arguments, int argnum)
2676 Expression *lenExpr = interpret((*arguments)[argnum], istate);
2677 if (exceptionOrCantInterpret(lenExpr))
2678 return lenExpr;
2679 size_t len = (size_t)(lenExpr->toInteger());
2680 Type *elemType = ((TypeArray *)newtype)->next;
2681 if (elemType->ty == Tarray && argnum < (int)arguments->dim - 1)
2683 Expression *elem = recursivelyCreateArrayLiteral(loc, elemType, istate,
2684 arguments, argnum + 1);
2685 if (exceptionOrCantInterpret(elem))
2686 return elem;
2688 Expressions *elements = new Expressions();
2689 elements->setDim(len);
2690 for (size_t i = 0; i < len; i++)
2691 (*elements)[i] = copyLiteral(elem).copy();
2692 ArrayLiteralExp *ae = new ArrayLiteralExp(loc, elements);
2693 ae->type = newtype;
2694 ae->ownedByCtfe = OWNEDctfe;
2695 return ae;
2697 assert(argnum == (int)arguments->dim - 1);
2698 if (elemType->ty == Tchar || elemType->ty == Twchar || elemType->ty == Tdchar)
2700 const unsigned ch = (unsigned)elemType->defaultInitLiteral(loc)->toInteger();
2701 const unsigned char sz = (unsigned char)elemType->size();
2702 return createBlockDuplicatedStringLiteral(loc, newtype, ch, len, sz);
2704 else
2706 Expression *el = interpret(elemType->defaultInitLiteral(loc), istate);
2707 return createBlockDuplicatedArrayLiteral(loc, newtype, el, len);
2711 void visit(NewExp *e)
2713 if (e->allocator)
2715 e->error("member allocators not supported by CTFE");
2716 result = CTFEExp::cantexp;
2717 return;
2720 result = interpret(e->argprefix, istate, ctfeNeedNothing);
2721 if (exceptionOrCant(result))
2722 return;
2724 if (e->newtype->ty == Tarray && e->arguments)
2726 result = recursivelyCreateArrayLiteral(e->loc, e->newtype, istate, e->arguments, 0);
2727 return;
2729 if (e->newtype->toBasetype()->ty == Tstruct)
2731 if (e->member)
2733 Expression *se = e->newtype->defaultInitLiteral(e->loc);
2734 se = interpret(se, istate);
2735 if (exceptionOrCant(se))
2736 return;
2737 result = interpretFunction(e->member, istate, e->arguments, se);
2739 // Repaint as same as CallExp::interpret() does.
2740 result->loc = e->loc;
2742 else
2744 StructDeclaration *sd = ((TypeStruct *)e->newtype->toBasetype())->sym;
2745 Expressions *exps = new Expressions();
2746 exps->reserve(sd->fields.dim);
2747 if (e->arguments)
2749 exps->setDim(e->arguments->dim);
2750 for (size_t i = 0; i < exps->dim; i++)
2752 Expression *ex = (*e->arguments)[i];
2753 ex = interpret(ex, istate);
2754 if (exceptionOrCant(ex))
2755 return;
2756 (*exps)[i] = ex;
2759 sd->fill(e->loc, exps, false);
2761 StructLiteralExp *se = new StructLiteralExp(e->loc, sd, exps, e->newtype);
2762 se->type = e->newtype;
2763 se->ownedByCtfe = OWNEDctfe;
2764 result = interpret(se, istate);
2766 if (exceptionOrCant(result))
2767 return;
2768 new(pue) AddrExp(e->loc, result, e->type);
2769 result = pue->exp();
2770 return;
2772 if (e->newtype->toBasetype()->ty == Tclass)
2774 ClassDeclaration *cd = ((TypeClass *)e->newtype->toBasetype())->sym;
2775 size_t totalFieldCount = 0;
2776 for (ClassDeclaration *c = cd; c; c = c->baseClass)
2777 totalFieldCount += c->fields.dim;
2778 Expressions *elems = new Expressions;
2779 elems->setDim(totalFieldCount);
2780 size_t fieldsSoFar = totalFieldCount;
2781 for (ClassDeclaration *c = cd; c; c = c->baseClass)
2783 fieldsSoFar -= c->fields.dim;
2784 for (size_t i = 0; i < c->fields.dim; i++)
2786 VarDeclaration *v = c->fields[i];
2787 if (v->inuse)
2789 e->error("circular reference to '%s'", v->toPrettyChars());
2790 result = CTFEExp::cantexp;
2791 return;
2793 Expression *m;
2794 if (v->_init)
2796 if (v->_init->isVoidInitializer())
2797 m = voidInitLiteral(v->type, v).copy();
2798 else
2799 m = v->getConstInitializer(true);
2801 else
2802 m = v->type->defaultInitLiteral(e->loc);
2803 if (exceptionOrCant(m))
2804 return;
2805 (*elems)[fieldsSoFar+i] = copyLiteral(m).copy();
2808 // Hack: we store a ClassDeclaration instead of a StructDeclaration.
2809 // We probably won't get away with this.
2810 StructLiteralExp *se = new StructLiteralExp(e->loc, (StructDeclaration *)cd, elems, e->newtype);
2811 se->ownedByCtfe = OWNEDctfe;
2812 Expression *eref = new ClassReferenceExp(e->loc, se, e->type);
2813 if (e->member)
2815 // Call constructor
2816 if (!e->member->fbody)
2818 Expression *ctorfail = evaluateIfBuiltin(istate, e->loc, e->member, e->arguments, eref);
2819 if (ctorfail)
2821 if (exceptionOrCant(ctorfail))
2822 return;
2823 result = eref;
2824 return;
2826 e->member->error("%s cannot be constructed at compile time, because the constructor has no available source code", e->newtype->toChars());
2827 result = CTFEExp::cantexp;
2828 return;
2830 Expression *ctorfail = interpretFunction(e->member, istate, e->arguments, eref);
2831 if (exceptionOrCant(ctorfail))
2832 return;
2834 /* Bugzilla 14465: Repaint the loc, because a super() call
2835 * in the constructor modifies the loc of ClassReferenceExp
2836 * in CallExp::interpret().
2838 eref->loc = e->loc;
2840 result = eref;
2841 return;
2843 if (e->newtype->toBasetype()->isscalar())
2845 Expression *newval;
2846 if (e->arguments && e->arguments->dim)
2847 newval = (*e->arguments)[0];
2848 else
2849 newval = e->newtype->defaultInitLiteral(e->loc);
2850 newval = interpret(newval, istate);
2851 if (exceptionOrCant(newval))
2852 return;
2854 // Create a CTFE pointer &[newval][0]
2855 Expressions *elements = new Expressions();
2856 elements->setDim(1);
2857 (*elements)[0] = newval;
2858 ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, elements);
2859 ae->type = e->newtype->arrayOf();
2860 ae->ownedByCtfe = OWNEDctfe;
2862 IndexExp *ei = new IndexExp(e->loc, ae, new IntegerExp(Loc(), 0, Type::tsize_t));
2863 ei->type = e->newtype;
2864 new(pue) AddrExp(e->loc, ei, e->type);
2865 result = pue->exp();
2866 return;
2868 e->error("cannot interpret %s at compile time", e->toChars());
2869 result = CTFEExp::cantexp;
2872 void visit(UnaExp *e)
2874 UnionExp ue;
2875 Expression *e1 = interpret(&ue, e->e1, istate);
2876 if (exceptionOrCant(e1))
2877 return;
2878 switch (e->op)
2880 case TOKneg: *pue = Neg(e->type, e1); break;
2881 case TOKtilde: *pue = Com(e->type, e1); break;
2882 case TOKnot: *pue = Not(e->type, e1); break;
2883 case TOKvector: result = e; return; // do nothing
2884 default: assert(0);
2886 result = (*pue).exp();
2889 void visit(DotTypeExp *e)
2891 UnionExp ue;
2892 Expression *e1 = interpret(&ue, e->e1, istate);
2893 if (exceptionOrCant(e1))
2894 return;
2896 if (e1 == e->e1)
2897 result = e; // optimize: reuse this CTFE reference
2898 else
2900 DotTypeExp *edt = (DotTypeExp *)e->copy();
2901 edt->e1 = (e1 == ue.exp()) ? e1->copy() : e1; // don't return pointer to ue
2902 result = edt;
2906 bool evalOperand(UnionExp *pue, Expression *e, Expression *ex, Expression *&er)
2908 er = interpret(pue, ex, istate);
2909 if (exceptionOrCant(er))
2910 return false;
2911 if (er->isConst() != 1)
2913 if (er->op == TOKarrayliteral)
2914 // Until we get it to work, issue a reasonable error message
2915 e->error("cannot interpret array literal expression %s at compile time", e->toChars());
2916 else
2917 e->error("CTFE internal error: non-constant value %s", ex->toChars());
2918 result = CTFEExp::cantexp;
2919 return false;
2921 return true;
2924 void interpretCommon(BinExp *e, fp_t fp)
2926 if (e->e1->type->ty == Tpointer && e->e2->type->ty == Tpointer && e->op == TOKmin)
2928 UnionExp ue1;
2929 Expression *e1 = interpret(&ue1, e->e1, istate);
2930 if (exceptionOrCant(e1))
2931 return;
2932 UnionExp ue2;
2933 Expression *e2 = interpret(&ue2, e->e2, istate);
2934 if (exceptionOrCant(e2))
2935 return;
2936 *pue = pointerDifference(e->loc, e->type, e1, e2);
2937 result = (*pue).exp();
2938 return;
2940 if (e->e1->type->ty == Tpointer && e->e2->type->isintegral())
2942 UnionExp ue1;
2943 Expression *e1 = interpret(&ue1, e->e1, istate);
2944 if (exceptionOrCant(e1))
2945 return;
2946 UnionExp ue2;
2947 Expression *e2 = interpret(&ue2, e->e2, istate);
2948 if (exceptionOrCant(e2))
2949 return;
2950 *pue = pointerArithmetic(e->loc, e->op, e->type, e1, e2);
2951 result = (*pue).exp();
2952 return;
2954 if (e->e2->type->ty == Tpointer && e->e1->type->isintegral() && e->op == TOKadd)
2956 UnionExp ue1;
2957 Expression *e1 = interpret(&ue1, e->e1, istate);
2958 if (exceptionOrCant(e1))
2959 return;
2960 UnionExp ue2;
2961 Expression *e2 = interpret(&ue2, e->e2, istate);
2962 if (exceptionOrCant(e2))
2963 return;
2964 *pue = pointerArithmetic(e->loc, e->op, e->type, e2, e1);
2965 result = (*pue).exp();
2966 return;
2968 if (e->e1->type->ty == Tpointer || e->e2->type->ty == Tpointer)
2970 e->error("pointer expression %s cannot be interpreted at compile time", e->toChars());
2971 result = CTFEExp::cantexp;
2972 return;
2975 UnionExp ue1;
2976 Expression *e1;
2977 if (!evalOperand(&ue1, e, e->e1, e1))
2978 return;
2979 UnionExp ue2;
2980 Expression *e2;
2981 if (!evalOperand(&ue2, e, e->e2, e2))
2982 return;
2984 if (e->op == TOKshr || e->op == TOKshl || e->op == TOKushr)
2986 const sinteger_t i2 = e2->toInteger();
2987 const d_uns64 sz = e1->type->size() * 8;
2988 if (i2 < 0 || (d_uns64)i2 >= sz)
2990 e->error("shift by %lld is outside the range 0..%llu", i2, (ulonglong)sz - 1);
2991 result = CTFEExp::cantexp;
2992 return;
2995 *pue = (*fp)(e->loc, e->type, e1, e2);
2996 result = (*pue).exp();
2997 if (CTFEExp::isCantExp(result))
2998 e->error("%s cannot be interpreted at compile time", e->toChars());
3001 void interpretCompareCommon(BinExp *e, fp2_t fp)
3003 UnionExp ue1;
3004 UnionExp ue2;
3005 if (e->e1->type->ty == Tpointer && e->e2->type->ty == Tpointer)
3007 Expression *e1 = interpret(&ue1, e->e1, istate);
3008 if (exceptionOrCant(e1))
3009 return;
3010 Expression *e2 = interpret(&ue2, e->e2, istate);
3011 if (exceptionOrCant(e2))
3012 return;
3013 //printf("e1 = %s %s, e2 = %s %s\n", e1->type->toChars(), e1->toChars(), e2->type->toChars(), e2->toChars());
3014 dinteger_t ofs1, ofs2;
3015 Expression *agg1 = getAggregateFromPointer(e1, &ofs1);
3016 Expression *agg2 = getAggregateFromPointer(e2, &ofs2);
3017 //printf("agg1 = %p %s, agg2 = %p %s\n", agg1, agg1->toChars(), agg2, agg2->toChars());
3018 const int cmp = comparePointers(e->op, agg1, ofs1, agg2, ofs2);
3019 if (cmp == -1)
3021 char dir = (e->op == TOKgt || e->op == TOKge) ? '<' : '>';
3022 e->error("the ordering of pointers to unrelated memory blocks is indeterminate in CTFE."
3023 " To check if they point to the same memory block, use both > and < inside && or ||, "
3024 "eg (%s && %s %c= %s + 1)",
3025 e->toChars(), e->e1->toChars(), dir, e->e2->toChars());
3026 result = CTFEExp::cantexp;
3027 return;
3029 new(pue) IntegerExp(e->loc, cmp, e->type);
3030 result = (*pue).exp();
3031 return;
3033 Expression *e1 = interpret(&ue1, e->e1, istate);
3034 if (exceptionOrCant(e1))
3035 return;
3036 if (!isCtfeComparable(e1))
3038 e->error("cannot compare %s at compile time", e1->toChars());
3039 result = CTFEExp::cantexp;
3040 return;
3042 Expression *e2 = interpret(&ue2, e->e2, istate);
3043 if (exceptionOrCant(e2))
3044 return;
3045 if (!isCtfeComparable(e2))
3047 e->error("cannot compare %s at compile time", e2->toChars());
3048 result = CTFEExp::cantexp;
3049 return;
3051 const int cmp = (*fp)(e->loc, e->op, e1, e2);
3052 new(pue) IntegerExp(e->loc, cmp, e->type);
3053 result = (*pue).exp();
3056 void visit(BinExp *e)
3058 switch (e->op)
3060 case TOKadd: interpretCommon(e, &Add); return;
3061 case TOKmin: interpretCommon(e, &Min); return;
3062 case TOKmul: interpretCommon(e, &Mul); return;
3063 case TOKdiv: interpretCommon(e, &Div); return;
3064 case TOKmod: interpretCommon(e, &Mod); return;
3065 case TOKshl: interpretCommon(e, &Shl); return;
3066 case TOKshr: interpretCommon(e, &Shr); return;
3067 case TOKushr: interpretCommon(e, &Ushr); return;
3068 case TOKand: interpretCommon(e, &And); return;
3069 case TOKor: interpretCommon(e, &Or); return;
3070 case TOKxor: interpretCommon(e, &Xor); return;
3071 case TOKpow: interpretCommon(e, &Pow); return;
3072 case TOKequal:
3073 case TOKnotequal:
3074 interpretCompareCommon(e, &ctfeEqual);
3075 return;
3076 case TOKidentity:
3077 case TOKnotidentity:
3078 interpretCompareCommon(e, &ctfeIdentity);
3079 return;
3080 case TOKlt:
3081 case TOKle:
3082 case TOKgt:
3083 case TOKge:
3084 interpretCompareCommon(e, &ctfeCmp);
3085 return;
3086 default:
3087 printf("be = '%s' %s at [%s]\n", Token::toChars(e->op), e->toChars(), e->loc.toChars());
3088 assert(0);
3089 return;
3093 /* Helper functions for BinExp::interpretAssignCommon
3096 // Returns the variable which is eventually modified, or NULL if an rvalue.
3097 // thisval is the current value of 'this'.
3098 static VarDeclaration *findParentVar(Expression *e)
3100 for (;;)
3102 if (e->op == TOKvar)
3103 break;
3104 if (e->op == TOKindex)
3105 e = ((IndexExp *)e)->e1;
3106 else if (e->op == TOKdotvar)
3107 e = ((DotVarExp *)e)->e1;
3108 else if (e->op == TOKdotti)
3109 e = ((DotTemplateInstanceExp *)e)->e1;
3110 else if (e->op == TOKslice)
3111 e = ((SliceExp *)e)->e1;
3112 else
3113 return NULL;
3115 VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration();
3116 assert(v);
3117 return v;
3120 void interpretAssignCommon(BinExp *e, fp_t fp, int post = 0)
3122 result = CTFEExp::cantexp;
3123 Expression *e1 = e->e1;
3124 if (!istate)
3126 e->error("value of %s is not known at compile time", e1->toChars());
3127 return;
3130 ++CtfeStatus::numAssignments;
3132 /* Before we begin, we need to know if this is a reference assignment
3133 * (dynamic array, AA, or class) or a value assignment.
3134 * Determining this for slice assignments are tricky: we need to know
3135 * if it is a block assignment (a[] = e) rather than a direct slice
3136 * assignment (a[] = b[]). Note that initializers of multi-dimensional
3137 * static arrays can have 2D block assignments (eg, int[7][7] x = 6;).
3138 * So we need to recurse to determine if it is a block assignment.
3140 bool isBlockAssignment = false;
3141 if (e1->op == TOKslice)
3143 // a[] = e can have const e. So we compare the naked types.
3144 Type *tdst = e1->type->toBasetype();
3145 Type *tsrc = e->e2->type->toBasetype();
3146 while (tdst->ty == Tsarray || tdst->ty == Tarray)
3148 tdst = ((TypeArray *)tdst)->next->toBasetype();
3149 if (tsrc->equivalent(tdst))
3151 isBlockAssignment = true;
3152 break;
3157 // ---------------------------------------
3158 // Deal with reference assignment
3159 // ---------------------------------------
3160 // If it is a construction of a ref variable, it is a ref assignment
3161 if ((e->op == TOKconstruct || e->op == TOKblit) &&
3162 (((AssignExp *)e)->memset & referenceInit))
3164 assert(!fp);
3166 Expression *newval = interpret(e->e2, istate, ctfeNeedLvalue);
3167 if (exceptionOrCant(newval))
3168 return;
3170 VarDeclaration *v = ((VarExp *)e1)->var->isVarDeclaration();
3171 setValue(v, newval);
3173 // Get the value to return. Note that 'newval' is an Lvalue,
3174 // so if we need an Rvalue, we have to interpret again.
3175 if (goal == ctfeNeedRvalue)
3176 result = interpret(newval, istate);
3177 else
3178 result = e1; // VarExp is a CTFE reference
3179 return;
3182 if (fp)
3184 while (e1->op == TOKcast)
3186 CastExp *ce = (CastExp *)e1;
3187 e1 = ce->e1;
3191 // ---------------------------------------
3192 // Interpret left hand side
3193 // ---------------------------------------
3194 AssocArrayLiteralExp *existingAA = NULL;
3195 Expression *lastIndex = NULL;
3196 Expression *oldval = NULL;
3197 if (e1->op == TOKindex && ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray)
3199 // ---------------------------------------
3200 // Deal with AA index assignment
3201 // ---------------------------------------
3202 /* This needs special treatment if the AA doesn't exist yet.
3203 * There are two special cases:
3204 * (1) If the AA is itself an index of another AA, we may need to create
3205 * multiple nested AA literals before we can insert the new value.
3206 * (2) If the ultimate AA is null, no insertion happens at all. Instead,
3207 * we create nested AA literals, and change it into a assignment.
3209 IndexExp *ie = (IndexExp *)e1;
3210 int depth = 0; // how many nested AA indices are there?
3211 while (ie->e1->op == TOKindex &&
3212 ((IndexExp *)ie->e1)->e1->type->toBasetype()->ty == Taarray)
3214 assert(ie->modifiable);
3215 ie = (IndexExp *)ie->e1;
3216 ++depth;
3219 // Get the AA value to be modified.
3220 Expression *aggregate = interpret(ie->e1, istate);
3221 if (exceptionOrCant(aggregate))
3222 return;
3223 if (aggregate->op == TOKassocarrayliteral)
3225 existingAA = (AssocArrayLiteralExp *)aggregate;
3227 // Normal case, ultimate parent AA already exists
3228 // We need to walk from the deepest index up, checking that an AA literal
3229 // already exists on each level.
3230 lastIndex = interpret(((IndexExp *)e1)->e2, istate);
3231 lastIndex = resolveSlice(lastIndex); // only happens with AA assignment
3232 if (exceptionOrCant(lastIndex))
3233 return;
3235 while (depth > 0)
3237 // Walk the syntax tree to find the indexExp at this depth
3238 IndexExp *xe = (IndexExp *)e1;
3239 for (int d= 0; d < depth; ++d)
3240 xe = (IndexExp *)xe->e1;
3242 Expression *ekey = interpret(xe->e2, istate);
3243 if (exceptionOrCant(ekey))
3244 return;
3245 UnionExp ekeyTmp;
3246 ekey = resolveSlice(ekey, &ekeyTmp); // only happens with AA assignment
3248 // Look up this index in it up in the existing AA, to get the next level of AA.
3249 AssocArrayLiteralExp *newAA = (AssocArrayLiteralExp *)findKeyInAA(e->loc, existingAA, ekey);
3250 if (exceptionOrCant(newAA))
3251 return;
3252 if (!newAA)
3254 // Doesn't exist yet, create an empty AA...
3255 Expressions *keysx = new Expressions();
3256 Expressions *valuesx = new Expressions();
3257 newAA = new AssocArrayLiteralExp(e->loc, keysx, valuesx);
3258 newAA->type = xe->type;
3259 newAA->ownedByCtfe = OWNEDctfe;
3260 //... and insert it into the existing AA.
3261 existingAA->keys->push(ekey);
3262 existingAA->values->push(newAA);
3264 existingAA = newAA;
3265 --depth;
3268 if (fp)
3270 oldval = findKeyInAA(e->loc, existingAA, lastIndex);
3271 if (!oldval)
3272 oldval = copyLiteral(e->e1->type->defaultInitLiteral(e->loc)).copy();
3275 else
3277 /* The AA is currently null. 'aggregate' is actually a reference to
3278 * whatever contains it. It could be anything: var, dotvarexp, ...
3279 * We rewrite the assignment from:
3280 * aa[i][j] op= newval;
3281 * into:
3282 * aa = [i:[j:T.init]];
3283 * aa[j] op= newval;
3285 oldval = copyLiteral(e->e1->type->defaultInitLiteral(e->loc)).copy();
3287 Expression *newaae = oldval;
3288 while (e1->op == TOKindex && ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray)
3290 Expression *ekey = interpret(((IndexExp *)e1)->e2, istate);
3291 if (exceptionOrCant(ekey))
3292 return;
3293 ekey = resolveSlice(ekey); // only happens with AA assignment
3294 Expressions *keysx = new Expressions();
3295 Expressions *valuesx = new Expressions();
3296 keysx->push(ekey);
3297 valuesx->push(newaae);
3298 AssocArrayLiteralExp *aae = new AssocArrayLiteralExp(e->loc, keysx, valuesx);
3299 aae->type = ((IndexExp *)e1)->e1->type;
3300 aae->ownedByCtfe = OWNEDctfe;
3301 if (!existingAA)
3303 existingAA = aae;
3304 lastIndex = ekey;
3306 newaae = aae;
3307 e1 = ((IndexExp *)e1)->e1;
3310 // We must set to aggregate with newaae
3311 e1 = interpret(e1, istate, ctfeNeedLvalue);
3312 if (exceptionOrCant(e1))
3313 return;
3314 e1 = assignToLvalue(e, e1, newaae);
3315 if (exceptionOrCant(e1))
3316 return;
3318 assert(existingAA && lastIndex);
3319 e1 = NULL; // stomp
3321 else if (e1->op == TOKarraylength)
3323 oldval = interpret(e1, istate);
3324 if (exceptionOrCant(oldval))
3325 return;
3327 else if (e->op == TOKconstruct || e->op == TOKblit)
3329 // Unless we have a simple var assignment, we're
3330 // only modifying part of the variable. So we need to make sure
3331 // that the parent variable exists.
3332 VarDeclaration *ultimateVar = findParentVar(e1);
3333 if (e1->op == TOKvar)
3335 VarDeclaration *v = ((VarExp *)e1)->var->isVarDeclaration();
3336 assert(v);
3337 if (v->storage_class & STCout)
3338 goto L1;
3340 else if (ultimateVar && !getValue(ultimateVar))
3342 Expression *ex = interpret(ultimateVar->type->defaultInitLiteral(e->loc), istate);
3343 if (exceptionOrCant(ex))
3344 return;
3345 setValue(ultimateVar, ex);
3347 else
3348 goto L1;
3350 else
3353 e1 = interpret(e1, istate, ctfeNeedLvalue);
3354 if (exceptionOrCant(e1))
3355 return;
3357 if (e1->op == TOKindex && ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray)
3359 IndexExp *ie = (IndexExp *)e1;
3360 assert(ie->e1->op == TOKassocarrayliteral);
3361 existingAA = (AssocArrayLiteralExp *)ie->e1;
3362 lastIndex = ie->e2;
3366 // ---------------------------------------
3367 // Interpret right hand side
3368 // ---------------------------------------
3369 Expression *newval = interpret(e->e2, istate);
3370 if (exceptionOrCant(newval))
3371 return;
3372 if (e->op == TOKblit && newval->op == TOKint64)
3374 Type *tbn = e->type->baseElemOf();
3375 if (tbn->ty == Tstruct)
3377 /* Look for special case of struct being initialized with 0.
3379 newval = e->type->defaultInitLiteral(e->loc);
3380 if (newval->op == TOKerror)
3382 result = CTFEExp::cantexp;
3383 return;
3385 newval = interpret(newval, istate); // copy and set ownedByCtfe flag
3386 if (exceptionOrCant(newval))
3387 return;
3391 // ----------------------------------------------------
3392 // Deal with read-modify-write assignments.
3393 // Set 'newval' to the final assignment value
3394 // Also determine the return value (except for slice
3395 // assignments, which are more complicated)
3396 // ----------------------------------------------------
3397 if (fp)
3399 if (!oldval)
3401 // Load the left hand side after interpreting the right hand side.
3402 oldval = interpret(e1, istate);
3403 if (exceptionOrCant(oldval))
3404 return;
3407 if (e->e1->type->ty != Tpointer)
3409 // ~= can create new values (see bug 6052)
3410 if (e->op == TOKcatass)
3412 // We need to dup it and repaint the type. For a dynamic array
3413 // we can skip duplication, because it gets copied later anyway.
3414 if (newval->type->ty != Tarray)
3416 newval = copyLiteral(newval).copy();
3417 newval->type = e->e2->type; // repaint type
3419 else
3421 newval = paintTypeOntoLiteral(e->e2->type, newval);
3422 newval = resolveSlice(newval);
3425 oldval = resolveSlice(oldval);
3427 newval = (*fp)(e->loc, e->type, oldval, newval).copy();
3429 else if (e->e2->type->isintegral() &&
3430 (e->op == TOKaddass ||
3431 e->op == TOKminass ||
3432 e->op == TOKplusplus ||
3433 e->op == TOKminusminus))
3435 newval = pointerArithmetic(e->loc, e->op, e->type, oldval, newval).copy();
3437 else
3439 e->error("pointer expression %s cannot be interpreted at compile time", e->toChars());
3440 result = CTFEExp::cantexp;
3441 return;
3443 if (exceptionOrCant(newval))
3445 if (CTFEExp::isCantExp(newval))
3446 e->error("cannot interpret %s at compile time", e->toChars());
3447 return;
3451 if (existingAA)
3453 if (existingAA->ownedByCtfe != OWNEDctfe)
3455 e->error("cannot modify read-only constant %s", existingAA->toChars());
3456 result = CTFEExp::cantexp;
3457 return;
3460 //printf("\t+L%d existingAA = %s, lastIndex = %s, oldval = %s, newval = %s\n",
3461 // __LINE__, existingAA->toChars(), lastIndex->toChars(), oldval ? oldval->toChars() : NULL, newval->toChars());
3462 assignAssocArrayElement(e->loc, existingAA, lastIndex, newval);
3464 // Determine the return value
3465 result = ctfeCast(e->loc, e->type, e->type, fp && post ? oldval : newval);
3466 return;
3468 if (e1->op == TOKarraylength)
3470 /* Change the assignment from:
3471 * arr.length = n;
3472 * into:
3473 * arr = new_length_array; (result is n)
3476 // Determine the return value
3477 result = ctfeCast(e->loc, e->type, e->type, fp && post ? oldval : newval);
3478 if (exceptionOrCant(result))
3479 return;
3481 size_t oldlen = (size_t)oldval->toInteger();
3482 size_t newlen = (size_t)newval->toInteger();
3483 if (oldlen == newlen) // no change required -- we're done!
3484 return;
3486 // We have changed it into a reference assignment
3487 // Note that returnValue is still the new length.
3488 e1 = ((ArrayLengthExp *)e1)->e1;
3489 Type *t = e1->type->toBasetype();
3490 if (t->ty != Tarray)
3492 e->error("%s is not yet supported at compile time", e->toChars());
3493 result = CTFEExp::cantexp;
3494 return;
3496 e1 = interpret(e1, istate, ctfeNeedLvalue);
3497 if (exceptionOrCant(e1))
3498 return;
3500 if (oldlen != 0) // Get the old array literal.
3501 oldval = interpret(e1, istate);
3502 newval = changeArrayLiteralLength(e->loc, (TypeArray *)t, oldval,
3503 oldlen, newlen).copy();
3505 e1 = assignToLvalue(e, e1, newval);
3506 if (exceptionOrCant(e1))
3507 return;
3509 return;
3512 if (!isBlockAssignment)
3514 newval = ctfeCast(e->loc, e->type, e->type, newval);
3515 if (exceptionOrCant(newval))
3516 return;
3518 // Determine the return value
3519 if (goal == ctfeNeedLvalue) // Bugzilla 14371
3520 result = e1;
3521 else
3522 result = ctfeCast(e->loc, e->type, e->type, fp && post ? oldval : newval);
3523 if (exceptionOrCant(result))
3524 return;
3526 if (exceptionOrCant(newval))
3527 return;
3529 /* Block assignment or element-wise assignment.
3531 if (e1->op == TOKslice ||
3532 e1->op == TOKvector ||
3533 e1->op == TOKarrayliteral ||
3534 e1->op == TOKstring ||
3535 (e1->op == TOKnull && e1->type->toBasetype()->ty == Tarray))
3537 // Note that slice assignments don't support things like ++, so
3538 // we don't need to remember 'returnValue'.
3539 result = interpretAssignToSlice(e, e1, newval, isBlockAssignment);
3540 if (exceptionOrCant(result))
3541 return;
3542 if (e->e1->op == TOKslice)
3544 Expression *e1x = interpret(((SliceExp*)e->e1)->e1, istate, ctfeNeedLvalue);
3545 if (e1x->op == TOKdotvar)
3547 DotVarExp *dve = (DotVarExp*)e1x;
3548 Expression *ex = dve->e1;
3549 StructLiteralExp *sle = ex->op == TOKstructliteral ? ((StructLiteralExp *)ex)
3550 : ex->op == TOKclassreference ? ((ClassReferenceExp *)ex)->value
3551 : NULL;
3552 VarDeclaration *v = dve->var->isVarDeclaration();
3553 if (!sle || !v)
3555 e->error("CTFE internal error: dotvar slice assignment");
3556 result = CTFEExp::cantexp;
3557 return;
3559 stompOverlappedFields(sle, v);
3562 return;
3565 assert(result);
3567 /* Assignment to a CTFE reference.
3569 if (Expression *ex = assignToLvalue(e, e1, newval))
3570 result = ex;
3572 return;
3575 /* Set all sibling fields which overlap with v to VoidExp.
3577 void stompOverlappedFields(StructLiteralExp *sle, VarDeclaration *v)
3579 if (!v->overlapped)
3580 return;
3582 for (size_t i = 0; i < sle->sd->fields.dim; i++)
3584 VarDeclaration *v2 = sle->sd->fields[i];
3585 if (v == v2 || !v->isOverlappedWith(v2))
3586 continue;
3587 Expression *e = (*sle->elements)[i];
3588 if (e->op != TOKvoid)
3589 (*sle->elements)[i] = voidInitLiteral(e->type, v).copy();
3593 Expression *assignToLvalue(BinExp *e, Expression *e1, Expression *newval)
3595 VarDeclaration *vd = NULL;
3596 Expression **payload = NULL; // dead-store to prevent spurious warning
3597 Expression *oldval;
3599 if (e1->op == TOKvar)
3601 vd = ((VarExp *)e1)->var->isVarDeclaration();
3602 oldval = getValue(vd);
3604 else if (e1->op == TOKdotvar)
3606 /* Assignment to member variable of the form:
3607 * e.v = newval
3609 Expression *ex = ((DotVarExp *)e1)->e1;
3610 StructLiteralExp *sle =
3611 ex->op == TOKstructliteral ? ((StructLiteralExp *)ex):
3612 ex->op == TOKclassreference ? ((ClassReferenceExp *)ex)->value
3613 : NULL;
3614 VarDeclaration *v = ((DotVarExp *)e1)->var->isVarDeclaration();
3615 if (!sle || !v)
3617 e->error("CTFE internal error: dotvar assignment");
3618 return CTFEExp::cantexp;
3620 if (sle->ownedByCtfe != OWNEDctfe)
3622 e->error("cannot modify read-only constant %s", sle->toChars());
3623 return CTFEExp::cantexp;
3626 int fieldi = ex->op == TOKstructliteral
3627 ? findFieldIndexByName(sle->sd, v)
3628 : ((ClassReferenceExp *)ex)->findFieldIndexByName(v);
3629 if (fieldi == -1)
3631 e->error("CTFE internal error: cannot find field %s in %s", v->toChars(), ex->toChars());
3632 return CTFEExp::cantexp;
3634 assert(0 <= fieldi && fieldi < (int)sle->elements->dim);
3636 // If it's a union, set all other members of this union to void
3637 stompOverlappedFields(sle, v);
3639 payload = &(*sle->elements)[fieldi];
3640 oldval = *payload;
3642 else if (e1->op == TOKindex)
3644 IndexExp *ie = (IndexExp *)e1;
3645 assert(ie->e1->type->toBasetype()->ty != Taarray);
3647 Expression *aggregate;
3648 uinteger_t indexToModify;
3649 if (!resolveIndexing(ie, istate, &aggregate, &indexToModify, true))
3651 return CTFEExp::cantexp;
3653 size_t index = (size_t)indexToModify;
3655 if (aggregate->op == TOKstring)
3657 StringExp *existingSE = (StringExp *)aggregate;
3658 if (existingSE->ownedByCtfe != OWNEDctfe)
3660 e->error("cannot modify read-only string literal %s", ie->e1->toChars());
3661 return CTFEExp::cantexp;
3663 void *s = existingSE->string;
3664 dinteger_t value = newval->toInteger();
3665 switch (existingSE->sz)
3667 case 1: (( utf8_t *)s)[index] = ( utf8_t)value; break;
3668 case 2: ((utf16_t *)s)[index] = (utf16_t)value; break;
3669 case 4: ((utf32_t *)s)[index] = (utf32_t)value; break;
3670 default: assert(0); break;
3672 return NULL;
3674 if (aggregate->op != TOKarrayliteral)
3676 e->error("index assignment %s is not yet supported in CTFE ", e->toChars());
3677 return CTFEExp::cantexp;
3680 ArrayLiteralExp *existingAE = (ArrayLiteralExp *)aggregate;
3681 if (existingAE->ownedByCtfe != OWNEDctfe)
3683 e->error("cannot modify read-only constant %s", existingAE->toChars());
3684 return CTFEExp::cantexp;
3687 payload = &(*existingAE->elements)[index];
3688 oldval = *payload;
3690 else
3692 e->error("%s cannot be evaluated at compile time", e->toChars());
3693 return CTFEExp::cantexp;
3696 Type *t1b = e1->type->toBasetype();
3697 bool wantCopy = t1b->baseElemOf()->ty == Tstruct;
3699 if (newval->op == TOKstructliteral && oldval)
3701 newval = copyLiteral(newval).copy();
3702 assignInPlace(oldval, newval);
3704 else if (wantCopy && e->op == TOKassign)
3706 // Currently postblit/destructor calls on static array are done
3707 // in the druntime internal functions so they don't appear in AST.
3708 // Therefore interpreter should handle them specially.
3710 assert(oldval);
3711 #if 1 // todo: instead we can directly access to each elements of the slice
3712 newval = resolveSlice(newval);
3713 if (CTFEExp::isCantExp(newval))
3715 e->error("CTFE internal error: assignment %s", e->toChars());
3716 return CTFEExp::cantexp;
3718 #endif
3719 assert(oldval->op == TOKarrayliteral);
3720 assert(newval->op == TOKarrayliteral);
3722 Expressions *oldelems = ((ArrayLiteralExp *)oldval)->elements;
3723 Expressions *newelems = ((ArrayLiteralExp *)newval)->elements;
3724 assert(oldelems->dim == newelems->dim);
3726 Type *elemtype = oldval->type->nextOf();
3727 for (size_t i = 0; i < newelems->dim; i++)
3729 Expression *oldelem = (*oldelems)[i];
3730 Expression *newelem = paintTypeOntoLiteral(elemtype, (*newelems)[i]);
3731 // Bugzilla 9245
3732 if (e->e2->isLvalue())
3734 if (Expression *ex = evaluatePostblit(istate, newelem))
3735 return ex;
3737 // Bugzilla 13661
3738 if (Expression *ex = evaluateDtor(istate, oldelem))
3739 return ex;
3740 (*oldelems)[i] = newelem;
3743 else
3745 // e1 has its own payload, so we have to create a new literal.
3746 if (wantCopy)
3747 newval = copyLiteral(newval).copy();
3749 if (t1b->ty == Tsarray && e->op == TOKconstruct && e->e2->isLvalue())
3751 // Bugzilla 9245
3752 if (Expression *ex = evaluatePostblit(istate, newval))
3753 return ex;
3756 oldval = newval;
3759 if (vd)
3760 setValue(vd, oldval);
3761 else
3762 *payload = oldval;
3764 // Blit assignment should return the newly created value.
3765 if (e->op == TOKblit)
3766 return oldval;
3768 return NULL;
3771 /*************
3772 * Deal with assignments of the form:
3773 * dest[] = newval
3774 * dest[low..upp] = newval
3775 * where newval has already been interpreted
3777 * This could be a slice assignment or a block assignment, and
3778 * dest could be either an array literal, or a string.
3780 * Returns TOKcantexp on failure. If there are no errors,
3781 * it returns aggregate[low..upp], except that as an optimisation,
3782 * if goal == ctfeNeedNothing, it will return NULL
3784 Expression *interpretAssignToSlice(BinExp *e,
3785 Expression *e1, Expression *newval, bool isBlockAssignment)
3787 dinteger_t lowerbound;
3788 dinteger_t upperbound;
3790 Expression *aggregate;
3791 dinteger_t firstIndex;
3793 if (e1->op == TOKvector)
3794 e1 = ((VectorExp *)e1)->e1;
3795 if (e1->op == TOKslice)
3797 // ------------------------------
3798 // aggregate[] = newval
3799 // aggregate[low..upp] = newval
3800 // ------------------------------
3802 SliceExp *se = (SliceExp *)e1;
3803 #if 1 // should be move in interpretAssignCommon as the evaluation of e1
3804 Expression *oldval = interpret(se->e1, istate);
3806 // Set the $ variable
3807 uinteger_t dollar = resolveArrayLength(oldval);
3808 if (se->lengthVar)
3810 Expression *dollarExp = new IntegerExp(e1->loc, dollar, Type::tsize_t);
3811 ctfeStack.push(se->lengthVar);
3812 setValue(se->lengthVar, dollarExp);
3814 Expression *lwr = interpret(se->lwr, istate);
3815 if (exceptionOrCantInterpret(lwr))
3817 if (se->lengthVar)
3818 ctfeStack.pop(se->lengthVar);
3819 return lwr;
3821 Expression *upr = interpret(se->upr, istate);
3822 if (exceptionOrCantInterpret(upr))
3824 if (se->lengthVar)
3825 ctfeStack.pop(se->lengthVar);
3826 return upr;
3828 if (se->lengthVar)
3829 ctfeStack.pop(se->lengthVar); // $ is defined only in [L..U]
3831 unsigned dim = (unsigned)dollar;
3832 lowerbound = (int)(lwr ? lwr->toInteger() : 0);
3833 upperbound = (size_t)(upr ? upr->toInteger() : dim);
3835 if ((int)lowerbound < 0 || dim < upperbound)
3837 e->error("array bounds [0..%d] exceeded in slice [%d..%d]",
3838 dim, lowerbound, upperbound);
3839 return CTFEExp::cantexp;
3841 #endif
3842 aggregate = oldval;
3843 firstIndex = lowerbound;
3845 if (aggregate->op == TOKslice)
3847 // Slice of a slice --> change the bounds
3848 SliceExp *oldse = (SliceExp *)aggregate;
3849 if (oldse->upr->toInteger() < upperbound + oldse->lwr->toInteger())
3851 e->error("slice [%d..%d] exceeds array bounds [0..%lld]",
3852 lowerbound, upperbound,
3853 oldse->upr->toInteger() - oldse->lwr->toInteger());
3854 return CTFEExp::cantexp;
3856 aggregate = oldse->e1;
3857 firstIndex = lowerbound + oldse->lwr->toInteger();
3860 else
3862 if (e1->op == TOKarrayliteral)
3864 lowerbound = 0;
3865 upperbound = ((ArrayLiteralExp *)e1)->elements->dim;
3867 else if (e1->op == TOKstring)
3869 lowerbound = 0;
3870 upperbound = ((StringExp *)e1)->len;
3872 else if (e1->op == TOKnull)
3874 lowerbound = 0;
3875 upperbound = 0;
3877 else
3878 assert(0);
3880 aggregate = e1;
3881 firstIndex = lowerbound;
3883 if (upperbound == lowerbound)
3884 return newval;
3886 // For slice assignment, we check that the lengths match.
3887 if (!isBlockAssignment)
3889 size_t srclen = (size_t)resolveArrayLength(newval);
3890 if (srclen != (upperbound - lowerbound))
3892 e->error("array length mismatch assigning [0..%d] to [%d..%d]",
3893 srclen, lowerbound, upperbound);
3894 return CTFEExp::cantexp;
3898 if (aggregate->op == TOKstring)
3900 StringExp *existingSE = (StringExp *)aggregate;
3901 if (existingSE->ownedByCtfe != OWNEDctfe)
3903 e->error("cannot modify read-only string literal %s", existingSE->toChars());
3904 return CTFEExp::cantexp;
3907 if (newval->op == TOKslice)
3909 SliceExp *se = (SliceExp *)newval;
3910 Expression *aggr2 = se->e1;
3911 const dinteger_t srclower = se->lwr->toInteger();
3912 const dinteger_t srcupper = se->upr->toInteger();
3914 if (aggregate == aggr2 &&
3915 lowerbound < srcupper && srclower < upperbound)
3917 e->error("overlapping slice assignment [%d..%d] = [%llu..%llu]",
3918 lowerbound, upperbound, srclower, srcupper);
3919 return CTFEExp::cantexp;
3921 #if 1 // todo: instead we can directly access to each elements of the slice
3922 Expression *orignewval = newval;
3923 newval = resolveSlice(newval);
3924 if (CTFEExp::isCantExp(newval))
3926 e->error("CTFE internal error: slice %s", orignewval->toChars());
3927 return CTFEExp::cantexp;
3929 #endif
3930 assert(newval->op != TOKslice);
3932 if (newval->op == TOKstring)
3934 sliceAssignStringFromString((StringExp *)existingSE, (StringExp *)newval, (size_t)firstIndex);
3935 return newval;
3937 if (newval->op == TOKarrayliteral)
3939 /* Mixed slice: it was initialized as a string literal.
3940 * Now a slice of it is being set with an array literal.
3942 sliceAssignStringFromArrayLiteral(existingSE, (ArrayLiteralExp *)newval, (size_t)firstIndex);
3943 return newval;
3946 // String literal block slice assign
3947 dinteger_t value = newval->toInteger();
3948 void *s = existingSE->string;
3949 for (size_t i = 0; i < upperbound - lowerbound; i++)
3951 switch (existingSE->sz)
3953 case 1: (( utf8_t *)s)[(size_t)(i + firstIndex)] = ( utf8_t)value; break;
3954 case 2: ((utf16_t *)s)[(size_t)(i + firstIndex)] = (utf16_t)value; break;
3955 case 4: ((utf32_t *)s)[(size_t)(i + firstIndex)] = (utf32_t)value; break;
3956 default: assert(0); break;
3959 if (goal == ctfeNeedNothing)
3960 return NULL; // avoid creating an unused literal
3961 SliceExp *retslice = new SliceExp(e->loc, existingSE,
3962 new IntegerExp(e->loc, firstIndex, Type::tsize_t),
3963 new IntegerExp(e->loc, firstIndex + upperbound - lowerbound, Type::tsize_t));
3964 retslice->type = e->type;
3965 return interpret(retslice, istate);
3967 if (aggregate->op == TOKarrayliteral)
3969 ArrayLiteralExp *existingAE = (ArrayLiteralExp *)aggregate;
3970 if (existingAE->ownedByCtfe != OWNEDctfe)
3972 e->error("cannot modify read-only constant %s", existingAE->toChars());
3973 return CTFEExp::cantexp;
3976 if (newval->op == TOKslice && !isBlockAssignment)
3978 SliceExp *se = (SliceExp *)newval;
3979 Expression *aggr2 = se->e1;
3980 const dinteger_t srclower = se->lwr->toInteger();
3981 const dinteger_t srcupper = se->upr->toInteger();
3982 const bool wantCopy = (newval->type->toBasetype()->nextOf()->baseElemOf()->ty == Tstruct);
3984 //printf("oldval = %p %s[%d..%u]\nnewval = %p %s[%llu..%llu] wantCopy = %d\n",
3985 // aggregate, aggregate->toChars(), lowerbound, upperbound,
3986 // aggr2, aggr2->toChars(), srclower, srcupper, wantCopy);
3987 if (wantCopy)
3989 // Currently overlapping for struct array is allowed.
3990 // The order of elements processing depends on the overlapping.
3991 // See bugzilla 14024.
3992 assert(aggr2->op == TOKarrayliteral);
3993 Expressions *oldelems = existingAE->elements;
3994 Expressions *newelems = ((ArrayLiteralExp *)aggr2)->elements;
3996 Type *elemtype = aggregate->type->nextOf();
3997 bool needsPostblit = e->e2->isLvalue();
3999 if (aggregate == aggr2 &&
4000 srclower < lowerbound && lowerbound < srcupper)
4002 // reverse order
4003 for (size_t i = upperbound - lowerbound; 0 < i--; )
4005 Expression *oldelem = (*oldelems)[(size_t)(i + firstIndex)];
4006 Expression *newelem = (*newelems)[(size_t)(i + srclower)];
4007 newelem = copyLiteral(newelem).copy();
4008 newelem->type = elemtype;
4009 if (needsPostblit)
4011 if (Expression *x = evaluatePostblit(istate, newelem))
4012 return x;
4014 if (Expression *x = evaluateDtor(istate, oldelem))
4015 return x;
4016 (*oldelems)[lowerbound + i] = newelem;
4019 else
4021 // normal order
4022 for (size_t i = 0; i < upperbound - lowerbound; i++)
4024 Expression *oldelem = (*oldelems)[(size_t)(i + firstIndex)];
4025 Expression *newelem = (*newelems)[(size_t)(i + srclower)];
4026 newelem = copyLiteral(newelem).copy();
4027 newelem->type = elemtype;
4028 if (needsPostblit)
4030 if (Expression *x = evaluatePostblit(istate, newelem))
4031 return x;
4033 if (Expression *x = evaluateDtor(istate, oldelem))
4034 return x;
4035 (*oldelems)[lowerbound + i] = newelem;
4039 //assert(0);
4040 return newval; // oldval?
4042 if (aggregate == aggr2 &&
4043 lowerbound < srcupper && srclower < upperbound)
4045 e->error("overlapping slice assignment [%d..%d] = [%llu..%llu]",
4046 lowerbound, upperbound, srclower, srcupper);
4047 return CTFEExp::cantexp;
4049 #if 1 // todo: instead we can directly access to each elements of the slice
4050 Expression *orignewval = newval;
4051 newval = resolveSlice(newval);
4052 if (CTFEExp::isCantExp(newval))
4054 e->error("CTFE internal error: slice %s", orignewval->toChars());
4055 return CTFEExp::cantexp;
4057 #endif
4058 // no overlapping
4059 //length?
4060 assert(newval->op != TOKslice);
4062 if (newval->op == TOKstring && !isBlockAssignment)
4064 /* Mixed slice: it was initialized as an array literal of chars/integers.
4065 * Now a slice of it is being set with a string.
4067 sliceAssignArrayLiteralFromString(existingAE, (StringExp *)newval, (size_t)firstIndex);
4068 return newval;
4070 if (newval->op == TOKarrayliteral && !isBlockAssignment)
4072 Expressions *oldelems = existingAE->elements;
4073 Expressions *newelems = ((ArrayLiteralExp *)newval)->elements;
4074 Type *elemtype = existingAE->type->nextOf();
4075 bool needsPostblit = e->op != TOKblit && e->e2->isLvalue();
4076 for (size_t j = 0; j < newelems->dim; j++)
4078 Expression *newelem = (*newelems)[j];
4079 newelem = paintTypeOntoLiteral(elemtype, newelem);
4080 if (needsPostblit)
4082 Expression *x = evaluatePostblit(istate, newelem);
4083 if (exceptionOrCantInterpret(x))
4084 return x;
4086 (*oldelems)[(size_t)(j + firstIndex)] = newelem;
4088 return newval;
4091 /* Block assignment, initialization of static arrays
4092 * x[] = newval
4093 * x may be a multidimensional static array. (Note that this
4094 * only happens with array literals, never with strings).
4096 struct RecursiveBlock
4098 InterState *istate;
4099 Expression *newval;
4100 bool refCopy;
4101 bool needsPostblit;
4102 bool needsDtor;
4104 Expression *assignTo(ArrayLiteralExp *ae)
4106 return assignTo(ae, 0, ae->elements->dim);
4109 Expression *assignTo(ArrayLiteralExp *ae, size_t lwr, size_t upr)
4111 Expressions *w = ae->elements;
4113 assert(ae->type->ty == Tsarray ||
4114 ae->type->ty == Tarray);
4115 bool directblk = ((TypeArray *)ae->type)->next->equivalent(newval->type);
4117 for (size_t k = lwr; k < upr; k++)
4119 if (!directblk && (*w)[k]->op == TOKarrayliteral)
4121 // Multidimensional array block assign
4122 if (Expression *ex = assignTo((ArrayLiteralExp *)(*w)[k]))
4123 return ex;
4125 else if (refCopy)
4127 (*w)[k] = newval;
4129 else if (!needsPostblit && !needsDtor)
4131 assignInPlace((*w)[k], newval);
4133 else
4135 Expression *oldelem = (*w)[k];
4136 Expression *tmpelem = needsDtor ? copyLiteral(oldelem).copy() : NULL;
4138 assignInPlace(oldelem, newval);
4140 if (needsPostblit)
4142 if (Expression *ex = evaluatePostblit(istate, oldelem))
4143 return ex;
4145 if (needsDtor)
4147 // Bugzilla 14860
4148 if (Expression *ex = evaluateDtor(istate, tmpelem))
4149 return ex;
4153 return NULL;
4157 Type *tn = newval->type->toBasetype();
4158 bool wantRef = (tn->ty == Tarray || isAssocArray(tn) ||tn->ty == Tclass);
4159 bool cow = newval->op != TOKstructliteral &&
4160 newval->op != TOKarrayliteral &&
4161 newval->op != TOKstring;
4162 Type *tb = tn->baseElemOf();
4163 StructDeclaration *sd = (tb->ty == Tstruct ? ((TypeStruct *)tb)->sym : NULL);
4165 RecursiveBlock rb;
4166 rb.istate = istate;
4167 rb.newval = newval;
4168 rb.refCopy = wantRef || cow;
4169 rb.needsPostblit = sd && sd->postblit && e->op != TOKblit && e->e2->isLvalue();
4170 rb.needsDtor = sd && sd->dtor && e->op == TOKassign;
4172 if (Expression *ex = rb.assignTo(existingAE, lowerbound, upperbound))
4173 return ex;
4175 if (goal == ctfeNeedNothing)
4176 return NULL; // avoid creating an unused literal
4177 SliceExp *retslice = new SliceExp(e->loc, existingAE,
4178 new IntegerExp(e->loc, firstIndex, Type::tsize_t),
4179 new IntegerExp(e->loc, firstIndex + upperbound - lowerbound, Type::tsize_t));
4180 retslice->type = e->type;
4181 return interpret(retslice, istate);
4184 e->error("slice operation %s = %s cannot be evaluated at compile time",
4185 e1->toChars(), newval->toChars());
4186 return CTFEExp::cantexp;
4189 void visit(AssignExp *e)
4191 interpretAssignCommon(e, NULL);
4194 void visit(BinAssignExp *e)
4196 switch (e->op)
4198 case TOKaddass: interpretAssignCommon(e, &Add); return;
4199 case TOKminass: interpretAssignCommon(e, &Min); return;
4200 case TOKcatass: interpretAssignCommon(e, &ctfeCat); return;
4201 case TOKmulass: interpretAssignCommon(e, &Mul); return;
4202 case TOKdivass: interpretAssignCommon(e, &Div); return;
4203 case TOKmodass: interpretAssignCommon(e, &Mod); return;
4204 case TOKshlass: interpretAssignCommon(e, &Shl); return;
4205 case TOKshrass: interpretAssignCommon(e, &Shr); return;
4206 case TOKushrass: interpretAssignCommon(e, &Ushr); return;
4207 case TOKandass: interpretAssignCommon(e, &And); return;
4208 case TOKorass: interpretAssignCommon(e, &Or); return;
4209 case TOKxorass: interpretAssignCommon(e, &Xor); return;
4210 case TOKpowass: interpretAssignCommon(e, &Pow); return;
4211 default:
4212 assert(0);
4213 return;
4217 void visit(PostExp *e)
4219 if (e->op == TOKplusplus)
4220 interpretAssignCommon(e, &Add, 1);
4221 else
4222 interpretAssignCommon(e, &Min, 1);
4225 /* Return 1 if e is a p1 > p2 or p1 >= p2 pointer comparison;
4226 * -1 if e is a p1 < p2 or p1 <= p2 pointer comparison;
4227 * 0 otherwise
4229 static int isPointerCmpExp(Expression *e, Expression **p1, Expression **p2)
4231 int ret = 1;
4232 while (e->op == TOKnot)
4234 ret *= -1;
4235 e = ((NotExp *)e)->e1;
4237 switch (e->op)
4239 case TOKlt:
4240 case TOKle:
4241 ret *= -1;
4242 /* fall through */
4243 case TOKgt:
4244 case TOKge:
4245 *p1 = ((BinExp *)e)->e1;
4246 *p2 = ((BinExp *)e)->e2;
4247 if (!(isPointer((*p1)->type) && isPointer((*p2)->type)))
4248 ret = 0;
4249 break;
4250 default:
4251 ret = 0;
4252 break;
4254 return ret;
4257 /** Negate a relational operator, eg >= becomes <
4259 static TOK reverseRelation(TOK op)
4261 switch (op)
4263 case TOKge: return TOKlt;
4264 case TOKgt: return TOKle;
4265 case TOKle: return TOKgt;
4266 case TOKlt: return TOKge;
4267 default:
4268 return assert(0), TOKreserved;
4272 /** If this is a four pointer relation, evaluate it, else return NULL.
4274 * This is an expression of the form (p1 > q1 && p2 < q2) or (p1 < q1 || p2 > q2)
4275 * where p1, p2 are expressions yielding pointers to memory block p,
4276 * and q1, q2 are expressions yielding pointers to memory block q.
4277 * This expression is valid even if p and q are independent memory
4278 * blocks and are therefore not normally comparable; the && form returns true
4279 * if [p1..p2] lies inside [q1..q2], and false otherwise; the || form returns
4280 * true if [p1..p2] lies outside [q1..q2], and false otherwise.
4282 * Within the expression, any ordering of p1, p2, q1, q2 is permissible;
4283 * the comparison operators can be any of >, <, <=, >=, provided that
4284 * both directions (p > q and p < q) are checked. Additionally the
4285 * relational sub-expressions can be negated, eg
4286 * (!(q1 < p1) && p2 <= q2) is valid.
4288 void interpretFourPointerRelation(BinExp *e)
4290 assert(e->op == TOKandand || e->op == TOKoror);
4292 /* It can only be an isInside expression, if both e1 and e2 are
4293 * directional pointer comparisons.
4294 * Note that this check can be made statically; it does not depends on
4295 * any runtime values. This allows a JIT implementation to compile a
4296 * special AndAndPossiblyInside, keeping the normal AndAnd case efficient.
4299 // Save the pointer expressions and the comparison directions,
4300 // so we can use them later.
4301 Expression *p1 = NULL;
4302 Expression *p2 = NULL;
4303 Expression *p3 = NULL;
4304 Expression *p4 = NULL;
4305 int dir1 = isPointerCmpExp(e->e1, &p1, &p2);
4306 int dir2 = isPointerCmpExp(e->e2, &p3, &p4);
4307 if (dir1 == 0 || dir2 == 0)
4309 result = NULL;
4310 return;
4313 //printf("FourPointerRelation %s\n", toChars());
4315 // Evaluate the first two pointers
4316 p1 = interpret(p1, istate);
4317 if (exceptionOrCant(p1))
4318 return;
4319 p2 = interpret(p2, istate);
4320 if (exceptionOrCant(p2))
4321 return;
4322 dinteger_t ofs1, ofs2;
4323 Expression *agg1 = getAggregateFromPointer(p1, &ofs1);
4324 Expression *agg2 = getAggregateFromPointer(p2, &ofs2);
4326 if (!pointToSameMemoryBlock(agg1, agg2) &&
4327 agg1->op != TOKnull &&
4328 agg2->op != TOKnull)
4330 // Here it is either CANT_INTERPRET,
4331 // or an IsInside comparison returning false.
4332 p3 = interpret(p3, istate);
4333 if (CTFEExp::isCantExp(p3))
4334 return;
4335 // Note that it is NOT legal for it to throw an exception!
4336 Expression *except = NULL;
4337 if (exceptionOrCantInterpret(p3))
4338 except = p3;
4339 else
4341 p4 = interpret(p4, istate);
4342 if (CTFEExp::isCantExp(p4))
4344 result = p4;
4345 return;
4347 if (exceptionOrCantInterpret(p4))
4348 except = p4;
4350 if (except)
4352 e->error("comparison %s of pointers to unrelated memory blocks remains "
4353 "indeterminate at compile time "
4354 "because exception %s was thrown while evaluating %s",
4355 e->e1->toChars(), except->toChars(), e->e2->toChars());
4356 result = CTFEExp::cantexp;
4357 return;
4359 dinteger_t ofs3, ofs4;
4360 Expression *agg3 = getAggregateFromPointer(p3, &ofs3);
4361 Expression *agg4 = getAggregateFromPointer(p4, &ofs4);
4362 // The valid cases are:
4363 // p1 > p2 && p3 > p4 (same direction, also for < && <)
4364 // p1 > p2 && p3 < p4 (different direction, also < && >)
4365 // Changing any > into >= doesnt affect the result
4366 if ((dir1 == dir2 && pointToSameMemoryBlock(agg1, agg4) && pointToSameMemoryBlock(agg2, agg3)) ||
4367 (dir1 != dir2 && pointToSameMemoryBlock(agg1, agg3) && pointToSameMemoryBlock(agg2, agg4)))
4369 // it's a legal two-sided comparison
4370 result = new IntegerExp(e->loc, (e->op == TOKandand) ? 0 : 1, e->type);
4371 return;
4373 // It's an invalid four-pointer comparison. Either the second
4374 // comparison is in the same direction as the first, or else
4375 // more than two memory blocks are involved (either two independent
4376 // invalid comparisons are present, or else agg3 == agg4).
4377 e->error("comparison %s of pointers to unrelated memory blocks is "
4378 "indeterminate at compile time, even when combined with %s.",
4379 e->e1->toChars(), e->e2->toChars());
4380 result = CTFEExp::cantexp;
4381 return;
4383 // The first pointer expression didn't need special treatment, so we
4384 // we need to interpret the entire expression exactly as a normal && or ||.
4385 // This is easy because we haven't evaluated e2 at all yet, and we already
4386 // know it will return a bool.
4387 // But we mustn't evaluate the pointer expressions in e1 again, in case
4388 // they have side-effects.
4389 bool nott = false;
4390 Expression *ex = e->e1;
4391 while (ex->op == TOKnot)
4393 nott = !nott;
4394 ex = ((NotExp *)ex)->e1;
4396 TOK cmpop = ex->op;
4397 if (nott)
4398 cmpop = reverseRelation(cmpop);
4399 int cmp = comparePointers(cmpop, agg1, ofs1, agg2, ofs2);
4400 // We already know this is a valid comparison.
4401 assert(cmp >= 0);
4402 if ((e->op == TOKandand && cmp == 1) ||
4403 (e->op == TOKoror && cmp == 0))
4405 result = interpret(e->e2, istate);
4406 return;
4408 result = new IntegerExp(e->loc, (e->op == TOKandand) ? 0 : 1, e->type);
4411 void visit(AndAndExp *e)
4413 // Check for an insidePointer expression, evaluate it if so
4414 interpretFourPointerRelation(e);
4415 if (result)
4416 return;
4418 result = interpret(e->e1, istate);
4419 if (exceptionOrCant(result))
4420 return;
4422 int res;
4423 if (result->isBool(false))
4424 res = 0;
4425 else if (isTrueBool(result))
4427 UnionExp ue2;
4428 result = interpret(&ue2, e->e2, istate);
4429 if (exceptionOrCant(result))
4430 return;
4431 if (result->op == TOKvoidexp)
4433 assert(e->type->ty == Tvoid);
4434 result = NULL;
4435 return;
4437 if (result->isBool(false))
4438 res = 0;
4439 else if (isTrueBool(result))
4440 res = 1;
4441 else
4443 result->error("%s does not evaluate to a boolean", result->toChars());
4444 result = CTFEExp::cantexp;
4445 return;
4448 else
4450 result->error("%s cannot be interpreted as a boolean", result->toChars());
4451 result = CTFEExp::cantexp;
4452 return;
4454 if (goal != ctfeNeedNothing)
4456 new(pue) IntegerExp(e->loc, res, e->type);
4457 result = pue->exp();
4461 void visit(OrOrExp *e)
4463 // Check for an insidePointer expression, evaluate it if so
4464 interpretFourPointerRelation(e);
4465 if (result)
4466 return;
4468 result = interpret(e->e1, istate);
4469 if (exceptionOrCant(result))
4470 return;
4472 int res;
4473 if (isTrueBool(result))
4474 res = 1;
4475 else if (result->isBool(false))
4477 UnionExp ue2;
4478 result = interpret(&ue2, e->e2, istate);
4479 if (exceptionOrCant(result))
4480 return;
4481 if (result->op == TOKvoidexp)
4483 assert(e->type->ty == Tvoid);
4484 result = NULL;
4485 return;
4487 if (result->isBool(false))
4488 res = 0;
4489 else if (isTrueBool(result))
4490 res = 1;
4491 else
4493 result->error("%s cannot be interpreted as a boolean", result->toChars());
4494 result = CTFEExp::cantexp;
4495 return;
4498 else
4500 result->error("%s cannot be interpreted as a boolean", result->toChars());
4501 result = CTFEExp::cantexp;
4502 return;
4504 if (goal != ctfeNeedNothing)
4506 new(pue) IntegerExp(e->loc, res, e->type);
4507 result = pue->exp();
4511 // Print a stack trace, starting from callingExp which called fd.
4512 // To shorten the stack trace, try to detect recursion.
4513 void showCtfeBackTrace(CallExp * callingExp, FuncDeclaration *fd)
4515 if (CtfeStatus::stackTraceCallsToSuppress > 0)
4517 --CtfeStatus::stackTraceCallsToSuppress;
4518 return;
4520 errorSupplemental(callingExp->loc, "called from here: %s", callingExp->toChars());
4521 // Quit if it's not worth trying to compress the stack trace
4522 if (CtfeStatus::callDepth < 6 || global.params.verbose)
4523 return;
4524 // Recursion happens if the current function already exists in the call stack.
4525 int numToSuppress = 0;
4526 int recurseCount = 0;
4527 int depthSoFar = 0;
4528 InterState *lastRecurse = istate;
4529 for (InterState * cur = istate; cur; cur = cur->caller)
4531 if (cur->fd == fd)
4533 ++recurseCount;
4534 numToSuppress = depthSoFar;
4535 lastRecurse = cur;
4537 ++depthSoFar;
4539 // We need at least three calls to the same function, to make compression worthwhile
4540 if (recurseCount < 2)
4541 return;
4542 // We found a useful recursion. Print all the calls involved in the recursion
4543 errorSupplemental(fd->loc, "%d recursive calls to function %s", recurseCount, fd->toChars());
4544 for (InterState *cur = istate; cur->fd != fd; cur = cur->caller)
4546 errorSupplemental(cur->fd->loc, "recursively called from function %s", cur->fd->toChars());
4548 // We probably didn't enter the recursion in this function.
4549 // Go deeper to find the real beginning.
4550 InterState * cur = istate;
4551 while (lastRecurse->caller && cur->fd == lastRecurse->caller->fd)
4553 cur = cur->caller;
4554 lastRecurse = lastRecurse->caller;
4555 ++numToSuppress;
4557 CtfeStatus::stackTraceCallsToSuppress = numToSuppress;
4560 void visit(CallExp *e)
4562 Expression *pthis = NULL;
4563 FuncDeclaration *fd = NULL;
4565 Expression *ecall = interpret(e->e1, istate);
4566 if (exceptionOrCant(ecall))
4567 return;
4569 if (ecall->op == TOKdotvar)
4571 DotVarExp *dve = (DotVarExp *)ecall;
4573 // Calling a member function
4574 pthis = dve->e1;
4575 fd = dve->var->isFuncDeclaration();
4576 assert(fd);
4578 if (pthis->op == TOKdottype)
4579 pthis = ((DotTypeExp *)dve->e1)->e1;
4581 else if (ecall->op == TOKvar)
4583 fd = ((VarExp *)ecall)->var->isFuncDeclaration();
4584 assert(fd);
4586 if (fd->ident == Id::_ArrayPostblit ||
4587 fd->ident == Id::_ArrayDtor)
4589 assert(e->arguments->dim == 1);
4590 Expression *ea = (*e->arguments)[0];
4591 //printf("1 ea = %s %s\n", ea->type->toChars(), ea->toChars());
4592 if (ea->op == TOKslice)
4593 ea = ((SliceExp *)ea)->e1;
4594 if (ea->op == TOKcast)
4595 ea = ((CastExp *)ea)->e1;
4597 //printf("2 ea = %s, %s %s\n", ea->type->toChars(), Token::toChars(ea->op), ea->toChars());
4598 if (ea->op == TOKvar || ea->op == TOKsymoff)
4599 result = getVarExp(e->loc, istate, ((SymbolExp *)ea)->var, ctfeNeedRvalue);
4600 else if (ea->op == TOKaddress)
4601 result = interpret(((AddrExp *)ea)->e1, istate);
4602 else
4603 assert(0);
4604 if (CTFEExp::isCantExp(result))
4605 return;
4607 if (fd->ident == Id::_ArrayPostblit)
4608 result = evaluatePostblit(istate, result);
4609 else
4610 result = evaluateDtor(istate, result);
4611 if (!result)
4612 result = CTFEExp::voidexp;
4613 return;
4616 else if (ecall->op == TOKsymoff)
4618 SymOffExp *soe = (SymOffExp *)ecall;
4619 fd = soe->var->isFuncDeclaration();
4620 assert(fd && soe->offset == 0);
4622 else if (ecall->op == TOKdelegate)
4624 // Calling a delegate
4625 fd = ((DelegateExp *)ecall)->func;
4626 pthis = ((DelegateExp *)ecall)->e1;
4628 // Special handling for: &nestedfunc --> DelegateExp(VarExp(nestedfunc), nestedfunc)
4629 if (pthis->op == TOKvar && ((VarExp *)pthis)->var == fd)
4630 pthis = NULL; // context is not necessary for CTFE
4632 else if (ecall->op == TOKfunction)
4634 // Calling a delegate literal
4635 fd = ((FuncExp *)ecall)->fd;
4637 else
4639 // delegate.funcptr()
4640 // others
4641 e->error("cannot call %s at compile time", e->toChars());
4642 result = CTFEExp::cantexp;
4643 return;
4646 if (!fd)
4648 e->error("CTFE internal error: cannot evaluate %s at compile time", e->toChars());
4649 result = CTFEExp::cantexp;
4650 return;
4652 if (pthis)
4654 // Member function call
4656 // Currently this is satisfied because closure is not yet supported.
4657 assert(!fd->isNested());
4659 if (pthis->op == TOKtypeid)
4661 pthis->error("static variable %s cannot be read at compile time", pthis->toChars());
4662 result = CTFEExp::cantexp;
4663 return;
4665 assert(pthis);
4667 if (pthis->op == TOKnull)
4669 assert(pthis->type->toBasetype()->ty == Tclass);
4670 e->error("function call through null class reference %s", pthis->toChars());
4671 result = CTFEExp::cantexp;
4672 return;
4674 assert(pthis->op == TOKstructliteral || pthis->op == TOKclassreference);
4676 if (fd->isVirtual() && !e->directcall)
4678 // Make a virtual function call.
4679 // Get the function from the vtable of the original class
4680 assert(pthis->op == TOKclassreference);
4681 ClassDeclaration *cd = ((ClassReferenceExp *)pthis)->originalClass();
4683 // We can't just use the vtable index to look it up, because
4684 // vtables for interfaces don't get populated until the glue layer.
4685 fd = cd->findFunc(fd->ident, (TypeFunction *)fd->type);
4686 assert(fd);
4690 if (fd && fd->semanticRun >= PASSsemantic3done && fd->semantic3Errors)
4692 e->error("CTFE failed because of previous errors in %s", fd->toChars());
4693 result = CTFEExp::cantexp;
4694 return;
4697 // Check for built-in functions
4698 result = evaluateIfBuiltin(istate, e->loc, fd, e->arguments, pthis);
4699 if (result)
4700 return;
4702 if (!fd->fbody)
4704 e->error("%s cannot be interpreted at compile time,"
4705 " because it has no available source code", fd->toChars());
4706 result = CTFEExp::cantexp;
4707 return;
4710 result = interpretFunction(fd, istate, e->arguments, pthis);
4711 if (result->op == TOKvoidexp)
4712 return;
4713 if (!exceptionOrCantInterpret(result))
4715 if (goal != ctfeNeedLvalue) // Peel off CTFE reference if it's unnesessary
4716 result = interpret(result, istate);
4718 if (!exceptionOrCantInterpret(result))
4720 result = paintTypeOntoLiteral(e->type, result);
4721 result->loc = e->loc;
4723 else if (CTFEExp::isCantExp(result) && !global.gag)
4724 showCtfeBackTrace(e, fd); // Print a stack trace.
4727 void endTempStackFrame(InterState *pistateComma)
4729 // If we created a temporary stack frame, end it now.
4730 if (istate == pistateComma)
4731 ctfeStack.endFrame();
4734 void visit(CommaExp *e)
4736 CommaExp *firstComma = e;
4737 while (firstComma->e1->op == TOKcomma)
4738 firstComma = (CommaExp *)firstComma->e1;
4740 // If it creates a variable, and there's no context for
4741 // the variable to be created in, we need to create one now.
4742 InterState istateComma;
4743 if (!istate && firstComma->e1->op == TOKdeclaration)
4745 ctfeStack.startFrame(NULL);
4746 istate = &istateComma;
4749 result = CTFEExp::cantexp;
4751 // If the comma returns a temporary variable, it needs to be an lvalue
4752 // (this is particularly important for struct constructors)
4753 if (e->e1->op == TOKdeclaration && e->e2->op == TOKvar &&
4754 ((DeclarationExp *)e->e1)->declaration == ((VarExp*)e->e2)->var &&
4755 ((VarExp*)e->e2)->var->storage_class & STCctfe) // same as Expression::isTemp
4757 VarExp *ve = (VarExp *)e->e2;
4758 VarDeclaration *v = ve->var->isVarDeclaration();
4759 ctfeStack.push(v);
4760 if (!v->_init && !getValue(v))
4762 setValue(v, copyLiteral(v->type->defaultInitLiteral(e->loc)).copy());
4764 if (!getValue(v))
4766 Expression *newval = initializerToExpression(v->_init);
4767 // Bug 4027. Copy constructors are a weird case where the
4768 // initializer is a void function (the variable is modified
4769 // through a reference parameter instead).
4770 newval = interpret(newval, istate);
4771 if (exceptionOrCant(newval))
4772 return endTempStackFrame(&istateComma);
4773 if (newval->op != TOKvoidexp)
4775 // v isn't necessarily null.
4776 setValueWithoutChecking(v, copyLiteral(newval).copy());
4780 else
4782 UnionExp ue;
4783 Expression *e1 = interpret(&ue, e->e1, istate, ctfeNeedNothing);
4784 if (exceptionOrCant(e1))
4785 return endTempStackFrame(&istateComma);
4787 result = interpret(pue, e->e2, istate, goal);
4788 return endTempStackFrame(&istateComma);
4791 void visit(CondExp *e)
4793 UnionExp uecond;
4794 Expression *econd;
4795 econd = interpret(&uecond, e->econd, istate);
4796 if (exceptionOrCant(econd))
4797 return;
4799 if (isPointer(e->econd->type))
4801 if (econd->op != TOKnull)
4803 new(&uecond) IntegerExp(e->loc, 1, Type::tbool);
4804 econd = uecond.exp();
4808 if (isTrueBool(econd))
4809 result = interpret(pue, e->e1, istate, goal);
4810 else if (econd->isBool(false))
4811 result = interpret(pue, e->e2, istate, goal);
4812 else
4814 e->error("%s does not evaluate to boolean result at compile time", e->econd->toChars());
4815 result = CTFEExp::cantexp;
4819 void visit(ArrayLengthExp *e)
4821 UnionExp ue1;
4822 Expression *e1 = interpret(&ue1, e->e1, istate);
4823 assert(e1);
4824 if (exceptionOrCant(e1))
4825 return;
4826 if (e1->op != TOKstring &&
4827 e1->op != TOKarrayliteral &&
4828 e1->op != TOKslice &&
4829 e1->op != TOKnull)
4831 e->error("%s cannot be evaluated at compile time", e->toChars());
4832 result = CTFEExp::cantexp;
4833 return;
4835 new(pue) IntegerExp(e->loc, resolveArrayLength(e1), e->type);
4836 result = pue->exp();
4839 void visit(DelegatePtrExp *e)
4841 Expression *e1 = interpret(pue, e->e1, istate);
4842 assert(e1);
4843 if (exceptionOrCant(e1))
4844 return;
4845 e->error("%s cannot be evaluated at compile time", e->toChars());
4846 result = CTFEExp::cantexp;
4849 void visit(DelegateFuncptrExp *e)
4851 Expression *e1 = interpret(pue, e->e1, istate);
4852 assert(e1);
4853 if (exceptionOrCant(e1))
4854 return;
4855 e->error("%s cannot be evaluated at compile time", e->toChars());
4856 result = CTFEExp::cantexp;
4859 static bool resolveIndexing(IndexExp *e, InterState *istate, Expression **pagg, uinteger_t *pidx, bool modify)
4861 assert(e->e1->type->toBasetype()->ty != Taarray);
4863 if (e->e1->type->toBasetype()->ty == Tpointer)
4865 // Indexing a pointer. Note that there is no $ in this case.
4866 Expression *e1 = interpret(e->e1, istate);
4867 if (exceptionOrCantInterpret(e1))
4868 return false;
4870 Expression *e2 = interpret(e->e2, istate);
4871 if (exceptionOrCantInterpret(e2))
4872 return false;
4873 sinteger_t indx = e2->toInteger();
4875 dinteger_t ofs;
4876 Expression *agg = getAggregateFromPointer(e1, &ofs);
4878 if (agg->op == TOKnull)
4880 e->error("cannot index through null pointer %s", e->e1->toChars());
4881 return false;
4883 if (agg->op == TOKint64)
4885 e->error("cannot index through invalid pointer %s of value %s",
4886 e->e1->toChars(), e1->toChars());
4887 return false;
4889 // Pointer to a non-array variable
4890 if (agg->op == TOKsymoff)
4892 e->error("mutable variable %s cannot be %s at compile time, even through a pointer",
4893 (modify ? "modified" : "read"), ((SymOffExp *)agg)->var->toChars());
4894 return false;
4897 if (agg->op == TOKarrayliteral || agg->op == TOKstring)
4899 dinteger_t len = resolveArrayLength(agg);
4900 if (ofs + indx >= len)
4902 e->error("pointer index [%lld] exceeds allocated memory block [0..%lld]",
4903 ofs + indx, len);
4904 return false;
4907 else
4909 if (ofs + indx != 0)
4911 e->error("pointer index [%lld] lies outside memory block [0..1]",
4912 ofs + indx);
4913 return false;
4916 *pagg = agg;
4917 *pidx = ofs + indx;
4918 return true;
4921 Expression *e1 = interpret(e->e1, istate);
4922 if (exceptionOrCantInterpret(e1))
4923 return false;
4924 if (e1->op == TOKnull)
4926 e->error("cannot index null array %s", e->e1->toChars());
4927 return false;
4929 if (e1->op == TOKvector)
4930 e1 = ((VectorExp *)e1)->e1;
4932 // Set the $ variable, and find the array literal to modify
4933 if (e1->op != TOKarrayliteral &&
4934 e1->op != TOKstring &&
4935 e1->op != TOKslice)
4937 e->error("cannot determine length of %s at compile time",
4938 e->e1->toChars());
4939 return false;
4942 dinteger_t len = resolveArrayLength(e1);
4943 if (e->lengthVar)
4945 Expression *dollarExp = new IntegerExp(e->loc, len, Type::tsize_t);
4946 ctfeStack.push(e->lengthVar);
4947 setValue(e->lengthVar, dollarExp);
4949 Expression *e2 = interpret(e->e2, istate);
4950 if (e->lengthVar)
4951 ctfeStack.pop(e->lengthVar); // $ is defined only inside []
4952 if (exceptionOrCantInterpret(e2))
4953 return false;
4954 if (e2->op != TOKint64)
4956 e->error("CTFE internal error: non-integral index [%s]", e->e2->toChars());
4957 return false;
4960 if (e1->op == TOKslice)
4962 // Simplify index of slice: agg[lwr..upr][indx] --> agg[indx']
4963 uinteger_t index = e2->toInteger();
4964 uinteger_t ilwr = ((SliceExp *)e1)->lwr->toInteger();
4965 uinteger_t iupr = ((SliceExp *)e1)->upr->toInteger();
4967 if (index > iupr - ilwr)
4969 e->error("index %llu exceeds array length %llu", index, iupr - ilwr);
4970 return false;
4972 *pagg = ((SliceExp *)e1)->e1;
4973 *pidx = index + ilwr;
4975 else
4977 *pagg = e1;
4978 *pidx = e2->toInteger();
4979 if (len <= *pidx)
4981 e->error("array index %lld is out of bounds [0..%lld]",
4982 *pidx, len);
4983 return false;
4986 return true;
4989 void visit(IndexExp *e)
4991 if (e->e1->type->toBasetype()->ty == Tpointer)
4993 Expression *agg;
4994 uinteger_t indexToAccess;
4995 if (!resolveIndexing(e, istate, &agg, &indexToAccess, false))
4997 result = CTFEExp::cantexp;
4998 return;
5000 if (agg->op == TOKarrayliteral || agg->op == TOKstring)
5002 if (goal == ctfeNeedLvalue)
5004 // if we need a reference, IndexExp shouldn't be interpreting
5005 // the expression to a value, it should stay as a reference
5006 new(pue) IndexExp(e->loc, agg, new IntegerExp(e->e2->loc, indexToAccess, e->e2->type));
5007 result = pue->exp();
5008 result->type = e->type;
5009 return;
5011 result = ctfeIndex(e->loc, e->type, agg, indexToAccess);
5012 return;
5014 else
5016 assert(indexToAccess == 0);
5017 result = interpret(agg, istate, goal);
5018 if (exceptionOrCant(result))
5019 return;
5020 result = paintTypeOntoLiteral(e->type, result);
5021 return;
5025 if (e->e1->type->toBasetype()->ty == Taarray)
5027 Expression *e1 = interpret(e->e1, istate);
5028 if (exceptionOrCant(e1))
5029 return;
5030 if (e1->op == TOKnull)
5032 if (goal == ctfeNeedLvalue && e1->type->ty == Taarray && e->modifiable)
5034 assert(0); // does not reach here?
5035 return;
5037 e->error("cannot index null array %s", e->e1->toChars());
5038 result = CTFEExp::cantexp;
5039 return;
5041 Expression *e2 = interpret(e->e2, istate);
5042 if (exceptionOrCant(e2))
5043 return;
5045 if (goal == ctfeNeedLvalue)
5047 // Pointer or reference of a scalar type
5048 if (e1 == e->e1 && e2 == e->e2)
5049 result = e;
5050 else
5052 new(pue) IndexExp(e->loc, e1, e2);
5053 result = pue->exp();
5054 result->type = e->type;
5056 return;
5059 assert(e1->op == TOKassocarrayliteral);
5060 UnionExp e2tmp;
5061 e2 = resolveSlice(e2, &e2tmp);
5062 result = findKeyInAA(e->loc, (AssocArrayLiteralExp *)e1, e2);
5063 if (!result)
5065 e->error("key %s not found in associative array %s", e2->toChars(), e->e1->toChars());
5066 result = CTFEExp::cantexp;
5068 return;
5071 Expression *agg;
5072 uinteger_t indexToAccess;
5073 if (!resolveIndexing(e, istate, &agg, &indexToAccess, false))
5075 result = CTFEExp::cantexp;
5076 return;
5079 if (goal == ctfeNeedLvalue)
5081 Expression *e2 = new IntegerExp(e->e2->loc, indexToAccess, Type::tsize_t);
5082 new(pue) IndexExp(e->loc, agg, e2);
5083 result = pue->exp();
5084 result->type = e->type;
5085 return;
5088 result = ctfeIndex(e->loc, e->type, agg, indexToAccess);
5089 if (exceptionOrCant(result))
5090 return;
5091 if (result->op == TOKvoid)
5093 e->error("%s is used before initialized", e->toChars());
5094 errorSupplemental(result->loc, "originally uninitialized here");
5095 result = CTFEExp::cantexp;
5096 return;
5098 result = paintTypeOntoLiteral(e->type, result);
5101 void visit(SliceExp *e)
5103 if (e->e1->type->toBasetype()->ty == Tpointer)
5105 // Slicing a pointer. Note that there is no $ in this case.
5106 Expression *e1 = interpret(e->e1, istate);
5107 if (exceptionOrCant(e1))
5108 return;
5109 if (e1->op == TOKint64)
5111 e->error("cannot slice invalid pointer %s of value %s", e->e1->toChars(), e1->toChars());
5112 result = CTFEExp::cantexp;
5113 return;
5116 /* Evaluate lower and upper bounds of slice
5118 Expression *lwr = interpret(e->lwr, istate);
5119 if (exceptionOrCant(lwr))
5120 return;
5121 Expression *upr = interpret(e->upr, istate);
5122 if (exceptionOrCant(upr))
5123 return;
5124 uinteger_t ilwr = lwr->toInteger();
5125 uinteger_t iupr = upr->toInteger();
5127 dinteger_t ofs;
5128 Expression *agg = getAggregateFromPointer(e1, &ofs);
5129 ilwr += ofs;
5130 iupr += ofs;
5131 if (agg->op == TOKnull)
5133 if (iupr == ilwr)
5135 result = new NullExp(e->loc);
5136 result->type = e->type;
5137 return;
5139 e->error("cannot slice null pointer %s", e->e1->toChars());
5140 result = CTFEExp::cantexp;
5141 return;
5143 if (agg->op == TOKsymoff)
5145 e->error("slicing pointers to static variables is not supported in CTFE");
5146 result = CTFEExp::cantexp;
5147 return;
5149 if (agg->op != TOKarrayliteral && agg->op != TOKstring)
5151 e->error("pointer %s cannot be sliced at compile time (it does not point to an array)", e->e1->toChars());
5152 result = CTFEExp::cantexp;
5153 return;
5155 assert(agg->op == TOKarrayliteral || agg->op == TOKstring);
5156 dinteger_t len = ArrayLength(Type::tsize_t, agg).exp()->toInteger();
5157 //Type *pointee = ((TypePointer *)agg->type)->next;
5158 if (iupr > (len + 1) || iupr < ilwr)
5160 e->error("pointer slice [%lld..%lld] exceeds allocated memory block [0..%lld]", ilwr, iupr, len);
5161 result = CTFEExp::cantexp;
5162 return;
5164 if (ofs != 0)
5166 lwr = new IntegerExp(e->loc, ilwr, lwr->type);
5167 upr = new IntegerExp(e->loc, iupr, upr->type);
5169 new(pue) SliceExp(e->loc, agg, lwr, upr);
5170 result = pue->exp();
5171 result->type = e->type;
5172 return;
5175 Expression *e1 = interpret(e->e1, istate);
5176 if (exceptionOrCant(e1))
5177 return;
5179 if (!e->lwr)
5181 result = paintTypeOntoLiteral(e->type, e1);
5182 return;
5185 /* Set the $ variable
5187 if (e1->op != TOKarrayliteral && e1->op != TOKstring && e1->op != TOKnull && e1->op != TOKslice)
5189 e->error("cannot determine length of %s at compile time", e1->toChars());
5190 result = CTFEExp::cantexp;
5191 return;
5193 uinteger_t dollar = resolveArrayLength(e1);
5194 if (e->lengthVar)
5196 IntegerExp *dollarExp = new IntegerExp(e->loc, dollar, Type::tsize_t);
5197 ctfeStack.push(e->lengthVar);
5198 setValue(e->lengthVar, dollarExp);
5201 /* Evaluate lower and upper bounds of slice
5203 Expression *lwr = interpret(e->lwr, istate);
5204 if (exceptionOrCant(lwr))
5206 if (e->lengthVar)
5207 ctfeStack.pop(e->lengthVar);
5208 return;
5210 Expression *upr = interpret(e->upr, istate);
5211 if (exceptionOrCant(upr))
5213 if (e->lengthVar)
5214 ctfeStack.pop(e->lengthVar);
5215 return;
5217 if (e->lengthVar)
5218 ctfeStack.pop(e->lengthVar); // $ is defined only inside [L..U]
5220 uinteger_t ilwr = lwr->toInteger();
5221 uinteger_t iupr = upr->toInteger();
5222 if (e1->op == TOKnull)
5224 if (ilwr == 0 && iupr == 0)
5226 result = e1;
5227 return;
5229 e1->error("slice [%llu..%llu] is out of bounds", ilwr, iupr);
5230 result = CTFEExp::cantexp;
5231 return;
5233 if (e1->op == TOKslice)
5235 SliceExp *se = (SliceExp *)e1;
5236 // Simplify slice of slice:
5237 // aggregate[lo1..up1][lwr..upr] ---> aggregate[lwr'..upr']
5238 uinteger_t lo1 = se->lwr->toInteger();
5239 uinteger_t up1 = se->upr->toInteger();
5240 if (ilwr > iupr || iupr > up1 - lo1)
5242 e->error("slice[%llu..%llu] exceeds array bounds[%llu..%llu]", ilwr, iupr, lo1, up1);
5243 result = CTFEExp::cantexp;
5244 return;
5246 ilwr += lo1;
5247 iupr += lo1;
5248 new(pue) SliceExp(e->loc, se->e1, new IntegerExp(e->loc, ilwr, lwr->type), new IntegerExp(e->loc, iupr, upr->type));
5249 result = pue->exp();
5250 result->type = e->type;
5251 return;
5253 if (e1->op == TOKarrayliteral || e1->op == TOKstring)
5255 if (iupr < ilwr || dollar < iupr)
5257 e->error("slice [%lld..%lld] exceeds array bounds [0..%lld]", ilwr, iupr, dollar);
5258 result = CTFEExp::cantexp;
5259 return;
5262 new(pue) SliceExp(e->loc, e1, lwr, upr);
5263 result = pue->exp();
5264 result->type = e->type;
5267 void visit(InExp *e)
5269 Expression *e1 = interpret(e->e1, istate);
5270 if (exceptionOrCant(e1))
5271 return;
5272 Expression *e2 = interpret(e->e2, istate);
5273 if (exceptionOrCant(e2))
5274 return;
5275 if (e2->op == TOKnull)
5277 new(pue) NullExp(e->loc, e->type);
5278 result = pue->exp();
5279 return;
5281 if (e2->op != TOKassocarrayliteral)
5283 e->error("%s cannot be interpreted at compile time", e->toChars());
5284 result = CTFEExp::cantexp;
5285 return;
5288 e1 = resolveSlice(e1);
5289 result = findKeyInAA(e->loc, (AssocArrayLiteralExp *)e2, e1);
5290 if (exceptionOrCant(result))
5291 return;
5292 if (!result)
5294 new(pue) NullExp(e->loc, e->type);
5295 result = pue->exp();
5297 else
5299 // Create a CTFE pointer &aa[index]
5300 result = new IndexExp(e->loc, e2, e1);
5301 result->type = e->type->nextOf();
5302 new(pue) AddrExp(e->loc, result, e->type);
5303 result = pue->exp();
5307 void visit(CatExp *e)
5309 Expression *e1 = interpret(e->e1, istate);
5310 if (exceptionOrCant(e1))
5311 return;
5312 Expression *e2 = interpret(e->e2, istate);
5313 if (exceptionOrCant(e2))
5314 return;
5315 UnionExp e1tmp;
5316 e1 = resolveSlice(e1, &e1tmp);
5317 UnionExp e2tmp;
5318 e2 = resolveSlice(e2, &e2tmp);
5319 result = ctfeCat(e->loc, e->type, e1, e2).copy();
5320 if (CTFEExp::isCantExp(result))
5322 e->error("%s cannot be interpreted at compile time", e->toChars());
5323 return;
5325 // We know we still own it, because we interpreted both e1 and e2
5326 if (result->op == TOKarrayliteral)
5328 ArrayLiteralExp *ale = (ArrayLiteralExp *)result;
5329 ale->ownedByCtfe = OWNEDctfe;
5331 // Bugzilla 14686
5332 for (size_t i = 0; i < ale->elements->dim; i++)
5334 Expression *ex = evaluatePostblit(istate, (*ale->elements)[i]);
5335 if (exceptionOrCant(ex))
5336 return;
5339 if (result->op == TOKstring)
5340 ((StringExp *)result)->ownedByCtfe = OWNEDctfe;
5343 void visit(DeleteExp *e)
5345 result = interpret(e->e1, istate);
5346 if (exceptionOrCant(result))
5347 return;
5349 if (result->op == TOKnull)
5351 result = CTFEExp::voidexp;
5352 return;
5355 Type *tb = e->e1->type->toBasetype();
5356 switch (tb->ty)
5358 case Tclass:
5360 if (result->op != TOKclassreference)
5362 e->error("delete on invalid class reference '%s'", result->toChars());
5363 result = CTFEExp::cantexp;
5364 return;
5367 ClassReferenceExp *cre = (ClassReferenceExp *)result;
5368 ClassDeclaration *cd = cre->originalClass();
5369 if (cd->aggDelete)
5371 e->error("member deallocators not supported by CTFE");
5372 result = CTFEExp::cantexp;
5373 return;
5376 if (cd->dtor)
5378 result = interpretFunction(cd->dtor, istate, NULL, cre);
5379 if (exceptionOrCant(result))
5380 return;
5382 break;
5385 case Tpointer:
5387 tb = ((TypePointer *)tb)->next->toBasetype();
5388 if (tb->ty == Tstruct)
5390 if (result->op != TOKaddress ||
5391 ((AddrExp *)result)->e1->op != TOKstructliteral)
5393 e->error("delete on invalid struct pointer '%s'", result->toChars());
5394 result = CTFEExp::cantexp;
5395 return;
5398 StructDeclaration *sd = ((TypeStruct *)tb)->sym;
5399 StructLiteralExp *sle = (StructLiteralExp *)((AddrExp *)result)->e1;
5400 if (sd->aggDelete)
5402 e->error("member deallocators not supported by CTFE");
5403 result = CTFEExp::cantexp;
5404 return;
5407 if (sd->dtor)
5409 result = interpretFunction(sd->dtor, istate, NULL, sle);
5410 if (exceptionOrCant(result))
5411 return;
5414 break;
5417 case Tarray:
5419 Type *tv = tb->nextOf()->baseElemOf();
5420 if (tv->ty == Tstruct)
5422 if (result->op != TOKarrayliteral)
5424 e->error("delete on invalid struct array '%s'", result->toChars());
5425 result = CTFEExp::cantexp;
5426 return;
5429 StructDeclaration *sd = ((TypeStruct *)tv)->sym;
5430 if (sd->aggDelete)
5432 e->error("member deallocators not supported by CTFE");
5433 result = CTFEExp::cantexp;
5434 return;
5437 if (sd->dtor)
5439 ArrayLiteralExp *ale = (ArrayLiteralExp *)result;
5440 for (size_t i = 0; i < ale->elements->dim; i++)
5442 Expression *el = (*ale->elements)[i];
5443 result = interpretFunction(sd->dtor, istate, NULL, el);
5444 if (exceptionOrCant(result))
5445 return;
5449 break;
5452 default:
5453 assert(0);
5455 result = CTFEExp::voidexp;
5458 void visit(CastExp *e)
5460 Expression *e1 = interpret(e->e1, istate, goal);
5461 if (exceptionOrCant(e1))
5462 return;
5463 // If the expression has been cast to void, do nothing.
5464 if (e->to->ty == Tvoid)
5466 result = CTFEExp::voidexp;
5467 return;
5469 if (e->to->ty == Tpointer && e1->op != TOKnull)
5471 Type *pointee = ((TypePointer *)e->type)->next;
5472 // Implement special cases of normally-unsafe casts
5473 if (e1->op == TOKint64)
5475 // Happens with Windows HANDLEs, for example.
5476 result = paintTypeOntoLiteral(e->to, e1);
5477 return;
5479 bool castToSarrayPointer = false;
5480 bool castBackFromVoid = false;
5481 if (e1->type->ty == Tarray || e1->type->ty == Tsarray || e1->type->ty == Tpointer)
5483 // Check for unsupported type painting operations
5484 // For slices, we need the type being sliced,
5485 // since it may have already been type painted
5486 Type *elemtype = e1->type->nextOf();
5487 if (e1->op == TOKslice)
5488 elemtype = ((SliceExp *)e1)->e1->type->nextOf();
5489 // Allow casts from X* to void *, and X** to void** for any X.
5490 // But don't allow cast from X* to void**.
5491 // So, we strip all matching * from source and target to find X.
5492 // Allow casts to X* from void* only if the 'void' was originally an X;
5493 // we check this later on.
5494 Type *ultimatePointee = pointee;
5495 Type *ultimateSrc = elemtype;
5496 while (ultimatePointee->ty == Tpointer && ultimateSrc->ty == Tpointer)
5498 ultimatePointee = ultimatePointee->nextOf();
5499 ultimateSrc = ultimateSrc->nextOf();
5501 if (ultimatePointee->ty == Tsarray && ultimatePointee->nextOf()->equivalent(ultimateSrc))
5503 castToSarrayPointer = true;
5505 else if (ultimatePointee->ty != Tvoid && ultimateSrc->ty != Tvoid &&
5506 !isSafePointerCast(elemtype, pointee))
5508 e->error("reinterpreting cast from %s* to %s* is not supported in CTFE",
5509 elemtype->toChars(), pointee->toChars());
5510 result = CTFEExp::cantexp;
5511 return;
5513 if (ultimateSrc->ty == Tvoid)
5514 castBackFromVoid = true;
5517 if (e1->op == TOKslice)
5519 if (((SliceExp *)e1)->e1->op == TOKnull)
5521 result = paintTypeOntoLiteral(e->type, ((SliceExp *)e1)->e1);
5522 return;
5524 // Create a CTFE pointer &aggregate[1..2]
5525 IndexExp *ei = new IndexExp(e->loc, ((SliceExp *)e1)->e1, ((SliceExp *)e1)->lwr);
5526 ei->type = e->type->nextOf();
5527 new(pue) AddrExp(e->loc, ei, e->type);
5528 result = pue->exp();
5529 return;
5531 if (e1->op == TOKarrayliteral || e1->op == TOKstring)
5533 // Create a CTFE pointer &[1,2,3][0] or &"abc"[0]
5534 IndexExp *ei = new IndexExp(e->loc, e1, new IntegerExp(e->loc, 0, Type::tsize_t));
5535 ei->type = e->type->nextOf();
5536 new(pue) AddrExp(e->loc, ei, e->type);
5537 result = pue->exp();
5538 return;
5540 if (e1->op == TOKindex && !((IndexExp *)e1)->e1->type->equals(e1->type))
5542 // type painting operation
5543 IndexExp *ie = (IndexExp *)e1;
5544 result = new IndexExp(e1->loc, ie->e1, ie->e2);
5545 if (castBackFromVoid)
5547 // get the original type. For strings, it's just the type...
5548 Type *origType = ie->e1->type->nextOf();
5549 // ..but for arrays of type void*, it's the type of the element
5550 if (ie->e1->op == TOKarrayliteral && ie->e2->op == TOKint64)
5552 ArrayLiteralExp *ale = (ArrayLiteralExp *)ie->e1;
5553 size_t indx = (size_t)ie->e2->toInteger();
5554 if (indx < ale->elements->dim)
5556 Expression *xx = (*ale->elements)[indx];
5557 if (xx)
5559 if (xx->op == TOKindex)
5560 origType = ((IndexExp *)xx)->e1->type->nextOf();
5561 else if (xx->op == TOKaddress)
5562 origType= ((AddrExp *)xx)->e1->type;
5563 else if (xx->op == TOKvar)
5564 origType = ((VarExp *)xx)->var->type;
5568 if (!isSafePointerCast(origType, pointee))
5570 e->error("using void* to reinterpret cast from %s* to %s* is not supported in CTFE", origType->toChars(), pointee->toChars());
5571 result = CTFEExp::cantexp;
5572 return;
5575 result->type = e->type;
5576 return;
5578 if (e1->op == TOKaddress)
5580 Type *origType = ((AddrExp *)e1)->e1->type;
5581 if (isSafePointerCast(origType, pointee))
5583 new(pue) AddrExp(e->loc, ((AddrExp *)e1)->e1, e->type);
5584 result = pue->exp();
5585 return;
5587 if (castToSarrayPointer && pointee->toBasetype()->ty == Tsarray && ((AddrExp *)e1)->e1->op == TOKindex)
5589 // &val[idx]
5590 dinteger_t dim = ((TypeSArray *)pointee->toBasetype())->dim->toInteger();
5591 IndexExp *ie = (IndexExp *)((AddrExp *)e1)->e1;
5592 Expression *lwr = ie->e2;
5593 Expression *upr = new IntegerExp(ie->e2->loc, ie->e2->toInteger() + dim, Type::tsize_t);
5595 // Create a CTFE pointer &val[idx..idx+dim]
5596 SliceExp *er = new SliceExp(e->loc, ie->e1, lwr, upr);
5597 er->type = pointee;
5598 new(pue) AddrExp(e->loc, er, e->type);
5599 result = pue->exp();
5600 return;
5603 if (e1->op == TOKvar || e1->op == TOKsymoff)
5605 // type painting operation
5606 Type *origType = ((SymbolExp *)e1)->var->type;
5607 if (castBackFromVoid && !isSafePointerCast(origType, pointee))
5609 e->error("using void* to reinterpret cast from %s* to %s* is not supported in CTFE", origType->toChars(), pointee->toChars());
5610 result = CTFEExp::cantexp;
5611 return;
5613 if (e1->op == TOKvar)
5614 new(pue) VarExp(e->loc, ((VarExp *)e1)->var);
5615 else
5616 new(pue) SymOffExp(e->loc, ((SymOffExp *)e1)->var, ((SymOffExp *)e1)->offset);
5617 result = pue->exp();
5618 result->type = e->to;
5619 return;
5622 // Check if we have a null pointer (eg, inside a struct)
5623 e1 = interpret(e1, istate);
5624 if (e1->op != TOKnull)
5626 e->error("pointer cast from %s to %s is not supported at compile time", e1->type->toChars(), e->to->toChars());
5627 result = CTFEExp::cantexp;
5628 return;
5631 if (e->to->ty == Tsarray && e->e1->type->ty == Tvector)
5633 // Special handling for: cast(float[4])__vector([w, x, y, z])
5634 e1 = interpret(e->e1, istate);
5635 if (exceptionOrCant(e1))
5636 return;
5637 assert(e1->op == TOKvector);
5638 e1 = ((VectorExp *)e1)->e1;
5640 if (e->to->ty == Tarray && e1->op == TOKslice)
5642 // Note that the slice may be void[], so when checking for dangerous
5643 // casts, we need to use the original type, which is se->e1.
5644 SliceExp *se = (SliceExp *)e1;
5645 if (!isSafePointerCast(se->e1->type->nextOf(), e->to->nextOf()))
5647 e->error("array cast from %s to %s is not supported at compile time", se->e1->type->toChars(), e->to->toChars());
5648 result = CTFEExp::cantexp;
5649 return;
5651 new(pue) SliceExp(e1->loc, se->e1, se->lwr, se->upr);
5652 result = pue->exp();
5653 result->type = e->to;
5654 return;
5656 // Disallow array type painting, except for conversions between built-in
5657 // types of identical size.
5658 if ((e->to->ty == Tsarray || e->to->ty == Tarray) && (e1->type->ty == Tsarray || e1->type->ty == Tarray) && !isSafePointerCast(e1->type->nextOf(), e->to->nextOf()))
5660 e->error("array cast from %s to %s is not supported at compile time", e1->type->toChars(), e->to->toChars());
5661 result = CTFEExp::cantexp;
5662 return;
5664 if (e->to->ty == Tsarray)
5665 e1 = resolveSlice(e1);
5666 if (e->to->toBasetype()->ty == Tbool && e1->type->ty == Tpointer)
5668 new(pue) IntegerExp(e->loc, e1->op != TOKnull, e->to);
5669 result = pue->exp();
5670 return;
5672 result = ctfeCast(e->loc, e->type, e->to, e1);
5675 void visit(AssertExp *e)
5677 Expression *e1 = interpret(pue, e->e1, istate);
5678 if (exceptionOrCant(e1))
5679 return;
5680 if (isTrueBool(e1))
5683 else if (e1->isBool(false))
5685 if (e->msg)
5687 UnionExp ue;
5688 result = interpret(&ue, e->msg, istate);
5689 if (exceptionOrCant(result))
5690 return;
5691 e->error("%s", result->toChars());
5693 else
5694 e->error("%s failed", e->toChars());
5695 result = CTFEExp::cantexp;
5696 return;
5698 else
5700 e->error("%s is not a compile time boolean expression", e1->toChars());
5701 result = CTFEExp::cantexp;
5702 return;
5704 result = e1;
5705 return;
5708 void visit(PtrExp *e)
5710 // Check for int<->float and long<->double casts.
5711 if (e->e1->op == TOKsymoff && ((SymOffExp *)e->e1)->offset == 0 && ((SymOffExp *)e->e1)->var->isVarDeclaration() && isFloatIntPaint(e->type, ((SymOffExp *)e->e1)->var->type))
5713 // *(cast(int*)&v), where v is a float variable
5714 result = paintFloatInt(getVarExp(e->loc, istate, ((SymOffExp *)e->e1)->var, ctfeNeedRvalue), e->type);
5715 return;
5717 if (e->e1->op == TOKcast && ((CastExp *)e->e1)->e1->op == TOKaddress)
5719 // *(cast(int*)&x), where x is a float expression
5720 Expression *x = ((AddrExp *)(((CastExp *)e->e1)->e1))->e1;
5721 if (isFloatIntPaint(e->type, x->type))
5723 result = paintFloatInt(interpret(x, istate), e->type);
5724 return;
5728 // Constant fold *(&structliteral + offset)
5729 if (e->e1->op == TOKadd)
5731 AddExp *ae = (AddExp *)e->e1;
5732 if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64)
5734 AddrExp *ade = (AddrExp *)ae->e1;
5735 Expression *ex = interpret(ade->e1, istate);
5736 if (exceptionOrCant(ex))
5737 return;
5738 if (ex->op == TOKstructliteral)
5740 StructLiteralExp *se = (StructLiteralExp *)ex;
5741 dinteger_t offset = ae->e2->toInteger();
5742 result = se->getField(e->type, (unsigned)offset);
5743 if (result)
5744 return;
5749 // It's possible we have an array bounds error. We need to make sure it
5750 // errors with this line number, not the one where the pointer was set.
5751 result = interpret(e->e1, istate);
5752 if (exceptionOrCant(result))
5753 return;
5755 if (result->op == TOKfunction)
5756 return;
5757 if (result->op == TOKsymoff)
5759 SymOffExp *soe = (SymOffExp *)result;
5760 if (soe->offset == 0 && soe->var->isFuncDeclaration())
5761 return;
5762 e->error("cannot dereference pointer to static variable %s at compile time", soe->var->toChars());
5763 result = CTFEExp::cantexp;
5764 return;
5767 if (result->op != TOKaddress)
5769 if (result->op == TOKnull)
5770 e->error("dereference of null pointer '%s'", e->e1->toChars());
5771 else
5772 e->error("dereference of invalid pointer '%s'", result->toChars());
5773 result = CTFEExp::cantexp;
5774 return;
5777 // *(&x) ==> x
5778 result = ((AddrExp *)result)->e1;
5780 if (result->op == TOKslice && e->type->toBasetype()->ty == Tsarray)
5782 /* aggr[lwr..upr]
5783 * upr may exceed the upper boundary of aggr, but the check is deferred
5784 * until those out-of-bounds elements will be touched.
5786 return;
5788 result = interpret(result, istate, goal);
5789 if (exceptionOrCant(result))
5790 return;
5793 void visit(DotVarExp *e)
5795 Expression *ex = interpret(e->e1, istate);
5796 if (exceptionOrCant(ex))
5797 return;
5799 if (FuncDeclaration *f = e->var->isFuncDeclaration())
5801 if (ex == e->e1)
5802 result = e; // optimize: reuse this CTFE reference
5803 else
5805 new(pue) DotVarExp(e->loc, ex, f, false);
5806 result = pue->exp();
5807 result->type = e->type;
5809 return;
5812 VarDeclaration *v = e->var->isVarDeclaration();
5813 if (!v)
5815 e->error("CTFE internal error: %s", e->toChars());
5816 result = CTFEExp::cantexp;
5817 return;
5820 if (ex->op == TOKnull)
5822 if (ex->type->toBasetype()->ty == Tclass)
5823 e->error("class '%s' is null and cannot be dereferenced", e->e1->toChars());
5824 else
5825 e->error("CTFE internal error: null this '%s'", e->e1->toChars());
5826 result = CTFEExp::cantexp;
5827 return;
5829 if (ex->op != TOKstructliteral && ex->op != TOKclassreference)
5831 e->error("%s.%s is not yet implemented at compile time", e->e1->toChars(), e->var->toChars());
5832 result = CTFEExp::cantexp;
5833 return;
5836 StructLiteralExp *se;
5837 int i;
5839 // We can't use getField, because it makes a copy
5840 if (ex->op == TOKclassreference)
5842 se = ((ClassReferenceExp *)ex)->value;
5843 i = ((ClassReferenceExp *)ex)->findFieldIndexByName(v);
5845 else
5847 se = (StructLiteralExp *)ex;
5848 i = findFieldIndexByName(se->sd, v);
5850 if (i == -1)
5852 e->error("couldn't find field %s of type %s in %s", v->toChars(), e->type->toChars(), se->toChars());
5853 result = CTFEExp::cantexp;
5854 return;
5857 if (goal == ctfeNeedLvalue)
5859 Expression *ev = (*se->elements)[i];
5860 if (!ev || ev->op == TOKvoid)
5861 (*se->elements)[i] = voidInitLiteral(e->type, v).copy();
5862 // just return the (simplified) dotvar expression as a CTFE reference
5863 if (e->e1 == ex)
5864 result = e;
5865 else
5867 new(pue) DotVarExp(e->loc, ex, v);
5868 result = pue->exp();
5869 result->type = e->type;
5871 return;
5874 result = (*se->elements)[i];
5875 if (!result)
5877 e->error("Internal Compiler Error: null field %s", v->toChars());
5878 result = CTFEExp::cantexp;
5879 return;
5881 if (result->op == TOKvoid)
5883 VoidInitExp *ve = (VoidInitExp *)result;
5884 const char *s = ve->var->toChars();
5885 if (v->overlapped)
5887 e->error("reinterpretation through overlapped field %s is not allowed in CTFE", s);
5888 result = CTFEExp::cantexp;
5889 return;
5891 e->error("cannot read uninitialized variable %s in CTFE", s);
5892 result = CTFEExp::cantexp;
5893 return;
5896 if (v->type->ty != result->type->ty && v->type->ty == Tsarray)
5898 // Block assignment from inside struct literals
5899 TypeSArray *tsa = (TypeSArray *)v->type;
5900 size_t len = (size_t)tsa->dim->toInteger();
5901 result = createBlockDuplicatedArrayLiteral(ex->loc, v->type, ex, len);
5902 (*se->elements)[i] = result;
5906 void visit(RemoveExp *e)
5908 Expression *agg = interpret(e->e1, istate);
5909 if (exceptionOrCant(agg))
5910 return;
5911 Expression *index = interpret(e->e2, istate);
5912 if (exceptionOrCant(index))
5913 return;
5914 if (agg->op == TOKnull)
5916 result = CTFEExp::voidexp;
5917 return;
5919 assert(agg->op == TOKassocarrayliteral);
5920 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)agg;
5921 Expressions *keysx = aae->keys;
5922 Expressions *valuesx = aae->values;
5923 size_t removed = 0;
5924 for (size_t j = 0; j < valuesx->dim; ++j)
5926 Expression *ekey = (*keysx)[j];
5927 int eq = ctfeEqual(e->loc, TOKequal, ekey, index);
5928 if (eq)
5929 ++removed;
5930 else if (removed != 0)
5932 (*keysx)[j - removed] = ekey;
5933 (*valuesx)[j - removed] = (*valuesx)[j];
5936 valuesx->dim = valuesx->dim - removed;
5937 keysx->dim = keysx->dim - removed;
5938 new(pue) IntegerExp(e->loc, removed ? 1 : 0, Type::tbool);
5939 result = pue->exp();
5942 void visit(ClassReferenceExp *e)
5944 //printf("ClassReferenceExp::interpret() %s\n", e->value->toChars());
5945 result = e;
5948 void visit(VoidInitExp *e)
5950 e->error("CTFE internal error: trying to read uninitialized variable");
5951 assert(0);
5952 result = CTFEExp::cantexp;
5955 void visit(ThrownExceptionExp *e)
5957 assert(0); // This should never be interpreted
5958 result = e;
5963 /********************************************
5964 * Interpret the expression.
5965 * Params:
5966 * pue = non-null pointer to temporary storage that can be used to store the return value
5967 * e = Expression to interpret
5968 * istate = context
5969 * goal = what the result will be used for
5970 * Returns:
5971 * resulting expression
5974 static Expression *interpret(UnionExp *pue, Expression *e, InterState *istate, CtfeGoal goal)
5976 if (!e)
5977 return NULL;
5978 Interpreter v(pue, istate, goal);
5979 e->accept(&v);
5980 Expression *ex = v.result;
5981 assert(goal == ctfeNeedNothing || ex != NULL);
5982 return ex;
5986 Expression *interpret(Expression *e, InterState *istate, CtfeGoal goal)
5988 UnionExp ue;
5989 Expression *result = interpret(&ue, e, istate, goal);
5990 if (result == ue.exp())
5991 result = ue.copy();
5992 return result;
5995 /***********************************
5996 * Interpret the statement.
5997 * Params:
5998 * pue = non-null pointer to temporary storage that can be used to store the return value
5999 * s = Statement to interpret
6000 * istate = context
6001 * Returns:
6002 * NULL continue to next statement
6003 * TOKcantexp cannot interpret statement at compile time
6004 * !NULL expression from return statement, or thrown exception
6007 static Expression *interpret(UnionExp *pue, Statement *s, InterState *istate)
6009 if (!s)
6010 return NULL;
6011 Interpreter v(pue, istate, ctfeNeedNothing);
6012 s->accept(&v);
6013 return v.result;
6016 Expression *interpret(Statement *s, InterState *istate)
6018 UnionExp ue;
6019 Expression *result = interpret(&ue, s, istate);
6020 if (result == ue.exp())
6021 result = ue.copy();
6022 return result;
6025 Expression *scrubArray(Loc loc, Expressions *elems, bool structlit = false);
6027 /* All results destined for use outside of CTFE need to have their CTFE-specific
6028 * features removed.
6029 * In particular, all slices must be resolved.
6031 Expression *scrubReturnValue(Loc loc, Expression *e)
6033 if (e->op == TOKclassreference)
6035 StructLiteralExp *se = ((ClassReferenceExp*)e)->value;
6036 se->ownedByCtfe = OWNEDcode;
6037 if (!(se->stageflags & stageScrub))
6039 int old = se->stageflags;
6040 se->stageflags |= stageScrub;
6041 if (Expression *ex = scrubArray(loc, se->elements, true))
6042 return ex;
6043 se->stageflags = old;
6046 if (e->op == TOKvoid)
6048 error(loc, "uninitialized variable '%s' cannot be returned from CTFE", ((VoidInitExp *)e)->var->toChars());
6049 return new ErrorExp();
6051 e = resolveSlice(e);
6052 if (e->op == TOKstructliteral)
6054 StructLiteralExp *se = (StructLiteralExp *)e;
6055 se->ownedByCtfe = OWNEDcode;
6056 if (!(se->stageflags & stageScrub))
6058 int old = se->stageflags;
6059 se->stageflags |= stageScrub;
6060 if (Expression *ex = scrubArray(loc, se->elements, true))
6061 return ex;
6062 se->stageflags = old;
6065 if (e->op == TOKstring)
6067 ((StringExp *)e)->ownedByCtfe = OWNEDcode;
6069 if (e->op == TOKarrayliteral)
6071 ((ArrayLiteralExp *)e)->ownedByCtfe = OWNEDcode;
6072 if (Expression *ex = scrubArray(loc, ((ArrayLiteralExp *)e)->elements))
6073 return ex;
6075 if (e->op == TOKassocarrayliteral)
6077 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
6078 aae->ownedByCtfe = OWNEDcode;
6079 if (Expression *ex = scrubArray(loc, aae->keys))
6080 return ex;
6081 if (Expression *ex = scrubArray(loc, aae->values))
6082 return ex;
6083 aae->type = toBuiltinAAType(aae->type);
6085 return e;
6088 // Return true if every element is either void,
6089 // or is an array literal or struct literal of void elements.
6090 bool isEntirelyVoid(Expressions *elems)
6092 for (size_t i = 0; i < elems->dim; i++)
6094 Expression *m = (*elems)[i];
6095 // It can be NULL for performance reasons,
6096 // see StructLiteralExp::interpret().
6097 if (!m)
6098 continue;
6100 if (!(m->op == TOKvoid) &&
6101 !(m->op == TOKarrayliteral && isEntirelyVoid(((ArrayLiteralExp *)m)->elements)) &&
6102 !(m->op == TOKstructliteral && isEntirelyVoid(((StructLiteralExp *)m)->elements)))
6104 return false;
6107 return true;
6110 // Scrub all members of an array. Return false if error
6111 Expression *scrubArray(Loc loc, Expressions *elems, bool structlit)
6113 for (size_t i = 0; i < elems->dim; i++)
6115 Expression *m = (*elems)[i];
6116 // It can be NULL for performance reasons,
6117 // see StructLiteralExp::interpret().
6118 if (!m)
6119 continue;
6121 // A struct .init may contain void members.
6122 // Static array members are a weird special case (bug 10994).
6123 if (structlit &&
6124 ((m->op == TOKvoid) ||
6125 (m->op == TOKarrayliteral && m->type->ty == Tsarray && isEntirelyVoid(((ArrayLiteralExp *)m)->elements)) ||
6126 (m->op == TOKstructliteral && isEntirelyVoid(((StructLiteralExp *)m)->elements))))
6128 m = NULL;
6130 else
6132 m = scrubReturnValue(loc, m);
6133 if (CTFEExp::isCantExp(m) || m->op == TOKerror)
6134 return m;
6136 (*elems)[i] = m;
6138 return NULL;
6141 Expression *scrubArrayCache(Loc loc, Expressions *elems);
6143 Expression *scrubCacheValue(Loc loc, Expression *e)
6145 if (e->op == TOKclassreference)
6147 StructLiteralExp *sle = ((ClassReferenceExp*)e)->value;
6148 sle->ownedByCtfe = OWNEDcache;
6149 if (!(sle->stageflags & stageScrub))
6151 int old = sle->stageflags;
6152 sle->stageflags |= stageScrub;
6153 if (Expression *ex = scrubArrayCache(loc, sle->elements))
6154 return ex;
6155 sle->stageflags = old;
6158 if (e->op == TOKstructliteral)
6160 StructLiteralExp *sle = (StructLiteralExp *)e;
6161 sle->ownedByCtfe = OWNEDcache;
6162 if (!(sle->stageflags & stageScrub))
6164 int old = sle->stageflags;
6165 sle->stageflags |= stageScrub;
6166 if (Expression *ex = scrubArrayCache(loc, sle->elements))
6167 return ex;
6168 sle->stageflags = old;
6171 if (e->op == TOKstring)
6173 ((StringExp *)e)->ownedByCtfe = OWNEDcache;
6175 if (e->op == TOKarrayliteral)
6177 ((ArrayLiteralExp *)e)->ownedByCtfe = OWNEDcache;
6178 if (Expression *ex = scrubArrayCache(loc, ((ArrayLiteralExp *)e)->elements))
6179 return ex;
6181 if (e->op == TOKassocarrayliteral)
6183 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
6184 aae->ownedByCtfe = OWNEDcache;
6185 if (Expression *ex = scrubArrayCache(loc, aae->keys))
6186 return ex;
6187 if (Expression *ex = scrubArrayCache(loc, aae->values))
6188 return ex;
6190 return e;
6193 Expression *scrubArrayCache(Loc loc, Expressions *elems)
6195 for (size_t i = 0; i < elems->dim; i++)
6197 Expression *m = (*elems)[i];
6198 if (!m)
6199 continue;
6200 (*elems)[i] = scrubCacheValue(loc, m);
6202 return NULL;
6205 /******************************* Special Functions ***************************/
6207 Expression *interpret_length(InterState *istate, Expression *earg)
6209 //printf("interpret_length()\n");
6210 earg = interpret(earg, istate);
6211 if (exceptionOrCantInterpret(earg))
6212 return earg;
6213 dinteger_t len = 0;
6214 if (earg->op == TOKassocarrayliteral)
6215 len = ((AssocArrayLiteralExp *)earg)->keys->dim;
6216 else
6217 assert(earg->op == TOKnull);
6218 Expression *e = new IntegerExp(earg->loc, len, Type::tsize_t);
6219 return e;
6222 Expression *interpret_keys(InterState *istate, Expression *earg, Type *returnType)
6224 earg = interpret(earg, istate);
6225 if (exceptionOrCantInterpret(earg))
6226 return earg;
6227 if (earg->op == TOKnull)
6228 return new NullExp(earg->loc, returnType);
6229 if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray)
6230 return NULL;
6231 assert(earg->op == TOKassocarrayliteral);
6232 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
6233 ArrayLiteralExp *ae = new ArrayLiteralExp(aae->loc, aae->keys);
6234 ae->ownedByCtfe = aae->ownedByCtfe;
6235 ae->type = returnType;
6236 return copyLiteral(ae).copy();
6239 Expression *interpret_values(InterState *istate, Expression *earg, Type *returnType)
6241 earg = interpret(earg, istate);
6242 if (exceptionOrCantInterpret(earg))
6243 return earg;
6244 if (earg->op == TOKnull)
6245 return new NullExp(earg->loc, returnType);
6246 if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray)
6247 return NULL;
6248 assert(earg->op == TOKassocarrayliteral);
6249 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg;
6250 ArrayLiteralExp *ae = new ArrayLiteralExp(aae->loc, aae->values);
6251 ae->ownedByCtfe = aae->ownedByCtfe;
6252 ae->type = returnType;
6253 //printf("result is %s\n", e->toChars());
6254 return copyLiteral(ae).copy();
6257 Expression *interpret_dup(InterState *istate, Expression *earg)
6259 earg = interpret(earg, istate);
6260 if (exceptionOrCantInterpret(earg))
6261 return earg;
6262 if (earg->op == TOKnull)
6263 return new NullExp(earg->loc, earg->type);
6264 if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray)
6265 return NULL;
6266 assert(earg->op == TOKassocarrayliteral);
6267 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)copyLiteral(earg).copy();
6268 for (size_t i = 0; i < aae->keys->dim; i++)
6270 if (Expression *e = evaluatePostblit(istate, (*aae->keys)[i]))
6271 return e;
6272 if (Expression *e = evaluatePostblit(istate, (*aae->values)[i]))
6273 return e;
6275 aae->type = earg->type->mutableOf(); // repaint type from const(int[int]) to const(int)[int]
6276 //printf("result is %s\n", aae->toChars());
6277 return aae;
6280 // signature is int delegate(ref Value) OR int delegate(ref Key, ref Value)
6281 Expression *interpret_aaApply(InterState *istate, Expression *aa, Expression *deleg)
6283 aa = interpret(aa, istate);
6284 if (exceptionOrCantInterpret(aa))
6285 return aa;
6286 if (aa->op != TOKassocarrayliteral)
6287 return new IntegerExp(deleg->loc, 0, Type::tsize_t);
6289 FuncDeclaration *fd = NULL;
6290 Expression *pthis = NULL;
6291 if (deleg->op == TOKdelegate)
6293 fd = ((DelegateExp *)deleg)->func;
6294 pthis = ((DelegateExp *)deleg)->e1;
6296 else if (deleg->op == TOKfunction)
6297 fd = ((FuncExp*)deleg)->fd;
6299 assert(fd && fd->fbody);
6300 assert(fd->parameters);
6301 size_t numParams = fd->parameters->dim;
6302 assert(numParams == 1 || numParams == 2);
6304 Parameter *fparam = Parameter::getNth(((TypeFunction *)fd->type)->parameters, numParams - 1);
6305 bool wantRefValue = 0 != (fparam->storageClass & (STCout | STCref));
6307 Expressions args;
6308 args.setDim(numParams);
6310 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)aa;
6311 if (!ae->keys || ae->keys->dim == 0)
6312 return new IntegerExp(deleg->loc, 0, Type::tsize_t);
6313 Expression *eresult;
6315 for (size_t i = 0; i < ae->keys->dim; ++i)
6317 Expression *ekey = (*ae->keys)[i];
6318 Expression *evalue = (*ae->values)[i];
6319 if (wantRefValue)
6321 Type *t = evalue->type;
6322 evalue = new IndexExp(deleg->loc, ae, ekey);
6323 evalue->type = t;
6325 args[numParams - 1] = evalue;
6326 if (numParams == 2) args[0] = ekey;
6328 eresult = interpretFunction(fd, istate, &args, pthis);
6329 if (exceptionOrCantInterpret(eresult))
6330 return eresult;
6332 assert(eresult->op == TOKint64);
6333 if (((IntegerExp *)eresult)->getInteger() != 0)
6334 return eresult;
6336 return eresult;
6339 // Helper function: given a function of type A[] f(...),
6340 // return A[].
6341 Type *returnedArrayType(FuncDeclaration *fd)
6343 assert(fd->type->ty == Tfunction);
6344 assert(fd->type->nextOf()->ty == Tarray);
6345 return ((TypeFunction *)fd->type)->nextOf();
6348 /* Decoding UTF strings for foreach loops. Duplicates the functionality of
6349 * the twelve _aApplyXXn functions in aApply.d in the runtime.
6351 Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *deleg, bool rvs)
6353 FuncDeclaration *fd = NULL;
6354 Expression *pthis = NULL;
6355 if (deleg->op == TOKdelegate)
6357 fd = ((DelegateExp *)deleg)->func;
6358 pthis = ((DelegateExp *)deleg)->e1;
6360 else if (deleg->op == TOKfunction)
6361 fd = ((FuncExp*)deleg)->fd;
6363 assert(fd && fd->fbody);
6364 assert(fd->parameters);
6365 size_t numParams = fd->parameters->dim;
6366 assert(numParams == 1 || numParams == 2);
6367 Type *charType = (*fd->parameters)[numParams-1]->type;
6368 Type *indexType = numParams == 2 ? (*fd->parameters)[0]->type
6369 : Type::tsize_t;
6370 size_t len = (size_t)resolveArrayLength(str);
6371 if (len == 0)
6372 return new IntegerExp(deleg->loc, 0, indexType);
6374 str = resolveSlice(str);
6376 StringExp *se = NULL;
6377 ArrayLiteralExp *ale = NULL;
6378 if (str->op == TOKstring)
6379 se = (StringExp *) str;
6380 else if (str->op == TOKarrayliteral)
6381 ale = (ArrayLiteralExp *)str;
6382 else
6384 str->error("CTFE internal error: cannot foreach %s", str->toChars());
6385 return CTFEExp::cantexp;
6387 Expressions args;
6388 args.setDim(numParams);
6390 Expression *eresult = NULL; // ded-store to prevent spurious warning
6392 // Buffers for encoding; also used for decoding array literals
6393 utf8_t utf8buf[4];
6394 unsigned short utf16buf[2];
6396 size_t start = rvs ? len : 0;
6397 size_t end = rvs ? 0: len;
6398 for (size_t indx = start; indx != end;)
6400 // Step 1: Decode the next dchar from the string.
6402 const char *errmsg = NULL; // Used for reporting decoding errors
6403 dchar_t rawvalue; // Holds the decoded dchar
6404 size_t currentIndex = indx; // The index of the decoded character
6406 if (ale)
6408 // If it is an array literal, copy the code points into the buffer
6409 size_t buflen = 1; // #code points in the buffer
6410 size_t n = 1; // #code points in this char
6411 size_t sz = (size_t)ale->type->nextOf()->size();
6413 switch (sz)
6415 case 1:
6416 if (rvs)
6418 // find the start of the string
6419 --indx;
6420 buflen = 1;
6421 while (indx > 0 && buflen < 4)
6423 Expression * r = (*ale->elements)[indx];
6424 assert(r->op == TOKint64);
6425 utf8_t x = (utf8_t)(((IntegerExp *)r)->getInteger());
6426 if ((x & 0xC0) != 0x80)
6427 break;
6428 ++buflen;
6431 else
6432 buflen = (indx + 4 > len) ? len - indx : 4;
6433 for (size_t i = 0; i < buflen; ++i)
6435 Expression * r = (*ale->elements)[indx + i];
6436 assert(r->op == TOKint64);
6437 utf8buf[i] = (utf8_t)(((IntegerExp *)r)->getInteger());
6439 n = 0;
6440 errmsg = utf_decodeChar(&utf8buf[0], buflen, &n, &rawvalue);
6441 break;
6442 case 2:
6443 if (rvs)
6445 // find the start of the string
6446 --indx;
6447 buflen = 1;
6448 Expression * r = (*ale->elements)[indx];
6449 assert(r->op == TOKint64);
6450 unsigned short x = (unsigned short)(((IntegerExp *)r)->getInteger());
6451 if (indx > 0 && x >= 0xDC00 && x <= 0xDFFF)
6453 --indx;
6454 ++buflen;
6457 else
6458 buflen = (indx + 2 > len) ? len - indx : 2;
6459 for (size_t i=0; i < buflen; ++i)
6461 Expression * r = (*ale->elements)[indx + i];
6462 assert(r->op == TOKint64);
6463 utf16buf[i] = (unsigned short)(((IntegerExp *)r)->getInteger());
6465 n = 0;
6466 errmsg = utf_decodeWchar(&utf16buf[0], buflen, &n, &rawvalue);
6467 break;
6468 case 4:
6470 if (rvs)
6471 --indx;
6473 Expression * r = (*ale->elements)[indx];
6474 assert(r->op == TOKint64);
6475 rawvalue = (dchar_t)((IntegerExp *)r)->getInteger();
6476 n = 1;
6478 break;
6479 default:
6480 assert(0);
6482 if (!rvs)
6483 indx += n;
6485 else
6487 // String literals
6488 size_t saveindx; // used for reverse iteration
6490 switch (se->sz)
6492 case 1:
6493 if (rvs)
6495 // find the start of the string
6496 utf8_t *s = (utf8_t *)se->string;
6497 --indx;
6498 while (indx > 0 && ((s[indx]&0xC0) == 0x80))
6499 --indx;
6500 saveindx = indx;
6502 errmsg = utf_decodeChar((utf8_t *)se->string, se->len, &indx, &rawvalue);
6503 if (rvs)
6504 indx = saveindx;
6505 break;
6506 case 2:
6507 if (rvs)
6509 // find the start
6510 unsigned short *s = (unsigned short *)se->string;
6511 --indx;
6512 if (s[indx] >= 0xDC00 && s[indx]<= 0xDFFF)
6513 --indx;
6514 saveindx = indx;
6516 errmsg = utf_decodeWchar((unsigned short *)se->string, se->len, &indx, &rawvalue);
6517 if (rvs)
6518 indx = saveindx;
6519 break;
6520 case 4:
6521 if (rvs)
6522 --indx;
6523 rawvalue = ((unsigned *)(se->string))[indx];
6524 if (!rvs)
6525 ++indx;
6526 break;
6527 default:
6528 assert(0);
6531 if (errmsg)
6533 deleg->error("%s", errmsg);
6534 return CTFEExp::cantexp;
6537 // Step 2: encode the dchar in the target encoding
6539 int charlen = 1; // How many codepoints are involved?
6540 switch (charType->size())
6542 case 1:
6543 charlen = utf_codeLengthChar(rawvalue);
6544 utf_encodeChar(&utf8buf[0], rawvalue);
6545 break;
6546 case 2:
6547 charlen = utf_codeLengthWchar(rawvalue);
6548 utf_encodeWchar(&utf16buf[0], rawvalue);
6549 break;
6550 case 4:
6551 break;
6552 default:
6553 assert(0);
6555 if (rvs)
6556 currentIndex = indx;
6558 // Step 3: call the delegate once for each code point
6560 // The index only needs to be set once
6561 if (numParams == 2)
6562 args[0] = new IntegerExp(deleg->loc, currentIndex, indexType);
6564 Expression *val = NULL;
6566 for (int k= 0; k < charlen; ++k)
6568 dchar_t codepoint;
6569 switch (charType->size())
6571 case 1:
6572 codepoint = utf8buf[k];
6573 break;
6574 case 2:
6575 codepoint = utf16buf[k];
6576 break;
6577 case 4:
6578 codepoint = rawvalue;
6579 break;
6580 default:
6581 assert(0);
6583 val = new IntegerExp(str->loc, codepoint, charType);
6585 args[numParams - 1] = val;
6587 eresult = interpretFunction(fd, istate, &args, pthis);
6588 if (exceptionOrCantInterpret(eresult))
6589 return eresult;
6590 assert(eresult->op == TOKint64);
6591 if (((IntegerExp *)eresult)->getInteger() != 0)
6592 return eresult;
6595 return eresult;
6598 /* If this is a built-in function, return the interpreted result,
6599 * Otherwise, return NULL.
6601 Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
6602 FuncDeclaration *fd, Expressions *arguments, Expression *pthis)
6604 Expression *e = NULL;
6605 size_t nargs = arguments ? arguments->dim : 0;
6606 if (!pthis)
6608 if (isBuiltin(fd) == BUILTINyes)
6610 Expressions args;
6611 args.setDim(nargs);
6612 for (size_t i = 0; i < args.dim; i++)
6614 Expression *earg = (*arguments)[i];
6615 earg = interpret(earg, istate);
6616 if (exceptionOrCantInterpret(earg))
6617 return earg;
6618 args[i] = earg;
6620 e = eval_builtin(loc, fd, &args);
6621 if (!e)
6623 error(loc, "cannot evaluate unimplemented builtin %s at compile time", fd->toChars());
6624 e = CTFEExp::cantexp;
6628 if (!pthis)
6630 Expression *firstarg = nargs > 0 ? (*arguments)[0] : NULL;
6631 if (firstarg && firstarg->type->toBasetype()->ty == Taarray)
6633 TypeAArray *firstAAtype = (TypeAArray *)firstarg->type;
6634 const char *id = fd->ident->toChars();
6635 if (nargs == 1 && fd->ident == Id::aaLen)
6636 return interpret_length(istate, firstarg);
6637 if (nargs == 3 && !strcmp(id, "_aaApply"))
6638 return interpret_aaApply(istate, firstarg, (Expression *)(arguments->data[2]));
6639 if (nargs == 3 && !strcmp(id, "_aaApply2"))
6640 return interpret_aaApply(istate, firstarg, (Expression *)(arguments->data[2]));
6641 if (nargs == 1 && !strcmp(id, "keys") && !strcmp(fd->toParent2()->ident->toChars(), "object"))
6642 return interpret_keys(istate, firstarg, firstAAtype->index->arrayOf());
6643 if (nargs == 1 && !strcmp(id, "values") && !strcmp(fd->toParent2()->ident->toChars(), "object"))
6644 return interpret_values(istate, firstarg, firstAAtype->nextOf()->arrayOf());
6645 if (nargs == 1 && !strcmp(id, "rehash") && !strcmp(fd->toParent2()->ident->toChars(), "object"))
6646 return interpret(firstarg, istate);
6647 if (nargs == 1 && !strcmp(id, "dup") && !strcmp(fd->toParent2()->ident->toChars(), "object"))
6648 return interpret_dup(istate, firstarg);
6651 if (pthis && !fd->fbody && fd->isCtorDeclaration() && fd->parent && fd->parent->parent && fd->parent->parent->ident == Id::object)
6653 if (pthis->op == TOKclassreference && fd->parent->ident == Id::Throwable)
6655 // At present, the constructors just copy their arguments into the struct.
6656 // But we might need some magic if stack tracing gets added to druntime.
6657 StructLiteralExp *se = ((ClassReferenceExp *)pthis)->value;
6658 assert(arguments->dim <= se->elements->dim);
6659 for (size_t i = 0; i < arguments->dim; ++i)
6661 e = interpret((*arguments)[i], istate);
6662 if (exceptionOrCantInterpret(e))
6663 return e;
6664 (*se->elements)[i] = e;
6666 return CTFEExp::voidexp;
6669 if (nargs == 1 && !pthis &&
6670 (fd->ident == Id::criticalenter || fd->ident == Id::criticalexit))
6672 // Support synchronized{} as a no-op
6673 return CTFEExp::voidexp;
6675 if (!pthis)
6677 const char *id = fd->ident->toChars();
6678 size_t idlen = strlen(id);
6679 if (nargs == 2 && (idlen == 10 || idlen == 11) &&
6680 !strncmp(id, "_aApply", 7))
6682 // Functions from aApply.d and aApplyR.d in the runtime
6683 bool rvs = (idlen == 11); // true if foreach_reverse
6684 char c = id[idlen-3]; // char width: 'c', 'w', or 'd'
6685 char s = id[idlen-2]; // string width: 'c', 'w', or 'd'
6686 char n = id[idlen-1]; // numParams: 1 or 2.
6687 // There are 12 combinations
6688 if ((n == '1' || n == '2') &&
6689 (c == 'c' || c == 'w' || c == 'd') &&
6690 (s == 'c' || s == 'w' || s == 'd') && c != s)
6692 Expression *str = (*arguments)[0];
6693 str = interpret(str, istate);
6694 if (exceptionOrCantInterpret(str))
6695 return str;
6696 return foreachApplyUtf(istate, str, (*arguments)[1], rvs);
6700 return e;
6703 Expression *evaluatePostblit(InterState *istate, Expression *e)
6705 Type *tb = e->type->baseElemOf();
6706 if (tb->ty != Tstruct)
6707 return NULL;
6708 StructDeclaration *sd = ((TypeStruct *)tb)->sym;
6709 if (!sd->postblit)
6710 return NULL;
6712 if (e->op == TOKarrayliteral)
6714 ArrayLiteralExp *ale = (ArrayLiteralExp *)e;
6715 for (size_t i = 0; i < ale->elements->dim; i++)
6717 e = evaluatePostblit(istate, (*ale->elements)[i]);
6718 if (e)
6719 return e;
6721 return NULL;
6723 if (e->op == TOKstructliteral)
6725 // e.__postblit()
6726 e = interpretFunction(sd->postblit, istate, NULL, e);
6727 if (exceptionOrCantInterpret(e))
6728 return e;
6729 return NULL;
6731 assert(0);
6732 return NULL;
6735 Expression *evaluateDtor(InterState *istate, Expression *e)
6737 Type *tb = e->type->baseElemOf();
6738 if (tb->ty != Tstruct)
6739 return NULL;
6740 StructDeclaration *sd = ((TypeStruct *)tb)->sym;
6741 if (!sd->dtor)
6742 return NULL;
6744 if (e->op == TOKarrayliteral)
6746 ArrayLiteralExp *alex = (ArrayLiteralExp *)e;
6747 for (size_t i = alex->elements->dim; 0 < i--; )
6748 e = evaluateDtor(istate, (*alex->elements)[i]);
6750 else if (e->op == TOKstructliteral)
6752 // e.__dtor()
6753 e = interpretFunction(sd->dtor, istate, NULL, e);
6755 else
6756 assert(0);
6757 if (exceptionOrCantInterpret(e))
6758 return e;
6759 return NULL;
6762 /*************************** CTFE Sanity Checks ***************************/
6764 /* Setter functions for CTFE variable values.
6765 * These functions exist to check for compiler CTFE bugs.
6767 bool hasValue(VarDeclaration *vd)
6769 if (vd->ctfeAdrOnStack == -1)
6770 return false;
6771 return NULL != getValue(vd);
6774 Expression *getValue(VarDeclaration *vd)
6776 return ctfeStack.getValue(vd);
6779 void setValueNull(VarDeclaration *vd)
6781 ctfeStack.setValue(vd, NULL);
6784 // Don't check for validity
6785 void setValueWithoutChecking(VarDeclaration *vd, Expression *newval)
6787 ctfeStack.setValue(vd, newval);
6790 void setValue(VarDeclaration *vd, Expression *newval)
6792 assert((vd->storage_class & (STCout | STCref))
6793 ? isCtfeReferenceValid(newval)
6794 : isCtfeValueValid(newval));
6795 ctfeStack.setValue(vd, newval);