1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2021 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/expression.c
9  */
10 
11 #include "root/dsystem.h"
12 #include "root/rmem.h"
13 #include "root/root.h"
14 
15 #include "errors.h"
16 #include "mtype.h"
17 #include "init.h"
18 #include "expression.h"
19 #include "template.h"
20 #include "utf.h"
21 #include "enum.h"
22 #include "scope.h"
23 #include "statement.h"
24 #include "declaration.h"
25 #include "aggregate.h"
26 #include "import.h"
27 #include "id.h"
28 #include "dsymbol.h"
29 #include "module.h"
30 #include "attrib.h"
31 #include "hdrgen.h"
32 #include "parse.h"
33 #include "doc.h"
34 #include "root/aav.h"
35 #include "nspace.h"
36 #include "ctfe.h"
37 #include "target.h"
38 
39 bool walkPostorder(Expression *e, StoppableVisitor *v);
40 bool checkParamArgumentEscape(Scope *sc, FuncDeclaration *fdc, Identifier *par, Expression *arg, bool gag);
41 bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember);
42 VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e);
43 Expression *extractSideEffect(Scope *sc, const char *name, Expression **e0, Expression *e, bool alwaysCopy = false);
44 char *MODtoChars(MOD mod);
45 bool MODimplicitConv(MOD modfrom, MOD modto);
46 void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod);
47 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
48 bool checkUnsafeAccess(Scope *sc, Expression *e, bool readonly, bool printmsg);
49 void toAutoQualChars(const char **result, Type *t1, Type *t2);
50 
51 /*****************************************
52  * Determine if 'this' is available.
53  * If it is, return the FuncDeclaration that has it.
54  */
55 
hasThis(Scope * sc)56 FuncDeclaration *hasThis(Scope *sc)
57 {
58     //printf("hasThis()\n");
59     Dsymbol *p = sc->parent;
60     while (p && p->isTemplateMixin())
61         p = p->parent;
62     FuncDeclaration *fdthis = p ? p->isFuncDeclaration() : NULL;
63     //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : "");
64 
65     // Go upwards until we find the enclosing member function
66     FuncDeclaration *fd = fdthis;
67     while (1)
68     {
69         if (!fd)
70         {
71             goto Lno;
72         }
73         if (!fd->isNested())
74             break;
75 
76         Dsymbol *parent = fd->parent;
77         while (1)
78         {
79             if (!parent)
80                 goto Lno;
81             TemplateInstance *ti = parent->isTemplateInstance();
82             if (ti)
83                 parent = ti->parent;
84             else
85                 break;
86         }
87         fd = parent->isFuncDeclaration();
88     }
89 
90     if (!fd->isThis())
91     {   //printf("test '%s'\n", fd->toChars());
92         goto Lno;
93     }
94 
95     assert(fd->vthis);
96     return fd;
97 
98 Lno:
99     return NULL;                // don't have 'this' available
100 }
101 
isNeedThisScope(Scope * sc,Declaration * d)102 bool isNeedThisScope(Scope *sc, Declaration *d)
103 {
104     if (sc->intypeof == 1)
105         return false;
106 
107     AggregateDeclaration *ad = d->isThis();
108     if (!ad)
109         return false;
110     //printf("d = %s, ad = %s\n", d->toChars(), ad->toChars());
111 
112     for (Dsymbol *s = sc->parent; s; s = s->toParent2())
113     {
114         //printf("\ts = %s %s, toParent2() = %p\n", s->kind(), s->toChars(), s->toParent2());
115         if (AggregateDeclaration *ad2 = s->isAggregateDeclaration())
116         {
117             if (ad2 == ad)
118                 return false;
119             else if (ad2->isNested())
120                 continue;
121             else
122                 return true;
123         }
124         if (FuncDeclaration *f = s->isFuncDeclaration())
125         {
126             if (f->isMember2())
127                 break;
128         }
129     }
130     return true;
131 }
132 
133 /******************************
134  * check e is exp.opDispatch!(tiargs) or not
135  * It's used to switch to UFCS the semantic analysis path
136  */
137 
isDotOpDispatch(Expression * e)138 bool isDotOpDispatch(Expression *e)
139 {
140     return e->op == TOKdotti &&
141            ((DotTemplateInstanceExp *)e)->ti->name == Id::opDispatch;
142 }
143 
144 /****************************************
145  * Expand tuples.
146  * Input:
147  *      exps    aray of Expressions
148  * Output:
149  *      exps    rewritten in place
150  */
151 
expandTuples(Expressions * exps)152 void expandTuples(Expressions *exps)
153 {
154     //printf("expandTuples()\n");
155     if (exps)
156     {
157         for (size_t i = 0; i < exps->length; i++)
158         {
159             Expression *arg = (*exps)[i];
160             if (!arg)
161                 continue;
162 
163             // Look for tuple with 0 members
164             if (arg->op == TOKtype)
165             {
166                 TypeExp *e = (TypeExp *)arg;
167                 if (e->type->toBasetype()->ty == Ttuple)
168                 {
169                     TypeTuple *tt = (TypeTuple *)e->type->toBasetype();
170 
171                     if (!tt->arguments || tt->arguments->length == 0)
172                     {
173                         exps->remove(i);
174                         if (i == exps->length)
175                             return;
176                         i--;
177                         continue;
178                     }
179                 }
180             }
181 
182             // Inline expand all the tuples
183             while (arg->op == TOKtuple)
184             {
185                 TupleExp *te = (TupleExp *)arg;
186                 exps->remove(i);                // remove arg
187                 exps->insert(i, te->exps);      // replace with tuple contents
188                 if (i == exps->length)
189                     return;             // empty tuple, no more arguments
190                 (*exps)[i] = Expression::combine(te->e0, (*exps)[i]);
191                 arg = (*exps)[i];
192             }
193         }
194     }
195 }
196 
197 /****************************************
198  * Expand alias this tuples.
199  */
200 
isAliasThisTuple(Expression * e)201 TupleDeclaration *isAliasThisTuple(Expression *e)
202 {
203     if (!e->type)
204         return NULL;
205 
206     Type *t = e->type->toBasetype();
207 Lagain:
208     if (Dsymbol *s = t->toDsymbol(NULL))
209     {
210         AggregateDeclaration *ad = s->isAggregateDeclaration();
211         if (ad)
212         {
213             s = ad->aliasthis;
214             if (s && s->isVarDeclaration())
215             {
216                 TupleDeclaration *td = s->isVarDeclaration()->toAlias()->isTupleDeclaration();
217                 if (td && td->isexp)
218                     return td;
219             }
220             if (Type *att = t->aliasthisOf())
221             {
222                 t = att;
223                 goto Lagain;
224             }
225         }
226     }
227     return NULL;
228 }
229 
expandAliasThisTuples(Expressions * exps,size_t starti)230 int expandAliasThisTuples(Expressions *exps, size_t starti)
231 {
232     if (!exps || exps->length == 0)
233         return -1;
234 
235     for (size_t u = starti; u < exps->length; u++)
236     {
237         Expression *exp = (*exps)[u];
238         TupleDeclaration *td = isAliasThisTuple(exp);
239         if (td)
240         {
241             exps->remove(u);
242             for (size_t i = 0; i<td->objects->length; ++i)
243             {
244                 Expression *e = isExpression((*td->objects)[i]);
245                 assert(e);
246                 assert(e->op == TOKdsymbol);
247                 DsymbolExp *se = (DsymbolExp *)e;
248                 Declaration *d = se->s->isDeclaration();
249                 assert(d);
250                 e = new DotVarExp(exp->loc, exp, d);
251                 assert(d->type);
252                 e->type = d->type;
253                 exps->insert(u + i, e);
254             }
255             return (int)u;
256         }
257     }
258 
259     return -1;
260 }
261 
262 /****************************************
263  * Get TemplateDeclaration enclosing FuncDeclaration.
264  */
265 
getFuncTemplateDecl(Dsymbol * s)266 TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s)
267 {
268     FuncDeclaration *f = s->isFuncDeclaration();
269     if (f && f->parent)
270     {
271         TemplateInstance *ti = f->parent->isTemplateInstance();
272         if (ti && !ti->isTemplateMixin() &&
273             ti->tempdecl && ((TemplateDeclaration *)ti->tempdecl)->onemember &&
274             ti->tempdecl->ident == f->ident)
275         {
276             return (TemplateDeclaration *)ti->tempdecl;
277         }
278     }
279     return NULL;
280 }
281 
282 /************************************************
283  * If we want the value of this expression, but do not want to call
284  * the destructor on it.
285  */
286 
valueNoDtor(Expression * e)287 Expression *valueNoDtor(Expression *e)
288 {
289     if (e->op == TOKcall)
290     {
291         /* The struct value returned from the function is transferred
292          * so do not call the destructor on it.
293          * Recognize:
294          *       ((S _ctmp = S.init), _ctmp).this(...)
295          * and make sure the destructor is not called on _ctmp
296          * BUG: if e is a CommaExp, we should go down the right side.
297          */
298         CallExp *ce = (CallExp *)e;
299         if (ce->e1->op == TOKdotvar)
300         {
301             DotVarExp *dve = (DotVarExp *)ce->e1;
302             if (dve->var->isCtorDeclaration())
303             {
304                 // It's a constructor call
305                 if (dve->e1->op == TOKcomma)
306                 {
307                     CommaExp *comma = (CommaExp *)dve->e1;
308                     if (comma->e2->op == TOKvar)
309                     {
310                         VarExp *ve = (VarExp *)comma->e2;
311                         VarDeclaration *ctmp = ve->var->isVarDeclaration();
312                         if (ctmp)
313                         {
314                             ctmp->storage_class |= STCnodtor;
315                             assert(!ce->isLvalue());
316                         }
317                     }
318                 }
319             }
320         }
321     }
322     else if (e->op == TOKvar)
323     {
324         VarDeclaration *vtmp = ((VarExp *)e)->var->isVarDeclaration();
325         if (vtmp && vtmp->storage_class & STCrvalue)
326         {
327             vtmp->storage_class |= STCnodtor;
328         }
329     }
330     return e;
331 }
332 
333 /*********************************************
334  * If e is an instance of a struct, and that struct has a copy constructor,
335  * rewrite e as:
336  *    (tmp = e),tmp
337  * Input:
338  *      sc      just used to specify the scope of created temporary variable
339  */
callCpCtor(Scope * sc,Expression * e)340 Expression *callCpCtor(Scope *sc, Expression *e)
341 {
342     Type *tv = e->type->baseElemOf();
343     if (tv->ty == Tstruct)
344     {
345         StructDeclaration *sd = ((TypeStruct *)tv)->sym;
346         if (sd->postblit)
347         {
348             /* Create a variable tmp, and replace the argument e with:
349              *      (tmp = e),tmp
350              * and let AssignExp() handle the construction.
351              * This is not the most efficent, ideally tmp would be constructed
352              * directly onto the stack.
353              */
354             VarDeclaration *tmp = copyToTemp(STCrvalue, "__copytmp", e);
355             tmp->storage_class |= STCnodtor;
356             dsymbolSemantic(tmp, sc);
357             Expression *de = new DeclarationExp(e->loc, tmp);
358             Expression *ve = new VarExp(e->loc, tmp);
359             de->type = Type::tvoid;
360             ve->type = e->type;
361             e = Expression::combine(de, ve);
362         }
363     }
364     return e;
365 }
366 
367 /************************************************
368  * Handle the postblit call on lvalue, or the move of rvalue.
369  */
doCopyOrMove(Scope * sc,Expression * e)370 Expression *doCopyOrMove(Scope *sc, Expression *e)
371 {
372     if (e->op == TOKquestion)
373     {
374         CondExp *ce = (CondExp *)e;
375         ce->e1 = doCopyOrMove(sc, ce->e1);
376         ce->e2 = doCopyOrMove(sc, ce->e2);
377     }
378     else
379     {
380         e = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e);
381     }
382     return e;
383 }
384 
385 /******************************** Expression **************************/
386 
Expression(Loc loc,TOK op,int size)387 Expression::Expression(Loc loc, TOK op, int size)
388 {
389     //printf("Expression::Expression(op = %d) this = %p\n", op, this);
390     this->loc = loc;
391     this->op = op;
392     this->size = (unsigned char)size;
393     this->parens = 0;
394     type = NULL;
395 }
396 
_init()397 void Expression::_init()
398 {
399     CTFEExp::cantexp = new CTFEExp(TOKcantexp);
400     CTFEExp::voidexp = new CTFEExp(TOKvoidexp);
401     CTFEExp::breakexp = new CTFEExp(TOKbreak);
402     CTFEExp::continueexp = new CTFEExp(TOKcontinue);
403     CTFEExp::gotoexp = new CTFEExp(TOKgoto);
404 }
405 
syntaxCopy()406 Expression *Expression::syntaxCopy()
407 {
408     //printf("Expression::syntaxCopy()\n");
409     //print();
410     return copy();
411 }
412 
413 /*********************************
414  * Does *not* do a deep copy.
415  */
416 
copy()417 Expression *Expression::copy()
418 {
419     Expression *e;
420     if (!size)
421     {
422         assert(0);
423     }
424     void *pe = mem.xmalloc(size);
425     //printf("Expression::copy(op = %d) e = %p\n", op, pe);
426     e = (Expression *)memcpy(pe, (void *)this, size);
427     return e;
428 }
429 
print()430 void Expression::print()
431 {
432     fprintf(stderr, "%s\n", toChars());
433     fflush(stderr);
434 }
435 
toChars()436 const char *Expression::toChars()
437 {
438     OutBuffer buf;
439     HdrGenState hgs;
440     toCBuffer(this, &buf, &hgs);
441     return buf.extractChars();
442 }
443 
error(const char * format,...)444 void Expression::error(const char *format, ...) const
445 {
446     if (type != Type::terror)
447     {
448         va_list ap;
449         va_start(ap, format);
450         ::verror(loc, format, ap);
451         va_end( ap );
452     }
453 }
454 
warning(const char * format,...)455 void Expression::warning(const char *format, ...) const
456 {
457     if (type != Type::terror)
458     {
459         va_list ap;
460         va_start(ap, format);
461         ::vwarning(loc, format, ap);
462         va_end( ap );
463     }
464 }
465 
deprecation(const char * format,...)466 void Expression::deprecation(const char *format, ...) const
467 {
468     if (type != Type::terror)
469     {
470         va_list ap;
471         va_start(ap, format);
472         ::vdeprecation(loc, format, ap);
473         va_end( ap );
474     }
475 }
476 
477 /**********************************
478  * Combine e1 and e2 by CommaExp if both are not NULL.
479  */
combine(Expression * e1,Expression * e2)480 Expression *Expression::combine(Expression *e1, Expression *e2)
481 {
482     if (e1)
483     {
484         if (e2)
485         {
486             e1 = new CommaExp(e1->loc, e1, e2);
487             e1->type = e2->type;
488         }
489     }
490     else
491         e1 = e2;
492     return e1;
493 }
494 
495 /**********************************
496  * If 'e' is a tree of commas, returns the leftmost expression
497  * by stripping off it from the tree. The remained part of the tree
498  * is returned via *pe0.
499  * Otherwise 'e' is directly returned and *pe0 is set to NULL.
500  */
extractLast(Expression * e,Expression ** pe0)501 Expression *Expression::extractLast(Expression *e, Expression **pe0)
502 {
503     if (e->op != TOKcomma)
504     {
505         *pe0 = NULL;
506         return e;
507     }
508 
509     CommaExp *ce = (CommaExp *)e;
510     if (ce->e2->op != TOKcomma)
511     {
512         *pe0 = ce->e1;
513         return ce->e2;
514     }
515     else
516     {
517         *pe0 = e;
518 
519         Expression **pce = &ce->e2;
520         while (((CommaExp *)(*pce))->e2->op == TOKcomma)
521         {
522             pce = &((CommaExp *)(*pce))->e2;
523         }
524         assert((*pce)->op == TOKcomma);
525         ce = (CommaExp *)(*pce);
526         *pce = ce->e1;
527 
528         return ce->e2;
529     }
530 }
531 
toInteger()532 dinteger_t Expression::toInteger()
533 {
534     //printf("Expression %s\n", Token::toChars(op));
535     error("integer constant expression expected instead of %s", toChars());
536     return 0;
537 }
538 
toUInteger()539 uinteger_t Expression::toUInteger()
540 {
541     //printf("Expression %s\n", Token::toChars(op));
542     return (uinteger_t)toInteger();
543 }
544 
toReal()545 real_t Expression::toReal()
546 {
547     error("floating point constant expression expected instead of %s", toChars());
548     return CTFloat::zero;
549 }
550 
toImaginary()551 real_t Expression::toImaginary()
552 {
553     error("floating point constant expression expected instead of %s", toChars());
554     return CTFloat::zero;
555 }
556 
toComplex()557 complex_t Expression::toComplex()
558 {
559     error("floating point constant expression expected instead of %s", toChars());
560     return complex_t(CTFloat::zero);
561 }
562 
toStringExp()563 StringExp *Expression::toStringExp()
564 {
565     return NULL;
566 }
567 
toTupleExp()568 TupleExp *Expression::toTupleExp()
569 {
570     return NULL;
571 }
572 
573 /***************************************
574  * Return !=0 if expression is an lvalue.
575  */
576 
isLvalue()577 bool Expression::isLvalue()
578 {
579     return false;
580 }
581 
582 /*******************************
583  * Give error if we're not an lvalue.
584  * If we can, convert expression to be an lvalue.
585  */
586 
toLvalue(Scope *,Expression * e)587 Expression *Expression::toLvalue(Scope *, Expression *e)
588 {
589     if (!e)
590         e = this;
591     else if (!loc.filename)
592         loc = e->loc;
593 
594     if (e->op == TOKtype)
595         error("%s `%s` is a type, not an lvalue", e->type->kind(), e->type->toChars());
596     else
597         error("%s is not an lvalue", e->toChars());
598 
599     return new ErrorExp();
600 }
601 
602 /***************************************
603  * Parameters:
604  *      sc:     scope
605  *      flag:   1: do not issue error message for invalid modification
606  * Returns:
607  *      0:      is not modifiable
608  *      1:      is modifiable in default == being related to type->isMutable()
609  *      2:      is modifiable, because this is a part of initializing.
610  */
611 
checkModifiable(Scope *,int)612 int Expression::checkModifiable(Scope *, int)
613 {
614     return type ? 1 : 0;    // default modifiable
615 }
616 
modifiableLvalue(Scope * sc,Expression * e)617 Expression *Expression::modifiableLvalue(Scope *sc, Expression *e)
618 {
619     //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars());
620 
621     // See if this expression is a modifiable lvalue (i.e. not const)
622     if (checkModifiable(sc) == 1)
623     {
624         assert(type);
625         if (!type->isMutable())
626         {
627             error("cannot modify %s expression %s", MODtoChars(type->mod), toChars());
628             return new ErrorExp();
629         }
630         else if (!type->isAssignable())
631         {
632             error("cannot modify struct %s %s with immutable members", toChars(), type->toChars());
633             return new ErrorExp();
634         }
635     }
636     return toLvalue(sc, e);
637 }
638 
639 /****************************************
640  * Check that the expression has a valid type.
641  * If not, generates an error "... has no type".
642  * Returns:
643  *      true if the expression is not valid.
644  * Note:
645  *      When this function returns true, `checkValue()` should also return true.
646  */
checkType()647 bool Expression::checkType()
648 {
649     return false;
650 }
651 
652 /****************************************
653  * Check that the expression has a valid value.
654  * If not, generates an error "... has no value".
655  * Returns:
656  *      true if the expression is not valid or has void type.
657  */
checkValue()658 bool Expression::checkValue()
659 {
660     if (type && type->toBasetype()->ty == Tvoid)
661     {
662         error("expression %s is void and has no value", toChars());
663         //print(); halt();
664         if (!global.gag)
665             type = Type::terror;
666         return true;
667     }
668     return false;
669 }
670 
checkScalar()671 bool Expression::checkScalar()
672 {
673     if (op == TOKerror)
674         return true;
675     if (type->toBasetype()->ty == Terror)
676         return true;
677     if (!type->isscalar())
678     {
679         error("`%s` is not a scalar, it is a %s", toChars(), type->toChars());
680         return true;
681     }
682     return checkValue();
683 }
684 
checkNoBool()685 bool Expression::checkNoBool()
686 {
687     if (op == TOKerror)
688         return true;
689     if (type->toBasetype()->ty == Terror)
690         return true;
691     if (type->toBasetype()->ty == Tbool)
692     {
693         error("operation not allowed on bool `%s`", toChars());
694         return true;
695     }
696     return false;
697 }
698 
checkIntegral()699 bool Expression::checkIntegral()
700 {
701     if (op == TOKerror)
702         return true;
703     if (type->toBasetype()->ty == Terror)
704         return true;
705     if (!type->isintegral())
706     {
707         error("`%s` is not of integral type, it is a %s", toChars(), type->toChars());
708         return true;
709     }
710     return checkValue();
711 }
712 
checkArithmetic()713 bool Expression::checkArithmetic()
714 {
715     if (op == TOKerror)
716         return true;
717     if (type->toBasetype()->ty == Terror)
718         return true;
719     if (!type->isintegral() && !type->isfloating())
720     {
721         error("`%s` is not of arithmetic type, it is a %s", toChars(), type->toChars());
722         return true;
723     }
724     return checkValue();
725 }
726 
checkDeprecated(Scope * sc,Dsymbol * s)727 bool Expression::checkDeprecated(Scope *sc, Dsymbol *s)
728 {
729     return s->checkDeprecated(loc, sc);
730 }
731 
checkDisabled(Scope * sc,Dsymbol * s)732 bool Expression::checkDisabled(Scope *sc, Dsymbol *s)
733 {
734     if (Declaration *d = s->isDeclaration())
735     {
736         return d->checkDisabled(loc, sc);
737     }
738     return false;
739 }
740 
741 /*********************************************
742  * Calling function f.
743  * Check the purity, i.e. if we're in a pure function
744  * we can only call other pure functions.
745  * Returns true if error occurs.
746  */
checkPurity(Scope * sc,FuncDeclaration * f)747 bool Expression::checkPurity(Scope *sc, FuncDeclaration *f)
748 {
749     if (!sc->func)
750         return false;
751     if (sc->func == f)
752         return false;
753     if (sc->intypeof == 1)
754         return false;
755     if (sc->flags & (SCOPEctfe | SCOPEdebug))
756         return false;
757 
758     /* Given:
759      * void f() {
760      *   pure void g() {
761      *     /+pure+/ void h() {
762      *       /+pure+/ void i() { }
763      *     }
764      *   }
765      * }
766      * g() can call h() but not f()
767      * i() can call h() and g() but not f()
768      */
769 
770     // Find the closest pure parent of the calling function
771     FuncDeclaration *outerfunc = sc->func;
772     FuncDeclaration *calledparent = f;
773 
774     if (outerfunc->isInstantiated())
775     {
776         // The attributes of outerfunc should be inferred from the call of f.
777     }
778     else if (f->isInstantiated())
779     {
780         // The attributes of f are inferred from its body.
781     }
782     else if (f->isFuncLiteralDeclaration())
783     {
784         // The attributes of f are always inferred in its declared place.
785     }
786     else
787     {
788         /* Today, static local functions are impure by default, but they cannot
789          * violate purity of enclosing functions.
790          *
791          *  auto foo() pure {      // non instantiated funciton
792          *    static auto bar() {  // static, without pure attribute
793          *      impureFunc();      // impure call
794          *      // Although impureFunc is called inside bar, f(= impureFunc)
795          *      // is not callable inside pure outerfunc(= foo <- bar).
796          *    }
797          *
798          *    bar();
799          *    // Although bar is called inside foo, f(= bar) is callable
800          *    // bacause calledparent(= foo) is same with outerfunc(= foo).
801          *  }
802          */
803 
804         while (outerfunc->toParent2() &&
805                outerfunc->isPureBypassingInference() == PUREimpure &&
806                outerfunc->toParent2()->isFuncDeclaration())
807         {
808             outerfunc = outerfunc->toParent2()->isFuncDeclaration();
809             if (outerfunc->type->ty == Terror)
810                 return true;
811         }
812         while (calledparent->toParent2() &&
813                calledparent->isPureBypassingInference() == PUREimpure &&
814                calledparent->toParent2()->isFuncDeclaration())
815         {
816             calledparent = calledparent->toParent2()->isFuncDeclaration();
817             if (calledparent->type->ty == Terror)
818                 return true;
819         }
820     }
821 
822     // If the caller has a pure parent, then either the called func must be pure,
823     // OR, they must have the same pure parent.
824     if (!f->isPure() && calledparent != outerfunc)
825     {
826         FuncDeclaration *ff = outerfunc;
827         if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
828         {
829             error("pure %s `%s` cannot call impure %s `%s`",
830                 ff->kind(), ff->toPrettyChars(), f->kind(), f->toPrettyChars());
831             return true;
832         }
833     }
834     return false;
835 }
836 
837 /*******************************************
838  * Accessing variable v.
839  * Check for purity and safety violations.
840  * Returns true if error occurs.
841  */
checkPurity(Scope * sc,VarDeclaration * v)842 bool Expression::checkPurity(Scope *sc, VarDeclaration *v)
843 {
844     //printf("v = %s %s\n", v->type->toChars(), v->toChars());
845 
846     /* Look for purity and safety violations when accessing variable v
847      * from current function.
848      */
849     if (!sc->func)
850         return false;
851     if (sc->intypeof == 1)
852         return false;   // allow violations inside typeof(expression)
853     if (sc->flags & (SCOPEctfe | SCOPEdebug))
854         return false;   // allow violations inside compile-time evaluated expressions and debug conditionals
855     if (v->ident == Id::ctfe)
856         return false;   // magic variable never violates pure and safe
857     if (v->isImmutable())
858         return false;   // always safe and pure to access immutables...
859     if (v->isConst() && !v->isRef() && (v->isDataseg() || v->isParameter()) &&
860         v->type->implicitConvTo(v->type->immutableOf()))
861         return false;   // or const global/parameter values which have no mutable indirections
862     if (v->storage_class & STCmanifest)
863         return false;   // ...or manifest constants
864 
865     bool err = false;
866     if (v->isDataseg())
867     {
868         // Bugzilla 7533: Accessing implicit generated __gate is pure.
869         if (v->ident == Id::gate)
870             return false;
871 
872         /* Accessing global mutable state.
873          * Therefore, this function and all its immediately enclosing
874          * functions must be pure.
875          */
876         /* Today, static local functions are impure by default, but they cannot
877          * violate purity of enclosing functions.
878          *
879          *  auto foo() pure {      // non instantiated funciton
880          *    static auto bar() {  // static, without pure attribute
881          *      globalData++;      // impure access
882          *      // Although globalData is accessed inside bar,
883          *      // it is not accessible inside pure foo.
884          *    }
885          *  }
886          */
887         for (Dsymbol *s = sc->func; s; s = s->toParent2())
888         {
889             FuncDeclaration *ff = s->isFuncDeclaration();
890             if (!ff)
891                 break;
892             if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
893             {
894                 error("pure %s `%s` cannot access mutable static data `%s`",
895                     ff->kind(), ff->toPrettyChars(), v->toChars());
896                 err = true;
897                 break;
898             }
899             /* If the enclosing is an instantiated function or a lambda, its
900              * attribute inference result is preferred.
901              */
902             if (ff->isInstantiated())
903                 break;
904             if (ff->isFuncLiteralDeclaration())
905                 break;
906         }
907     }
908     else
909     {
910         /* Given:
911          * void f() {
912          *   int fx;
913          *   pure void g() {
914          *     int gx;
915          *     /+pure+/ void h() {
916          *       int hx;
917          *       /+pure+/ void i() { }
918          *     }
919          *   }
920          * }
921          * i() can modify hx and gx but not fx
922          */
923 
924         Dsymbol *vparent = v->toParent2();
925         for (Dsymbol *s = sc->func; !err && s; s = s->toParent2())
926         {
927             if (s == vparent)
928                 break;
929 
930             if (AggregateDeclaration *ad = s->isAggregateDeclaration())
931             {
932                 if (ad->isNested())
933                     continue;
934                 break;
935             }
936             FuncDeclaration *ff = s->isFuncDeclaration();
937             if (!ff)
938                 break;
939             if (ff->isNested() || ff->isThis())
940             {
941                 if (ff->type->isImmutable() ||
942                     (ff->type->isShared() && !MODimplicitConv(ff->type->mod, v->type->mod)))
943                 {
944                     OutBuffer ffbuf;
945                     OutBuffer vbuf;
946                     MODMatchToBuffer(&ffbuf, ff->type->mod, v->type->mod);
947                     MODMatchToBuffer(&vbuf, v->type->mod, ff->type->mod);
948                     error("%s%s `%s` cannot access %sdata `%s`",
949                         ffbuf.peekChars(), ff->kind(), ff->toPrettyChars(), vbuf.peekChars(), v->toChars());
950                     err = true;
951                     break;
952                 }
953                 continue;
954             }
955             break;
956         }
957     }
958 
959     /* Do not allow safe functions to access __gshared data
960      */
961     if (v->storage_class & STCgshared)
962     {
963         if (sc->func->setUnsafe())
964         {
965             error("safe %s `%s` cannot access __gshared data `%s`",
966                 sc->func->kind(), sc->func->toChars(), v->toChars());
967             err = true;
968         }
969     }
970 
971     return err;
972 }
973 
974 /*********************************************
975  * Calling function f.
976  * Check the safety, i.e. if we're in a @safe function
977  * we can only call @safe or @trusted functions.
978  * Returns true if error occurs.
979  */
checkSafety(Scope * sc,FuncDeclaration * f)980 bool Expression::checkSafety(Scope *sc, FuncDeclaration *f)
981 {
982     if (!sc->func)
983         return false;
984     if (sc->func == f)
985         return false;
986     if (sc->intypeof == 1)
987         return false;
988     if (sc->flags & SCOPEctfe)
989         return false;
990 
991     if (!f->isSafe() && !f->isTrusted())
992     {
993         if (sc->flags & SCOPEcompile ? sc->func->isSafeBypassingInference() : sc->func->setUnsafe())
994         {
995             if (loc.linnum == 0)  // e.g. implicitly generated dtor
996                 loc = sc->func->loc;
997 
998             error("@safe %s `%s` cannot call @system %s `%s`",
999                 sc->func->kind(), sc->func->toPrettyChars(), f->kind(), f->toPrettyChars());
1000             return true;
1001         }
1002     }
1003     return false;
1004 }
1005 
1006 /*********************************************
1007  * Calling function f.
1008  * Check the @nogc-ness, i.e. if we're in a @nogc function
1009  * we can only call other @nogc functions.
1010  * Returns true if error occurs.
1011  */
checkNogc(Scope * sc,FuncDeclaration * f)1012 bool Expression::checkNogc(Scope *sc, FuncDeclaration *f)
1013 {
1014     if (!sc->func)
1015         return false;
1016     if (sc->func == f)
1017         return false;
1018     if (sc->intypeof == 1)
1019         return false;
1020     if (sc->flags & SCOPEctfe)
1021         return false;
1022 
1023     if (!f->isNogc())
1024     {
1025         if (sc->flags & SCOPEcompile ? sc->func->isNogcBypassingInference() : sc->func->setGC())
1026         {
1027             if (loc.linnum == 0)  // e.g. implicitly generated dtor
1028                 loc = sc->func->loc;
1029 
1030             error("@nogc %s `%s` cannot call non-@nogc %s `%s`",
1031                 sc->func->kind(), sc->func->toPrettyChars(), f->kind(), f->toPrettyChars());
1032             return true;
1033         }
1034     }
1035     return false;
1036 }
1037 
1038 /********************************************
1039  * Check that the postblit is callable if t is an array of structs.
1040  * Returns true if error happens.
1041  */
checkPostblit(Scope * sc,Type * t)1042 bool Expression::checkPostblit(Scope *sc, Type *t)
1043 {
1044     t = t->baseElemOf();
1045     if (t->ty == Tstruct)
1046     {
1047         if (global.params.useTypeInfo && Type::dtypeinfo)
1048         {
1049             // Bugzilla 11395: Require TypeInfo generation for array concatenation
1050             semanticTypeInfo(sc, t);
1051         }
1052 
1053         StructDeclaration *sd = ((TypeStruct *)t)->sym;
1054         if (sd->postblit)
1055         {
1056             if (sd->postblit->checkDisabled(loc, sc))
1057                 return true;
1058             //checkDeprecated(sc, sd->postblit);        // necessary?
1059             checkPurity(sc, sd->postblit);
1060             checkSafety(sc, sd->postblit);
1061             checkNogc(sc, sd->postblit);
1062             //checkAccess(sd, loc, sc, sd->postblit);   // necessary?
1063             return false;
1064         }
1065     }
1066     return false;
1067 }
1068 
checkRightThis(Scope * sc)1069 bool Expression::checkRightThis(Scope *sc)
1070 {
1071     if (op == TOKerror)
1072         return true;
1073     if (op == TOKvar && type->ty != Terror)
1074     {
1075         VarExp *ve = (VarExp *)this;
1076         if (isNeedThisScope(sc, ve->var))
1077         {
1078             //printf("checkRightThis sc->intypeof = %d, ad = %p, func = %p, fdthis = %p\n",
1079             //        sc->intypeof, sc->getStructClassScope(), func, fdthis);
1080             error("need `this` for `%s` of type `%s`", ve->var->toChars(), ve->var->type->toChars());
1081             return true;
1082         }
1083     }
1084     return false;
1085 }
1086 
1087 /*******************************
1088  * Check whether the expression allows RMW operations, error with rmw operator diagnostic if not.
1089  * ex is the RHS expression, or NULL if ++/-- is used (for diagnostics)
1090  * Returns true if error occurs.
1091  */
checkReadModifyWrite(TOK rmwOp,Expression * ex)1092 bool Expression::checkReadModifyWrite(TOK rmwOp, Expression *ex)
1093 {
1094     //printf("Expression::checkReadModifyWrite() %s %s", toChars(), ex ? ex->toChars() : "");
1095     if (!type || !type->isShared())
1096         return false;
1097 
1098     // atomicOp uses opAssign (+=/-=) rather than opOp (++/--) for the CT string literal.
1099     switch (rmwOp)
1100     {
1101         case TOKplusplus:
1102         case TOKpreplusplus:
1103             rmwOp = TOKaddass;
1104             break;
1105 
1106         case TOKminusminus:
1107         case TOKpreminusminus:
1108             rmwOp = TOKminass;
1109             break;
1110 
1111         default:
1112             break;
1113     }
1114 
1115     deprecation("read-modify-write operations are not allowed for shared variables. "
1116                 "Use core.atomic.atomicOp!\"%s\"(%s, %s) instead.",
1117                 Token::tochars[rmwOp], toChars(), ex ? ex->toChars() : "1");
1118     return false;
1119 
1120     // note: enable when deprecation becomes an error.
1121     // return true;
1122 }
1123 
1124 /*****************************
1125  * If expression can be tested for true or false,
1126  * returns the modified expression.
1127  * Otherwise returns ErrorExp.
1128  */
toBoolean(Scope * sc)1129 Expression *Expression::toBoolean(Scope *sc)
1130 {
1131     // Default is 'yes' - do nothing
1132     Expression *e = this;
1133     Type *t = type;
1134     Type *tb = type->toBasetype();
1135     Type *att = NULL;
1136 Lagain:
1137     // Structs can be converted to bool using opCast(bool)()
1138     if (tb->ty == Tstruct)
1139     {
1140         AggregateDeclaration *ad = ((TypeStruct *)tb)->sym;
1141         /* Don't really need to check for opCast first, but by doing so we
1142          * get better error messages if it isn't there.
1143          */
1144         Dsymbol *fd = search_function(ad, Id::_cast);
1145         if (fd)
1146         {
1147             e = new CastExp(loc, e, Type::tbool);
1148             e = expressionSemantic(e, sc);
1149             return e;
1150         }
1151 
1152         // Forward to aliasthis.
1153         if (ad->aliasthis && tb != att)
1154         {
1155             if (!att && tb->checkAliasThisRec())
1156                 att = tb;
1157             e = resolveAliasThis(sc, e);
1158             t = e->type;
1159             tb = e->type->toBasetype();
1160             goto Lagain;
1161         }
1162     }
1163 
1164     if (!t->isBoolean())
1165     {
1166         if (tb != Type::terror)
1167             error("expression %s of type %s does not have a boolean value", toChars(), t->toChars());
1168         return new ErrorExp();
1169     }
1170     return e;
1171 }
1172 
1173 /******************************
1174  * Take address of expression.
1175  */
1176 
addressOf()1177 Expression *Expression::addressOf()
1178 {
1179     //printf("Expression::addressOf()\n");
1180     Expression *e = new AddrExp(loc, this);
1181     e->type = type->pointerTo();
1182     return e;
1183 }
1184 
1185 /******************************
1186  * If this is a reference, dereference it.
1187  */
1188 
deref()1189 Expression *Expression::deref()
1190 {
1191     //printf("Expression::deref()\n");
1192     // type could be null if forward referencing an 'auto' variable
1193     if (type && type->ty == Treference)
1194     {
1195         Expression *e = new PtrExp(loc, this);
1196         e->type = ((TypeReference *)type)->next;
1197         return e;
1198     }
1199     return this;
1200 }
1201 
1202 /********************************
1203  * Does this expression statically evaluate to a boolean 'result' (true or false)?
1204  */
isBool(bool)1205 bool Expression::isBool(bool)
1206 {
1207     return false;
1208 }
1209 
isIntegerExp()1210 IntegerExp *Expression::isIntegerExp()
1211 {
1212     return op == TOKint64 ? (IntegerExp *)this : NULL;
1213 }
1214 
isErrorExp()1215 ErrorExp *Expression::isErrorExp()
1216 {
1217     return op == TOKerror ? (ErrorExp *)this : NULL;
1218 }
1219 
isVoidInitExp()1220 VoidInitExp *Expression::isVoidInitExp()
1221 {
1222     return op == TOKvoid ? (VoidInitExp *)this : NULL;
1223 }
1224 
isRealExp()1225 RealExp *Expression::isRealExp()
1226 {
1227     return op == TOKfloat64 ? (RealExp *)this : NULL;
1228 }
1229 
isComplexExp()1230 ComplexExp *Expression::isComplexExp()
1231 {
1232     return op == TOKcomplex80 ? (ComplexExp *)this : NULL;
1233 }
1234 
isIdentifierExp()1235 IdentifierExp *Expression::isIdentifierExp()
1236 {
1237     return op == TOKidentifier ? (IdentifierExp *)this : NULL;
1238 }
1239 
isDollarExp()1240 DollarExp *Expression::isDollarExp()
1241 {
1242     return op == TOKdollar ? (DollarExp *)this : NULL;
1243 }
1244 
isDsymbolExp()1245 DsymbolExp *Expression::isDsymbolExp()
1246 {
1247     return op == TOKdsymbol ? (DsymbolExp *)this : NULL;
1248 }
1249 
isThisExp()1250 ThisExp *Expression::isThisExp()
1251 {
1252     return op == TOKthis ? (ThisExp *)this : NULL;
1253 }
1254 
isSuperExp()1255 SuperExp *Expression::isSuperExp()
1256 {
1257     return op == TOKsuper ? (SuperExp *)this : NULL;
1258 }
1259 
isNullExp()1260 NullExp *Expression::isNullExp()
1261 {
1262     return op == TOKnull ? (NullExp *)this : NULL;
1263 }
1264 
isStringExp()1265 StringExp *Expression::isStringExp()
1266 {
1267     return op == TOKstring ? (StringExp *)this : NULL;
1268 }
1269 
isTupleExp()1270 TupleExp *Expression::isTupleExp()
1271 {
1272     return op == TOKtuple ? (TupleExp *)this : NULL;
1273 }
1274 
isArrayLiteralExp()1275 ArrayLiteralExp *Expression::isArrayLiteralExp()
1276 {
1277     return op == TOKarrayliteral ? (ArrayLiteralExp *)this : NULL;
1278 }
1279 
isAssocArrayLiteralExp()1280 AssocArrayLiteralExp *Expression::isAssocArrayLiteralExp()
1281 {
1282     return op == TOKassocarrayliteral ? (AssocArrayLiteralExp *)this : NULL;
1283 }
1284 
isStructLiteralExp()1285 StructLiteralExp *Expression::isStructLiteralExp()
1286 {
1287     return op == TOKstructliteral ? (StructLiteralExp *)this : NULL;
1288 }
1289 
isTypeExp()1290 TypeExp *Expression::isTypeExp()
1291 {
1292     return op == TOKtype ? (TypeExp *)this : NULL;
1293 }
1294 
isScopeExp()1295 ScopeExp *Expression::isScopeExp()
1296 {
1297     return op == TOKscope ? (ScopeExp *)this : NULL;
1298 }
1299 
isTemplateExp()1300 TemplateExp *Expression::isTemplateExp()
1301 {
1302     return op == TOKtemplate ? (TemplateExp *)this : NULL;
1303 }
1304 
isNewExp()1305 NewExp *Expression::isNewExp()
1306 {
1307     return op == TOKnew ? (NewExp *)this : NULL;
1308 }
1309 
isNewAnonClassExp()1310 NewAnonClassExp *Expression::isNewAnonClassExp()
1311 {
1312     return op == TOKnewanonclass ? (NewAnonClassExp *)this : NULL;
1313 }
1314 
isSymOffExp()1315 SymOffExp *Expression::isSymOffExp()
1316 {
1317     return op == TOKsymoff ? (SymOffExp *)this : NULL;
1318 }
1319 
isVarExp()1320 VarExp *Expression::isVarExp()
1321 {
1322     return op == TOKvar ? (VarExp *)this : NULL;
1323 }
1324 
isOverExp()1325 OverExp *Expression::isOverExp()
1326 {
1327     return op == TOKoverloadset ? (OverExp *)this : NULL;
1328 }
1329 
isFuncExp()1330 FuncExp *Expression::isFuncExp()
1331 {
1332     return op == TOKfunction ? (FuncExp *)this : NULL;
1333 }
1334 
isDeclarationExp()1335 DeclarationExp *Expression::isDeclarationExp()
1336 {
1337     return op == TOKdeclaration ? (DeclarationExp *)this : NULL;
1338 }
1339 
isTypeidExp()1340 TypeidExp *Expression::isTypeidExp()
1341 {
1342     return op == TOKtypeid ? (TypeidExp *)this : NULL;
1343 }
1344 
isTraitsExp()1345 TraitsExp *Expression::isTraitsExp()
1346 {
1347     return op == TOKtraits ? (TraitsExp *)this : NULL;
1348 }
1349 
isHaltExp()1350 HaltExp *Expression::isHaltExp()
1351 {
1352     return op == TOKhalt ? (HaltExp *)this : NULL;
1353 }
1354 
isExp()1355 IsExp *Expression::isExp()
1356 {
1357     return op == TOKis ? (IsExp *)this : NULL;
1358 }
1359 
isCompileExp()1360 CompileExp *Expression::isCompileExp()
1361 {
1362     return op == TOKmixin ? (CompileExp *)this : NULL;
1363 }
1364 
isImportExp()1365 ImportExp *Expression::isImportExp()
1366 {
1367     return op == TOKimport ? (ImportExp *)this : NULL;
1368 }
1369 
isAssertExp()1370 AssertExp *Expression::isAssertExp()
1371 {
1372     return op == TOKassert ? (AssertExp *)this : NULL;
1373 }
1374 
isDotIdExp()1375 DotIdExp *Expression::isDotIdExp()
1376 {
1377     return op == TOKdotid ? (DotIdExp *)this : NULL;
1378 }
1379 
isDotTemplateExp()1380 DotTemplateExp *Expression::isDotTemplateExp()
1381 {
1382     return op == TOKdotti ? (DotTemplateExp *)this : NULL;
1383 }
1384 
isDotVarExp()1385 DotVarExp *Expression::isDotVarExp()
1386 {
1387     return op == TOKdotvar ? (DotVarExp *)this : NULL;
1388 }
1389 
isDotTemplateInstanceExp()1390 DotTemplateInstanceExp *Expression::isDotTemplateInstanceExp()
1391 {
1392     return op == TOKdotti ? (DotTemplateInstanceExp *)this : NULL;
1393 }
1394 
isDelegateExp()1395 DelegateExp *Expression::isDelegateExp()
1396 {
1397     return op == TOKdelegate ? (DelegateExp *)this : NULL;
1398 }
1399 
isDotTypeExp()1400 DotTypeExp *Expression::isDotTypeExp()
1401 {
1402     return op == TOKdottype ? (DotTypeExp *)this : NULL;
1403 }
1404 
isCallExp()1405 CallExp *Expression::isCallExp()
1406 {
1407     return op == TOKcall ? (CallExp *)this : NULL;
1408 }
1409 
isAddrExp()1410 AddrExp *Expression::isAddrExp()
1411 {
1412     return op == TOKaddress ? (AddrExp *)this : NULL;
1413 }
1414 
isPtrExp()1415 PtrExp *Expression::isPtrExp()
1416 {
1417     return op == TOKstar ? (PtrExp *)this : NULL;
1418 }
1419 
isNegExp()1420 NegExp *Expression::isNegExp()
1421 {
1422     return op == TOKneg ? (NegExp *)this : NULL;
1423 }
1424 
isUAddExp()1425 UAddExp *Expression::isUAddExp()
1426 {
1427     return op == TOKuadd ? (UAddExp *)this : NULL;
1428 }
1429 
isComExp()1430 ComExp *Expression::isComExp()
1431 {
1432     return op == TOKtilde ? (ComExp *)this : NULL;
1433 }
1434 
isNotExp()1435 NotExp *Expression::isNotExp()
1436 {
1437     return op == TOKnot ? (NotExp *)this : NULL;
1438 }
1439 
isDeleteExp()1440 DeleteExp *Expression::isDeleteExp()
1441 {
1442     return op == TOKdelete ? (DeleteExp *)this : NULL;
1443 }
1444 
isCastExp()1445 CastExp *Expression::isCastExp()
1446 {
1447     return op == TOKcast ? (CastExp *)this : NULL;
1448 }
1449 
isVectorExp()1450 VectorExp *Expression::isVectorExp()
1451 {
1452     return op == TOKvector ? (VectorExp *)this : NULL;
1453 }
1454 
isVectorArrayExp()1455 VectorArrayExp *Expression::isVectorArrayExp()
1456 {
1457     return op == TOKvectorarray ? (VectorArrayExp *)this : NULL;
1458 }
1459 
isSliceExp()1460 SliceExp *Expression::isSliceExp()
1461 {
1462     return op == TOKslice ? (SliceExp *)this : NULL;
1463 }
1464 
isArrayLengthExp()1465 ArrayLengthExp *Expression::isArrayLengthExp()
1466 {
1467     return op == TOKarraylength ? (ArrayLengthExp *)this : NULL;
1468 }
1469 
isArrayExp()1470 ArrayExp *Expression::isArrayExp()
1471 {
1472     return op == TOKarray ? (ArrayExp *)this : NULL;
1473 }
1474 
isDotExp()1475 DotExp *Expression::isDotExp()
1476 {
1477     return op == TOKdot ? (DotExp *)this : NULL;
1478 }
1479 
isCommaExp()1480 CommaExp *Expression::isCommaExp()
1481 {
1482     return op == TOKcomma ? (CommaExp *)this : NULL;
1483 }
1484 
isIntervalExp()1485 IntervalExp *Expression::isIntervalExp()
1486 {
1487     return op == TOKinterval ? (IntervalExp *)this : NULL;
1488 }
1489 
isDelegatePtrExp()1490 DelegatePtrExp *Expression::isDelegatePtrExp()
1491 {
1492     return op == TOKdelegateptr ? (DelegatePtrExp *)this : NULL;
1493 }
1494 
isDelegateFuncptrExp()1495 DelegateFuncptrExp *Expression::isDelegateFuncptrExp()
1496 {
1497     return op == TOKdelegatefuncptr ? (DelegateFuncptrExp *)this : NULL;
1498 }
1499 
isIndexExp()1500 IndexExp *Expression::isIndexExp()
1501 {
1502     return op == TOKindex ? (IndexExp *)this : NULL;
1503 }
1504 
isPostExp()1505 PostExp *Expression::isPostExp()
1506 {
1507     return (op == TOKplusplus || op == TOKminusminus) ? (PostExp *)this : NULL;
1508 }
1509 
isPreExp()1510 PreExp *Expression::isPreExp()
1511 {
1512     return (op == TOKpreplusplus || op == TOKpreminusminus) ? (PreExp *)this : NULL;
1513 }
1514 
isAssignExp()1515 AssignExp *Expression::isAssignExp()
1516 {
1517     return op == TOKassign ? (AssignExp *)this : NULL;
1518 }
1519 
isConstructExp()1520 ConstructExp *Expression::isConstructExp()
1521 {
1522     return op == TOKconstruct ? (ConstructExp *)this : NULL;
1523 }
1524 
isBlitExp()1525 BlitExp *Expression::isBlitExp()
1526 {
1527     return op == TOKblit ? (BlitExp *)this : NULL;
1528 }
1529 
isAddAssignExp()1530 AddAssignExp *Expression::isAddAssignExp()
1531 {
1532     return op == TOKaddass ? (AddAssignExp *)this : NULL;
1533 }
1534 
isMinAssignExp()1535 MinAssignExp *Expression::isMinAssignExp()
1536 {
1537     return op == TOKminass ? (MinAssignExp *)this : NULL;
1538 }
1539 
isMulAssignExp()1540 MulAssignExp *Expression::isMulAssignExp()
1541 {
1542     return op == TOKmulass ? (MulAssignExp *)this : NULL;
1543 }
1544 
1545 
isDivAssignExp()1546 DivAssignExp *Expression::isDivAssignExp()
1547 {
1548     return op == TOKdivass ? (DivAssignExp *)this : NULL;
1549 }
1550 
isModAssignExp()1551 ModAssignExp *Expression::isModAssignExp()
1552 {
1553     return op == TOKmodass ? (ModAssignExp *)this : NULL;
1554 }
1555 
isAndAssignExp()1556 AndAssignExp *Expression::isAndAssignExp()
1557 {
1558     return op == TOKandass ? (AndAssignExp *)this : NULL;
1559 }
1560 
isOrAssignExp()1561 OrAssignExp *Expression::isOrAssignExp()
1562 {
1563     return op == TOKorass ? (OrAssignExp *)this : NULL;
1564 }
1565 
isXorAssignExp()1566 XorAssignExp *Expression::isXorAssignExp()
1567 {
1568     return op == TOKxorass ? (XorAssignExp *)this : NULL;
1569 }
1570 
isPowAssignExp()1571 PowAssignExp *Expression::isPowAssignExp()
1572 {
1573     return op == TOKpowass ? (PowAssignExp *)this : NULL;
1574 }
1575 
1576 
isShlAssignExp()1577 ShlAssignExp *Expression::isShlAssignExp()
1578 {
1579     return op == TOKshlass ? (ShlAssignExp *)this : NULL;
1580 }
1581 
isShrAssignExp()1582 ShrAssignExp *Expression::isShrAssignExp()
1583 {
1584     return op == TOKshrass ? (ShrAssignExp *)this : NULL;
1585 }
1586 
isUshrAssignExp()1587 UshrAssignExp *Expression::isUshrAssignExp()
1588 {
1589     return op == TOKushrass ? (UshrAssignExp *)this : NULL;
1590 }
1591 
isCatAssignExp()1592 CatAssignExp *Expression::isCatAssignExp()
1593 {
1594     return op == TOKcatass ? (CatAssignExp *)this : NULL;
1595 }
1596 
isAddExp()1597 AddExp *Expression::isAddExp()
1598 {
1599     return op == TOKadd ? (AddExp *)this : NULL;
1600 }
1601 
isMinExp()1602 MinExp *Expression::isMinExp()
1603 {
1604     return op == TOKmin ? (MinExp *)this : NULL;
1605 }
1606 
isCatExp()1607 CatExp *Expression::isCatExp()
1608 {
1609     return op == TOKcat ? (CatExp *)this : NULL;
1610 }
1611 
isMulExp()1612 MulExp *Expression::isMulExp()
1613 {
1614     return op == TOKmul ? (MulExp *)this : NULL;
1615 }
1616 
isDivExp()1617 DivExp *Expression::isDivExp()
1618 {
1619     return op == TOKdiv ? (DivExp *)this : NULL;
1620 }
1621 
isModExp()1622 ModExp *Expression::isModExp()
1623 {
1624     return op == TOKmod ? (ModExp *)this : NULL;
1625 }
1626 
isPowExp()1627 PowExp *Expression::isPowExp()
1628 {
1629     return op == TOKpow ? (PowExp *)this : NULL;
1630 }
1631 
isShlExp()1632 ShlExp *Expression::isShlExp()
1633 {
1634     return op == TOKshl ? (ShlExp *)this : NULL;
1635 }
1636 
isShrExp()1637 ShrExp *Expression::isShrExp()
1638 {
1639     return op == TOKshr ? (ShrExp *)this : NULL;
1640 }
1641 
isUshrExp()1642 UshrExp *Expression::isUshrExp()
1643 {
1644     return op == TOKushr ? (UshrExp *)this : NULL;
1645 }
1646 
isAndExp()1647 AndExp *Expression::isAndExp()
1648 {
1649     return op == TOKand ? (AndExp *)this : NULL;
1650 }
1651 
isOrExp()1652 OrExp *Expression::isOrExp()
1653 {
1654     return op == TOKor ? (OrExp *)this : NULL;
1655 }
1656 
isXorExp()1657 XorExp *Expression::isXorExp()
1658 {
1659     return op == TOKxor ? (XorExp *)this : NULL;
1660 }
1661 
isLogicalExp()1662 LogicalExp *Expression::isLogicalExp()
1663 {
1664     return (op == TOKandand || op == TOKoror) ? (LogicalExp *)this : NULL;
1665 }
1666 
isInExp()1667 InExp *Expression::isInExp()
1668 {
1669     return op == TOKin ? (InExp *)this : NULL;
1670 }
1671 
isRemoveExp()1672 RemoveExp *Expression::isRemoveExp()
1673 {
1674     return op == TOKremove ? (RemoveExp *)this : NULL;
1675 }
1676 
isEqualExp()1677 EqualExp *Expression::isEqualExp()
1678 {
1679     return (op == TOKequal || op == TOKnotequal) ? (EqualExp *)this : NULL;
1680 }
1681 
isIdentityExp()1682 IdentityExp *Expression::isIdentityExp()
1683 {
1684     return (op == TOKidentity || op == TOKnotidentity) ? (IdentityExp *)this : NULL;
1685 }
1686 
isCondExp()1687 CondExp *Expression::isCondExp()
1688 {
1689     return op == TOKquestion ? (CondExp *)this : NULL;
1690 }
1691 
isDefaultInitExp()1692 DefaultInitExp *Expression::isDefaultInitExp()
1693 {
1694     return op == TOKdefault ? (DefaultInitExp *)this : NULL;
1695 }
1696 
isFileInitExp()1697 FileInitExp *Expression::isFileInitExp()
1698 {
1699     return (op == TOKfile || op == TOKfilefullpath) ? (FileInitExp *)this : NULL;
1700 }
1701 
isLineInitExp()1702 LineInitExp *Expression::isLineInitExp()
1703 {
1704     return op == TOKline ? (LineInitExp *)this : NULL;
1705 }
1706 
isModuleInitExp()1707 ModuleInitExp *Expression::isModuleInitExp()
1708 {
1709     return op == TOKmodulestring ? (ModuleInitExp *)this : NULL;
1710 }
1711 
isFuncInitExp()1712 FuncInitExp *Expression::isFuncInitExp()
1713 {
1714     return op == TOKfuncstring ? (FuncInitExp *)this : NULL;
1715 }
1716 
isPrettyFuncInitExp()1717 PrettyFuncInitExp *Expression::isPrettyFuncInitExp()
1718 {
1719     return op == TOKprettyfunc ? (PrettyFuncInitExp *)this : NULL;
1720 }
1721 
isClassReferenceExp()1722 ClassReferenceExp *Expression::isClassReferenceExp()
1723 {
1724     return op == TOKclassreference ? (ClassReferenceExp *)this : NULL;
1725 }
1726 
1727 
1728 /****************************************
1729  * Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__, __FILE__FULL_PATH__ to loc.
1730  */
1731 
resolveLoc(Loc,Scope *)1732 Expression *Expression::resolveLoc(Loc, Scope *)
1733 {
1734     return this;
1735 }
1736 
arraySyntaxCopy(Expressions * exps)1737 Expressions *Expression::arraySyntaxCopy(Expressions *exps)
1738 {
1739     Expressions *a = NULL;
1740     if (exps)
1741     {
1742         a = new Expressions();
1743         a->setDim(exps->length);
1744         for (size_t i = 0; i < a->length; i++)
1745         {
1746             Expression *e = (*exps)[i];
1747             (*a)[i] = e ? e->syntaxCopy() : NULL;
1748         }
1749     }
1750     return a;
1751 }
1752 
1753 /************************************************
1754  * Destructors are attached to VarDeclarations.
1755  * Hence, if expression returns a temp that needs a destructor,
1756  * make sure and create a VarDeclaration for that temp.
1757  */
1758 
addDtorHook(Scope *)1759 Expression *Expression::addDtorHook(Scope *)
1760 {
1761     return this;
1762 }
1763 
1764 /******************************** IntegerExp **************************/
1765 
IntegerExp(Loc loc,dinteger_t value,Type * type)1766 IntegerExp::IntegerExp(Loc loc, dinteger_t value, Type *type)
1767         : Expression(loc, TOKint64, sizeof(IntegerExp))
1768 {
1769     //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : "");
1770     assert(type);
1771     if (!type->isscalar())
1772     {
1773         //printf("%s, loc = %d\n", toChars(), loc.linnum);
1774         if (type->ty != Terror)
1775             error("integral constant must be scalar type, not %s", type->toChars());
1776         type = Type::terror;
1777     }
1778     this->type = type;
1779     setInteger(value);
1780 }
1781 
IntegerExp(dinteger_t value)1782 IntegerExp::IntegerExp(dinteger_t value)
1783         : Expression(Loc(), TOKint64, sizeof(IntegerExp))
1784 {
1785     this->type = Type::tint32;
1786     this->value = (d_int32) value;
1787 }
1788 
create(Loc loc,dinteger_t value,Type * type)1789 IntegerExp *IntegerExp::create(Loc loc, dinteger_t value, Type *type)
1790 {
1791     return new IntegerExp(loc, value, type);
1792 }
1793 
equals(RootObject * o)1794 bool IntegerExp::equals(RootObject *o)
1795 {
1796     if (this == o)
1797         return true;
1798     if (((Expression *)o)->op == TOKint64)
1799     {
1800         IntegerExp *ne = (IntegerExp *)o;
1801         if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
1802             value == ne->value)
1803         {
1804             return true;
1805         }
1806     }
1807     return false;
1808 }
1809 
setInteger(dinteger_t value)1810 void IntegerExp::setInteger(dinteger_t value)
1811 {
1812     this->value = value;
1813     normalize();
1814 }
1815 
normalize()1816 void IntegerExp::normalize()
1817 {
1818     /* 'Normalize' the value of the integer to be in range of the type
1819      */
1820     switch (type->toBasetype()->ty)
1821     {
1822         case Tbool:         value = (value != 0);           break;
1823         case Tint8:         value = (d_int8)  value;        break;
1824         case Tchar:
1825         case Tuns8:         value = (d_uns8)  value;        break;
1826         case Tint16:        value = (d_int16) value;        break;
1827         case Twchar:
1828         case Tuns16:        value = (d_uns16) value;        break;
1829         case Tint32:        value = (d_int32) value;        break;
1830         case Tdchar:
1831         case Tuns32:        value = (d_uns32) value;        break;
1832         case Tint64:        value = (d_int64) value;        break;
1833         case Tuns64:        value = (d_uns64) value;        break;
1834         case Tpointer:
1835             if (target.ptrsize == 8)
1836                 value = (d_uns64) value;
1837             else if (target.ptrsize == 4)
1838                 value = (d_uns32) value;
1839             else if (target.ptrsize == 2)
1840                 value = (d_uns16) value;
1841             else
1842                 assert(0);
1843             break;
1844         default:
1845             break;
1846     }
1847 }
1848 
toInteger()1849 dinteger_t IntegerExp::toInteger()
1850 {
1851     normalize();   // necessary until we fix all the paints of 'type'
1852     return value;
1853 }
1854 
toReal()1855 real_t IntegerExp::toReal()
1856 {
1857     normalize();   // necessary until we fix all the paints of 'type'
1858     Type *t = type->toBasetype();
1859     if (t->ty == Tuns64)
1860         return ldouble((d_uns64)value);
1861     else
1862         return ldouble((d_int64)value);
1863 }
1864 
toImaginary()1865 real_t IntegerExp::toImaginary()
1866 {
1867     return CTFloat::zero;
1868 }
1869 
toComplex()1870 complex_t IntegerExp::toComplex()
1871 {
1872     return (complex_t)toReal();
1873 }
1874 
isBool(bool result)1875 bool IntegerExp::isBool(bool result)
1876 {
1877     bool r = toInteger() != 0;
1878     return result ? r : !r;
1879 }
1880 
toLvalue(Scope *,Expression * e)1881 Expression *IntegerExp::toLvalue(Scope *, Expression *e)
1882 {
1883     if (!e)
1884         e = this;
1885     else if (!loc.filename)
1886         loc = e->loc;
1887     e->error("constant %s is not an lvalue", e->toChars());
1888     return new ErrorExp();
1889 }
1890 
1891 /******************************** ErrorExp **************************/
1892 
1893 /* Use this expression for error recovery.
1894  * It should behave as a 'sink' to prevent further cascaded error messages.
1895  */
1896 
ErrorExp()1897 ErrorExp::ErrorExp()
1898     : Expression(Loc(), TOKerror, sizeof(ErrorExp))
1899 {
1900     type = Type::terror;
1901 }
1902 
toLvalue(Scope *,Expression *)1903 Expression *ErrorExp::toLvalue(Scope *, Expression *)
1904 {
1905     return this;
1906 }
1907 
1908 /******************************** RealExp **************************/
1909 
RealExp(Loc loc,real_t value,Type * type)1910 RealExp::RealExp(Loc loc, real_t value, Type *type)
1911         : Expression(loc, TOKfloat64, sizeof(RealExp))
1912 {
1913     //printf("RealExp::RealExp(%Lg)\n", value);
1914     this->value = value;
1915     this->type = type;
1916 }
1917 
create(Loc loc,real_t value,Type * type)1918 RealExp *RealExp::create(Loc loc, real_t value, Type *type)
1919 {
1920     return new RealExp(loc, value,type);
1921 }
1922 
toInteger()1923 dinteger_t RealExp::toInteger()
1924 {
1925     return (sinteger_t) toReal();
1926 }
1927 
toUInteger()1928 uinteger_t RealExp::toUInteger()
1929 {
1930     return (uinteger_t) toReal();
1931 }
1932 
toReal()1933 real_t RealExp::toReal()
1934 {
1935     return type->isreal() ? value : CTFloat::zero;
1936 }
1937 
toImaginary()1938 real_t RealExp::toImaginary()
1939 {
1940     return type->isreal() ? CTFloat::zero : value;
1941 }
1942 
toComplex()1943 complex_t RealExp::toComplex()
1944 {
1945     return complex_t(toReal(), toImaginary());
1946 }
1947 
1948 /********************************
1949  * Test to see if two reals are the same.
1950  * Regard NaN's as equivalent.
1951  * Regard +0 and -0 as different.
1952  */
1953 
RealEquals(real_t x1,real_t x2)1954 int RealEquals(real_t x1, real_t x2)
1955 {
1956     return (CTFloat::isNaN(x1) && CTFloat::isNaN(x2)) ||
1957         CTFloat::isIdentical(x1, x2);
1958 }
1959 
equals(RootObject * o)1960 bool RealExp::equals(RootObject *o)
1961 {
1962     if (this == o)
1963         return true;
1964     if (((Expression *)o)->op == TOKfloat64)
1965     {
1966         RealExp *ne = (RealExp *)o;
1967         if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
1968             RealEquals(value, ne->value))
1969         {
1970             return true;
1971         }
1972     }
1973     return false;
1974 }
1975 
isBool(bool result)1976 bool RealExp::isBool(bool result)
1977 {
1978     return result ? (bool)value : !(bool)value;
1979 }
1980 
1981 /******************************** ComplexExp **************************/
1982 
ComplexExp(Loc loc,complex_t value,Type * type)1983 ComplexExp::ComplexExp(Loc loc, complex_t value, Type *type)
1984         : Expression(loc, TOKcomplex80, sizeof(ComplexExp)), value(value)
1985 {
1986     this->type = type;
1987     //printf("ComplexExp::ComplexExp(%s)\n", toChars());
1988 }
1989 
create(Loc loc,complex_t value,Type * type)1990 ComplexExp *ComplexExp::create(Loc loc, complex_t value, Type *type)
1991 {
1992     return new ComplexExp(loc, value, type);
1993 }
1994 
toInteger()1995 dinteger_t ComplexExp::toInteger()
1996 {
1997     return (sinteger_t) toReal();
1998 }
1999 
toUInteger()2000 uinteger_t ComplexExp::toUInteger()
2001 {
2002     return (uinteger_t) toReal();
2003 }
2004 
toReal()2005 real_t ComplexExp::toReal()
2006 {
2007     return creall(value);
2008 }
2009 
toImaginary()2010 real_t ComplexExp::toImaginary()
2011 {
2012     return cimagl(value);
2013 }
2014 
toComplex()2015 complex_t ComplexExp::toComplex()
2016 {
2017     return value;
2018 }
2019 
equals(RootObject * o)2020 bool ComplexExp::equals(RootObject *o)
2021 {
2022     if (this == o)
2023         return true;
2024     if (((Expression *)o)->op == TOKcomplex80)
2025     {
2026         ComplexExp *ne = (ComplexExp *)o;
2027         if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
2028             RealEquals(creall(value), creall(ne->value)) &&
2029             RealEquals(cimagl(value), cimagl(ne->value)))
2030         {
2031             return true;
2032         }
2033     }
2034     return false;
2035 }
2036 
isBool(bool result)2037 bool ComplexExp::isBool(bool result)
2038 {
2039     if (result)
2040         return (bool)(value);
2041     else
2042         return !value;
2043 }
2044 
2045 /******************************** IdentifierExp **************************/
2046 
IdentifierExp(Loc loc,Identifier * ident)2047 IdentifierExp::IdentifierExp(Loc loc, Identifier *ident)
2048         : Expression(loc, TOKidentifier, sizeof(IdentifierExp))
2049 {
2050     this->ident = ident;
2051 }
2052 
create(Loc loc,Identifier * ident)2053 IdentifierExp *IdentifierExp::create(Loc loc, Identifier *ident)
2054 {
2055     return new IdentifierExp(loc, ident);
2056 }
2057 
isLvalue()2058 bool IdentifierExp::isLvalue()
2059 {
2060     return true;
2061 }
2062 
toLvalue(Scope *,Expression *)2063 Expression *IdentifierExp::toLvalue(Scope *, Expression *)
2064 {
2065     return this;
2066 }
2067 
2068 /******************************** DollarExp **************************/
2069 
DollarExp(Loc loc)2070 DollarExp::DollarExp(Loc loc)
2071         : IdentifierExp(loc, Id::dollar)
2072 {
2073 }
2074 
2075 /******************************** DsymbolExp **************************/
2076 
DsymbolExp(Loc loc,Dsymbol * s,bool hasOverloads)2077 DsymbolExp::DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads)
2078         : Expression(loc, TOKdsymbol, sizeof(DsymbolExp))
2079 {
2080     this->s = s;
2081     this->hasOverloads = hasOverloads;
2082 }
2083 
2084 /****************************************
2085  * Resolve a symbol `s` and wraps it in an expression object.
2086  * Params:
2087  *      hasOverloads = works if the aliased symbol is a function.
2088  *          true:  it's overloaded and will be resolved later.
2089  *          false: it's exact function symbol.
2090  */
resolve(Loc loc,Scope * sc,Dsymbol * s,bool hasOverloads)2091 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads)
2092 {
2093 Lagain:
2094     Expression *e;
2095 
2096     //printf("DsymbolExp:: %p '%s' is a symbol\n", this, toChars());
2097     //printf("s = '%s', s->kind = '%s'\n", s->toChars(), s->kind());
2098     Dsymbol *olds = s;
2099     Declaration *d = s->isDeclaration();
2100     if (d && (d->storage_class & STCtemplateparameter))
2101     {
2102         s = s->toAlias();
2103     }
2104     else
2105     {
2106         if (!s->isFuncDeclaration())        // functions are checked after overloading
2107         {
2108             s->checkDeprecated(loc, sc);
2109             if (d)
2110                 d->checkDisabled(loc, sc);
2111         }
2112 
2113         // Bugzilla 12023: if 's' is a tuple variable, the tuple is returned.
2114         s = s->toAlias();
2115 
2116         //printf("s = '%s', s->kind = '%s', s->needThis() = %p\n", s->toChars(), s->kind(), s->needThis());
2117         if (s != olds && !s->isFuncDeclaration())
2118         {
2119             s->checkDeprecated(loc, sc);
2120             if (d)
2121                 d->checkDisabled(loc, sc);
2122         }
2123     }
2124 
2125     if (EnumMember *em = s->isEnumMember())
2126     {
2127         return em->getVarExp(loc, sc);
2128     }
2129     if (VarDeclaration *v = s->isVarDeclaration())
2130     {
2131         //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
2132         if (!v->type ||                    // during variable type inference
2133             (!v->type->deco && v->inuse))  // during variable type semantic
2134         {
2135             if (v->inuse)    // variable type depends on the variable itself
2136                 ::error(loc, "circular reference to %s `%s`", v->kind(), v->toPrettyChars());
2137             else             // variable type cannot be determined
2138                 ::error(loc, "forward reference to %s `%s`", v->kind(), v->toPrettyChars());
2139             return new ErrorExp();
2140         }
2141         if (v->type->ty == Terror)
2142             return new ErrorExp();
2143 
2144         if ((v->storage_class & STCmanifest) && v->_init)
2145         {
2146             if (v->inuse)
2147             {
2148                 ::error(loc, "circular initialization of %s `%s`", v->kind(), v->toPrettyChars());
2149                 return new ErrorExp();
2150             }
2151 
2152             e = v->expandInitializer(loc);
2153             v->inuse++;
2154             e = expressionSemantic(e, sc);
2155             v->inuse--;
2156             return e;
2157         }
2158 
2159         // Change the ancestor lambdas to delegate before hasThis(sc) call.
2160         if (v->checkNestedReference(sc, loc))
2161             return new ErrorExp();
2162 
2163         if (v->needThis() && hasThis(sc))
2164             e = new DotVarExp(loc, new ThisExp(loc), v);
2165         else
2166             e = new VarExp(loc, v);
2167         e = expressionSemantic(e, sc);
2168         return e;
2169     }
2170     if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
2171     {
2172         //printf("'%s' is a function literal\n", fld->toChars());
2173         e = new FuncExp(loc, fld);
2174         return expressionSemantic(e, sc);
2175     }
2176     if (FuncDeclaration *f = s->isFuncDeclaration())
2177     {
2178         f = f->toAliasFunc();
2179         if (!f->functionSemantic())
2180             return new ErrorExp();
2181 
2182         if (!hasOverloads && f->checkForwardRef(loc))
2183             return new ErrorExp();
2184 
2185         FuncDeclaration *fd = s->isFuncDeclaration();
2186         fd->type = f->type;
2187         return new VarExp(loc, fd, hasOverloads);
2188     }
2189     if (OverDeclaration *od = s->isOverDeclaration())
2190     {
2191         e = new VarExp(loc, od, true);
2192         e->type = Type::tvoid;
2193         return e;
2194     }
2195     if (OverloadSet *o = s->isOverloadSet())
2196     {
2197         //printf("'%s' is an overload set\n", o->toChars());
2198         return new OverExp(loc, o);
2199     }
2200 
2201     if (Import *imp = s->isImport())
2202     {
2203         if (!imp->pkg)
2204         {
2205             ::error(loc, "forward reference of import %s", imp->toChars());
2206             return new ErrorExp();
2207         }
2208         ScopeExp *ie = new ScopeExp(loc, imp->pkg);
2209         return expressionSemantic(ie, sc);
2210     }
2211     if (Package *pkg = s->isPackage())
2212     {
2213         ScopeExp *ie = new ScopeExp(loc, pkg);
2214         return expressionSemantic(ie, sc);
2215     }
2216     if (Module *mod = s->isModule())
2217     {
2218         ScopeExp *ie = new ScopeExp(loc, mod);
2219         return expressionSemantic(ie, sc);
2220     }
2221 
2222     if (Nspace *ns = s->isNspace())
2223     {
2224         ScopeExp *ie = new ScopeExp(loc, ns);
2225         return expressionSemantic(ie, sc);
2226     }
2227 
2228     if (Type *t = s->getType())
2229     {
2230         return expressionSemantic(new TypeExp(loc, t), sc);
2231     }
2232 
2233     if (TupleDeclaration *tup = s->isTupleDeclaration())
2234     {
2235         if (tup->needThis() && hasThis(sc))
2236             e = new DotVarExp(loc, new ThisExp(loc), tup);
2237         else
2238             e = new TupleExp(loc, tup);
2239         e = expressionSemantic(e, sc);
2240         return e;
2241     }
2242 
2243     if (TemplateInstance *ti = s->isTemplateInstance())
2244     {
2245         dsymbolSemantic(ti, sc);
2246         if (!ti->inst || ti->errors)
2247             return new ErrorExp();
2248         s = ti->toAlias();
2249         if (!s->isTemplateInstance())
2250             goto Lagain;
2251         e = new ScopeExp(loc, ti);
2252         e = expressionSemantic(e, sc);
2253         return e;
2254     }
2255     if (TemplateDeclaration *td = s->isTemplateDeclaration())
2256     {
2257         Dsymbol *p = td->toParent2();
2258         FuncDeclaration *fdthis = hasThis(sc);
2259         AggregateDeclaration *ad = p ? p->isAggregateDeclaration() : NULL;
2260         if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad &&
2261             (td->_scope->stc & STCstatic) == 0)
2262         {
2263             e = new DotTemplateExp(loc, new ThisExp(loc), td);
2264         }
2265         else
2266             e = new TemplateExp(loc, td);
2267         e = expressionSemantic(e, sc);
2268         return e;
2269     }
2270 
2271     ::error(loc, "%s `%s` is not a variable", s->kind(), s->toChars());
2272     return new ErrorExp();
2273 }
2274 
isLvalue()2275 bool DsymbolExp::isLvalue()
2276 {
2277     return true;
2278 }
2279 
toLvalue(Scope *,Expression *)2280 Expression *DsymbolExp::toLvalue(Scope *, Expression *)
2281 {
2282     return this;
2283 }
2284 
2285 /******************************** ThisExp **************************/
2286 
ThisExp(Loc loc)2287 ThisExp::ThisExp(Loc loc)
2288         : Expression(loc, TOKthis, sizeof(ThisExp))
2289 {
2290     //printf("ThisExp::ThisExp() loc = %d\n", loc.linnum);
2291     var = NULL;
2292 }
2293 
isBool(bool result)2294 bool ThisExp::isBool(bool result)
2295 {
2296     return result ? true : false;
2297 }
2298 
isLvalue()2299 bool ThisExp::isLvalue()
2300 {
2301     // Class `this` should be an rvalue; struct `this` should be an lvalue.
2302     return type->toBasetype()->ty != Tclass;
2303 }
2304 
toLvalue(Scope * sc,Expression * e)2305 Expression *ThisExp::toLvalue(Scope *sc, Expression *e)
2306 {
2307     if (type->toBasetype()->ty == Tclass)
2308     {
2309         // Class `this` is an rvalue; struct `this` is an lvalue.
2310         return Expression::toLvalue(sc, e);
2311     }
2312     return this;
2313 }
2314 
2315 /******************************** SuperExp **************************/
2316 
SuperExp(Loc loc)2317 SuperExp::SuperExp(Loc loc)
2318         : ThisExp(loc)
2319 {
2320     op = TOKsuper;
2321 }
2322 
2323 /******************************** NullExp **************************/
2324 
NullExp(Loc loc,Type * type)2325 NullExp::NullExp(Loc loc, Type *type)
2326         : Expression(loc, TOKnull, sizeof(NullExp))
2327 {
2328     committed = 0;
2329     this->type = type;
2330 }
2331 
equals(RootObject * o)2332 bool NullExp::equals(RootObject *o)
2333 {
2334     if (o && o->dyncast() == DYNCAST_EXPRESSION)
2335     {
2336         Expression *e = (Expression *)o;
2337         if (e->op == TOKnull &&
2338             type->equals(e->type))
2339         {
2340             return true;
2341         }
2342     }
2343     return false;
2344 }
2345 
isBool(bool result)2346 bool NullExp::isBool(bool result)
2347 {
2348     return result ? false : true;
2349 }
2350 
toStringExp()2351 StringExp *NullExp::toStringExp()
2352 {
2353     if (implicitConvTo(Type::tstring))
2354     {
2355         StringExp *se = new StringExp(loc, (char*)mem.xcalloc(1, 1), 0);
2356         se->type = Type::tstring;
2357         return se;
2358     }
2359     return NULL;
2360 }
2361 
2362 /******************************** StringExp **************************/
2363 
StringExp(Loc loc,char * string)2364 StringExp::StringExp(Loc loc, char *string)
2365         : Expression(loc, TOKstring, sizeof(StringExp))
2366 {
2367     this->string = string;
2368     this->len = strlen(string);
2369     this->sz = 1;
2370     this->committed = 0;
2371     this->postfix = 0;
2372     this->ownedByCtfe = OWNEDcode;
2373 }
2374 
StringExp(Loc loc,void * string,size_t len)2375 StringExp::StringExp(Loc loc, void *string, size_t len)
2376         : Expression(loc, TOKstring, sizeof(StringExp))
2377 {
2378     this->string = string;
2379     this->len = len;
2380     this->sz = 1;
2381     this->committed = 0;
2382     this->postfix = 0;
2383     this->ownedByCtfe = OWNEDcode;
2384 }
2385 
StringExp(Loc loc,void * string,size_t len,utf8_t postfix)2386 StringExp::StringExp(Loc loc, void *string, size_t len, utf8_t postfix)
2387         : Expression(loc, TOKstring, sizeof(StringExp))
2388 {
2389     this->string = string;
2390     this->len = len;
2391     this->sz = 1;
2392     this->committed = 0;
2393     this->postfix = postfix;
2394     this->ownedByCtfe = OWNEDcode;
2395 }
2396 
create(Loc loc,char * s)2397 StringExp *StringExp::create(Loc loc, char *s)
2398 {
2399     return new StringExp(loc, s);
2400 }
2401 
create(Loc loc,void * string,size_t len)2402 StringExp *StringExp::create(Loc loc, void *string, size_t len)
2403 {
2404     return new StringExp(loc, string, len);
2405 }
2406 
equals(RootObject * o)2407 bool StringExp::equals(RootObject *o)
2408 {
2409     //printf("StringExp::equals('%s') %s\n", o->toChars(), toChars());
2410     if (o && o->dyncast() == DYNCAST_EXPRESSION)
2411     {
2412         Expression *e = (Expression *)o;
2413         if (e->op == TOKstring)
2414         {
2415             return compare(o) == 0;
2416         }
2417     }
2418     return false;
2419 }
2420 
2421 /**********************************
2422  * Return the number of code units the string would be if it were re-encoded
2423  * as tynto.
2424  * Params:
2425  *      tynto = code unit type of the target encoding
2426  * Returns:
2427  *      number of code units
2428  */
2429 
numberOfCodeUnits(int tynto)2430 size_t StringExp::numberOfCodeUnits(int tynto) const
2431 {
2432     int encSize;
2433     switch (tynto)
2434     {
2435         case 0:      return len;
2436         case Tchar:  encSize = 1; break;
2437         case Twchar: encSize = 2; break;
2438         case Tdchar: encSize = 4; break;
2439         default:
2440             assert(0);
2441     }
2442     if (sz == encSize)
2443         return len;
2444 
2445     size_t result = 0;
2446     dchar_t c;
2447 
2448     switch (sz)
2449     {
2450         case 1:
2451             for (size_t u = 0; u < len;)
2452             {
2453                 if (const char *p = utf_decodeChar((utf8_t *)string, len, &u, &c))
2454                 {
2455                     error("%s", p);
2456                     return 0;
2457                 }
2458                 result += utf_codeLength(encSize, c);
2459             }
2460             break;
2461 
2462         case 2:
2463             for (size_t u = 0; u < len;)
2464             {
2465                 if (const char *p = utf_decodeWchar((utf16_t *)string, len, &u, &c))
2466                 {
2467                     error("%s", p);
2468                     return 0;
2469                 }
2470                 result += utf_codeLength(encSize, c);
2471             }
2472             break;
2473 
2474         case 4:
2475             for (size_t u = 0; u < len;)
2476             {
2477                 c = *((utf32_t *)((char *)string + u));
2478                 u += 4;
2479                 result += utf_codeLength(encSize, c);
2480             }
2481             break;
2482 
2483         default:
2484             assert(0);
2485     }
2486     return result;
2487 }
2488 
2489 /**********************************************
2490  * Write the contents of the string to dest.
2491  * Use numberOfCodeUnits() to determine size of result.
2492  * Params:
2493  *  dest = destination
2494  *  tyto = encoding type of the result
2495  *  zero = add terminating 0
2496  */
writeTo(void * dest,bool zero,int tyto)2497 void StringExp::writeTo(void *dest, bool zero, int tyto) const
2498 {
2499     int encSize;
2500     switch (tyto)
2501     {
2502         case 0:      encSize = sz; break;
2503         case Tchar:  encSize = 1; break;
2504         case Twchar: encSize = 2; break;
2505         case Tdchar: encSize = 4; break;
2506         default:
2507             assert(0);
2508     }
2509     if (sz == encSize)
2510     {
2511         memcpy(dest, string, len * sz);
2512         if (zero)
2513             memset((char *)dest + len * sz, 0, sz);
2514     }
2515     else
2516         assert(0);
2517 }
2518 
2519 /**************************************************
2520  * If the string data is UTF-8 and can be accessed directly,
2521  * return a pointer to it.
2522  * Do not assume a terminating 0.
2523  * Returns:
2524  *  pointer to string data if possible, null if not
2525  */
toPtr()2526 char *StringExp::toPtr()
2527 {
2528     return (sz == 1) ? (char*)string : NULL;
2529 }
2530 
toStringExp()2531 StringExp *StringExp::toStringExp()
2532 {
2533     return this;
2534 }
2535 
2536 /****************************************
2537  * Convert string to char[].
2538  */
2539 
toUTF8(Scope * sc)2540 StringExp *StringExp::toUTF8(Scope *sc)
2541 {
2542     if (sz != 1)
2543     {   // Convert to UTF-8 string
2544         committed = 0;
2545         Expression *e = castTo(sc, Type::tchar->arrayOf());
2546         e = e->optimize(WANTvalue);
2547         assert(e->op == TOKstring);
2548         StringExp *se = (StringExp *)e;
2549         assert(se->sz == 1);
2550         return se;
2551     }
2552     return this;
2553 }
2554 
compare(RootObject * obj)2555 int StringExp::compare(RootObject *obj)
2556 {
2557     //printf("StringExp::compare()\n");
2558     // Used to sort case statement expressions so we can do an efficient lookup
2559     StringExp *se2 = (StringExp *)(obj);
2560 
2561     // This is a kludge so isExpression() in template.c will return 5
2562     // for StringExp's.
2563     if (!se2)
2564         return 5;
2565 
2566     assert(se2->op == TOKstring);
2567 
2568     size_t len1 = len;
2569     size_t len2 = se2->len;
2570 
2571     //printf("sz = %d, len1 = %d, len2 = %d\n", sz, (int)len1, (int)len2);
2572     if (len1 == len2)
2573     {
2574         switch (sz)
2575         {
2576             case 1:
2577                 return memcmp((char *)string, (char *)se2->string, len1);
2578 
2579             case 2:
2580             {
2581                 d_uns16 *s1 = (d_uns16 *)string;
2582                 d_uns16 *s2 = (d_uns16 *)se2->string;
2583 
2584                 for (size_t u = 0; u < len; u++)
2585                 {
2586                     if (s1[u] != s2[u])
2587                         return s1[u] - s2[u];
2588                 }
2589             }
2590             break;
2591 
2592             case 4:
2593             {
2594                 d_uns32 *s1 = (d_uns32 *)string;
2595                 d_uns32 *s2 = (d_uns32 *)se2->string;
2596 
2597                 for (size_t u = 0; u < len; u++)
2598                 {
2599                     if (s1[u] != s2[u])
2600                         return s1[u] - s2[u];
2601                 }
2602             }
2603             break;
2604 
2605             default:
2606                 assert(0);
2607         }
2608     }
2609     return (int)(len1 - len2);
2610 }
2611 
isBool(bool result)2612 bool StringExp::isBool(bool result)
2613 {
2614     return result ? true : false;
2615 }
2616 
2617 
isLvalue()2618 bool StringExp::isLvalue()
2619 {
2620     /* string literal is rvalue in default, but
2621      * conversion to reference of static array is only allowed.
2622      */
2623     return (type && type->toBasetype()->ty == Tsarray);
2624 }
2625 
toLvalue(Scope * sc,Expression * e)2626 Expression *StringExp::toLvalue(Scope *sc, Expression *e)
2627 {
2628     //printf("StringExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL);
2629     return (type && type->toBasetype()->ty == Tsarray)
2630             ? this : Expression::toLvalue(sc, e);
2631 }
2632 
modifiableLvalue(Scope *,Expression *)2633 Expression *StringExp::modifiableLvalue(Scope *, Expression *)
2634 {
2635     error("cannot modify string literal %s", toChars());
2636     return new ErrorExp();
2637 }
2638 
charAt(uinteger_t i)2639 unsigned StringExp::charAt(uinteger_t i) const
2640 {   unsigned value;
2641 
2642     switch (sz)
2643     {
2644         case 1:
2645             value = ((utf8_t *)string)[(size_t)i];
2646             break;
2647 
2648         case 2:
2649             value = ((unsigned short *)string)[(size_t)i];
2650             break;
2651 
2652         case 4:
2653             value = ((unsigned int *)string)[(size_t)i];
2654             break;
2655 
2656         default:
2657             assert(0);
2658             break;
2659     }
2660     return value;
2661 }
2662 
2663 /************************ ArrayLiteralExp ************************************/
2664 
2665 // [ e1, e2, e3, ... ]
2666 
ArrayLiteralExp(Loc loc,Type * type,Expressions * elements)2667 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expressions *elements)
2668     : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
2669 {
2670     this->basis = NULL;
2671     this->type = type;
2672     this->elements = elements;
2673     this->ownedByCtfe = OWNEDcode;
2674 }
2675 
ArrayLiteralExp(Loc loc,Type * type,Expression * e)2676 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *e)
2677     : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
2678 {
2679     this->basis = NULL;
2680     this->type = type;
2681     elements = new Expressions;
2682     elements->push(e);
2683     this->ownedByCtfe = OWNEDcode;
2684 }
2685 
ArrayLiteralExp(Loc loc,Type * type,Expression * basis,Expressions * elements)2686 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements)
2687     : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
2688 {
2689     this->basis = basis;
2690     this->type = type;
2691     this->elements = elements;
2692     this->ownedByCtfe = OWNEDcode;
2693 }
2694 
create(Loc loc,Expressions * elements)2695 ArrayLiteralExp *ArrayLiteralExp::create(Loc loc, Expressions *elements)
2696 {
2697     return new ArrayLiteralExp(loc, NULL, elements);
2698 }
2699 
equals(RootObject * o)2700 bool ArrayLiteralExp::equals(RootObject *o)
2701 {
2702     if (this == o)
2703         return true;
2704     if (o && o->dyncast() == DYNCAST_EXPRESSION &&
2705         ((Expression *)o)->op == TOKarrayliteral)
2706     {
2707         ArrayLiteralExp *ae = (ArrayLiteralExp *)o;
2708         if (elements->length != ae->elements->length)
2709             return false;
2710         if (elements->length == 0 &&
2711             !type->equals(ae->type))
2712         {
2713             return false;
2714         }
2715         for (size_t i = 0; i < elements->length; i++)
2716         {
2717             Expression *e1 = (*elements)[i];
2718             Expression *e2 = (*ae->elements)[i];
2719             if (!e1)
2720                 e1 = basis;
2721             if (!e2)
2722                 e2 = basis;
2723             if (e1 != e2 &&
2724                 (!e1 || !e2 || !e1->equals(e2)))
2725                 return false;
2726         }
2727         return true;
2728     }
2729     return false;
2730 }
2731 
syntaxCopy()2732 Expression *ArrayLiteralExp::syntaxCopy()
2733 {
2734     return new ArrayLiteralExp(loc,
2735         NULL,
2736         basis ? basis->syntaxCopy() : NULL,
2737         arraySyntaxCopy(elements));
2738 }
2739 
getElement(size_t i)2740 Expression *ArrayLiteralExp::getElement(size_t i)
2741 {
2742     Expression *el = (*elements)[i];
2743     if (!el)
2744         el = basis;
2745     return el;
2746 }
2747 
appendArrayLiteral(Expressions * elems,ArrayLiteralExp * ale)2748 static void appendArrayLiteral(Expressions *elems, ArrayLiteralExp *ale)
2749 {
2750     if (!ale->elements)
2751         return;
2752     size_t d = elems->length;
2753     elems->append(ale->elements);
2754     for (size_t i = d; i < elems->length; i++)
2755     {
2756         Expression *el = (*elems)[i];
2757         if (!el)
2758             (*elems)[i] = ale->basis;
2759     }
2760 }
2761 
2762 /* Copy element `Expressions` in the parameters when they're `ArrayLiteralExp`s.
2763  * Params:
2764  *      e1  = If it's ArrayLiteralExp, its `elements` will be copied.
2765  *            Otherwise, `e1` itself will be pushed into the new `Expressions`.
2766  *      e2  = If it's not `null`, it will be pushed/appended to the new
2767  *            `Expressions` by the same way with `e1`.
2768  * Returns:
2769  *      Newly allocated `Expressions`. Note that it points to the original
2770  *      `Expression` values in e1 and e2.
2771  */
copyElements(Expression * e1,Expression * e2)2772 Expressions* ArrayLiteralExp::copyElements(Expression *e1, Expression *e2)
2773 {
2774     Expressions *elems = new Expressions();
2775 
2776     if (e1->op == TOKarrayliteral)
2777         appendArrayLiteral(elems, (ArrayLiteralExp *)e1);
2778     else
2779         elems->push(e1);
2780 
2781     if (e2)
2782     {
2783         if (e2->op == TOKarrayliteral)
2784             appendArrayLiteral(elems, (ArrayLiteralExp *)e2);
2785         else
2786             elems->push(e2);
2787     }
2788 
2789     return elems;
2790 }
2791 
isBool(bool result)2792 bool ArrayLiteralExp::isBool(bool result)
2793 {
2794     size_t dim = elements ? elements->length : 0;
2795     return result ? (dim != 0) : (dim == 0);
2796 }
2797 
toStringExp()2798 StringExp *ArrayLiteralExp::toStringExp()
2799 {
2800     TY telem = type->nextOf()->toBasetype()->ty;
2801 
2802     if (telem == Tchar || telem == Twchar || telem == Tdchar ||
2803         (telem == Tvoid && (!elements || elements->length == 0)))
2804     {
2805         unsigned char sz = 1;
2806         if (telem == Twchar) sz = 2;
2807         else if (telem == Tdchar) sz = 4;
2808 
2809         OutBuffer buf;
2810         if (elements)
2811         {
2812             for (size_t i = 0; i < elements->length; ++i)
2813             {
2814                 Expression *ch = getElement(i);
2815                 if (ch->op != TOKint64)
2816                     return NULL;
2817                 if (sz == 1)
2818                     buf.writeByte((unsigned)ch->toInteger());
2819                 else if (sz == 2)
2820                     buf.writeword((unsigned)ch->toInteger());
2821                 else
2822                     buf.write4((unsigned)ch->toInteger());
2823             }
2824         }
2825         char prefix;
2826              if (sz == 1) { prefix = 'c'; buf.writeByte(0); }
2827         else if (sz == 2) { prefix = 'w'; buf.writeword(0); }
2828         else              { prefix = 'd'; buf.write4(0); }
2829 
2830         const size_t len = buf.length() / sz - 1;
2831         StringExp *se = new StringExp(loc, buf.extractData(), len, prefix);
2832         se->sz = sz;
2833         se->type = type;
2834         return se;
2835     }
2836     return NULL;
2837 }
2838 
2839 /************************ AssocArrayLiteralExp ************************************/
2840 
2841 // [ key0 : value0, key1 : value1, ... ]
2842 
AssocArrayLiteralExp(Loc loc,Expressions * keys,Expressions * values)2843 AssocArrayLiteralExp::AssocArrayLiteralExp(Loc loc,
2844                 Expressions *keys, Expressions *values)
2845     : Expression(loc, TOKassocarrayliteral, sizeof(AssocArrayLiteralExp))
2846 {
2847     assert(keys->length == values->length);
2848     this->keys = keys;
2849     this->values = values;
2850     this->ownedByCtfe = OWNEDcode;
2851 }
2852 
equals(RootObject * o)2853 bool AssocArrayLiteralExp::equals(RootObject *o)
2854 {
2855     if (this == o)
2856         return true;
2857     if (o && o->dyncast() == DYNCAST_EXPRESSION &&
2858         ((Expression *)o)->op == TOKassocarrayliteral)
2859     {
2860         AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)o;
2861         if (keys->length != ae->keys->length)
2862             return false;
2863         size_t count = 0;
2864         for (size_t i = 0; i < keys->length; i++)
2865         {
2866             for (size_t j = 0; j < ae->keys->length; j++)
2867             {
2868                 if ((*keys)[i]->equals((*ae->keys)[j]))
2869                 {
2870                     if (!(*values)[i]->equals((*ae->values)[j]))
2871                         return false;
2872                     ++count;
2873                 }
2874             }
2875         }
2876         return count == keys->length;
2877     }
2878     return false;
2879 }
2880 
syntaxCopy()2881 Expression *AssocArrayLiteralExp::syntaxCopy()
2882 {
2883     return new AssocArrayLiteralExp(loc,
2884         arraySyntaxCopy(keys), arraySyntaxCopy(values));
2885 }
2886 
isBool(bool result)2887 bool AssocArrayLiteralExp::isBool(bool result)
2888 {
2889     size_t dim = keys->length;
2890     return result ? (dim != 0) : (dim == 0);
2891 }
2892 
2893 /************************ StructLiteralExp ************************************/
2894 
2895 // sd( e1, e2, e3, ... )
2896 
StructLiteralExp(Loc loc,StructDeclaration * sd,Expressions * elements,Type * stype)2897 StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype)
2898     : Expression(loc, TOKstructliteral, sizeof(StructLiteralExp))
2899 {
2900     this->sd = sd;
2901     if (!elements)
2902         elements = new Expressions();
2903     this->elements = elements;
2904     this->stype = stype;
2905     this->useStaticInit = false;
2906     this->sym = NULL;
2907     this->ownedByCtfe = OWNEDcode;
2908     this->origin = this;
2909     this->stageflags = 0;
2910     this->inlinecopy = NULL;
2911     //printf("StructLiteralExp::StructLiteralExp(%s)\n", toChars());
2912 }
2913 
create(Loc loc,StructDeclaration * sd,void * elements,Type * stype)2914 StructLiteralExp *StructLiteralExp::create(Loc loc, StructDeclaration *sd, void *elements, Type *stype)
2915 {
2916     return new StructLiteralExp(loc, sd, (Expressions *)elements, stype);
2917 }
2918 
equals(RootObject * o)2919 bool StructLiteralExp::equals(RootObject *o)
2920 {
2921     if (this == o)
2922         return true;
2923     if (o && o->dyncast() == DYNCAST_EXPRESSION &&
2924         ((Expression *)o)->op == TOKstructliteral)
2925     {
2926         StructLiteralExp *se = (StructLiteralExp *)o;
2927         if (!type->equals(se->type))
2928             return false;
2929         if (elements->length != se->elements->length)
2930             return false;
2931         for (size_t i = 0; i < elements->length; i++)
2932         {
2933             Expression *e1 = (*elements)[i];
2934             Expression *e2 = (*se->elements)[i];
2935             if (e1 != e2 &&
2936                 (!e1 || !e2 || !e1->equals(e2)))
2937                 return false;
2938         }
2939         return true;
2940     }
2941     return false;
2942 }
2943 
syntaxCopy()2944 Expression *StructLiteralExp::syntaxCopy()
2945 {
2946     StructLiteralExp *exp = new StructLiteralExp(loc, sd, arraySyntaxCopy(elements), type ? type : stype);
2947     exp->origin = this;
2948     return exp;
2949 }
2950 
addDtorHook(Scope * sc)2951 Expression *StructLiteralExp::addDtorHook(Scope *sc)
2952 {
2953     /* If struct requires a destructor, rewrite as:
2954      *    (S tmp = S()),tmp
2955      * so that the destructor can be hung on tmp.
2956      */
2957     if (sd->dtor && sc->func)
2958     {
2959         /* Make an identifier for the temporary of the form:
2960          *   __sl%s%d, where %s is the struct name
2961          */
2962         const size_t len = 10;
2963         char buf[len + 1];
2964         buf[len] = 0;
2965         strcpy(buf, "__sl");
2966         strncat(buf, sd->ident->toChars(), len - 4 - 1);
2967         assert(buf[len] == 0);
2968 
2969         VarDeclaration *tmp = copyToTemp(0, buf, this);
2970         Expression *ae = new DeclarationExp(loc, tmp);
2971         Expression *e = new CommaExp(loc, ae, new VarExp(loc, tmp));
2972         e = expressionSemantic(e, sc);
2973         return e;
2974     }
2975     return this;
2976 }
2977 
2978 /**************************************
2979  * Gets expression at offset of type.
2980  * Returns NULL if not found.
2981  */
2982 
getField(Type * type,unsigned offset)2983 Expression *StructLiteralExp::getField(Type *type, unsigned offset)
2984 {
2985     //printf("StructLiteralExp::getField(this = %s, type = %s, offset = %u)\n",
2986     //  /*toChars()*/"", type->toChars(), offset);
2987     Expression *e = NULL;
2988     int i = getFieldIndex(type, offset);
2989 
2990     if (i != -1)
2991     {
2992         //printf("\ti = %d\n", i);
2993         if (i == (int)sd->fields.length - 1 && sd->isNested())
2994             return NULL;
2995 
2996         assert(i < (int)elements->length);
2997         e = (*elements)[i];
2998         if (e)
2999         {
3000             //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars());
3001 
3002             /* If type is a static array, and e is an initializer for that array,
3003              * then the field initializer should be an array literal of e.
3004              */
3005             if (e->type->castMod(0) != type->castMod(0) && type->ty == Tsarray)
3006             {   TypeSArray *tsa = (TypeSArray *)type;
3007                 size_t length = (size_t)tsa->dim->toInteger();
3008                 Expressions *z = new Expressions;
3009                 z->setDim(length);
3010                 for (size_t q = 0; q < length; ++q)
3011                     (*z)[q] = e->copy();
3012                 e = new ArrayLiteralExp(loc, type, z);
3013             }
3014             else
3015             {
3016                 e = e->copy();
3017                 e->type = type;
3018             }
3019             if (useStaticInit && e->op == TOKstructliteral &&
3020                 e->type->needsNested())
3021             {
3022                 StructLiteralExp *se = (StructLiteralExp *)e;
3023                 se->useStaticInit = true;
3024             }
3025         }
3026     }
3027     return e;
3028 }
3029 
3030 /************************************
3031  * Get index of field.
3032  * Returns -1 if not found.
3033  */
3034 
getFieldIndex(Type * type,unsigned offset)3035 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset)
3036 {
3037     /* Find which field offset is by looking at the field offsets
3038      */
3039     if (elements->length)
3040     {
3041         for (size_t i = 0; i < sd->fields.length; i++)
3042         {
3043             VarDeclaration *v = sd->fields[i];
3044 
3045             if (offset == v->offset &&
3046                 type->size() == v->type->size())
3047             {
3048                 /* context field might not be filled. */
3049                 if (i == sd->fields.length - 1 && sd->isNested())
3050                     return (int)i;
3051                 Expression *e = (*elements)[i];
3052                 if (e)
3053                 {
3054                     return (int)i;
3055                 }
3056                 break;
3057             }
3058         }
3059     }
3060     return -1;
3061 }
3062 
3063 /************************ TypeDotIdExp ************************************/
3064 
3065 /* Things like:
3066  *      int.size
3067  *      foo.size
3068  *      (foo).size
3069  *      cast(foo).size
3070  */
3071 
typeDotIdExp(Loc loc,Type * type,Identifier * ident)3072 DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident)
3073 {
3074     return new DotIdExp(loc, new TypeExp(loc, type), ident);
3075 }
3076 
3077 
3078 /************************************************************/
3079 
3080 // Mainly just a placeholder
3081 
TypeExp(Loc loc,Type * type)3082 TypeExp::TypeExp(Loc loc, Type *type)
3083     : Expression(loc, TOKtype, sizeof(TypeExp))
3084 {
3085     //printf("TypeExp::TypeExp(%s)\n", type->toChars());
3086     this->type = type;
3087 }
3088 
syntaxCopy()3089 Expression *TypeExp::syntaxCopy()
3090 {
3091     return new TypeExp(loc, type->syntaxCopy());
3092 }
3093 
checkType()3094 bool TypeExp::checkType()
3095 {
3096     error("type %s is not an expression", toChars());
3097     return true;
3098 }
3099 
checkValue()3100 bool TypeExp::checkValue()
3101 {
3102     error("type %s has no value", toChars());
3103     return true;
3104 }
3105 
3106 /************************************************************/
3107 
3108 /***********************************************************
3109  * Mainly just a placeholder of
3110  *  Package, Module, Nspace, and TemplateInstance (including TemplateMixin)
3111  *
3112  * A template instance that requires IFTI:
3113  *      foo!tiargs(fargs)       // foo!tiargs
3114  * is left until CallExp::semantic() or resolveProperties()
3115  */
ScopeExp(Loc loc,ScopeDsymbol * sds)3116 ScopeExp::ScopeExp(Loc loc, ScopeDsymbol *sds)
3117     : Expression(loc, TOKscope, sizeof(ScopeExp))
3118 {
3119     //printf("ScopeExp::ScopeExp(sds = '%s')\n", sds->toChars());
3120     //static int count; if (++count == 38) *(char*)0=0;
3121     this->sds = sds;
3122     assert(!sds->isTemplateDeclaration());   // instead, you should use TemplateExp
3123 }
3124 
syntaxCopy()3125 Expression *ScopeExp::syntaxCopy()
3126 {
3127     return new ScopeExp(loc, (ScopeDsymbol *)sds->syntaxCopy(NULL));
3128 }
3129 
checkType()3130 bool ScopeExp::checkType()
3131 {
3132     if (sds->isPackage())
3133     {
3134         error("%s %s has no type", sds->kind(), sds->toChars());
3135         return true;
3136     }
3137     if (TemplateInstance *ti = sds->isTemplateInstance())
3138     {
3139         //assert(ti->needsTypeInference(sc));
3140         if (ti->tempdecl &&
3141             ti->semantictiargsdone &&
3142             ti->semanticRun == PASSinit)
3143         {
3144             error("partial %s %s has no type", sds->kind(), toChars());
3145             return true;
3146         }
3147     }
3148     return false;
3149 }
3150 
checkValue()3151 bool ScopeExp::checkValue()
3152 {
3153     error("%s %s has no value", sds->kind(), sds->toChars());
3154     return true;
3155 }
3156 
3157 /********************** TemplateExp **************************************/
3158 
3159 // Mainly just a placeholder
3160 
TemplateExp(Loc loc,TemplateDeclaration * td,FuncDeclaration * fd)3161 TemplateExp::TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd)
3162     : Expression(loc, TOKtemplate, sizeof(TemplateExp))
3163 {
3164     //printf("TemplateExp(): %s\n", td->toChars());
3165     this->td = td;
3166     this->fd = fd;
3167 }
3168 
checkType()3169 bool TemplateExp::checkType()
3170 {
3171     error("%s %s has no type", td->kind(), toChars());
3172     return true;
3173 }
3174 
checkValue()3175 bool TemplateExp::checkValue()
3176 {
3177     error("%s %s has no value", td->kind(), toChars());
3178     return true;
3179 }
3180 
isLvalue()3181 bool TemplateExp::isLvalue()
3182 {
3183     return fd != NULL;
3184 }
3185 
toLvalue(Scope * sc,Expression * e)3186 Expression *TemplateExp::toLvalue(Scope *sc, Expression *e)
3187 {
3188     if (!fd)
3189         return Expression::toLvalue(sc, e);
3190 
3191     assert(sc);
3192     return resolve(loc, sc, fd, true);
3193 }
3194 
3195 /********************** NewExp **************************************/
3196 
3197 /* thisexp.new(newargs) newtype(arguments) */
3198 
NewExp(Loc loc,Expression * thisexp,Expressions * newargs,Type * newtype,Expressions * arguments)3199 NewExp::NewExp(Loc loc, Expression *thisexp, Expressions *newargs,
3200         Type *newtype, Expressions *arguments)
3201     : Expression(loc, TOKnew, sizeof(NewExp))
3202 {
3203     this->thisexp = thisexp;
3204     this->newargs = newargs;
3205     this->newtype = newtype;
3206     this->arguments = arguments;
3207     argprefix = NULL;
3208     member = NULL;
3209     allocator = NULL;
3210     onstack = 0;
3211 }
3212 
create(Loc loc,Expression * thisexp,Expressions * newargs,Type * newtype,Expressions * arguments)3213 NewExp *NewExp::create(Loc loc, Expression *thisexp, Expressions *newargs,
3214         Type *newtype, Expressions *arguments)
3215 {
3216     return new NewExp(loc, thisexp, newargs, newtype, arguments);
3217 }
3218 
syntaxCopy()3219 Expression *NewExp::syntaxCopy()
3220 {
3221     return new NewExp(loc,
3222         thisexp ? thisexp->syntaxCopy() : NULL,
3223         arraySyntaxCopy(newargs),
3224         newtype->syntaxCopy(), arraySyntaxCopy(arguments));
3225 }
3226 
3227 /********************** NewAnonClassExp **************************************/
3228 
NewAnonClassExp(Loc loc,Expression * thisexp,Expressions * newargs,ClassDeclaration * cd,Expressions * arguments)3229 NewAnonClassExp::NewAnonClassExp(Loc loc, Expression *thisexp,
3230         Expressions *newargs, ClassDeclaration *cd, Expressions *arguments)
3231     : Expression(loc, TOKnewanonclass, sizeof(NewAnonClassExp))
3232 {
3233     this->thisexp = thisexp;
3234     this->newargs = newargs;
3235     this->cd = cd;
3236     this->arguments = arguments;
3237 }
3238 
syntaxCopy()3239 Expression *NewAnonClassExp::syntaxCopy()
3240 {
3241     return new NewAnonClassExp(loc,
3242         thisexp ? thisexp->syntaxCopy() : NULL,
3243         arraySyntaxCopy(newargs),
3244         (ClassDeclaration *)cd->syntaxCopy(NULL),
3245         arraySyntaxCopy(arguments));
3246 }
3247 
3248 /********************** SymbolExp **************************************/
3249 
SymbolExp(Loc loc,TOK op,int size,Declaration * var,bool hasOverloads)3250 SymbolExp::SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads)
3251     : Expression(loc, op, size)
3252 {
3253     assert(var);
3254     this->var = var;
3255     this->hasOverloads = hasOverloads;
3256 }
3257 
3258 /********************** SymOffExp **************************************/
3259 
SymOffExp(Loc loc,Declaration * var,dinteger_t offset,bool hasOverloads)3260 SymOffExp::SymOffExp(Loc loc, Declaration *var, dinteger_t offset, bool hasOverloads)
3261     : SymbolExp(loc, TOKsymoff, sizeof(SymOffExp), var,
3262                 var->isVarDeclaration() ? false : hasOverloads)
3263 {
3264     if (VarDeclaration *v = var->isVarDeclaration())
3265     {
3266         // FIXME: This error report will never be handled anyone.
3267         // It should be done before the SymOffExp construction.
3268         if (v->needThis())
3269             ::error(loc, "need `this` for address of %s", v->toChars());
3270     }
3271     this->offset = offset;
3272 }
3273 
isBool(bool result)3274 bool SymOffExp::isBool(bool result)
3275 {
3276     return result ? true : false;
3277 }
3278 
3279 /******************************** VarExp **************************/
3280 
VarExp(Loc loc,Declaration * var,bool hasOverloads)3281 VarExp::VarExp(Loc loc, Declaration *var, bool hasOverloads)
3282     : SymbolExp(loc, TOKvar, sizeof(VarExp), var,
3283                 var->isVarDeclaration() ? false : hasOverloads)
3284 {
3285     //printf("VarExp(this = %p, '%s', loc = %s)\n", this, var->toChars(), loc.toChars());
3286     //if (strcmp(var->ident->toChars(), "func") == 0) halt();
3287     this->type = var->type;
3288 }
3289 
create(Loc loc,Declaration * var,bool hasOverloads)3290 VarExp *VarExp::create(Loc loc, Declaration *var, bool hasOverloads)
3291 {
3292     return new VarExp(loc, var, hasOverloads);
3293 }
3294 
equals(RootObject * o)3295 bool VarExp::equals(RootObject *o)
3296 {
3297     if (this == o)
3298         return true;
3299     if (((Expression *)o)->op == TOKvar)
3300     {
3301         VarExp *ne = (VarExp *)o;
3302         if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
3303             var == ne->var)
3304         {
3305             return true;
3306         }
3307     }
3308     return false;
3309 }
3310 
isLvalue()3311 bool VarExp::isLvalue()
3312 {
3313     if (var->storage_class & (STClazy | STCrvalue | STCmanifest))
3314         return false;
3315     return true;
3316 }
3317 
toLvalue(Scope *,Expression *)3318 Expression *VarExp::toLvalue(Scope *, Expression *)
3319 {
3320     if (var->storage_class & STCmanifest)
3321     {
3322         error("manifest constant `%s` is not lvalue", var->toChars());
3323         return new ErrorExp();
3324     }
3325     if (var->storage_class & STClazy)
3326     {
3327         error("lazy variables cannot be lvalues");
3328         return new ErrorExp();
3329     }
3330     if (var->ident == Id::ctfe)
3331     {
3332         error("compiler-generated variable __ctfe is not an lvalue");
3333         return new ErrorExp();
3334     }
3335     if (var->ident == Id::dollar)   // Bugzilla 13574
3336     {
3337         error("`$` is not an lvalue");
3338         return new ErrorExp();
3339     }
3340     return this;
3341 }
3342 
checkModifiable(Scope * sc,int flag)3343 int VarExp::checkModifiable(Scope *sc, int flag)
3344 {
3345     //printf("VarExp::checkModifiable %s", toChars());
3346     assert(type);
3347     return var->checkModify(loc, sc, type, NULL, flag);
3348 }
3349 
modifiableLvalue(Scope * sc,Expression * e)3350 Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e)
3351 {
3352     //printf("VarExp::modifiableLvalue('%s')\n", var->toChars());
3353     if (var->storage_class & STCmanifest)
3354     {
3355         error("cannot modify manifest constant `%s`", toChars());
3356         return new ErrorExp();
3357     }
3358     // See if this expression is a modifiable lvalue (i.e. not const)
3359     return Expression::modifiableLvalue(sc, e);
3360 }
3361 
3362 
3363 /******************************** OverExp **************************/
3364 
OverExp(Loc loc,OverloadSet * s)3365 OverExp::OverExp(Loc loc, OverloadSet *s)
3366         : Expression(loc, TOKoverloadset, sizeof(OverExp))
3367 {
3368     //printf("OverExp(this = %p, '%s')\n", this, var->toChars());
3369     vars = s;
3370     type = Type::tvoid;
3371 }
3372 
isLvalue()3373 bool OverExp::isLvalue()
3374 {
3375     return true;
3376 }
3377 
toLvalue(Scope *,Expression *)3378 Expression *OverExp::toLvalue(Scope *, Expression *)
3379 {
3380     return this;
3381 }
3382 
3383 /******************************** TupleExp **************************/
3384 
TupleExp(Loc loc,Expression * e0,Expressions * exps)3385 TupleExp::TupleExp(Loc loc, Expression *e0, Expressions *exps)
3386         : Expression(loc, TOKtuple, sizeof(TupleExp))
3387 {
3388     //printf("TupleExp(this = %p)\n", this);
3389     this->e0 = e0;
3390     this->exps = exps;
3391 }
3392 
TupleExp(Loc loc,Expressions * exps)3393 TupleExp::TupleExp(Loc loc, Expressions *exps)
3394         : Expression(loc, TOKtuple, sizeof(TupleExp))
3395 {
3396     //printf("TupleExp(this = %p)\n", this);
3397     this->e0 = NULL;
3398     this->exps = exps;
3399 }
3400 
TupleExp(Loc loc,TupleDeclaration * tup)3401 TupleExp::TupleExp(Loc loc, TupleDeclaration *tup)
3402         : Expression(loc, TOKtuple, sizeof(TupleExp))
3403 {
3404     this->e0 = NULL;
3405     this->exps = new Expressions();
3406 
3407     this->exps->reserve(tup->objects->length);
3408     for (size_t i = 0; i < tup->objects->length; i++)
3409     {   RootObject *o = (*tup->objects)[i];
3410         if (Dsymbol *s = getDsymbol(o))
3411         {
3412             /* If tuple element represents a symbol, translate to DsymbolExp
3413              * to supply implicit 'this' if needed later.
3414              */
3415             Expression *e = new DsymbolExp(loc, s);
3416             this->exps->push(e);
3417         }
3418         else if (o->dyncast() == DYNCAST_EXPRESSION)
3419         {
3420             Expression *e = ((Expression *)o)->copy();
3421             e->loc = loc;    // Bugzilla 15669
3422             this->exps->push(e);
3423         }
3424         else if (o->dyncast() == DYNCAST_TYPE)
3425         {
3426             Type *t = (Type *)o;
3427             Expression *e = new TypeExp(loc, t);
3428             this->exps->push(e);
3429         }
3430         else
3431         {
3432             error("%s is not an expression", o->toChars());
3433         }
3434     }
3435 }
3436 
equals(RootObject * o)3437 bool TupleExp::equals(RootObject *o)
3438 {
3439     if (this == o)
3440         return true;
3441     if (((Expression *)o)->op == TOKtuple)
3442     {
3443         TupleExp *te = (TupleExp *)o;
3444         if (exps->length != te->exps->length)
3445             return false;
3446         if ((e0 && !e0->equals(te->e0)) || (!e0 && te->e0))
3447             return false;
3448         for (size_t i = 0; i < exps->length; i++)
3449         {
3450             Expression *e1 = (*exps)[i];
3451             Expression *e2 = (*te->exps)[i];
3452             if (!e1->equals(e2))
3453                 return false;
3454         }
3455         return true;
3456     }
3457     return false;
3458 }
3459 
syntaxCopy()3460 Expression *TupleExp::syntaxCopy()
3461 {
3462     return new TupleExp(loc, e0 ? e0->syntaxCopy() : NULL, arraySyntaxCopy(exps));
3463 }
3464 
toTupleExp()3465 TupleExp *TupleExp::toTupleExp()
3466 {
3467     return this;
3468 }
3469 
3470 /******************************** FuncExp *********************************/
3471 
FuncExp(Loc loc,Dsymbol * s)3472 FuncExp::FuncExp(Loc loc, Dsymbol *s)
3473         : Expression(loc, TOKfunction, sizeof(FuncExp))
3474 {
3475     this->td = s->isTemplateDeclaration();
3476     this->fd = s->isFuncLiteralDeclaration();
3477     if (td)
3478     {
3479         assert(td->literal);
3480         assert(td->members && td->members->length == 1);
3481         fd = (*td->members)[0]->isFuncLiteralDeclaration();
3482     }
3483     tok = fd->tok;  // save original kind of function/delegate/(infer)
3484     assert(fd->fbody);
3485 }
3486 
equals(RootObject * o)3487 bool FuncExp::equals(RootObject *o)
3488 {
3489     if (this == o)
3490         return true;
3491     if (o->dyncast() != DYNCAST_EXPRESSION)
3492         return false;
3493     if (((Expression *)o)->op == TOKfunction)
3494     {
3495         FuncExp *fe = (FuncExp *)o;
3496         return fd == fe->fd;
3497     }
3498     return false;
3499 }
3500 
genIdent(Scope * sc)3501 void FuncExp::genIdent(Scope *sc)
3502 {
3503     if (fd->ident == Id::empty)
3504     {
3505         const char *s;
3506         if (fd->fes)                        s = "__foreachbody";
3507         else if (fd->tok == TOKreserved)    s = "__lambda";
3508         else if (fd->tok == TOKdelegate)    s = "__dgliteral";
3509         else                                s = "__funcliteral";
3510 
3511         DsymbolTable *symtab;
3512         if (FuncDeclaration *func = sc->parent->isFuncDeclaration())
3513         {
3514             if (func->localsymtab == NULL)
3515             {
3516                 // Inside template constraint, symtab is not set yet.
3517                 // Initialize it lazily.
3518                 func->localsymtab = new DsymbolTable();
3519             }
3520             symtab = func->localsymtab;
3521         }
3522         else
3523         {
3524             ScopeDsymbol *sds = sc->parent->isScopeDsymbol();
3525             if (!sds->symtab)
3526             {
3527                 // Inside template constraint, symtab may not be set yet.
3528                 // Initialize it lazily.
3529                 assert(sds->isTemplateInstance());
3530                 sds->symtab = new DsymbolTable();
3531             }
3532             symtab = sds->symtab;
3533         }
3534         assert(symtab);
3535         int num = (int)dmd_aaLen(symtab->tab) + 1;
3536         Identifier *id = Identifier::generateId(s, num);
3537         fd->ident = id;
3538         if (td) td->ident = id;
3539         symtab->insert(td ? (Dsymbol *)td : (Dsymbol *)fd);
3540     }
3541 }
3542 
syntaxCopy()3543 Expression *FuncExp::syntaxCopy()
3544 {
3545     if (td)
3546         return new FuncExp(loc, td->syntaxCopy(NULL));
3547     else if (fd->semanticRun == PASSinit)
3548         return new FuncExp(loc, fd->syntaxCopy(NULL));
3549     else    // Bugzilla 13481: Prevent multiple semantic analysis of lambda body.
3550         return new FuncExp(loc, fd);
3551 }
3552 
matchType(Type * to,Scope * sc,FuncExp ** presult,int flag)3553 MATCH FuncExp::matchType(Type *to, Scope *sc, FuncExp **presult, int flag)
3554 {
3555     //printf("FuncExp::matchType('%s'), to=%s\n", type ? type->toChars() : "null", to->toChars());
3556     if (presult)
3557         *presult = NULL;
3558 
3559     TypeFunction *tof = NULL;
3560     if (to->ty == Tdelegate)
3561     {
3562         if (tok == TOKfunction)
3563         {
3564             if (!flag)
3565                 error("cannot match function literal to delegate type `%s`", to->toChars());
3566             return MATCHnomatch;
3567         }
3568         tof = (TypeFunction *)to->nextOf();
3569     }
3570     else if (to->ty == Tpointer && to->nextOf()->ty == Tfunction)
3571     {
3572         if (tok == TOKdelegate)
3573         {
3574             if (!flag)
3575                 error("cannot match delegate literal to function pointer type `%s`", to->toChars());
3576             return MATCHnomatch;
3577         }
3578         tof = (TypeFunction *)to->nextOf();
3579     }
3580 
3581     if (td)
3582     {
3583         if (!tof)
3584         {
3585         L1:
3586             if (!flag)
3587                 error("cannot infer parameter types from %s", to->toChars());
3588             return MATCHnomatch;
3589         }
3590 
3591         // Parameter types inference from 'tof'
3592         assert(td->_scope);
3593         TypeFunction *tf = (TypeFunction *)fd->type;
3594         //printf("\ttof = %s\n", tof->toChars());
3595         //printf("\ttf  = %s\n", tf->toChars());
3596         size_t dim = tf->parameterList.length();
3597 
3598         if (tof->parameterList.length() != dim ||
3599             tof->parameterList.varargs != tf->parameterList.varargs)
3600             goto L1;
3601 
3602         Objects *tiargs = new Objects();
3603         tiargs->reserve(td->parameters->length);
3604 
3605         for (size_t i = 0; i < td->parameters->length; i++)
3606         {
3607             TemplateParameter *tp = (*td->parameters)[i];
3608             size_t u = 0;
3609             for (; u < dim; u++)
3610             {
3611                 Parameter *p = tf->parameterList[u];
3612                 if (p->type->ty == Tident &&
3613                     ((TypeIdentifier *)p->type)->ident == tp->ident)
3614                 {
3615                     break;
3616                 }
3617             }
3618             assert(u < dim);
3619             Parameter *pto = tof->parameterList[u];
3620             Type *t = pto->type;
3621             if (t->ty == Terror)
3622                 goto L1;
3623             tiargs->push(t);
3624         }
3625 
3626         // Set target of return type inference
3627         if (!tf->next && tof->next)
3628             fd->treq = to;
3629 
3630         TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
3631         Expression *ex = new ScopeExp(loc, ti);
3632         ex = expressionSemantic(ex, td->_scope);
3633 
3634         // Reset inference target for the later re-semantic
3635         fd->treq = NULL;
3636 
3637         if (ex->op == TOKerror)
3638             return MATCHnomatch;
3639         if (ex->op != TOKfunction)
3640             goto L1;
3641         return ((FuncExp *)ex)->matchType(to, sc, presult, flag);
3642     }
3643 
3644     if (!tof || !tof->next)
3645         return MATCHnomatch;
3646 
3647     assert(type && type != Type::tvoid);
3648     TypeFunction *tfx = (TypeFunction *)fd->type;
3649     bool convertMatch = (type->ty != to->ty);
3650 
3651     if (fd->inferRetType && tfx->next->implicitConvTo(tof->next) == MATCHconvert)
3652     {
3653         /* If return type is inferred and covariant return,
3654          * tweak return statements to required return type.
3655          *
3656          * interface I {}
3657          * class C : Object, I{}
3658          *
3659          * I delegate() dg = delegate() { return new class C(); }
3660          */
3661         convertMatch = true;
3662 
3663         TypeFunction *tfy = new TypeFunction(tfx->parameterList, tof->next, tfx->linkage, STCundefined);
3664         tfy->mod = tfx->mod;
3665         tfy->isnothrow  = tfx->isnothrow;
3666         tfy->isnogc     = tfx->isnogc;
3667         tfy->purity     = tfx->purity;
3668         tfy->isproperty = tfx->isproperty;
3669         tfy->isref      = tfx->isref;
3670         tfy->iswild     = tfx->iswild;
3671         tfy->deco = tfy->merge()->deco;
3672 
3673         tfx = tfy;
3674     }
3675 
3676     Type *tx;
3677     if (tok == TOKdelegate ||
3678         (tok == TOKreserved && (type->ty == Tdelegate ||
3679                                 (type->ty == Tpointer && to->ty == Tdelegate))))
3680     {
3681         // Allow conversion from implicit function pointer to delegate
3682         tx = new TypeDelegate(tfx);
3683         tx->deco = tx->merge()->deco;
3684     }
3685     else
3686     {
3687         assert(tok == TOKfunction ||
3688                (tok == TOKreserved && type->ty == Tpointer));
3689         tx = tfx->pointerTo();
3690     }
3691     //printf("\ttx = %s, to = %s\n", tx->toChars(), to->toChars());
3692 
3693     MATCH m = tx->implicitConvTo(to);
3694     if (m > MATCHnomatch)
3695     {
3696         // MATCHexact:      exact type match
3697         // MATCHconst:      covairiant type match (eg. attributes difference)
3698         // MATCHconvert:    context conversion
3699         m = convertMatch ? MATCHconvert : tx->equals(to) ? MATCHexact : MATCHconst;
3700 
3701         if (presult)
3702         {
3703             (*presult) = (FuncExp *)copy();
3704             (*presult)->type = to;
3705 
3706             // Bugzilla 12508: Tweak function body for covariant returns.
3707             (*presult)->fd->modifyReturns(sc, tof->next);
3708         }
3709     }
3710     else if (!flag)
3711     {
3712         const char *ts[2];
3713         toAutoQualChars(ts, tx, to);
3714         error("cannot implicitly convert expression (%s) of type %s to %s",
3715                 toChars(), ts[0], ts[1]);
3716     }
3717     return m;
3718 }
3719 
toChars()3720 const char *FuncExp::toChars()
3721 {
3722     return fd->toChars();
3723 }
3724 
checkType()3725 bool FuncExp::checkType()
3726 {
3727     if (td)
3728     {
3729         error("template lambda has no type");
3730         return true;
3731     }
3732     return false;
3733 }
3734 
checkValue()3735 bool FuncExp::checkValue()
3736 {
3737     if (td)
3738     {
3739         error("template lambda has no value");
3740         return true;
3741     }
3742     return false;
3743 }
3744 
3745 /******************************** DeclarationExp **************************/
3746 
DeclarationExp(Loc loc,Dsymbol * declaration)3747 DeclarationExp::DeclarationExp(Loc loc, Dsymbol *declaration)
3748         : Expression(loc, TOKdeclaration, sizeof(DeclarationExp))
3749 {
3750     this->declaration = declaration;
3751 }
3752 
syntaxCopy()3753 Expression *DeclarationExp::syntaxCopy()
3754 {
3755     return new DeclarationExp(loc, declaration->syntaxCopy(NULL));
3756 }
3757 
hasCode()3758 bool DeclarationExp::hasCode()
3759 {
3760     if (VarDeclaration *vd = declaration->isVarDeclaration())
3761     {
3762         return !(vd->storage_class & (STCmanifest | STCstatic));
3763     }
3764     return false;
3765 }
3766 
3767 /************************ TypeidExp ************************************/
3768 
3769 /*
3770  *      typeid(int)
3771  */
3772 
TypeidExp(Loc loc,RootObject * o)3773 TypeidExp::TypeidExp(Loc loc, RootObject *o)
3774     : Expression(loc, TOKtypeid, sizeof(TypeidExp))
3775 {
3776     this->obj = o;
3777 }
3778 
syntaxCopy()3779 Expression *TypeidExp::syntaxCopy()
3780 {
3781     return new TypeidExp(loc, objectSyntaxCopy(obj));
3782 }
3783 
3784 /************************ TraitsExp ************************************/
3785 /*
3786  *      __traits(identifier, args...)
3787  */
3788 
TraitsExp(Loc loc,Identifier * ident,Objects * args)3789 TraitsExp::TraitsExp(Loc loc, Identifier *ident, Objects *args)
3790     : Expression(loc, TOKtraits, sizeof(TraitsExp))
3791 {
3792     this->ident = ident;
3793     this->args = args;
3794 }
3795 
syntaxCopy()3796 Expression *TraitsExp::syntaxCopy()
3797 {
3798     return new TraitsExp(loc, ident, TemplateInstance::arraySyntaxCopy(args));
3799 }
3800 
3801 /************************************************************/
3802 
HaltExp(Loc loc)3803 HaltExp::HaltExp(Loc loc)
3804         : Expression(loc, TOKhalt, sizeof(HaltExp))
3805 {
3806 }
3807 
3808 /************************************************************/
3809 
IsExp(Loc loc,Type * targ,Identifier * id,TOK tok,Type * tspec,TOK tok2,TemplateParameters * parameters)3810 IsExp::IsExp(Loc loc, Type *targ, Identifier *id, TOK tok,
3811         Type *tspec, TOK tok2, TemplateParameters *parameters)
3812         : Expression(loc, TOKis, sizeof(IsExp))
3813 {
3814     this->targ = targ;
3815     this->id = id;
3816     this->tok = tok;
3817     this->tspec = tspec;
3818     this->tok2 = tok2;
3819     this->parameters = parameters;
3820 }
3821 
syntaxCopy()3822 Expression *IsExp::syntaxCopy()
3823 {
3824     // This section is identical to that in TemplateDeclaration::syntaxCopy()
3825     TemplateParameters *p = NULL;
3826     if (parameters)
3827     {
3828         p = new TemplateParameters();
3829         p->setDim(parameters->length);
3830         for (size_t i = 0; i < p->length; i++)
3831             (*p)[i] = (*parameters)[i]->syntaxCopy();
3832     }
3833     return new IsExp(loc,
3834         targ->syntaxCopy(),
3835         id,
3836         tok,
3837         tspec ? tspec->syntaxCopy() : NULL,
3838         tok2,
3839         p);
3840 }
3841 
3842 void unSpeculative(Scope *sc, RootObject *o);
3843 
3844 /************************************************************/
3845 
UnaExp(Loc loc,TOK op,int size,Expression * e1)3846 UnaExp::UnaExp(Loc loc, TOK op, int size, Expression *e1)
3847         : Expression(loc, op, size)
3848 {
3849     this->e1 = e1;
3850     this->att1 = NULL;
3851 }
3852 
syntaxCopy()3853 Expression *UnaExp::syntaxCopy()
3854 {
3855     UnaExp *e = (UnaExp *)copy();
3856     e->type = NULL;
3857     e->e1 = e->e1->syntaxCopy();
3858     return e;
3859 }
3860 
3861 /********************************
3862  * The type for a unary expression is incompatible.
3863  * Print error message.
3864  * Returns:
3865  *  ErrorExp
3866  */
incompatibleTypes()3867 Expression *UnaExp::incompatibleTypes()
3868 {
3869     if (e1->type->toBasetype() == Type::terror)
3870         return e1;
3871 
3872     if (e1->op == TOKtype)
3873     {
3874         error("incompatible type for (%s(%s)): cannot use `%s` with types",
3875               Token::toChars(op), e1->toChars(), Token::toChars(op));
3876     }
3877     else
3878     {
3879         error("incompatible type for (%s(%s)): `%s`",
3880               Token::toChars(op), e1->toChars(), e1->type->toChars());
3881     }
3882     return new ErrorExp();
3883 }
3884 
resolveLoc(Loc loc,Scope * sc)3885 Expression *UnaExp::resolveLoc(Loc loc, Scope *sc)
3886 {
3887     e1 = e1->resolveLoc(loc, sc);
3888     return this;
3889 }
3890 
3891 /************************************************************/
3892 
BinExp(Loc loc,TOK op,int size,Expression * e1,Expression * e2)3893 BinExp::BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2)
3894         : Expression(loc, op, size)
3895 {
3896     this->e1 = e1;
3897     this->e2 = e2;
3898 
3899     this->att1 = NULL;
3900     this->att2 = NULL;
3901 }
3902 
syntaxCopy()3903 Expression *BinExp::syntaxCopy()
3904 {
3905     BinExp *e = (BinExp *)copy();
3906     e->type = NULL;
3907     e->e1 = e->e1->syntaxCopy();
3908     e->e2 = e->e2->syntaxCopy();
3909     return e;
3910 }
3911 
checkOpAssignTypes(Scope * sc)3912 Expression *BinExp::checkOpAssignTypes(Scope *sc)
3913 {
3914     // At that point t1 and t2 are the merged types. type is the original type of the lhs.
3915     Type *t1 = e1->type;
3916     Type *t2 = e2->type;
3917 
3918     // T opAssign floating yields a floating. Prevent truncating conversions (float to int).
3919     // See issue 3841.
3920     // Should we also prevent double to float (type->isfloating() && type->size() < t2 ->size()) ?
3921     if (op == TOKaddass || op == TOKminass ||
3922         op == TOKmulass || op == TOKdivass || op == TOKmodass ||
3923         op == TOKpowass)
3924     {
3925         if ((type->isintegral() && t2->isfloating()))
3926         {
3927             warning("%s %s %s is performing truncating conversion",
3928                     type->toChars(), Token::toChars(op), t2->toChars());
3929         }
3930     }
3931 
3932     // generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary
3933     if (op == TOKmulass || op == TOKdivass || op == TOKmodass)
3934     {
3935         // Any multiplication by an imaginary or complex number yields a complex result.
3936         // r *= c, i*=c, r*=i, i*=i are all forbidden operations.
3937         const char *opstr = Token::toChars(op);
3938         if (t1->isreal() && t2->iscomplex())
3939         {
3940             error("%s %s %s is undefined. Did you mean %s %s %s.re ?",
3941                 t1->toChars(), opstr, t2->toChars(),
3942                 t1->toChars(), opstr, t2->toChars());
3943             return new ErrorExp();
3944         }
3945         else if (t1->isimaginary() && t2->iscomplex())
3946         {
3947             error("%s %s %s is undefined. Did you mean %s %s %s.im ?",
3948                 t1->toChars(), opstr, t2->toChars(),
3949                 t1->toChars(), opstr, t2->toChars());
3950             return new ErrorExp();
3951         }
3952         else if ((t1->isreal() || t1->isimaginary()) &&
3953             t2->isimaginary())
3954         {
3955             error("%s %s %s is an undefined operation", t1->toChars(), opstr, t2->toChars());
3956             return new ErrorExp();
3957         }
3958     }
3959 
3960     // generate an error if this is a nonsensical += or -=, eg real += imaginary
3961     if (op == TOKaddass || op == TOKminass)
3962     {
3963         // Addition or subtraction of a real and an imaginary is a complex result.
3964         // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations.
3965         if ((t1->isreal() && (t2->isimaginary() || t2->iscomplex())) ||
3966             (t1->isimaginary() && (t2->isreal() || t2->iscomplex())))
3967         {
3968             error("%s %s %s is undefined (result is complex)",
3969                 t1->toChars(), Token::toChars(op), t2->toChars());
3970             return new ErrorExp();
3971         }
3972         if (type->isreal() || type->isimaginary())
3973         {
3974             assert(global.errors || t2->isfloating());
3975             e2 = e2->castTo(sc, t1);
3976         }
3977     }
3978 
3979     if (op == TOKmulass)
3980     {
3981         if (t2->isfloating())
3982         {
3983             if (t1->isreal())
3984             {
3985                 if (t2->isimaginary() || t2->iscomplex())
3986                 {
3987                     e2 = e2->castTo(sc, t1);
3988                 }
3989             }
3990             else if (t1->isimaginary())
3991             {
3992                 if (t2->isimaginary() || t2->iscomplex())
3993                 {
3994                     switch (t1->ty)
3995                     {
3996                         case Timaginary32: t2 = Type::tfloat32; break;
3997                         case Timaginary64: t2 = Type::tfloat64; break;
3998                         case Timaginary80: t2 = Type::tfloat80; break;
3999                         default:
4000                             assert(0);
4001                     }
4002                     e2 = e2->castTo(sc, t2);
4003                 }
4004             }
4005         }
4006     }
4007     else if (op == TOKdivass)
4008     {
4009         if (t2->isimaginary())
4010         {
4011             if (t1->isreal())
4012             {
4013                 // x/iv = i(-x/v)
4014                 // Therefore, the result is 0
4015                 e2 = new CommaExp(loc, e2, new RealExp(loc, CTFloat::zero, t1));
4016                 e2->type = t1;
4017                 Expression *e = new AssignExp(loc, e1, e2);
4018                 e->type = t1;
4019                 return e;
4020             }
4021             else if (t1->isimaginary())
4022             {
4023                 Type *t3;
4024                 switch (t1->ty)
4025                 {
4026                     case Timaginary32: t3 = Type::tfloat32; break;
4027                     case Timaginary64: t3 = Type::tfloat64; break;
4028                     case Timaginary80: t3 = Type::tfloat80; break;
4029                     default:
4030                         assert(0);
4031                 }
4032                 e2 = e2->castTo(sc, t3);
4033                 Expression *e = new AssignExp(loc, e1, e2);
4034                 e->type = t1;
4035                 return e;
4036             }
4037         }
4038     }
4039     else if (op == TOKmodass)
4040     {
4041         if (t2->iscomplex())
4042         {
4043             error("cannot perform modulo complex arithmetic");
4044             return new ErrorExp();
4045         }
4046     }
4047     return this;
4048 }
4049 
4050 /********************************
4051  * The types for a binary expression are incompatible.
4052  * Print error message.
4053  * Returns:
4054  *  ErrorExp
4055  */
incompatibleTypes()4056 Expression *BinExp::incompatibleTypes()
4057 {
4058     if (e1->type->toBasetype() == Type::terror)
4059         return e1;
4060     if (e2->type->toBasetype() == Type::terror)
4061         return e2;
4062 
4063     // CondExp uses 'a ? b : c' but we're comparing 'b : c'
4064     TOK thisOp = (op == TOKquestion) ? TOKcolon : op;
4065     if (e1->op == TOKtype || e2->op == TOKtype)
4066     {
4067         error("incompatible types for ((%s) %s (%s)): cannot use `%s` with types",
4068             e1->toChars(), Token::toChars(thisOp), e2->toChars(), Token::toChars(op));
4069     }
4070     else if (e1->type->equals(e2->type))
4071     {
4072         error("incompatible types for ((%s) %s (%s)): both operands are of type `%s`",
4073             e1->toChars(), Token::toChars(thisOp), e2->toChars(), e1->type->toChars());
4074     }
4075     else
4076     {
4077         const char *ts[2];
4078         toAutoQualChars(ts, e1->type, e2->type);
4079         error("incompatible types for ((%s) %s (%s)): `%s` and `%s`",
4080             e1->toChars(), Token::toChars(thisOp), e2->toChars(), ts[0], ts[1]);
4081     }
4082     return new ErrorExp();
4083 }
4084 
checkIntegralBin()4085 bool BinExp::checkIntegralBin()
4086 {
4087     bool r1 = e1->checkIntegral();
4088     bool r2 = e2->checkIntegral();
4089     return (r1 || r2);
4090 }
4091 
checkArithmeticBin()4092 bool BinExp::checkArithmeticBin()
4093 {
4094     bool r1 = e1->checkArithmetic();
4095     bool r2 = e2->checkArithmetic();
4096     return (r1 || r2);
4097 }
4098 
4099 /********************** BinAssignExp **************************************/
4100 
BinAssignExp(Loc loc,TOK op,int size,Expression * e1,Expression * e2)4101 BinAssignExp::BinAssignExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2)
4102         : BinExp(loc, op, size, e1, e2)
4103 {
4104 }
4105 
isLvalue()4106 bool BinAssignExp::isLvalue()
4107 {
4108     return true;
4109 }
4110 
toLvalue(Scope *,Expression *)4111 Expression *BinAssignExp::toLvalue(Scope *, Expression *)
4112 {
4113     // Lvalue-ness will be handled in glue layer.
4114     return this;
4115 }
4116 
modifiableLvalue(Scope * sc,Expression *)4117 Expression *BinAssignExp::modifiableLvalue(Scope *sc, Expression *)
4118 {
4119     // should check e1->checkModifiable() ?
4120     return toLvalue(sc, this);
4121 }
4122 
4123 /************************************************************/
4124 
CompileExp(Loc loc,Expressions * exps)4125 CompileExp::CompileExp(Loc loc, Expressions *exps)
4126     : Expression(loc, TOKmixin, sizeof(CompileExp))
4127 {
4128     this->exps = exps;
4129 }
4130 
syntaxCopy()4131 Expression *CompileExp::syntaxCopy()
4132 {
4133     return new CompileExp(loc, arraySyntaxCopy(exps));
4134 }
4135 
equals(RootObject * o)4136 bool CompileExp::equals(RootObject *o)
4137 {
4138     if (this == o)
4139         return true;
4140     if (o && o->dyncast() == DYNCAST_EXPRESSION && ((Expression *)o)->op == TOKmixin)
4141     {
4142         CompileExp *ce = (CompileExp *)o;
4143         if (exps->length != ce->exps->length)
4144             return false;
4145         for (size_t i = 0; i < exps->length; i++)
4146         {
4147             Expression *e1 = (*exps)[i];
4148             Expression *e2 = (*ce->exps)[i];
4149             if (e1 != e2 && (!e1 || !e2 || !e1->equals(e2)))
4150                 return false;
4151         }
4152         return true;
4153     }
4154     return false;
4155 }
4156 
4157 /************************************************************/
4158 
ImportExp(Loc loc,Expression * e)4159 ImportExp::ImportExp(Loc loc, Expression *e)
4160         : UnaExp(loc, TOKimport, sizeof(ImportExp), e)
4161 {
4162 }
4163 
4164 /************************************************************/
4165 
AssertExp(Loc loc,Expression * e,Expression * msg)4166 AssertExp::AssertExp(Loc loc, Expression *e, Expression *msg)
4167         : UnaExp(loc, TOKassert, sizeof(AssertExp), e)
4168 {
4169     this->msg = msg;
4170 }
4171 
syntaxCopy()4172 Expression *AssertExp::syntaxCopy()
4173 {
4174     return new AssertExp(loc, e1->syntaxCopy(), msg ? msg->syntaxCopy() : NULL);
4175 }
4176 
4177 /************************************************************/
4178 
DotIdExp(Loc loc,Expression * e,Identifier * ident)4179 DotIdExp::DotIdExp(Loc loc, Expression *e, Identifier *ident)
4180         : UnaExp(loc, TOKdotid, sizeof(DotIdExp), e)
4181 {
4182     this->ident = ident;
4183     this->wantsym = false;
4184     this->noderef = false;
4185 }
4186 
create(Loc loc,Expression * e,Identifier * ident)4187 DotIdExp *DotIdExp::create(Loc loc, Expression *e, Identifier *ident)
4188 {
4189     return new DotIdExp(loc, e, ident);
4190 }
4191 
4192 /********************** DotTemplateExp ***********************************/
4193 
4194 // Mainly just a placeholder
4195 
DotTemplateExp(Loc loc,Expression * e,TemplateDeclaration * td)4196 DotTemplateExp::DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td)
4197         : UnaExp(loc, TOKdottd, sizeof(DotTemplateExp), e)
4198 
4199 {
4200     this->td = td;
4201 }
4202 
4203 /************************************************************/
4204 
DotVarExp(Loc loc,Expression * e,Declaration * var,bool hasOverloads)4205 DotVarExp::DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads)
4206         : UnaExp(loc, TOKdotvar, sizeof(DotVarExp), e)
4207 {
4208     //printf("DotVarExp()\n");
4209     this->var = var;
4210     this->hasOverloads = var->isVarDeclaration() ? false : hasOverloads;
4211 }
4212 
isLvalue()4213 bool DotVarExp::isLvalue()
4214 {
4215     return true;
4216 }
4217 
toLvalue(Scope *,Expression *)4218 Expression *DotVarExp::toLvalue(Scope *, Expression *)
4219 {
4220     //printf("DotVarExp::toLvalue(%s)\n", toChars());
4221     return this;
4222 }
4223 
4224 /***********************************************
4225  * Mark variable v as modified if it is inside a constructor that var
4226  * is a field in.
4227  */
modifyFieldVar(Loc loc,Scope * sc,VarDeclaration * var,Expression * e1)4228 int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1)
4229 {
4230     //printf("modifyFieldVar(var = %s)\n", var->toChars());
4231     Dsymbol *s = sc->func;
4232     while (1)
4233     {
4234         FuncDeclaration *fd = NULL;
4235         if (s)
4236             fd = s->isFuncDeclaration();
4237         if (fd &&
4238             ((fd->isCtorDeclaration() && var->isField()) ||
4239              (fd->isStaticCtorDeclaration() && !var->isField())) &&
4240             fd->toParent2() == var->toParent2() &&
4241             (!e1 || e1->op == TOKthis)
4242            )
4243         {
4244             bool result = true;
4245 
4246             var->ctorinit = true;
4247             //printf("setting ctorinit\n");
4248 
4249             if (var->isField() && sc->fieldinit && !sc->intypeof)
4250             {
4251                 assert(e1);
4252                 bool mustInit = ((var->storage_class & STCnodefaultctor) != 0 ||
4253                                  var->type->needsNested());
4254 
4255                 size_t dim = sc->fieldinit_dim;
4256                 AggregateDeclaration *ad = fd->isMember2();
4257                 assert(ad);
4258                 size_t i;
4259                 for (i = 0; i < dim; i++)   // same as findFieldIndexByName in ctfeexp.c ?
4260                 {
4261                     if (ad->fields[i] == var)
4262                         break;
4263                 }
4264                 assert(i < dim);
4265                 unsigned fi = sc->fieldinit[i];
4266 
4267                 if (fi & CSXthis_ctor)
4268                 {
4269                     if (var->type->isMutable() && e1->type->isMutable())
4270                         result = false;
4271                     else
4272                     {
4273                         const char *modStr = !var->type->isMutable() ? MODtoChars(var->type->mod) : MODtoChars(e1->type->mod);
4274                         ::error(loc, "%s field `%s` initialized multiple times", modStr, var->toChars());
4275                     }
4276                 }
4277                 else if (sc->noctor || (fi & CSXlabel))
4278                 {
4279                     if (!mustInit && var->type->isMutable() && e1->type->isMutable())
4280                         result = false;
4281                     else
4282                     {
4283                         const char *modStr = !var->type->isMutable() ? MODtoChars(var->type->mod) : MODtoChars(e1->type->mod);
4284                         ::error(loc, "%s field `%s` initialization is not allowed in loops or after labels", modStr, var->toChars());
4285                     }
4286                 }
4287                 sc->fieldinit[i] |= CSXthis_ctor;
4288                 if (var->overlapped) // Bugzilla 15258
4289                 {
4290                     for (size_t j = 0; j < ad->fields.length; j++)
4291                     {
4292                         VarDeclaration *v = ad->fields[j];
4293                         if (v == var || !var->isOverlappedWith(v))
4294                             continue;
4295                         v->ctorinit = true;
4296                         sc->fieldinit[j] = CSXthis_ctor;
4297                     }
4298                 }
4299             }
4300             else if (fd != sc->func)
4301             {
4302                 if (var->type->isMutable())
4303                     result = false;
4304                 else if (sc->func->fes)
4305                 {
4306                     const char *p = var->isField() ? "field" : var->kind();
4307                     ::error(loc, "%s %s `%s` initialization is not allowed in foreach loop",
4308                         MODtoChars(var->type->mod), p, var->toChars());
4309                 }
4310                 else
4311                 {
4312                     const char *p = var->isField() ? "field" : var->kind();
4313                     ::error(loc, "%s %s `%s` initialization is not allowed in nested function `%s`",
4314                         MODtoChars(var->type->mod), p, var->toChars(), sc->func->toChars());
4315                 }
4316             }
4317             return result;
4318         }
4319         else
4320         {
4321             if (s)
4322             {
4323                 s = s->toParent2();
4324                 continue;
4325             }
4326         }
4327         break;
4328     }
4329     return false;
4330 }
4331 
checkModifiable(Scope * sc,int flag)4332 int DotVarExp::checkModifiable(Scope *sc, int flag)
4333 {
4334     //printf("DotVarExp::checkModifiable %s %s\n", toChars(), type->toChars());
4335     if (checkUnsafeAccess(sc, this, false, !flag))
4336         return 2;
4337 
4338     if (e1->op == TOKthis)
4339         return var->checkModify(loc, sc, type, e1, flag);
4340 
4341     //printf("\te1 = %s\n", e1->toChars());
4342     return e1->checkModifiable(sc, flag);
4343 }
4344 
modifiableLvalue(Scope * sc,Expression * e)4345 Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e)
4346 {
4347     return Expression::modifiableLvalue(sc, e);
4348 }
4349 
4350 /************************************************************/
4351 
4352 /* Things like:
4353  *      foo.bar!(args)
4354  */
4355 
DotTemplateInstanceExp(Loc loc,Expression * e,Identifier * name,Objects * tiargs)4356 DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs)
4357         : UnaExp(loc, TOKdotti, sizeof(DotTemplateInstanceExp), e)
4358 {
4359     //printf("DotTemplateInstanceExp()\n");
4360     this->ti = new TemplateInstance(loc, name);
4361     this->ti->tiargs = tiargs;
4362 }
4363 
DotTemplateInstanceExp(Loc loc,Expression * e,TemplateInstance * ti)4364 DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti)
4365         : UnaExp(loc, TOKdotti, sizeof(DotTemplateInstanceExp), e)
4366 {
4367     this->ti = ti;
4368 }
4369 
syntaxCopy()4370 Expression *DotTemplateInstanceExp::syntaxCopy()
4371 {
4372     return new DotTemplateInstanceExp(loc,
4373         e1->syntaxCopy(),
4374         ti->name,
4375         TemplateInstance::arraySyntaxCopy(ti->tiargs));
4376 }
4377 
findTempDecl(Scope * sc)4378 bool DotTemplateInstanceExp::findTempDecl(Scope *sc)
4379 {
4380     if (ti->tempdecl)
4381         return true;
4382 
4383     Expression *e = new DotIdExp(loc, e1, ti->name);
4384     e = expressionSemantic(e, sc);
4385     if (e->op == TOKdot)
4386         e = ((DotExp *)e)->e2;
4387 
4388     Dsymbol *s = NULL;
4389     switch (e->op)
4390     {
4391         case TOKoverloadset:    s = ((OverExp *)e)->vars;       break;
4392         case TOKdottd:          s = ((DotTemplateExp *)e)->td;  break;
4393         case TOKscope:          s = ((ScopeExp *)e)->sds;       break;
4394         case TOKdotvar:         s = ((DotVarExp *)e)->var;      break;
4395         case TOKvar:            s = ((VarExp *)e)->var;         break;
4396         default:                return false;
4397     }
4398     return ti->updateTempDecl(sc, s);
4399 }
4400 
4401 /************************************************************/
4402 
DelegateExp(Loc loc,Expression * e,FuncDeclaration * f,bool hasOverloads)4403 DelegateExp::DelegateExp(Loc loc, Expression *e, FuncDeclaration *f, bool hasOverloads)
4404         : UnaExp(loc, TOKdelegate, sizeof(DelegateExp), e)
4405 {
4406     this->func = f;
4407     this->hasOverloads = hasOverloads;
4408 }
4409 
4410 /************************************************************/
4411 
DotTypeExp(Loc loc,Expression * e,Dsymbol * s)4412 DotTypeExp::DotTypeExp(Loc loc, Expression *e, Dsymbol *s)
4413         : UnaExp(loc, TOKdottype, sizeof(DotTypeExp), e)
4414 {
4415     this->sym = s;
4416     this->type = NULL;
4417 }
4418 
4419 /************************************************************/
4420 
CallExp(Loc loc,Expression * e,Expressions * exps)4421 CallExp::CallExp(Loc loc, Expression *e, Expressions *exps)
4422         : UnaExp(loc, TOKcall, sizeof(CallExp), e)
4423 {
4424     this->arguments = exps;
4425     this->f = NULL;
4426     this->directcall = false;
4427 }
4428 
CallExp(Loc loc,Expression * e)4429 CallExp::CallExp(Loc loc, Expression *e)
4430         : UnaExp(loc, TOKcall, sizeof(CallExp), e)
4431 {
4432     this->arguments = NULL;
4433     this->f = NULL;
4434     this->directcall = false;
4435 }
4436 
CallExp(Loc loc,Expression * e,Expression * earg1)4437 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1)
4438         : UnaExp(loc, TOKcall, sizeof(CallExp), e)
4439 {
4440     Expressions *arguments = new Expressions();
4441     if (earg1)
4442     {
4443         arguments->setDim(1);
4444         (*arguments)[0] = earg1;
4445     }
4446     this->arguments = arguments;
4447     this->f = NULL;
4448     this->directcall = false;
4449 }
4450 
CallExp(Loc loc,Expression * e,Expression * earg1,Expression * earg2)4451 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2)
4452         : UnaExp(loc, TOKcall, sizeof(CallExp), e)
4453 {
4454     Expressions *arguments = new Expressions();
4455     arguments->setDim(2);
4456     (*arguments)[0] = earg1;
4457     (*arguments)[1] = earg2;
4458 
4459     this->arguments = arguments;
4460     this->f = NULL;
4461     this->directcall = false;
4462 }
4463 
create(Loc loc,Expression * e,Expressions * exps)4464 CallExp *CallExp::create(Loc loc, Expression *e, Expressions *exps)
4465 {
4466     return new CallExp(loc, e, exps);
4467 }
4468 
create(Loc loc,Expression * e)4469 CallExp *CallExp::create(Loc loc, Expression *e)
4470 {
4471     return new CallExp(loc, e);
4472 }
4473 
create(Loc loc,Expression * e,Expression * earg1)4474 CallExp *CallExp::create(Loc loc, Expression *e, Expression *earg1)
4475 {
4476     return new CallExp(loc, e, earg1);
4477 }
4478 
syntaxCopy()4479 Expression *CallExp::syntaxCopy()
4480 {
4481     return new CallExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
4482 }
4483 
isLvalue()4484 bool CallExp::isLvalue()
4485 {
4486     Type *tb = e1->type->toBasetype();
4487     if (tb->ty == Tdelegate || tb->ty == Tpointer)
4488         tb = tb->nextOf();
4489     if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref)
4490     {
4491         if (e1->op == TOKdotvar)
4492             if (((DotVarExp *)e1)->var->isCtorDeclaration())
4493                 return false;
4494         return true;               // function returns a reference
4495     }
4496     return false;
4497 }
4498 
toLvalue(Scope * sc,Expression * e)4499 Expression *CallExp::toLvalue(Scope *sc, Expression *e)
4500 {
4501     if (isLvalue())
4502         return this;
4503     return Expression::toLvalue(sc, e);
4504 }
4505 
addDtorHook(Scope * sc)4506 Expression *CallExp::addDtorHook(Scope *sc)
4507 {
4508     /* Only need to add dtor hook if it's a type that needs destruction.
4509      * Use same logic as VarDeclaration::callScopeDtor()
4510      */
4511 
4512     if (e1->type && e1->type->ty == Tfunction)
4513     {
4514         TypeFunction *tf = (TypeFunction *)e1->type;
4515         if (tf->isref)
4516             return this;
4517     }
4518 
4519     Type *tv = type->baseElemOf();
4520     if (tv->ty == Tstruct)
4521     {
4522         TypeStruct *ts = (TypeStruct *)tv;
4523         StructDeclaration *sd = ts->sym;
4524         if (sd->dtor)
4525         {
4526             /* Type needs destruction, so declare a tmp
4527              * which the back end will recognize and call dtor on
4528              */
4529             VarDeclaration *tmp = copyToTemp(0, "__tmpfordtor", this);
4530             DeclarationExp *de = new DeclarationExp(loc, tmp);
4531             VarExp *ve = new VarExp(loc, tmp);
4532             Expression *e = new CommaExp(loc, de, ve);
4533             e = expressionSemantic(e, sc);
4534             return e;
4535         }
4536     }
4537     return this;
4538 }
4539 
4540 FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL)
4541 {
4542     if (e->op == TOKaddress)
4543     {
4544         Expression *ae1 = ((AddrExp *)e)->e1;
4545         if (ae1->op == TOKvar)
4546         {
4547             VarExp *ve = (VarExp *)ae1;
4548             if (hasOverloads)
4549                 *hasOverloads = ve->hasOverloads;
4550             return ve->var->isFuncDeclaration();
4551         }
4552         if (ae1->op == TOKdotvar)
4553         {
4554             DotVarExp *dve = (DotVarExp *)ae1;
4555             if (hasOverloads)
4556                 *hasOverloads = dve->hasOverloads;
4557             return dve->var->isFuncDeclaration();
4558         }
4559     }
4560     else
4561     {
4562         if (e->op == TOKsymoff)
4563         {
4564             SymOffExp *soe = (SymOffExp *)e;
4565             if (hasOverloads)
4566                 *hasOverloads = soe->hasOverloads;
4567             return soe->var->isFuncDeclaration();
4568         }
4569         if (e->op == TOKdelegate)
4570         {
4571             DelegateExp *dge = (DelegateExp *)e;
4572             if (hasOverloads)
4573                 *hasOverloads = dge->hasOverloads;
4574             return dge->func->isFuncDeclaration();
4575         }
4576     }
4577     return NULL;
4578 }
4579 
4580 /************************************************************/
4581 
AddrExp(Loc loc,Expression * e)4582 AddrExp::AddrExp(Loc loc, Expression *e)
4583         : UnaExp(loc, TOKaddress, sizeof(AddrExp), e)
4584 {
4585 }
4586 
AddrExp(Loc loc,Expression * e,Type * t)4587 AddrExp::AddrExp(Loc loc, Expression *e, Type *t)
4588         : UnaExp(loc, TOKaddress, sizeof(AddrExp), e)
4589 {
4590     type = t;
4591 }
4592 
4593 /************************************************************/
4594 
PtrExp(Loc loc,Expression * e)4595 PtrExp::PtrExp(Loc loc, Expression *e)
4596         : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
4597 {
4598 //    if (e->type)
4599 //      type = ((TypePointer *)e->type)->next;
4600 }
4601 
PtrExp(Loc loc,Expression * e,Type * t)4602 PtrExp::PtrExp(Loc loc, Expression *e, Type *t)
4603         : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
4604 {
4605     type = t;
4606 }
4607 
isLvalue()4608 bool PtrExp::isLvalue()
4609 {
4610     return true;
4611 }
4612 
toLvalue(Scope *,Expression *)4613 Expression *PtrExp::toLvalue(Scope *, Expression *)
4614 {
4615     return this;
4616 }
4617 
checkModifiable(Scope * sc,int flag)4618 int PtrExp::checkModifiable(Scope *sc, int flag)
4619 {
4620     if (e1->op == TOKsymoff)
4621     {   SymOffExp *se = (SymOffExp *)e1;
4622         return se->var->checkModify(loc, sc, type, NULL, flag);
4623     }
4624     else if (e1->op == TOKaddress)
4625     {
4626         AddrExp *ae = (AddrExp *)e1;
4627         return ae->e1->checkModifiable(sc, flag);
4628     }
4629     return 1;
4630 }
4631 
modifiableLvalue(Scope * sc,Expression * e)4632 Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e)
4633 {
4634     //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars());
4635     return Expression::modifiableLvalue(sc, e);
4636 }
4637 
4638 /************************************************************/
4639 
NegExp(Loc loc,Expression * e)4640 NegExp::NegExp(Loc loc, Expression *e)
4641         : UnaExp(loc, TOKneg, sizeof(NegExp), e)
4642 {
4643 }
4644 
4645 /************************************************************/
4646 
UAddExp(Loc loc,Expression * e)4647 UAddExp::UAddExp(Loc loc, Expression *e)
4648         : UnaExp(loc, TOKuadd, sizeof(UAddExp), e)
4649 {
4650 }
4651 
4652 /************************************************************/
4653 
ComExp(Loc loc,Expression * e)4654 ComExp::ComExp(Loc loc, Expression *e)
4655         : UnaExp(loc, TOKtilde, sizeof(ComExp), e)
4656 {
4657 }
4658 
4659 /************************************************************/
4660 
NotExp(Loc loc,Expression * e)4661 NotExp::NotExp(Loc loc, Expression *e)
4662         : UnaExp(loc, TOKnot, sizeof(NotExp), e)
4663 {
4664 }
4665 
4666 /************************************************************/
4667 
DeleteExp(Loc loc,Expression * e,bool isRAII)4668 DeleteExp::DeleteExp(Loc loc, Expression *e, bool isRAII)
4669         : UnaExp(loc, TOKdelete, sizeof(DeleteExp), e)
4670 {
4671     this->isRAII = isRAII;
4672 }
4673 
toBoolean(Scope *)4674 Expression *DeleteExp::toBoolean(Scope *)
4675 {
4676     error("delete does not give a boolean result");
4677     return new ErrorExp();
4678 }
4679 
4680 /************************************************************/
4681 
CastExp(Loc loc,Expression * e,Type * t)4682 CastExp::CastExp(Loc loc, Expression *e, Type *t)
4683         : UnaExp(loc, TOKcast, sizeof(CastExp), e)
4684 {
4685     this->to = t;
4686     this->mod = (unsigned char)~0;
4687 }
4688 
4689 /* For cast(const) and cast(immutable)
4690  */
CastExp(Loc loc,Expression * e,unsigned char mod)4691 CastExp::CastExp(Loc loc, Expression *e, unsigned char mod)
4692         : UnaExp(loc, TOKcast, sizeof(CastExp), e)
4693 {
4694     this->to = NULL;
4695     this->mod = mod;
4696 }
4697 
syntaxCopy()4698 Expression *CastExp::syntaxCopy()
4699 {
4700     return to ? new CastExp(loc, e1->syntaxCopy(), to->syntaxCopy())
4701               : new CastExp(loc, e1->syntaxCopy(), mod);
4702 }
4703 
4704 /************************************************************/
4705 
VectorExp(Loc loc,Expression * e,Type * t)4706 VectorExp::VectorExp(Loc loc, Expression *e, Type *t)
4707         : UnaExp(loc, TOKvector, sizeof(VectorExp), e)
4708 {
4709     assert(t->ty == Tvector);
4710     to = (TypeVector *)t;
4711     dim = ~0;
4712     ownedByCtfe = OWNEDcode;
4713 }
4714 
create(Loc loc,Expression * e,Type * t)4715 VectorExp *VectorExp::create(Loc loc, Expression *e, Type *t)
4716 {
4717     return new VectorExp(loc, e, t);
4718 }
4719 
syntaxCopy()4720 Expression *VectorExp::syntaxCopy()
4721 {
4722     return new VectorExp(loc, e1->syntaxCopy(), to->syntaxCopy());
4723 }
4724 
4725 /************************************************************/
4726 
VectorArrayExp(Loc loc,Expression * e1)4727 VectorArrayExp::VectorArrayExp(Loc loc, Expression *e1)
4728         : UnaExp(loc, TOKvectorarray, sizeof(VectorArrayExp), e1)
4729 {
4730 }
4731 
isLvalue()4732 bool VectorArrayExp::isLvalue()
4733 {
4734     return e1->isLvalue();
4735 }
4736 
toLvalue(Scope * sc,Expression * e)4737 Expression *VectorArrayExp::toLvalue(Scope *sc, Expression *e)
4738 {
4739     e1 = e1->toLvalue(sc, e);
4740     return this;
4741 }
4742 
4743 /************************************************************/
4744 
SliceExp(Loc loc,Expression * e1,IntervalExp * ie)4745 SliceExp::SliceExp(Loc loc, Expression *e1, IntervalExp *ie)
4746         : UnaExp(loc, TOKslice, sizeof(SliceExp), e1)
4747 {
4748     this->upr = ie ? ie->upr : NULL;
4749     this->lwr = ie ? ie->lwr : NULL;
4750     lengthVar = NULL;
4751     upperIsInBounds = false;
4752     lowerIsLessThanUpper = false;
4753     arrayop = false;
4754 }
4755 
SliceExp(Loc loc,Expression * e1,Expression * lwr,Expression * upr)4756 SliceExp::SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr)
4757         : UnaExp(loc, TOKslice, sizeof(SliceExp), e1)
4758 {
4759     this->upr = upr;
4760     this->lwr = lwr;
4761     lengthVar = NULL;
4762     upperIsInBounds = false;
4763     lowerIsLessThanUpper = false;
4764     arrayop = false;
4765 }
4766 
syntaxCopy()4767 Expression *SliceExp::syntaxCopy()
4768 {
4769     SliceExp *se = new SliceExp(loc, e1->syntaxCopy(),
4770         lwr ? lwr->syntaxCopy() : NULL,
4771         upr ? upr->syntaxCopy() : NULL);
4772     se->lengthVar = this->lengthVar;    // bug7871
4773     return se;
4774 }
4775 
checkModifiable(Scope * sc,int flag)4776 int SliceExp::checkModifiable(Scope *sc, int flag)
4777 {
4778     //printf("SliceExp::checkModifiable %s\n", toChars());
4779     if (e1->type->ty == Tsarray ||
4780         (e1->op == TOKindex && e1->type->ty != Tarray) ||
4781         e1->op == TOKslice)
4782     {
4783         return e1->checkModifiable(sc, flag);
4784     }
4785     return 1;
4786 }
4787 
isLvalue()4788 bool SliceExp::isLvalue()
4789 {
4790     /* slice expression is rvalue in default, but
4791      * conversion to reference of static array is only allowed.
4792      */
4793     return (type && type->toBasetype()->ty == Tsarray);
4794 }
4795 
toLvalue(Scope * sc,Expression * e)4796 Expression *SliceExp::toLvalue(Scope *sc, Expression *e)
4797 {
4798     //printf("SliceExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL);
4799     return (type && type->toBasetype()->ty == Tsarray)
4800             ? this : Expression::toLvalue(sc, e);
4801 }
4802 
modifiableLvalue(Scope *,Expression *)4803 Expression *SliceExp::modifiableLvalue(Scope *, Expression *)
4804 {
4805     error("slice expression %s is not a modifiable lvalue", toChars());
4806     return this;
4807 }
4808 
isBool(bool result)4809 bool SliceExp::isBool(bool result)
4810 {
4811     return e1->isBool(result);
4812 }
4813 
4814 /********************** ArrayLength **************************************/
4815 
ArrayLengthExp(Loc loc,Expression * e1)4816 ArrayLengthExp::ArrayLengthExp(Loc loc, Expression *e1)
4817         : UnaExp(loc, TOKarraylength, sizeof(ArrayLengthExp), e1)
4818 {
4819 }
4820 
4821 /*********************** IntervalExp ********************************/
4822 
4823 // Mainly just a placeholder
4824 
IntervalExp(Loc loc,Expression * lwr,Expression * upr)4825 IntervalExp::IntervalExp(Loc loc, Expression *lwr, Expression *upr)
4826         : Expression(loc, TOKinterval, sizeof(IntervalExp))
4827 {
4828     this->lwr = lwr;
4829     this->upr = upr;
4830 }
4831 
syntaxCopy()4832 Expression *IntervalExp::syntaxCopy()
4833 {
4834     return new IntervalExp(loc, lwr->syntaxCopy(), upr->syntaxCopy());
4835 }
4836 
4837 /********************** DelegatePtrExp **************************************/
4838 
DelegatePtrExp(Loc loc,Expression * e1)4839 DelegatePtrExp::DelegatePtrExp(Loc loc, Expression *e1)
4840         : UnaExp(loc, TOKdelegateptr, sizeof(DelegatePtrExp), e1)
4841 {
4842 }
4843 
isLvalue()4844 bool DelegatePtrExp::isLvalue()
4845 {
4846     return e1->isLvalue();
4847 }
4848 
toLvalue(Scope * sc,Expression * e)4849 Expression *DelegatePtrExp::toLvalue(Scope *sc, Expression *e)
4850 {
4851     e1 = e1->toLvalue(sc, e);
4852     return this;
4853 }
4854 
modifiableLvalue(Scope * sc,Expression * e)4855 Expression *DelegatePtrExp::modifiableLvalue(Scope *sc, Expression *e)
4856 {
4857     if (sc->func->setUnsafe())
4858     {
4859         error("cannot modify delegate pointer in @safe code %s", toChars());
4860         return new ErrorExp();
4861     }
4862     return Expression::modifiableLvalue(sc, e);
4863 }
4864 
4865 /********************** DelegateFuncptrExp **************************************/
4866 
DelegateFuncptrExp(Loc loc,Expression * e1)4867 DelegateFuncptrExp::DelegateFuncptrExp(Loc loc, Expression *e1)
4868         : UnaExp(loc, TOKdelegatefuncptr, sizeof(DelegateFuncptrExp), e1)
4869 {
4870 }
4871 
isLvalue()4872 bool DelegateFuncptrExp::isLvalue()
4873 {
4874     return e1->isLvalue();
4875 }
4876 
toLvalue(Scope * sc,Expression * e)4877 Expression *DelegateFuncptrExp::toLvalue(Scope *sc, Expression *e)
4878 {
4879     e1 = e1->toLvalue(sc, e);
4880     return this;
4881 }
4882 
modifiableLvalue(Scope * sc,Expression * e)4883 Expression *DelegateFuncptrExp::modifiableLvalue(Scope *sc, Expression *e)
4884 {
4885     if (sc->func->setUnsafe())
4886     {
4887         error("cannot modify delegate function pointer in @safe code %s", toChars());
4888         return new ErrorExp();
4889     }
4890     return Expression::modifiableLvalue(sc, e);
4891 }
4892 
4893 /*********************** ArrayExp *************************************/
4894 
4895 // e1 [ i1, i2, i3, ... ]
4896 
ArrayExp(Loc loc,Expression * e1,Expression * index)4897 ArrayExp::ArrayExp(Loc loc, Expression *e1, Expression *index)
4898         : UnaExp(loc, TOKarray, sizeof(ArrayExp), e1)
4899 {
4900     arguments = new Expressions();
4901     if (index)
4902         arguments->push(index);
4903     lengthVar = NULL;
4904     currentDimension = 0;
4905 }
4906 
ArrayExp(Loc loc,Expression * e1,Expressions * args)4907 ArrayExp::ArrayExp(Loc loc, Expression *e1, Expressions *args)
4908         : UnaExp(loc, TOKarray, sizeof(ArrayExp), e1)
4909 {
4910     arguments = args;
4911     lengthVar = NULL;
4912     currentDimension = 0;
4913 }
4914 
syntaxCopy()4915 Expression *ArrayExp::syntaxCopy()
4916 {
4917     ArrayExp *ae = new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
4918     ae->lengthVar = this->lengthVar;    // bug7871
4919     return ae;
4920 }
4921 
isLvalue()4922 bool ArrayExp::isLvalue()
4923 {
4924     if (type && type->toBasetype()->ty == Tvoid)
4925         return false;
4926     return true;
4927 }
4928 
toLvalue(Scope *,Expression *)4929 Expression *ArrayExp::toLvalue(Scope *, Expression *)
4930 {
4931     if (type && type->toBasetype()->ty == Tvoid)
4932         error("voids have no value");
4933     return this;
4934 }
4935 
4936 /************************* DotExp ***********************************/
4937 
DotExp(Loc loc,Expression * e1,Expression * e2)4938 DotExp::DotExp(Loc loc, Expression *e1, Expression *e2)
4939         : BinExp(loc, TOKdot, sizeof(DotExp), e1, e2)
4940 {
4941 }
4942 
4943 /************************* CommaExp ***********************************/
4944 
CommaExp(Loc loc,Expression * e1,Expression * e2,bool generated)4945 CommaExp::CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated)
4946         : BinExp(loc, TOKcomma, sizeof(CommaExp), e1, e2)
4947 {
4948     isGenerated = generated;
4949     allowCommaExp = generated;
4950 }
4951 
isLvalue()4952 bool CommaExp::isLvalue()
4953 {
4954     return e2->isLvalue();
4955 }
4956 
toLvalue(Scope * sc,Expression *)4957 Expression *CommaExp::toLvalue(Scope *sc, Expression *)
4958 {
4959     e2 = e2->toLvalue(sc, NULL);
4960     return this;
4961 }
4962 
checkModifiable(Scope * sc,int flag)4963 int CommaExp::checkModifiable(Scope *sc, int flag)
4964 {
4965     return e2->checkModifiable(sc, flag);
4966 }
4967 
modifiableLvalue(Scope * sc,Expression * e)4968 Expression *CommaExp::modifiableLvalue(Scope *sc, Expression *e)
4969 {
4970     e2 = e2->modifiableLvalue(sc, e);
4971     return this;
4972 }
4973 
isBool(bool result)4974 bool CommaExp::isBool(bool result)
4975 {
4976     return e2->isBool(result);
4977 }
4978 
toBoolean(Scope * sc)4979 Expression *CommaExp::toBoolean(Scope *sc)
4980 {
4981     Expression *ex2 = e2->toBoolean(sc);
4982     if (ex2->op == TOKerror)
4983         return ex2;
4984     e2 = ex2;
4985     type = e2->type;
4986     return this;
4987 }
4988 
addDtorHook(Scope * sc)4989 Expression *CommaExp::addDtorHook(Scope *sc)
4990 {
4991     e2 = e2->addDtorHook(sc);
4992     return this;
4993 }
4994 
4995 /************************** IndexExp **********************************/
4996 
4997 // e1 [ e2 ]
4998 
IndexExp(Loc loc,Expression * e1,Expression * e2)4999 IndexExp::IndexExp(Loc loc, Expression *e1, Expression *e2)
5000         : BinExp(loc, TOKindex, sizeof(IndexExp), e1, e2)
5001 {
5002     //printf("IndexExp::IndexExp('%s')\n", toChars());
5003     lengthVar = NULL;
5004     modifiable = false;     // assume it is an rvalue
5005     indexIsInBounds = false;
5006 }
5007 
syntaxCopy()5008 Expression *IndexExp::syntaxCopy()
5009 {
5010     IndexExp *ie = new IndexExp(loc, e1->syntaxCopy(), e2->syntaxCopy());
5011     ie->lengthVar = this->lengthVar;    // bug7871
5012     return ie;
5013 }
5014 
isLvalue()5015 bool IndexExp::isLvalue()
5016 {
5017     return true;
5018 }
5019 
toLvalue(Scope *,Expression *)5020 Expression *IndexExp::toLvalue(Scope *, Expression *)
5021 {
5022     return this;
5023 }
5024 
checkModifiable(Scope * sc,int flag)5025 int IndexExp::checkModifiable(Scope *sc, int flag)
5026 {
5027     if (e1->type->ty == Tsarray ||
5028         e1->type->ty == Taarray ||
5029         (e1->op == TOKindex && e1->type->ty != Tarray) ||
5030         e1->op == TOKslice)
5031     {
5032         return e1->checkModifiable(sc, flag);
5033     }
5034     return 1;
5035 }
5036 
modifiableLvalue(Scope * sc,Expression * e)5037 Expression *IndexExp::modifiableLvalue(Scope *sc, Expression *e)
5038 {
5039     //printf("IndexExp::modifiableLvalue(%s)\n", toChars());
5040     Expression *ex = markSettingAAElem();
5041     if (ex->op == TOKerror)
5042         return ex;
5043 
5044     return Expression::modifiableLvalue(sc, e);
5045 }
5046 
markSettingAAElem()5047 Expression *IndexExp::markSettingAAElem()
5048 {
5049     if (e1->type->toBasetype()->ty == Taarray)
5050     {
5051         Type *t2b = e2->type->toBasetype();
5052         if (t2b->ty == Tarray && t2b->nextOf()->isMutable())
5053         {
5054             error("associative arrays can only be assigned values with immutable keys, not %s", e2->type->toChars());
5055             return new ErrorExp();
5056         }
5057         modifiable = true;
5058 
5059         if (e1->op == TOKindex)
5060         {
5061             Expression *ex = ((IndexExp *)e1)->markSettingAAElem();
5062             if (ex->op == TOKerror)
5063                 return ex;
5064             assert(ex == e1);
5065         }
5066     }
5067     return this;
5068 }
5069 
5070 /************************* PostExp ***********************************/
5071 
PostExp(TOK op,Loc loc,Expression * e)5072 PostExp::PostExp(TOK op, Loc loc, Expression *e)
5073         : BinExp(loc, op, sizeof(PostExp), e,
5074           new IntegerExp(loc, 1, Type::tint32))
5075 {
5076 }
5077 
5078 /************************* PreExp ***********************************/
5079 
PreExp(TOK op,Loc loc,Expression * e)5080 PreExp::PreExp(TOK op, Loc loc, Expression *e)
5081         : UnaExp(loc, op, sizeof(PreExp), e)
5082 {
5083 }
5084 
5085 /************************************************************/
5086 
5087 /* op can be TOKassign, TOKconstruct, or TOKblit */
5088 
AssignExp(Loc loc,Expression * e1,Expression * e2)5089 AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2)
5090         : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2)
5091 {
5092     memset = 0;
5093 }
5094 
isLvalue()5095 bool AssignExp::isLvalue()
5096 {
5097     // Array-op 'x[] = y[]' should make an rvalue.
5098     // Setting array length 'x.length = v' should make an rvalue.
5099     if (e1->op == TOKslice ||
5100         e1->op == TOKarraylength)
5101     {
5102         return false;
5103     }
5104     return true;
5105 }
5106 
toLvalue(Scope * sc,Expression * ex)5107 Expression *AssignExp::toLvalue(Scope *sc, Expression *ex)
5108 {
5109     if (e1->op == TOKslice ||
5110         e1->op == TOKarraylength)
5111     {
5112         return Expression::toLvalue(sc, ex);
5113     }
5114 
5115     /* In front-end level, AssignExp should make an lvalue of e1.
5116      * Taking the address of e1 will be handled in low level layer,
5117      * so this function does nothing.
5118      */
5119     return this;
5120 }
5121 
toBoolean(Scope *)5122 Expression *AssignExp::toBoolean(Scope *)
5123 {
5124     // Things like:
5125     //  if (a = b) ...
5126     // are usually mistakes.
5127 
5128     error("assignment cannot be used as a condition, perhaps == was meant?");
5129     return new ErrorExp();
5130 }
5131 
5132 /************************************************************/
5133 
ConstructExp(Loc loc,Expression * e1,Expression * e2)5134 ConstructExp::ConstructExp(Loc loc, Expression *e1, Expression *e2)
5135     : AssignExp(loc, e1, e2)
5136 {
5137     op = TOKconstruct;
5138 }
5139 
ConstructExp(Loc loc,VarDeclaration * v,Expression * e2)5140 ConstructExp::ConstructExp(Loc loc, VarDeclaration *v, Expression *e2)
5141     : AssignExp(loc, new VarExp(loc, v), e2)
5142 {
5143     assert(v->type && e1->type);
5144     op = TOKconstruct;
5145 
5146     if (v->storage_class & (STCref | STCout))
5147         memset |= referenceInit;
5148 }
5149 
5150 /************************************************************/
5151 
BlitExp(Loc loc,Expression * e1,Expression * e2)5152 BlitExp::BlitExp(Loc loc, Expression *e1, Expression *e2)
5153     : AssignExp(loc, e1, e2)
5154 {
5155     op = TOKblit;
5156 }
5157 
BlitExp(Loc loc,VarDeclaration * v,Expression * e2)5158 BlitExp::BlitExp(Loc loc, VarDeclaration *v, Expression *e2)
5159     : AssignExp(loc, new VarExp(loc, v), e2)
5160 {
5161     assert(v->type && e1->type);
5162     op = TOKblit;
5163 
5164     if (v->storage_class & (STCref | STCout))
5165         memset |= referenceInit;
5166 }
5167 
5168 /************************************************************/
5169 
AddAssignExp(Loc loc,Expression * e1,Expression * e2)5170 AddAssignExp::AddAssignExp(Loc loc, Expression *e1, Expression *e2)
5171         : BinAssignExp(loc, TOKaddass, sizeof(AddAssignExp), e1, e2)
5172 {
5173 }
5174 
5175 /************************************************************/
5176 
MinAssignExp(Loc loc,Expression * e1,Expression * e2)5177 MinAssignExp::MinAssignExp(Loc loc, Expression *e1, Expression *e2)
5178         : BinAssignExp(loc, TOKminass, sizeof(MinAssignExp), e1, e2)
5179 {
5180 }
5181 
5182 /************************************************************/
5183 
CatAssignExp(Loc loc,Expression * e1,Expression * e2)5184 CatAssignExp::CatAssignExp(Loc loc, Expression *e1, Expression *e2)
5185         : BinAssignExp(loc, TOKcatass, sizeof(CatAssignExp), e1, e2)
5186 {
5187 }
5188 
5189 /************************************************************/
5190 
MulAssignExp(Loc loc,Expression * e1,Expression * e2)5191 MulAssignExp::MulAssignExp(Loc loc, Expression *e1, Expression *e2)
5192         : BinAssignExp(loc, TOKmulass, sizeof(MulAssignExp), e1, e2)
5193 {
5194 }
5195 
5196 /************************************************************/
5197 
DivAssignExp(Loc loc,Expression * e1,Expression * e2)5198 DivAssignExp::DivAssignExp(Loc loc, Expression *e1, Expression *e2)
5199         : BinAssignExp(loc, TOKdivass, sizeof(DivAssignExp), e1, e2)
5200 {
5201 }
5202 
5203 /************************************************************/
5204 
ModAssignExp(Loc loc,Expression * e1,Expression * e2)5205 ModAssignExp::ModAssignExp(Loc loc, Expression *e1, Expression *e2)
5206         : BinAssignExp(loc, TOKmodass, sizeof(ModAssignExp), e1, e2)
5207 {
5208 }
5209 
5210 /************************************************************/
5211 
ShlAssignExp(Loc loc,Expression * e1,Expression * e2)5212 ShlAssignExp::ShlAssignExp(Loc loc, Expression *e1, Expression *e2)
5213         : BinAssignExp(loc, TOKshlass, sizeof(ShlAssignExp), e1, e2)
5214 {
5215 }
5216 
5217 /************************************************************/
5218 
ShrAssignExp(Loc loc,Expression * e1,Expression * e2)5219 ShrAssignExp::ShrAssignExp(Loc loc, Expression *e1, Expression *e2)
5220         : BinAssignExp(loc, TOKshrass, sizeof(ShrAssignExp), e1, e2)
5221 {
5222 }
5223 
5224 /************************************************************/
5225 
UshrAssignExp(Loc loc,Expression * e1,Expression * e2)5226 UshrAssignExp::UshrAssignExp(Loc loc, Expression *e1, Expression *e2)
5227         : BinAssignExp(loc, TOKushrass, sizeof(UshrAssignExp), e1, e2)
5228 {
5229 }
5230 
5231 /************************************************************/
5232 
AndAssignExp(Loc loc,Expression * e1,Expression * e2)5233 AndAssignExp::AndAssignExp(Loc loc, Expression *e1, Expression *e2)
5234         : BinAssignExp(loc, TOKandass, sizeof(AndAssignExp), e1, e2)
5235 {
5236 }
5237 
5238 /************************************************************/
5239 
OrAssignExp(Loc loc,Expression * e1,Expression * e2)5240 OrAssignExp::OrAssignExp(Loc loc, Expression *e1, Expression *e2)
5241         : BinAssignExp(loc, TOKorass, sizeof(OrAssignExp), e1, e2)
5242 {
5243 }
5244 
5245 /************************************************************/
5246 
XorAssignExp(Loc loc,Expression * e1,Expression * e2)5247 XorAssignExp::XorAssignExp(Loc loc, Expression *e1, Expression *e2)
5248         : BinAssignExp(loc, TOKxorass, sizeof(XorAssignExp), e1, e2)
5249 {
5250 }
5251 
5252 /***************** PowAssignExp *******************************************/
5253 
PowAssignExp(Loc loc,Expression * e1,Expression * e2)5254 PowAssignExp::PowAssignExp(Loc loc, Expression *e1, Expression *e2)
5255         : BinAssignExp(loc, TOKpowass, sizeof(PowAssignExp), e1, e2)
5256 {
5257 }
5258 
5259 /************************* AddExp *****************************/
5260 
AddExp(Loc loc,Expression * e1,Expression * e2)5261 AddExp::AddExp(Loc loc, Expression *e1, Expression *e2)
5262         : BinExp(loc, TOKadd, sizeof(AddExp), e1, e2)
5263 {
5264 }
5265 
5266 /************************************************************/
5267 
MinExp(Loc loc,Expression * e1,Expression * e2)5268 MinExp::MinExp(Loc loc, Expression *e1, Expression *e2)
5269         : BinExp(loc, TOKmin, sizeof(MinExp), e1, e2)
5270 {
5271 }
5272 
5273 /************************* CatExp *****************************/
5274 
CatExp(Loc loc,Expression * e1,Expression * e2)5275 CatExp::CatExp(Loc loc, Expression *e1, Expression *e2)
5276         : BinExp(loc, TOKcat, sizeof(CatExp), e1, e2)
5277 {
5278 }
5279 
5280 /************************************************************/
5281 
MulExp(Loc loc,Expression * e1,Expression * e2)5282 MulExp::MulExp(Loc loc, Expression *e1, Expression *e2)
5283         : BinExp(loc, TOKmul, sizeof(MulExp), e1, e2)
5284 {
5285 }
5286 
5287 /************************************************************/
5288 
DivExp(Loc loc,Expression * e1,Expression * e2)5289 DivExp::DivExp(Loc loc, Expression *e1, Expression *e2)
5290         : BinExp(loc, TOKdiv, sizeof(DivExp), e1, e2)
5291 {
5292 }
5293 
5294 /************************************************************/
5295 
ModExp(Loc loc,Expression * e1,Expression * e2)5296 ModExp::ModExp(Loc loc, Expression *e1, Expression *e2)
5297         : BinExp(loc, TOKmod, sizeof(ModExp), e1, e2)
5298 {
5299 }
5300 
5301 /************************************************************/
5302 
PowExp(Loc loc,Expression * e1,Expression * e2)5303 PowExp::PowExp(Loc loc, Expression *e1, Expression *e2)
5304         : BinExp(loc, TOKpow, sizeof(PowExp), e1, e2)
5305 {
5306 }
5307 
5308 /************************************************************/
5309 
ShlExp(Loc loc,Expression * e1,Expression * e2)5310 ShlExp::ShlExp(Loc loc, Expression *e1, Expression *e2)
5311         : BinExp(loc, TOKshl, sizeof(ShlExp), e1, e2)
5312 {
5313 }
5314 
5315 /************************************************************/
5316 
ShrExp(Loc loc,Expression * e1,Expression * e2)5317 ShrExp::ShrExp(Loc loc, Expression *e1, Expression *e2)
5318         : BinExp(loc, TOKshr, sizeof(ShrExp), e1, e2)
5319 {
5320 }
5321 
5322 /************************************************************/
5323 
UshrExp(Loc loc,Expression * e1,Expression * e2)5324 UshrExp::UshrExp(Loc loc, Expression *e1, Expression *e2)
5325         : BinExp(loc, TOKushr, sizeof(UshrExp), e1, e2)
5326 {
5327 }
5328 
5329 /************************************************************/
5330 
AndExp(Loc loc,Expression * e1,Expression * e2)5331 AndExp::AndExp(Loc loc, Expression *e1, Expression *e2)
5332         : BinExp(loc, TOKand, sizeof(AndExp), e1, e2)
5333 {
5334 }
5335 
5336 /************************************************************/
5337 
OrExp(Loc loc,Expression * e1,Expression * e2)5338 OrExp::OrExp(Loc loc, Expression *e1, Expression *e2)
5339         : BinExp(loc, TOKor, sizeof(OrExp), e1, e2)
5340 {
5341 }
5342 
5343 /************************************************************/
5344 
XorExp(Loc loc,Expression * e1,Expression * e2)5345 XorExp::XorExp(Loc loc, Expression *e1, Expression *e2)
5346         : BinExp(loc, TOKxor, sizeof(XorExp), e1, e2)
5347 {
5348 }
5349 
5350 /************************************************************/
5351 
LogicalExp(Loc loc,TOK op,Expression * e1,Expression * e2)5352 LogicalExp::LogicalExp(Loc loc, TOK op, Expression *e1, Expression *e2)
5353         : BinExp(loc, op, sizeof(LogicalExp), e1, e2)
5354 {
5355 }
5356 
toBoolean(Scope * sc)5357 Expression *LogicalExp::toBoolean(Scope *sc)
5358 {
5359     Expression *ex2 = e2->toBoolean(sc);
5360     if (ex2->op == TOKerror)
5361         return ex2;
5362     e2 = ex2;
5363     return this;
5364 }
5365 
5366 /************************************************************/
5367 
InExp(Loc loc,Expression * e1,Expression * e2)5368 InExp::InExp(Loc loc, Expression *e1, Expression *e2)
5369         : BinExp(loc, TOKin, sizeof(InExp), e1, e2)
5370 {
5371 }
5372 
5373 /************************************************************/
5374 
5375 /* This deletes the key e1 from the associative array e2
5376  */
5377 
RemoveExp(Loc loc,Expression * e1,Expression * e2)5378 RemoveExp::RemoveExp(Loc loc, Expression *e1, Expression *e2)
5379         : BinExp(loc, TOKremove, sizeof(RemoveExp), e1, e2)
5380 {
5381     type = Type::tbool;
5382 }
5383 
5384 /************************************************************/
5385 
CmpExp(TOK op,Loc loc,Expression * e1,Expression * e2)5386 CmpExp::CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2)
5387         : BinExp(loc, op, sizeof(CmpExp), e1, e2)
5388 {
5389 }
5390 
5391 /************************************************************/
5392 
EqualExp(TOK op,Loc loc,Expression * e1,Expression * e2)5393 EqualExp::EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2)
5394         : BinExp(loc, op, sizeof(EqualExp), e1, e2)
5395 {
5396     assert(op == TOKequal || op == TOKnotequal);
5397 }
5398 
5399 /************************************************************/
5400 
IdentityExp(TOK op,Loc loc,Expression * e1,Expression * e2)5401 IdentityExp::IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2)
5402         : BinExp(loc, op, sizeof(IdentityExp), e1, e2)
5403 {
5404 }
5405 
5406 /****************************************************************/
5407 
CondExp(Loc loc,Expression * econd,Expression * e1,Expression * e2)5408 CondExp::CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2)
5409         : BinExp(loc, TOKquestion, sizeof(CondExp), e1, e2)
5410 {
5411     this->econd = econd;
5412 }
5413 
syntaxCopy()5414 Expression *CondExp::syntaxCopy()
5415 {
5416     return new CondExp(loc, econd->syntaxCopy(), e1->syntaxCopy(), e2->syntaxCopy());
5417 }
5418 
hookDtors(Scope * sc)5419 void CondExp::hookDtors(Scope *sc)
5420 {
5421     class DtorVisitor : public StoppableVisitor
5422     {
5423     public:
5424         Scope *sc;
5425         CondExp *ce;
5426         VarDeclaration *vcond;
5427         bool isThen;
5428 
5429         DtorVisitor(Scope *sc, CondExp *ce)
5430         {
5431             this->sc = sc;
5432             this->ce = ce;
5433             this->vcond = NULL;
5434         }
5435 
5436         void visit(Expression *)
5437         {
5438             //printf("(e = %s)\n", e->toChars());
5439         }
5440 
5441         void visit(DeclarationExp *e)
5442         {
5443             VarDeclaration *v = e->declaration->isVarDeclaration();
5444             if (v && !v->isDataseg())
5445             {
5446                 if (v->_init)
5447                 {
5448                     ExpInitializer *ei = v->_init->isExpInitializer();
5449                     if (ei)
5450                         ei->exp->accept(this);
5451                 }
5452 
5453                 if (v->needsScopeDtor())
5454                 {
5455                     if (!vcond)
5456                     {
5457                         vcond = copyToTemp(STCvolatile, "__cond", ce->econd);
5458                         dsymbolSemantic(vcond, sc);
5459 
5460                         Expression *de = new DeclarationExp(ce->econd->loc, vcond);
5461                         de = expressionSemantic(de, sc);
5462 
5463                         Expression *ve = new VarExp(ce->econd->loc, vcond);
5464                         ce->econd = Expression::combine(de, ve);
5465                     }
5466 
5467                     //printf("\t++v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars());
5468                     Expression *ve = new VarExp(vcond->loc, vcond);
5469                     if (isThen)
5470                         v->edtor = new LogicalExp(v->edtor->loc, TOKandand, ve, v->edtor);
5471                     else
5472                         v->edtor = new LogicalExp(v->edtor->loc, TOKoror, ve, v->edtor);
5473                     v->edtor = expressionSemantic(v->edtor, sc);
5474                     //printf("\t--v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars());
5475                 }
5476             }
5477         }
5478     };
5479 
5480     DtorVisitor v(sc, this);
5481     //printf("+%s\n", toChars());
5482     v.isThen = true;    walkPostorder(e1, &v);
5483     v.isThen = false;   walkPostorder(e2, &v);
5484     //printf("-%s\n", toChars());
5485 }
5486 
isLvalue()5487 bool CondExp::isLvalue()
5488 {
5489     return e1->isLvalue() && e2->isLvalue();
5490 }
5491 
5492 
toLvalue(Scope * sc,Expression *)5493 Expression *CondExp::toLvalue(Scope *sc, Expression *)
5494 {
5495     // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)
5496     CondExp *e = (CondExp *)copy();
5497     e->e1 = e1->toLvalue(sc, NULL)->addressOf();
5498     e->e2 = e2->toLvalue(sc, NULL)->addressOf();
5499     e->type = type->pointerTo();
5500     return new PtrExp(loc, e, type);
5501 }
5502 
checkModifiable(Scope * sc,int flag)5503 int CondExp::checkModifiable(Scope *sc, int flag)
5504 {
5505     return e1->checkModifiable(sc, flag) && e2->checkModifiable(sc, flag);
5506 }
5507 
modifiableLvalue(Scope * sc,Expression *)5508 Expression *CondExp::modifiableLvalue(Scope *sc, Expression *)
5509 {
5510     //error("conditional expression %s is not a modifiable lvalue", toChars());
5511     e1 = e1->modifiableLvalue(sc, e1);
5512     e2 = e2->modifiableLvalue(sc, e2);
5513     return toLvalue(sc, this);
5514 }
5515 
toBoolean(Scope * sc)5516 Expression *CondExp::toBoolean(Scope *sc)
5517 {
5518     Expression *ex1 = e1->toBoolean(sc);
5519     Expression *ex2 = e2->toBoolean(sc);
5520     if (ex1->op == TOKerror)
5521         return ex1;
5522     if (ex2->op == TOKerror)
5523         return ex2;
5524     e1 = ex1;
5525     e2 = ex2;
5526     return this;
5527 }
5528 
5529 /****************************************************************/
5530 
DefaultInitExp(Loc loc,TOK subop,int size)5531 DefaultInitExp::DefaultInitExp(Loc loc, TOK subop, int size)
5532     : Expression(loc, TOKdefault, size)
5533 {
5534     this->subop = subop;
5535 }
5536 
5537 /****************************************************************/
5538 
FileInitExp(Loc loc,TOK tok)5539 FileInitExp::FileInitExp(Loc loc, TOK tok)
5540     : DefaultInitExp(loc, tok, sizeof(FileInitExp))
5541 {
5542 }
5543 
resolveLoc(Loc loc,Scope * sc)5544 Expression *FileInitExp::resolveLoc(Loc loc, Scope *sc)
5545 {
5546     //printf("FileInitExp::resolve() %s\n", toChars());
5547     const char *s;
5548     if (subop == TOKfilefullpath)
5549         s = FileName::toAbsolute(loc.filename != NULL ? loc.filename : sc->_module->srcfile->name->toChars());
5550     else
5551         s = loc.filename != NULL ? loc.filename : sc->_module->ident->toChars();
5552 
5553     Expression *e = new StringExp(loc, const_cast<char *>(s));
5554     e = expressionSemantic(e, sc);
5555     e = e->castTo(sc, type);
5556     return e;
5557 }
5558 
5559 /****************************************************************/
5560 
LineInitExp(Loc loc)5561 LineInitExp::LineInitExp(Loc loc)
5562     : DefaultInitExp(loc, TOKline, sizeof(LineInitExp))
5563 {
5564 }
5565 
resolveLoc(Loc loc,Scope * sc)5566 Expression *LineInitExp::resolveLoc(Loc loc, Scope *sc)
5567 {
5568     Expression *e = new IntegerExp(loc, loc.linnum, Type::tint32);
5569     e = e->castTo(sc, type);
5570     return e;
5571 }
5572 
5573 /****************************************************************/
5574 
ModuleInitExp(Loc loc)5575 ModuleInitExp::ModuleInitExp(Loc loc)
5576     : DefaultInitExp(loc, TOKmodulestring, sizeof(ModuleInitExp))
5577 {
5578 }
5579 
resolveLoc(Loc loc,Scope * sc)5580 Expression *ModuleInitExp::resolveLoc(Loc loc, Scope *sc)
5581 {
5582     const char *s;
5583     if (sc->callsc)
5584         s = sc->callsc->_module->toPrettyChars();
5585     else
5586         s = sc->_module->toPrettyChars();
5587     Expression *e = new StringExp(loc, const_cast<char *>(s));
5588     e = expressionSemantic(e, sc);
5589     e = e->castTo(sc, type);
5590     return e;
5591 }
5592 
5593 /****************************************************************/
5594 
FuncInitExp(Loc loc)5595 FuncInitExp::FuncInitExp(Loc loc)
5596     : DefaultInitExp(loc, TOKfuncstring, sizeof(FuncInitExp))
5597 {
5598 }
5599 
resolveLoc(Loc loc,Scope * sc)5600 Expression *FuncInitExp::resolveLoc(Loc loc, Scope *sc)
5601 {
5602     const char *s;
5603     if (sc->callsc && sc->callsc->func)
5604         s = sc->callsc->func->Dsymbol::toPrettyChars();
5605     else if (sc->func)
5606         s = sc->func->Dsymbol::toPrettyChars();
5607     else
5608         s = "";
5609     Expression *e = new StringExp(loc, const_cast<char *>(s));
5610     e = expressionSemantic(e, sc);
5611     e = e->castTo(sc, type);
5612     return e;
5613 }
5614 
5615 /****************************************************************/
5616 
PrettyFuncInitExp(Loc loc)5617 PrettyFuncInitExp::PrettyFuncInitExp(Loc loc)
5618     : DefaultInitExp(loc, TOKprettyfunc, sizeof(PrettyFuncInitExp))
5619 {
5620 }
5621 
resolveLoc(Loc loc,Scope * sc)5622 Expression *PrettyFuncInitExp::resolveLoc(Loc loc, Scope *sc)
5623 {
5624     FuncDeclaration *fd;
5625     if (sc->callsc && sc->callsc->func)
5626         fd = sc->callsc->func;
5627     else
5628         fd = sc->func;
5629 
5630     const char *s;
5631     if (fd)
5632     {
5633         const char *funcStr = fd->Dsymbol::toPrettyChars();
5634         OutBuffer buf;
5635         functionToBufferWithIdent((TypeFunction *)fd->type, &buf, funcStr);
5636         s = buf.extractChars();
5637     }
5638     else
5639     {
5640         s = "";
5641     }
5642 
5643     Expression *e = new StringExp(loc, const_cast<char *>(s));
5644     e = expressionSemantic(e, sc);
5645     e = e->castTo(sc, type);
5646     return e;
5647 }
5648 
reorderSettingAAElem(Scope * sc)5649 Expression *BinExp::reorderSettingAAElem(Scope *sc)
5650 {
5651     BinExp *be = this;
5652 
5653     if (be->e1->op != TOKindex)
5654         return be;
5655     IndexExp *ie = (IndexExp *)be->e1;
5656     if (ie->e1->type->toBasetype()->ty != Taarray)
5657         return be;
5658 
5659     /* Fix evaluation order of setting AA element. (Bugzilla 3825)
5660      * Rewrite:
5661      *     aa[k1][k2][k3] op= val;
5662      * as:
5663      *     auto ref __aatmp = aa;
5664      *     auto ref __aakey3 = k1, __aakey2 = k2, __aakey1 = k3;
5665      *     auto ref __aaval = val;
5666      *     __aatmp[__aakey3][__aakey2][__aakey1] op= __aaval;  // assignment
5667      */
5668 
5669     Expression *e0 = NULL;
5670     while (1)
5671     {
5672         Expression *de = NULL;
5673         ie->e2 = extractSideEffect(sc, "__aakey", &de, ie->e2);
5674         e0 = Expression::combine(de, e0);
5675 
5676         Expression *ie1 = ie->e1;
5677         if (ie1->op != TOKindex ||
5678             ((IndexExp *)ie1)->e1->type->toBasetype()->ty != Taarray)
5679         {
5680             break;
5681         }
5682         ie = (IndexExp *)ie1;
5683     }
5684     assert(ie->e1->type->toBasetype()->ty == Taarray);
5685 
5686     Expression *de = NULL;
5687     ie->e1 = extractSideEffect(sc, "__aatmp", &de, ie->e1);
5688     e0 = Expression::combine(de, e0);
5689 
5690     be->e2 = extractSideEffect(sc, "__aaval", &e0, be->e2, true);
5691 
5692     //printf("-e0 = %s, be = %s\n", e0->toChars(), be->toChars());
5693     return Expression::combine(e0, be);
5694 }
5695