1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2019 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 MOD MODmerge(MOD mod1, MOD mod2);
47 void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod);
48 Expression *trySemantic(Expression *e, Scope *sc);
49 Expression *semantic(Expression *e, Scope *sc);
50 Expression *semanticX(DotIdExp *exp, Scope *sc);
51 Expression *semanticY(DotIdExp *exp, Scope *sc, int flag);
52 Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag);
53 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
54 bool checkUnsafeAccess(Scope *sc, Expression *e, bool readonly, bool printmsg);
55 
56 /*************************************************************
57  * Given var, we need to get the
58  * right 'this' pointer if var is in an outer class, but our
59  * existing 'this' pointer is in an inner class.
60  * Input:
61  *      e1      existing 'this'
62  *      ad      struct or class we need the correct 'this' for
63  *      var     the specific member of ad we're accessing
64  */
65 
66 Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
67         Expression *e1, Declaration *var, int flag = 0)
68 {
69     //printf("\ngetRightThis(e1 = %s, ad = %s, var = %s)\n", e1->toChars(), ad->toChars(), var->toChars());
70  L1:
71     Type *t = e1->type->toBasetype();
72     //printf("e1->type = %s, var->type = %s\n", e1->type->toChars(), var->type->toChars());
73 
74     /* If e1 is not the 'this' pointer for ad
75      */
76     if (ad &&
77         !(t->ty == Tpointer && t->nextOf()->ty == Tstruct &&
78           ((TypeStruct *)t->nextOf())->sym == ad)
79         &&
80         !(t->ty == Tstruct &&
81           ((TypeStruct *)t)->sym == ad)
82        )
83     {
84         ClassDeclaration *cd = ad->isClassDeclaration();
85         ClassDeclaration *tcd = t->isClassHandle();
86 
87         /* e1 is the right this if ad is a base class of e1
88          */
89         if (!cd || !tcd ||
90             !(tcd == cd || cd->isBaseOf(tcd, NULL))
91            )
92         {
93             /* Only classes can be inner classes with an 'outer'
94              * member pointing to the enclosing class instance
95              */
96             if (tcd && tcd->isNested())
97             {
98                 /* e1 is the 'this' pointer for an inner class: tcd.
99                  * Rewrite it as the 'this' pointer for the outer class.
100                  */
101 
102                 e1 = new DotVarExp(loc, e1, tcd->vthis);
103                 e1->type = tcd->vthis->type;
104                 e1->type = e1->type->addMod(t->mod);
105                 // Do not call checkNestedRef()
106                 //e1 = semantic(e1, sc);
107 
108                 // Skip up over nested functions, and get the enclosing
109                 // class type.
110                 int n = 0;
111                 Dsymbol *s;
112                 for (s = tcd->toParent();
113                      s && s->isFuncDeclaration();
114                      s = s->toParent())
115                 {
116                     FuncDeclaration *f = s->isFuncDeclaration();
117                     if (f->vthis)
118                     {
119                         //printf("rewriting e1 to %s's this\n", f->toChars());
120                         n++;
121                         e1 = new VarExp(loc, f->vthis);
122                     }
123                     else
124                     {
125                         e1->error("need 'this' of type %s to access member %s"
126                                   " from static function %s",
127                             ad->toChars(), var->toChars(), f->toChars());
128                         e1 = new ErrorExp();
129                         return e1;
130                     }
131                 }
132                 if (s && s->isClassDeclaration())
133                 {
134                     e1->type = s->isClassDeclaration()->type;
135                     e1->type = e1->type->addMod(t->mod);
136                     if (n > 1)
137                         e1 = semantic(e1, sc);
138                 }
139                 else
140                     e1 = semantic(e1, sc);
141                 goto L1;
142             }
143 
144             /* Can't find a path from e1 to ad
145              */
146             if (flag)
147                 return NULL;
148             e1->error("this for %s needs to be type %s not type %s",
149                 var->toChars(), ad->toChars(), t->toChars());
150             return new ErrorExp();
151         }
152     }
153     return e1;
154 }
155 
156 /*****************************************
157  * Determine if 'this' is available.
158  * If it is, return the FuncDeclaration that has it.
159  */
160 
hasThis(Scope * sc)161 FuncDeclaration *hasThis(Scope *sc)
162 {
163     //printf("hasThis()\n");
164     Dsymbol *p = sc->parent;
165     while (p && p->isTemplateMixin())
166         p = p->parent;
167     FuncDeclaration *fdthis = p ? p->isFuncDeclaration() : NULL;
168     //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : "");
169 
170     // Go upwards until we find the enclosing member function
171     FuncDeclaration *fd = fdthis;
172     while (1)
173     {
174         if (!fd)
175         {
176             goto Lno;
177         }
178         if (!fd->isNested())
179             break;
180 
181         Dsymbol *parent = fd->parent;
182         while (1)
183         {
184             if (!parent)
185                 goto Lno;
186             TemplateInstance *ti = parent->isTemplateInstance();
187             if (ti)
188                 parent = ti->parent;
189             else
190                 break;
191         }
192         fd = parent->isFuncDeclaration();
193     }
194 
195     if (!fd->isThis())
196     {   //printf("test '%s'\n", fd->toChars());
197         goto Lno;
198     }
199 
200     assert(fd->vthis);
201     return fd;
202 
203 Lno:
204     return NULL;                // don't have 'this' available
205 }
206 
isNeedThisScope(Scope * sc,Declaration * d)207 bool isNeedThisScope(Scope *sc, Declaration *d)
208 {
209     if (sc->intypeof == 1)
210         return false;
211 
212     AggregateDeclaration *ad = d->isThis();
213     if (!ad)
214         return false;
215     //printf("d = %s, ad = %s\n", d->toChars(), ad->toChars());
216 
217     for (Dsymbol *s = sc->parent; s; s = s->toParent2())
218     {
219         //printf("\ts = %s %s, toParent2() = %p\n", s->kind(), s->toChars(), s->toParent2());
220         if (AggregateDeclaration *ad2 = s->isAggregateDeclaration())
221         {
222             if (ad2 == ad)
223                 return false;
224             else if (ad2->isNested())
225                 continue;
226             else
227                 return true;
228         }
229         if (FuncDeclaration *f = s->isFuncDeclaration())
230         {
231             if (f->isMember2())
232                 break;
233         }
234     }
235     return true;
236 }
237 
238 /***************************************
239  * Pull out any properties.
240  */
241 
242 Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2 = NULL)
243 {
244     //printf("resolvePropertiesX, e1 = %s %s, e2 = %s\n", Token::toChars(e1->op), e1->toChars(), e2 ? e2->toChars() : NULL);
245     Loc loc = e1->loc;
246 
247     OverloadSet *os;
248     Dsymbol *s;
249     Objects *tiargs;
250     Type *tthis;
251     if (e1->op == TOKdot)
252     {
253         DotExp *de = (DotExp *)e1;
254         if (de->e2->op == TOKoverloadset)
255         {
256             tiargs = NULL;
257             tthis  = de->e1->type;
258             os = ((OverExp *)de->e2)->vars;
259             goto Los;
260         }
261     }
262     else if (e1->op == TOKoverloadset)
263     {
264         tiargs = NULL;
265         tthis  = NULL;
266         os = ((OverExp *)e1)->vars;
267     Los:
268         assert(os);
269         FuncDeclaration *fd = NULL;
270         if (e2)
271         {
272             e2 = semantic(e2, sc);
273             if (e2->op == TOKerror)
274                 return new ErrorExp();
275             e2 = resolveProperties(sc, e2);
276 
277             Expressions a;
278             a.push(e2);
279 
280             for (size_t i = 0; i < os->a.dim; i++)
281             {
282                 FuncDeclaration *f = resolveFuncCall(loc, sc, os->a[i], tiargs, tthis, &a, 1);
283                 if (f)
284                 {
285                     if (f->errors)
286                         return new ErrorExp();
287                     fd = f;
288                     assert(fd->type->ty == Tfunction);
289                 }
290             }
291             if (fd)
292             {
293                 Expression *e = new CallExp(loc, e1, e2);
294                 return semantic(e, sc);
295             }
296         }
297         {
298             for (size_t i = 0; i < os->a.dim; i++)
299             {
300                 FuncDeclaration *f = resolveFuncCall(loc, sc, os->a[i], tiargs, tthis, NULL, 1);
301                 if (f)
302                 {
303                     if (f->errors)
304                         return new ErrorExp();
305                     fd = f;
306                     assert(fd->type->ty == Tfunction);
307                     TypeFunction *tf = (TypeFunction *)fd->type;
308                     if (!tf->isref && e2)
309                         goto Leproplvalue;
310                 }
311             }
312             if (fd)
313             {
314                 Expression *e = new CallExp(loc, e1);
315                 if (e2)
316                     e = new AssignExp(loc, e, e2);
317                 return semantic(e, sc);
318             }
319         }
320         if (e2)
321             goto Leprop;
322     }
323     else if (e1->op == TOKdotti)
324     {
325         DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e1;
326         if (!dti->findTempDecl(sc))
327             goto Leprop;
328         if (!dti->ti->semanticTiargs(sc))
329             goto Leprop;
330         tiargs = dti->ti->tiargs;
331         tthis  = dti->e1->type;
332         if ((os = dti->ti->tempdecl->isOverloadSet()) != NULL)
333             goto Los;
334         if ((s = dti->ti->tempdecl) != NULL)
335             goto Lfd;
336     }
337     else if (e1->op == TOKdottd)
338     {
339         DotTemplateExp *dte = (DotTemplateExp *)e1;
340         s      = dte->td;
341         tiargs = NULL;
342         tthis  = dte->e1->type;
343         goto Lfd;
344     }
345     else if (e1->op == TOKscope)
346     {
347         s = ((ScopeExp *)e1)->sds;
348         TemplateInstance *ti = s->isTemplateInstance();
349         if (ti && !ti->semanticRun && ti->tempdecl)
350         {
351             //assert(ti->needsTypeInference(sc));
352             if (!ti->semanticTiargs(sc))
353                 goto Leprop;
354             tiargs = ti->tiargs;
355             tthis  = NULL;
356             if ((os = ti->tempdecl->isOverloadSet()) != NULL)
357                 goto Los;
358             if ((s = ti->tempdecl) != NULL)
359                 goto Lfd;
360         }
361     }
362     else if (e1->op == TOKtemplate)
363     {
364         s      = ((TemplateExp *)e1)->td;
365         tiargs = NULL;
366         tthis  = NULL;
367         goto Lfd;
368     }
369     else if (e1->op == TOKdotvar && e1->type && e1->type->toBasetype()->ty == Tfunction)
370     {
371         DotVarExp *dve = (DotVarExp *)e1;
372         s      = dve->var->isFuncDeclaration();
373         tiargs = NULL;
374         tthis  = dve->e1->type;
375         goto Lfd;
376     }
377     else if (e1->op == TOKvar && e1->type && e1->type->toBasetype()->ty == Tfunction)
378     {
379         s      = ((VarExp *)e1)->var->isFuncDeclaration();
380         tiargs = NULL;
381         tthis  = NULL;
382     Lfd:
383         assert(s);
384         if (e2)
385         {
386             e2 = semantic(e2, sc);
387             if (e2->op == TOKerror)
388                 return new ErrorExp();
389             e2 = resolveProperties(sc, e2);
390 
391             Expressions a;
392             a.push(e2);
393 
394             FuncDeclaration *fd = resolveFuncCall(loc, sc, s, tiargs, tthis, &a, 1);
395             if (fd && fd->type)
396             {
397                 if (fd->errors)
398                     return new ErrorExp();
399                 assert(fd->type->ty == Tfunction);
400                 Expression *e = new CallExp(loc, e1, e2);
401                 return semantic(e, sc);
402             }
403         }
404         {
405             FuncDeclaration *fd = resolveFuncCall(loc, sc, s, tiargs, tthis, NULL, 1);
406             if (fd && fd->type)
407             {
408                 if (fd->errors)
409                     return new ErrorExp();
410                 assert(fd->type->ty == Tfunction);
411                 TypeFunction *tf = (TypeFunction *)fd->type;
412                 if (!e2 || tf->isref)
413                 {
414                     Expression *e = new CallExp(loc, e1);
415                     if (e2)
416                         e = new AssignExp(loc, e, e2);
417                     return semantic(e, sc);
418                 }
419             }
420         }
421         if (FuncDeclaration *fd = s->isFuncDeclaration())
422         {
423             // Keep better diagnostic message for invalid property usage of functions
424             assert(fd->type->ty == Tfunction);
425             Expression *e = new CallExp(loc, e1, e2);
426             return semantic(e, sc);
427         }
428         if (e2)
429             goto Leprop;
430     }
431     if (e1->op == TOKvar)
432     {
433         VarExp *ve = (VarExp *)e1;
434         VarDeclaration *v = ve->var->isVarDeclaration();
435         if (v && ve->checkPurity(sc, v))
436             return new ErrorExp();
437     }
438     if (e2)
439         return NULL;
440 
441     if (e1->type &&
442         e1->op != TOKtype)      // function type is not a property
443     {
444         /* Look for e1 being a lazy parameter; rewrite as delegate call
445          */
446         if (e1->op == TOKvar)
447         {
448             VarExp *ve = (VarExp *)e1;
449 
450             if (ve->var->storage_class & STClazy)
451             {
452                 Expression *e = new CallExp(loc, e1);
453                 return semantic(e, sc);
454             }
455         }
456         else if (e1->op == TOKdotvar)
457         {
458             // Check for reading overlapped pointer field in @safe code.
459             if (checkUnsafeAccess(sc, e1, true, true))
460                 return new ErrorExp();
461         }
462         else if (e1->op == TOKcall)
463         {
464             CallExp *ce = (CallExp *)e1;
465             // Check for reading overlapped pointer field in @safe code.
466             if (checkUnsafeAccess(sc, ce->e1, true, true))
467                 return new ErrorExp();
468         }
469     }
470 
471     if (!e1->type)
472     {
473         error(loc, "cannot resolve type for %s", e1->toChars());
474         e1 = new ErrorExp();
475     }
476     return e1;
477 
478 Leprop:
479     error(loc, "not a property %s", e1->toChars());
480     return new ErrorExp();
481 
482 Leproplvalue:
483     error(loc, "%s is not an lvalue", e1->toChars());
484     return new ErrorExp();
485 }
486 
resolveProperties(Scope * sc,Expression * e)487 Expression *resolveProperties(Scope *sc, Expression *e)
488 {
489     //printf("resolveProperties(%s)\n", e->toChars());
490 
491     e = resolvePropertiesX(sc, e);
492     if (e->checkRightThis(sc))
493         return new ErrorExp();
494     return e;
495 }
496 
497 /******************************
498  * Check the tail CallExp is really property function call.
499  */
checkPropertyCall(Expression * e)500 static bool checkPropertyCall(Expression *e)
501 {
502     while (e->op == TOKcomma)
503         e = ((CommaExp *)e)->e2;
504 
505     if (e->op == TOKcall)
506     {
507         CallExp *ce = (CallExp *)e;
508         TypeFunction *tf;
509         if (ce->f)
510         {
511             tf = (TypeFunction *)ce->f->type;
512             /* If a forward reference to ce->f, try to resolve it
513              */
514             if (!tf->deco && ce->f->semanticRun < PASSsemanticdone)
515             {
516                 ce->f->semantic(NULL);
517                 tf = (TypeFunction *)ce->f->type;
518             }
519         }
520         else if (ce->e1->type->ty == Tfunction)
521             tf = (TypeFunction *)ce->e1->type;
522         else if (ce->e1->type->ty == Tdelegate)
523             tf = (TypeFunction *)ce->e1->type->nextOf();
524         else if (ce->e1->type->ty == Tpointer && ce->e1->type->nextOf()->ty == Tfunction)
525             tf = (TypeFunction *)ce->e1->type->nextOf();
526         else
527             assert(0);
528     }
529     return false;
530 }
531 
532 /******************************
533  * If e1 is a property function (template), resolve it.
534  */
535 
resolvePropertiesOnly(Scope * sc,Expression * e1)536 Expression *resolvePropertiesOnly(Scope *sc, Expression *e1)
537 {
538     //printf("e1 = %s %s\n", Token::toChars(e1->op), e1->toChars());
539     OverloadSet *os;
540     FuncDeclaration *fd;
541     TemplateDeclaration *td;
542 
543     if (e1->op == TOKdot)
544     {
545         DotExp *de = (DotExp *)e1;
546         if (de->e2->op == TOKoverloadset)
547         {
548             os = ((OverExp *)de->e2)->vars;
549             goto Los;
550         }
551     }
552     else if (e1->op == TOKoverloadset)
553     {
554         os = ((OverExp *)e1)->vars;
555     Los:
556         assert(os);
557         for (size_t i = 0; i < os->a.dim; i++)
558         {
559             Dsymbol *s = os->a[i];
560             fd = s->isFuncDeclaration();
561             td = s->isTemplateDeclaration();
562             if (fd)
563             {
564                 if (((TypeFunction *)fd->type)->isproperty)
565                     return resolveProperties(sc, e1);
566             }
567             else if (td && td->onemember &&
568                      (fd = td->onemember->isFuncDeclaration()) != NULL)
569             {
570                 if (((TypeFunction *)fd->type)->isproperty ||
571                     (fd->storage_class2 & STCproperty) ||
572                     (td->_scope->stc & STCproperty))
573                 {
574                     return resolveProperties(sc, e1);
575                 }
576             }
577         }
578     }
579     else if (e1->op == TOKdotti)
580     {
581         DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e1;
582         if (dti->ti->tempdecl && (td = dti->ti->tempdecl->isTemplateDeclaration()) != NULL)
583             goto Ltd;
584     }
585     else if (e1->op == TOKdottd)
586     {
587         td = ((DotTemplateExp *)e1)->td;
588         goto Ltd;
589     }
590     else if (e1->op == TOKscope)
591     {
592         Dsymbol *s = ((ScopeExp *)e1)->sds;
593         TemplateInstance *ti = s->isTemplateInstance();
594         if (ti && !ti->semanticRun && ti->tempdecl)
595         {
596             if ((td = ti->tempdecl->isTemplateDeclaration()) != NULL)
597                 goto Ltd;
598         }
599     }
600     else if (e1->op == TOKtemplate)
601     {
602         td = ((TemplateExp *)e1)->td;
603     Ltd:
604         assert(td);
605         if (td->onemember &&
606             (fd = td->onemember->isFuncDeclaration()) != NULL)
607         {
608             if (((TypeFunction *)fd->type)->isproperty ||
609                 (fd->storage_class2 & STCproperty) ||
610                 (td->_scope->stc & STCproperty))
611             {
612                 return resolveProperties(sc, e1);
613             }
614         }
615     }
616     else if (e1->op == TOKdotvar && e1->type->ty == Tfunction)
617     {
618         DotVarExp *dve = (DotVarExp *)e1;
619         fd = dve->var->isFuncDeclaration();
620         goto Lfd;
621     }
622     else if (e1->op == TOKvar && e1->type->ty == Tfunction &&
623         (sc->intypeof || !((VarExp *)e1)->var->needThis()))
624     {
625         fd = ((VarExp *)e1)->var->isFuncDeclaration();
626     Lfd:
627         assert(fd);
628         if (((TypeFunction *)fd->type)->isproperty)
629             return resolveProperties(sc, e1);
630     }
631     return e1;
632 }
633 
634 
635 // TODO: merge with Scope::search::searchScopes()
searchScopes(Scope * sc,Loc loc,Identifier * ident,int flags)636 static Dsymbol *searchScopes(Scope *sc, Loc loc, Identifier *ident, int flags)
637 {
638     Dsymbol *s = NULL;
639     for (Scope *scx = sc; scx; scx = scx->enclosing)
640     {
641         if (!scx->scopesym)
642             continue;
643         if (scx->scopesym->isModule())
644             flags |= SearchUnqualifiedModule;    // tell Module.search() that SearchLocalsOnly is to be obeyed
645         s = scx->scopesym->search(loc, ident, flags);
646         if (s)
647         {
648             // overload set contains only module scope symbols.
649             if (s->isOverloadSet())
650                 break;
651             // selective/renamed imports also be picked up
652             if (AliasDeclaration *ad = s->isAliasDeclaration())
653             {
654                 if (ad->_import)
655                     break;
656             }
657             // See only module scope symbols for UFCS target.
658             Dsymbol *p = s->toParent2();
659             if (p && p->isModule())
660                 break;
661         }
662         s = NULL;
663 
664         // Stop when we hit a module, but keep going if that is not just under the global scope
665         if (scx->scopesym->isModule() && !(scx->enclosing && !scx->enclosing->enclosing))
666             break;
667     }
668     return s;
669 }
670 
671 /******************************
672  * Find symbol in accordance with the UFCS name look up rule
673  */
674 
searchUFCS(Scope * sc,UnaExp * ue,Identifier * ident)675 Expression *searchUFCS(Scope *sc, UnaExp *ue, Identifier *ident)
676 {
677     //printf("searchUFCS(ident = %s)\n", ident->toChars());
678     Loc loc = ue->loc;
679     int flags = 0;
680     Dsymbol *s = NULL;
681 
682     if (sc->flags & SCOPEignoresymbolvisibility)
683         flags |= IgnoreSymbolVisibility;
684 
685     Dsymbol *sold = NULL;
686     if (global.params.bug10378 || global.params.check10378)
687     {
688         sold = searchScopes(sc, loc, ident, flags | IgnoreSymbolVisibility);
689         if (!global.params.check10378)
690         {
691             s = sold;
692             goto Lsearchdone;
693         }
694     }
695 
696     // First look in local scopes
697     s = searchScopes(sc, loc, ident, flags | SearchLocalsOnly);
698     if (!s)
699     {
700         // Second look in imported modules
701         s = searchScopes(sc, loc, ident, flags | SearchImportsOnly);
702 
703         /** Still find private symbols, so that symbols that weren't access
704          * checked by the compiler remain usable.  Once the deprecation is over,
705          * this should be moved to search_correct instead.
706          */
707         if (!s && !(flags & IgnoreSymbolVisibility))
708         {
709             s = searchScopes(sc, loc, ident, flags | SearchLocalsOnly | IgnoreSymbolVisibility);
710             if (!s)
711                 s = searchScopes(sc, loc, ident, flags | SearchImportsOnly | IgnoreSymbolVisibility);
712             if (s)
713                 ::deprecation(loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toChars());
714         }
715     }
716     if (global.params.check10378)
717     {
718         Dsymbol *snew = s;
719         if (sold != snew)
720             Scope::deprecation10378(loc, sold, snew);
721         if (global.params.bug10378)
722             s = sold;
723     }
724 Lsearchdone:
725 
726     if (!s)
727         return ue->e1->type->Type::getProperty(loc, ident, 0);
728 
729     FuncDeclaration *f = s->isFuncDeclaration();
730     if (f)
731     {
732         TemplateDeclaration *td = getFuncTemplateDecl(f);
733         if (td)
734         {
735             if (td->overroot)
736                 td = td->overroot;
737             s = td;
738         }
739     }
740 
741     if (ue->op == TOKdotti)
742     {
743         DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)ue;
744         TemplateInstance *ti = new TemplateInstance(loc, s->ident);
745         ti->tiargs = dti->ti->tiargs;   // for better diagnostic message
746         if (!ti->updateTempDecl(sc, s))
747             return new ErrorExp();
748         return new ScopeExp(loc, ti);
749     }
750     else
751     {
752         //printf("-searchUFCS() %s\n", s->toChars());
753         return new DsymbolExp(loc, s);
754     }
755 }
756 
757 /******************************
758  * check e is exp.opDispatch!(tiargs) or not
759  * It's used to switch to UFCS the semantic analysis path
760  */
761 
isDotOpDispatch(Expression * e)762 bool isDotOpDispatch(Expression *e)
763 {
764     return e->op == TOKdotti &&
765            ((DotTemplateInstanceExp *)e)->ti->name == Id::opDispatch;
766 }
767 
768 /******************************
769  * Pull out callable entity with UFCS.
770  */
771 
resolveUFCS(Scope * sc,CallExp * ce)772 Expression *resolveUFCS(Scope *sc, CallExp *ce)
773 {
774     Loc loc = ce->loc;
775     Expression *eleft;
776     Expression *e;
777 
778     if (ce->e1->op == TOKdotid)
779     {
780         DotIdExp *die = (DotIdExp *)ce->e1;
781         Identifier *ident = die->ident;
782 
783         Expression *ex = semanticX(die, sc);
784         if (ex != die)
785         {
786             ce->e1 = ex;
787             return NULL;
788         }
789         eleft = die->e1;
790 
791         Type *t = eleft->type->toBasetype();
792         if (t->ty == Tarray || t->ty == Tsarray ||
793             t->ty == Tnull  || (t->isTypeBasic() && t->ty != Tvoid))
794         {
795             /* Built-in types and arrays have no callable properties, so do shortcut.
796              * It is necessary in: e.init()
797              */
798         }
799         else if (t->ty == Taarray)
800         {
801             if (ident == Id::remove)
802             {
803                 /* Transform:
804                  *  aa.remove(arg) into delete aa[arg]
805                  */
806                 if (!ce->arguments || ce->arguments->dim != 1)
807                 {
808                     ce->error("expected key as argument to aa.remove()");
809                     return new ErrorExp();
810                 }
811                 if (!eleft->type->isMutable())
812                 {
813                     ce->error("cannot remove key from %s associative array %s",
814                             MODtoChars(t->mod), eleft->toChars());
815                     return new ErrorExp();
816                 }
817                 Expression *key = (*ce->arguments)[0];
818                 key = semantic(key, sc);
819                 key = resolveProperties(sc, key);
820 
821                 TypeAArray *taa = (TypeAArray *)t;
822                 key = key->implicitCastTo(sc, taa->index);
823 
824                 if (key->checkValue())
825                     return new ErrorExp();
826 
827                 semanticTypeInfo(sc, taa->index);
828 
829                 return new RemoveExp(loc, eleft, key);
830             }
831         }
832         else
833         {
834             if (Expression *ey = semanticY(die, sc, 1))
835             {
836                 if (ey->op == TOKerror)
837                     return ey;
838                 ce->e1 = ey;
839                 if (isDotOpDispatch(ey))
840                 {
841                     unsigned errors = global.startGagging();
842                     e = semantic(ce->syntaxCopy(), sc);
843                     if (!global.endGagging(errors))
844                         return e;
845                     /* fall down to UFCS */
846                 }
847                 else
848                     return NULL;
849             }
850         }
851         e = searchUFCS(sc, die, ident);
852     }
853     else if (ce->e1->op == TOKdotti)
854     {
855         DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)ce->e1;
856         if (Expression *ey = semanticY(dti, sc, 1))
857         {
858             ce->e1 = ey;
859             return NULL;
860         }
861         eleft = dti->e1;
862         e = searchUFCS(sc, dti, dti->ti->name);
863     }
864     else
865         return NULL;
866 
867     // Rewrite
868     ce->e1 = e;
869     if (!ce->arguments)
870         ce->arguments = new Expressions();
871     ce->arguments->shift(eleft);
872 
873     return NULL;
874 }
875 
876 /******************************
877  * Pull out property with UFCS.
878  */
879 
880 Expression *resolveUFCSProperties(Scope *sc, Expression *e1, Expression *e2 = NULL)
881 {
882     Loc loc = e1->loc;
883     Expression *eleft;
884     Expression *e;
885 
886     if (e1->op == TOKdotid)
887     {
888         DotIdExp *die = (DotIdExp *)e1;
889         eleft = die->e1;
890         e = searchUFCS(sc, die, die->ident);
891     }
892     else if (e1->op == TOKdotti)
893     {
894         DotTemplateInstanceExp *dti;
895         dti = (DotTemplateInstanceExp *)e1;
896         eleft = dti->e1;
897         e = searchUFCS(sc, dti, dti->ti->name);
898     }
899     else
900         return NULL;
901 
902     if (e == NULL)
903         return NULL;
904 
905     // Rewrite
906     if (e2)
907     {
908         // run semantic without gagging
909         e2 = semantic(e2, sc);
910 
911         /* f(e1) = e2
912          */
913         Expression *ex = e->copy();
914         Expressions *a1 = new Expressions();
915         a1->setDim(1);
916         (*a1)[0] = eleft;
917         ex = new CallExp(loc, ex, a1);
918         ex = trySemantic(ex, sc);
919 
920         /* f(e1, e2)
921          */
922         Expressions *a2 = new Expressions();
923         a2->setDim(2);
924         (*a2)[0] = eleft;
925         (*a2)[1] = e2;
926         e = new CallExp(loc, e, a2);
927         if (ex)
928         {   // if fallback setter exists, gag errors
929             e = trySemantic(e, sc);
930             if (!e)
931             {   checkPropertyCall(ex);
932                 ex = new AssignExp(loc, ex, e2);
933                 return semantic(ex, sc);
934             }
935         }
936         else
937         {   // strict setter prints errors if fails
938             e = semantic(e, sc);
939         }
940         checkPropertyCall(e);
941         return e;
942     }
943     else
944     {
945         /* f(e1)
946          */
947         Expressions *arguments = new Expressions();
948         arguments->setDim(1);
949         (*arguments)[0] = eleft;
950         e = new CallExp(loc, e, arguments);
951         e = semantic(e, sc);
952         checkPropertyCall(e);
953         return semantic(e, sc);
954     }
955 }
956 
957 /******************************
958  * Perform semantic() on an array of Expressions.
959  */
960 
arrayExpressionSemantic(Expressions * exps,Scope * sc,bool preserveErrors)961 bool arrayExpressionSemantic(Expressions *exps, Scope *sc, bool preserveErrors)
962 {
963     bool err = false;
964     if (exps)
965     {
966         for (size_t i = 0; i < exps->dim; i++)
967         {
968             Expression *e = (*exps)[i];
969             if (e)
970             {
971                 e = semantic(e, sc);
972                 if (e->op == TOKerror)
973                     err = true;
974                 if (preserveErrors || e->op != TOKerror)
975                     (*exps)[i] = e;
976             }
977         }
978     }
979     return err;
980 }
981 
982 /****************************************
983  * Expand tuples.
984  * Input:
985  *      exps    aray of Expressions
986  * Output:
987  *      exps    rewritten in place
988  */
989 
expandTuples(Expressions * exps)990 void expandTuples(Expressions *exps)
991 {
992     //printf("expandTuples()\n");
993     if (exps)
994     {
995         for (size_t i = 0; i < exps->dim; i++)
996         {
997             Expression *arg = (*exps)[i];
998             if (!arg)
999                 continue;
1000 
1001             // Look for tuple with 0 members
1002             if (arg->op == TOKtype)
1003             {
1004                 TypeExp *e = (TypeExp *)arg;
1005                 if (e->type->toBasetype()->ty == Ttuple)
1006                 {
1007                     TypeTuple *tt = (TypeTuple *)e->type->toBasetype();
1008 
1009                     if (!tt->arguments || tt->arguments->dim == 0)
1010                     {
1011                         exps->remove(i);
1012                         if (i == exps->dim)
1013                             return;
1014                         i--;
1015                         continue;
1016                     }
1017                 }
1018             }
1019 
1020             // Inline expand all the tuples
1021             while (arg->op == TOKtuple)
1022             {
1023                 TupleExp *te = (TupleExp *)arg;
1024                 exps->remove(i);                // remove arg
1025                 exps->insert(i, te->exps);      // replace with tuple contents
1026                 if (i == exps->dim)
1027                     return;             // empty tuple, no more arguments
1028                 (*exps)[i] = Expression::combine(te->e0, (*exps)[i]);
1029                 arg = (*exps)[i];
1030             }
1031         }
1032     }
1033 }
1034 
1035 /****************************************
1036  * Expand alias this tuples.
1037  */
1038 
isAliasThisTuple(Expression * e)1039 TupleDeclaration *isAliasThisTuple(Expression *e)
1040 {
1041     if (!e->type)
1042         return NULL;
1043 
1044     Type *t = e->type->toBasetype();
1045 Lagain:
1046     if (Dsymbol *s = t->toDsymbol(NULL))
1047     {
1048         AggregateDeclaration *ad = s->isAggregateDeclaration();
1049         if (ad)
1050         {
1051             s = ad->aliasthis;
1052             if (s && s->isVarDeclaration())
1053             {
1054                 TupleDeclaration *td = s->isVarDeclaration()->toAlias()->isTupleDeclaration();
1055                 if (td && td->isexp)
1056                     return td;
1057             }
1058             if (Type *att = t->aliasthisOf())
1059             {
1060                 t = att;
1061                 goto Lagain;
1062             }
1063         }
1064     }
1065     return NULL;
1066 }
1067 
expandAliasThisTuples(Expressions * exps,size_t starti)1068 int expandAliasThisTuples(Expressions *exps, size_t starti)
1069 {
1070     if (!exps || exps->dim == 0)
1071         return -1;
1072 
1073     for (size_t u = starti; u < exps->dim; u++)
1074     {
1075         Expression *exp = (*exps)[u];
1076         TupleDeclaration *td = isAliasThisTuple(exp);
1077         if (td)
1078         {
1079             exps->remove(u);
1080             for (size_t i = 0; i<td->objects->dim; ++i)
1081             {
1082                 Expression *e = isExpression((*td->objects)[i]);
1083                 assert(e);
1084                 assert(e->op == TOKdsymbol);
1085                 DsymbolExp *se = (DsymbolExp *)e;
1086                 Declaration *d = se->s->isDeclaration();
1087                 assert(d);
1088                 e = new DotVarExp(exp->loc, exp, d);
1089                 assert(d->type);
1090                 e->type = d->type;
1091                 exps->insert(u + i, e);
1092             }
1093             return (int)u;
1094         }
1095     }
1096 
1097     return -1;
1098 }
1099 
1100 /****************************************
1101  * The common type is determined by applying ?: to each pair.
1102  * Output:
1103  *      exps[]  properties resolved, implicitly cast to common type, rewritten in place
1104  *      *pt     if pt is not NULL, set to the common type
1105  * Returns:
1106  *      true    a semantic error was detected
1107  */
1108 
arrayExpressionToCommonType(Scope * sc,Expressions * exps,Type ** pt)1109 bool arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt)
1110 {
1111     /* Still have a problem with:
1112      *  ubyte[][] = [ cast(ubyte[])"hello", [1]];
1113      * which works if the array literal is initialized top down with the ubyte[][]
1114      * type, but fails with this function doing bottom up typing.
1115      */
1116     //printf("arrayExpressionToCommonType()\n");
1117     IntegerExp integerexp(0);
1118     CondExp condexp(Loc(), &integerexp, NULL, NULL);
1119 
1120     Type *t0 = NULL;
1121     Expression *e0 = NULL;      // dead-store to prevent spurious warning
1122     size_t j0 = ~0;             // dead-store to prevent spurious warning
1123     bool foundType = false;
1124 
1125     for (size_t i = 0; i < exps->dim; i++)
1126     {
1127         Expression *e = (*exps)[i];
1128         if (!e)
1129             continue;
1130 
1131         e = resolveProperties(sc, e);
1132         if (!e->type)
1133         {
1134             e->error("%s has no value", e->toChars());
1135             t0 = Type::terror;
1136             continue;
1137         }
1138         if (e->op == TOKtype)
1139         {
1140             foundType = true;   // do not break immediately, there might be more errors
1141             e->checkValue();    // report an error "type T has no value"
1142             t0 = Type::terror;
1143             continue;
1144         }
1145         if (e->type->ty == Tvoid)
1146         {
1147             // void expressions do not concur to the determination of the common
1148             // type.
1149             continue;
1150         }
1151         if (checkNonAssignmentArrayOp(e))
1152         {
1153             t0 = Type::terror;
1154             continue;
1155         }
1156 
1157         e = doCopyOrMove(sc, e);
1158 
1159         if (!foundType && t0 && !t0->equals(e->type))
1160         {
1161             /* This applies ?: to merge the types. It's backwards;
1162              * ?: should call this function to merge types.
1163              */
1164             condexp.type = NULL;
1165             condexp.e1 = e0;
1166             condexp.e2 = e;
1167             condexp.loc = e->loc;
1168             Expression *ex = semantic(&condexp, sc);
1169             if (ex->op == TOKerror)
1170                 e = ex;
1171             else
1172             {
1173                 (*exps)[j0] = condexp.e1;
1174                 e = condexp.e2;
1175             }
1176         }
1177         j0 = i;
1178         e0 = e;
1179         t0 = e->type;
1180         if (e->op != TOKerror)
1181             (*exps)[i] = e;
1182     }
1183 
1184     if (!t0)
1185         t0 = Type::tvoid;               // [] is typed as void[]
1186     else if (t0->ty != Terror)
1187     {
1188         for (size_t i = 0; i < exps->dim; i++)
1189         {
1190             Expression *e = (*exps)[i];
1191             if (!e)
1192                 continue;
1193 
1194             e = e->implicitCastTo(sc, t0);
1195             //assert(e->op != TOKerror);
1196             if (e->op == TOKerror)
1197             {
1198                 /* Bugzilla 13024: a workaround for the bug in typeMerge -
1199                  * it should paint e1 and e2 by deduced common type,
1200                  * but doesn't in this particular case.
1201                  */
1202                 t0 = Type::terror;
1203                 break;
1204             }
1205             (*exps)[i] = e;
1206         }
1207     }
1208     if (pt)
1209         *pt = t0;
1210 
1211     return (t0 == Type::terror);
1212 }
1213 
1214 /****************************************
1215  * Get TemplateDeclaration enclosing FuncDeclaration.
1216  */
1217 
getFuncTemplateDecl(Dsymbol * s)1218 TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s)
1219 {
1220     FuncDeclaration *f = s->isFuncDeclaration();
1221     if (f && f->parent)
1222     {
1223         TemplateInstance *ti = f->parent->isTemplateInstance();
1224         if (ti && !ti->isTemplateMixin() &&
1225             ti->tempdecl && ((TemplateDeclaration *)ti->tempdecl)->onemember &&
1226             ti->tempdecl->ident == f->ident)
1227         {
1228             return (TemplateDeclaration *)ti->tempdecl;
1229         }
1230     }
1231     return NULL;
1232 }
1233 
1234 /************************************************
1235  * If we want the value of this expression, but do not want to call
1236  * the destructor on it.
1237  */
1238 
valueNoDtor(Expression * e)1239 Expression *valueNoDtor(Expression *e)
1240 {
1241     if (e->op == TOKcall)
1242     {
1243         /* The struct value returned from the function is transferred
1244          * so do not call the destructor on it.
1245          * Recognize:
1246          *       ((S _ctmp = S.init), _ctmp).this(...)
1247          * and make sure the destructor is not called on _ctmp
1248          * BUG: if e is a CommaExp, we should go down the right side.
1249          */
1250         CallExp *ce = (CallExp *)e;
1251         if (ce->e1->op == TOKdotvar)
1252         {
1253             DotVarExp *dve = (DotVarExp *)ce->e1;
1254             if (dve->var->isCtorDeclaration())
1255             {
1256                 // It's a constructor call
1257                 if (dve->e1->op == TOKcomma)
1258                 {
1259                     CommaExp *comma = (CommaExp *)dve->e1;
1260                     if (comma->e2->op == TOKvar)
1261                     {
1262                         VarExp *ve = (VarExp *)comma->e2;
1263                         VarDeclaration *ctmp = ve->var->isVarDeclaration();
1264                         if (ctmp)
1265                         {
1266                             ctmp->storage_class |= STCnodtor;
1267                             assert(!ce->isLvalue());
1268                         }
1269                     }
1270                 }
1271             }
1272         }
1273     }
1274     else if (e->op == TOKvar)
1275     {
1276         VarDeclaration *vtmp = ((VarExp *)e)->var->isVarDeclaration();
1277         if (vtmp && vtmp->storage_class & STCrvalue)
1278         {
1279             vtmp->storage_class |= STCnodtor;
1280         }
1281     }
1282     return e;
1283 }
1284 
1285 /********************************************
1286  * Issue an error if default construction is disabled for type t.
1287  * Default construction is required for arrays and 'out' parameters.
1288  * Returns:
1289  *      true    an error was issued
1290  */
checkDefCtor(Loc loc,Type * t)1291 bool checkDefCtor(Loc loc, Type *t)
1292 {
1293     t = t->baseElemOf();
1294     if (t->ty == Tstruct)
1295     {
1296         StructDeclaration *sd = ((TypeStruct *)t)->sym;
1297         if (sd->noDefaultCtor)
1298         {
1299             sd->error(loc, "default construction is disabled");
1300             return true;
1301         }
1302     }
1303     return false;
1304 }
1305 
1306 /*********************************************
1307  * If e is an instance of a struct, and that struct has a copy constructor,
1308  * rewrite e as:
1309  *    (tmp = e),tmp
1310  * Input:
1311  *      sc      just used to specify the scope of created temporary variable
1312  */
callCpCtor(Scope * sc,Expression * e)1313 Expression *callCpCtor(Scope *sc, Expression *e)
1314 {
1315     Type *tv = e->type->baseElemOf();
1316     if (tv->ty == Tstruct)
1317     {
1318         StructDeclaration *sd = ((TypeStruct *)tv)->sym;
1319         if (sd->postblit)
1320         {
1321             /* Create a variable tmp, and replace the argument e with:
1322              *      (tmp = e),tmp
1323              * and let AssignExp() handle the construction.
1324              * This is not the most efficent, ideally tmp would be constructed
1325              * directly onto the stack.
1326              */
1327             VarDeclaration *tmp = copyToTemp(STCrvalue, "__copytmp", e);
1328             tmp->storage_class |= STCnodtor;
1329             tmp->semantic(sc);
1330             Expression *de = new DeclarationExp(e->loc, tmp);
1331             Expression *ve = new VarExp(e->loc, tmp);
1332             de->type = Type::tvoid;
1333             ve->type = e->type;
1334             e = Expression::combine(de, ve);
1335         }
1336     }
1337     return e;
1338 }
1339 
1340 /************************************************
1341  * Handle the postblit call on lvalue, or the move of rvalue.
1342  */
doCopyOrMove(Scope * sc,Expression * e)1343 Expression *doCopyOrMove(Scope *sc, Expression *e)
1344 {
1345     if (e->op == TOKquestion)
1346     {
1347         CondExp *ce = (CondExp *)e;
1348         ce->e1 = doCopyOrMove(sc, ce->e1);
1349         ce->e2 = doCopyOrMove(sc, ce->e2);
1350     }
1351     else
1352     {
1353         e = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e);
1354     }
1355     return e;
1356 }
1357 
1358 /****************************************
1359  * Now that we know the exact type of the function we're calling,
1360  * the arguments[] need to be adjusted:
1361  *      1. implicitly convert argument to the corresponding parameter type
1362  *      2. add default arguments for any missing arguments
1363  *      3. do default promotions on arguments corresponding to ...
1364  *      4. add hidden _arguments[] argument
1365  *      5. call copy constructor for struct value arguments
1366  * Input:
1367  *      tf      type of the function
1368  *      fd      the function being called, NULL if called indirectly
1369  * Output:
1370  *      *prettype return type of function
1371  *      *peprefix expression to execute before arguments[] are evaluated, NULL if none
1372  * Returns:
1373  *      true    errors happened
1374  */
1375 
functionParameters(Loc loc,Scope * sc,TypeFunction * tf,Type * tthis,Expressions * arguments,FuncDeclaration * fd,Type ** prettype,Expression ** peprefix)1376 bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
1377         Type *tthis, Expressions *arguments, FuncDeclaration *fd, Type **prettype, Expression **peprefix)
1378 {
1379     //printf("functionParameters()\n");
1380     assert(arguments);
1381     assert(fd || tf->next);
1382     size_t nargs = arguments ? arguments->dim : 0;
1383     size_t nparams = Parameter::dim(tf->parameters);
1384     unsigned olderrors = global.errors;
1385     bool err = false;
1386     *prettype = Type::terror;
1387     Expression *eprefix = NULL;
1388     *peprefix = NULL;
1389 
1390     if (nargs > nparams && tf->varargs == 0)
1391     {
1392         error(loc, "expected %llu arguments, not %llu for non-variadic function type %s", (ulonglong)nparams, (ulonglong)nargs, tf->toChars());
1393         return true;
1394     }
1395 
1396     // If inferring return type, and semantic3() needs to be run if not already run
1397     if (!tf->next && fd->inferRetType)
1398     {
1399         fd->functionSemantic();
1400     }
1401     else if (fd && fd->parent)
1402     {
1403         TemplateInstance *ti = fd->parent->isTemplateInstance();
1404         if (ti && ti->tempdecl)
1405         {
1406             fd->functionSemantic3();
1407         }
1408     }
1409     bool isCtorCall = fd && fd->needThis() && fd->isCtorDeclaration();
1410 
1411     size_t n = (nargs > nparams) ? nargs : nparams;   // n = max(nargs, nparams)
1412 
1413     /* If the function return type has wildcards in it, we'll need to figure out the actual type
1414      * based on the actual argument types.
1415      */
1416     MOD wildmatch = 0;
1417     if (tthis && tf->isWild() && !isCtorCall)
1418     {
1419         Type *t = tthis;
1420         if (t->isImmutable())
1421             wildmatch = MODimmutable;
1422         else if (t->isWildConst())
1423             wildmatch = MODwildconst;
1424         else if (t->isWild())
1425             wildmatch = MODwild;
1426         else if (t->isConst())
1427             wildmatch = MODconst;
1428         else
1429             wildmatch = MODmutable;
1430     }
1431 
1432     int done = 0;
1433     for (size_t i = 0; i < n; i++)
1434     {
1435         Expression *arg;
1436 
1437         if (i < nargs)
1438             arg = (*arguments)[i];
1439         else
1440             arg = NULL;
1441 
1442         if (i < nparams)
1443         {
1444             Parameter *p = Parameter::getNth(tf->parameters, i);
1445 
1446             if (!arg)
1447             {
1448                 if (!p->defaultArg)
1449                 {
1450                     if (tf->varargs == 2 && i + 1 == nparams)
1451                         goto L2;
1452                     error(loc, "expected %llu function arguments, not %llu", (ulonglong)nparams, (ulonglong)nargs);
1453                     return true;
1454                 }
1455                 arg = p->defaultArg;
1456                 arg = inlineCopy(arg, sc);
1457                 // __FILE__, __LINE__, __MODULE__, __FUNCTION__, and __PRETTY_FUNCTION__
1458                 arg = arg->resolveLoc(loc, sc);
1459                 arguments->push(arg);
1460                 nargs++;
1461             }
1462 
1463             if (tf->varargs == 2 && i + 1 == nparams)
1464             {
1465                 //printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars());
1466                 {
1467                     MATCH m;
1468                     if ((m = arg->implicitConvTo(p->type)) > MATCHnomatch)
1469                     {
1470                         if (p->type->nextOf() && arg->implicitConvTo(p->type->nextOf()) >= m)
1471                             goto L2;
1472                         else if (nargs != nparams)
1473                         {   error(loc, "expected %llu function arguments, not %llu", (ulonglong)nparams, (ulonglong)nargs);
1474                             return true;
1475                         }
1476                         goto L1;
1477                     }
1478                 }
1479              L2:
1480                 Type *tb = p->type->toBasetype();
1481                 Type *tret = p->isLazyArray();
1482                 switch (tb->ty)
1483                 {
1484                     case Tsarray:
1485                     case Tarray:
1486                     {
1487                         /* Create a static array variable v of type arg->type:
1488                          *  T[dim] __arrayArg = [ arguments[i], ..., arguments[nargs-1] ];
1489                          *
1490                          * The array literal in the initializer of the hidden variable
1491                          * is now optimized. See Bugzilla 2356.
1492                          */
1493                         Type *tbn = ((TypeArray *)tb)->next;
1494 
1495                         Expressions *elements = new Expressions();
1496                         elements->setDim(nargs - i);
1497                         for (size_t u = 0; u < elements->dim; u++)
1498                         {
1499                             Expression *a = (*arguments)[i + u];
1500                             if (tret && a->implicitConvTo(tret))
1501                             {
1502                                 a = a->implicitCastTo(sc, tret);
1503                                 a = a->optimize(WANTvalue);
1504                                 a = toDelegate(a, a->type, sc);
1505                             }
1506                             else
1507                                 a = a->implicitCastTo(sc, tbn);
1508                             (*elements)[u] = a;
1509                         }
1510                         // Bugzilla 14395: Convert to a static array literal, or its slice.
1511                         arg = new ArrayLiteralExp(loc, tbn->sarrayOf(nargs - i), elements);
1512                         if (tb->ty == Tarray)
1513                         {
1514                             arg = new SliceExp(loc, arg, NULL, NULL);
1515                             arg->type = p->type;
1516                         }
1517                         break;
1518                     }
1519                     case Tclass:
1520                     {
1521                         /* Set arg to be:
1522                          *      new Tclass(arg0, arg1, ..., argn)
1523                          */
1524                         Expressions *args = new Expressions();
1525                         args->setDim(nargs - i);
1526                         for (size_t u = i; u < nargs; u++)
1527                             (*args)[u - i] = (*arguments)[u];
1528                         arg = new NewExp(loc, NULL, NULL, p->type, args);
1529                         break;
1530                     }
1531                     default:
1532                         if (!arg)
1533                         {
1534                             error(loc, "not enough arguments");
1535                             return true;
1536                         }
1537                         break;
1538                 }
1539                 arg = semantic(arg, sc);
1540                 //printf("\targ = '%s'\n", arg->toChars());
1541                 arguments->setDim(i + 1);
1542                 (*arguments)[i] =  arg;
1543                 nargs = i + 1;
1544                 done = 1;
1545             }
1546 
1547         L1:
1548             if (!(p->storageClass & STClazy && p->type->ty == Tvoid))
1549             {
1550                 bool isRef = (p->storageClass & (STCref | STCout)) != 0;
1551                 if (unsigned char wm = arg->type->deduceWild(p->type, isRef))
1552                 {
1553                     if (wildmatch)
1554                         wildmatch = MODmerge(wildmatch, wm);
1555                     else
1556                         wildmatch = wm;
1557                     //printf("[%d] p = %s, a = %s, wm = %d, wildmatch = %d\n", i, p->type->toChars(), arg->type->toChars(), wm, wildmatch);
1558                 }
1559             }
1560         }
1561         if (done)
1562             break;
1563     }
1564     if ((wildmatch == MODmutable || wildmatch == MODimmutable) &&
1565         tf->next->hasWild() &&
1566         (tf->isref || !tf->next->implicitConvTo(tf->next->immutableOf())))
1567     {
1568         if (fd)
1569         {
1570             /* If the called function may return the reference to
1571              * outer inout data, it should be rejected.
1572              *
1573              * void foo(ref inout(int) x) {
1574              *   ref inout(int) bar(inout(int)) { return x; }
1575              *   struct S { ref inout(int) bar() inout { return x; } }
1576              *   bar(int.init) = 1;  // bad!
1577              *   S().bar() = 1;      // bad!
1578              * }
1579              */
1580             Dsymbol *s = NULL;
1581             if (fd->isThis() || fd->isNested())
1582                 s = fd->toParent2();
1583             for (; s; s = s->toParent2())
1584             {
1585                 if (AggregateDeclaration *ad = s->isAggregateDeclaration())
1586                 {
1587                     if (ad->isNested())
1588                         continue;
1589                     break;
1590                 }
1591                 if (FuncDeclaration *ff = s->isFuncDeclaration())
1592                 {
1593                     if (((TypeFunction *)ff->type)->iswild)
1594                         goto Linouterr;
1595 
1596                     if (ff->isNested() || ff->isThis())
1597                         continue;
1598                 }
1599                 break;
1600             }
1601         }
1602         else if (tf->isWild())
1603         {
1604         Linouterr:
1605             const char *s = wildmatch == MODmutable ? "mutable" : MODtoChars(wildmatch);
1606             error(loc, "modify inout to %s is not allowed inside inout function", s);
1607             return true;
1608         }
1609     }
1610 
1611     assert(nargs >= nparams);
1612     for (size_t i = 0; i < nargs; i++)
1613     {
1614         Expression *arg = (*arguments)[i];
1615         assert(arg);
1616         if (i < nparams)
1617         {
1618             Parameter *p = Parameter::getNth(tf->parameters, i);
1619 
1620             if (!(p->storageClass & STClazy && p->type->ty == Tvoid))
1621             {
1622                 Type *tprm = p->type;
1623                 if (p->type->hasWild())
1624                     tprm = p->type->substWildTo(wildmatch);
1625                 if (!tprm->equals(arg->type))
1626                 {
1627                     //printf("arg->type = %s, p->type = %s\n", arg->type->toChars(), p->type->toChars());
1628                     arg = arg->implicitCastTo(sc, tprm);
1629                     arg = arg->optimize(WANTvalue, (p->storageClass & (STCref | STCout)) != 0);
1630                 }
1631             }
1632             if (p->storageClass & STCref)
1633             {
1634                 arg = arg->toLvalue(sc, arg);
1635 
1636                 // Look for mutable misaligned pointer, etc., in @safe mode
1637                 err |= checkUnsafeAccess(sc, arg, false, true);
1638             }
1639             else if (p->storageClass & STCout)
1640             {
1641                 Type *t = arg->type;
1642                 if (!t->isMutable() || !t->isAssignable())  // check blit assignable
1643                 {
1644                     arg->error("cannot modify struct %s with immutable members", arg->toChars());
1645                     err = true;
1646                 }
1647                 else
1648                 {
1649                     // Look for misaligned pointer, etc., in @safe mode
1650                     err |= checkUnsafeAccess(sc, arg, false, true);
1651                     err |= checkDefCtor(arg->loc, t);   // t must be default constructible
1652                 }
1653                 arg = arg->toLvalue(sc, arg);
1654             }
1655             else if (p->storageClass & STClazy)
1656             {
1657                 // Convert lazy argument to a delegate
1658                 if (p->type->ty == Tvoid)
1659                     arg = toDelegate(arg, p->type, sc);
1660                 else
1661                     arg = toDelegate(arg, arg->type, sc);
1662             }
1663 
1664             //printf("arg: %s\n", arg->toChars());
1665             //printf("type: %s\n", arg->type->toChars());
1666             if (tf->parameterEscapes(p))
1667             {
1668                 /* Argument value can escape from the called function.
1669                  * Check arg to see if it matters.
1670                  */
1671                 if (global.params.vsafe)
1672                     err |= checkParamArgumentEscape(sc, fd, p->ident, arg, false);
1673             }
1674             else
1675             {
1676                 /* Argument value cannot escape from the called function.
1677                  */
1678                 Expression *a = arg;
1679                 if (a->op == TOKcast)
1680                     a = ((CastExp *)a)->e1;
1681 
1682                 if (a->op == TOKfunction)
1683                 {
1684                     /* Function literals can only appear once, so if this
1685                      * appearance was scoped, there cannot be any others.
1686                      */
1687                     FuncExp *fe = (FuncExp *)a;
1688                     fe->fd->tookAddressOf = 0;
1689                 }
1690                 else if (a->op == TOKdelegate)
1691                 {
1692                     /* For passing a delegate to a scoped parameter,
1693                      * this doesn't count as taking the address of it.
1694                      * We only worry about 'escaping' references to the function.
1695                      */
1696                     DelegateExp *de = (DelegateExp *)a;
1697                     if (de->e1->op == TOKvar)
1698                     {   VarExp *ve = (VarExp *)de->e1;
1699                         FuncDeclaration *f = ve->var->isFuncDeclaration();
1700                         if (f)
1701                         {   f->tookAddressOf--;
1702                             //printf("tookAddressOf = %d\n", f->tookAddressOf);
1703                         }
1704                     }
1705                 }
1706             }
1707             arg = arg->optimize(WANTvalue, (p->storageClass & (STCref | STCout)) != 0);
1708         }
1709         else
1710         {
1711             // These will be the trailing ... arguments
1712 
1713             // If not D linkage, do promotions
1714             if (tf->linkage != LINKd)
1715             {
1716                 // Promote bytes, words, etc., to ints
1717                 arg = integralPromotions(arg, sc);
1718 
1719                 // Promote floats to doubles
1720                 switch (arg->type->ty)
1721                 {
1722                     case Tfloat32:
1723                         arg = arg->castTo(sc, Type::tfloat64);
1724                         break;
1725 
1726                     case Timaginary32:
1727                         arg = arg->castTo(sc, Type::timaginary64);
1728                         break;
1729                 }
1730 
1731                 if (tf->varargs == 1)
1732                 {
1733                     const char *p = tf->linkage == LINKc ? "extern(C)" : "extern(C++)";
1734                     if (arg->type->ty == Tarray)
1735                     {
1736                         arg->error("cannot pass dynamic arrays to %s vararg functions", p);
1737                         err = true;
1738                     }
1739                     if (arg->type->ty == Tsarray)
1740                     {
1741                         arg->error("cannot pass static arrays to %s vararg functions", p);
1742                         err = true;
1743                     }
1744                 }
1745             }
1746 
1747             // Do not allow types that need destructors
1748             if (arg->type->needsDestruction())
1749             {
1750                 arg->error("cannot pass types that need destruction as variadic arguments");
1751                 err = true;
1752             }
1753 
1754             // Convert static arrays to dynamic arrays
1755             // BUG: I don't think this is right for D2
1756             Type *tb = arg->type->toBasetype();
1757             if (tb->ty == Tsarray)
1758             {
1759                 TypeSArray *ts = (TypeSArray *)tb;
1760                 Type *ta = ts->next->arrayOf();
1761                 if (ts->size(arg->loc) == 0)
1762                     arg = new NullExp(arg->loc, ta);
1763                 else
1764                     arg = arg->castTo(sc, ta);
1765             }
1766             if (tb->ty == Tstruct)
1767             {
1768                 //arg = callCpCtor(sc, arg);
1769             }
1770 
1771             // Give error for overloaded function addresses
1772             if (arg->op == TOKsymoff)
1773             {   SymOffExp *se = (SymOffExp *)arg;
1774                 if (se->hasOverloads &&
1775                     !se->var->isFuncDeclaration()->isUnique())
1776                 {   arg->error("function %s is overloaded", arg->toChars());
1777                     err = true;
1778                 }
1779             }
1780             if (arg->checkValue())
1781                 err = true;
1782             arg = arg->optimize(WANTvalue);
1783         }
1784         (*arguments)[i] = arg;
1785     }
1786 
1787     /* Remaining problems:
1788      * 1. order of evaluation - some function push L-to-R, others R-to-L. Until we resolve what array assignment does (which is
1789      *    implemented by calling a function) we'll defer this for now.
1790      * 2. value structs (or static arrays of them) that need to be copy constructed
1791      * 3. value structs (or static arrays of them) that have destructors, and subsequent arguments that may throw before the
1792      *    function gets called (functions normally destroy their parameters)
1793      * 2 and 3 are handled by doing the argument construction in 'eprefix' so that if a later argument throws, they are cleaned
1794      * up properly. Pushing arguments on the stack then cannot fail.
1795      */
1796     if (1)
1797     {
1798         /* TODO: tackle problem 1)
1799          */
1800         const bool leftToRight = true; // TODO: something like !fd.isArrayOp
1801         if (!leftToRight)
1802             assert(nargs == nparams); // no variadics for RTL order, as they would probably be evaluated LTR and so add complexity
1803 
1804         const ptrdiff_t start = (leftToRight ? 0 : (ptrdiff_t)nargs - 1);
1805         const ptrdiff_t end = (leftToRight ? (ptrdiff_t)nargs : -1);
1806         const ptrdiff_t step = (leftToRight ? 1 : -1);
1807 
1808         /* Compute indices of last throwing argument and first arg needing destruction.
1809          * Used to not set up destructors unless an arg needs destruction on a throw
1810          * in a later argument.
1811          */
1812         ptrdiff_t lastthrow = -1;
1813         ptrdiff_t firstdtor = -1;
1814         for (ptrdiff_t i = start; i != end; i += step)
1815         {
1816             Expression *arg = (*arguments)[i];
1817             if (canThrow(arg, sc->func, false))
1818                 lastthrow = i;
1819             if (firstdtor == -1 && arg->type->needsDestruction())
1820             {
1821                 Parameter *p = (i >= (ptrdiff_t)nparams ? NULL : Parameter::getNth(tf->parameters, i));
1822                 if (!(p && (p->storageClass & (STClazy | STCref | STCout))))
1823                     firstdtor = i;
1824             }
1825         }
1826 
1827         /* Does problem 3) apply to this call?
1828          */
1829         const bool needsPrefix = (firstdtor >= 0 && lastthrow >= 0
1830             && (lastthrow - firstdtor) * step > 0);
1831 
1832         /* If so, initialize 'eprefix' by declaring the gate
1833          */
1834         VarDeclaration *gate = NULL;
1835         if (needsPrefix)
1836         {
1837             // eprefix => bool __gate [= false]
1838             Identifier *idtmp = Identifier::generateId("__gate");
1839             gate = new VarDeclaration(loc, Type::tbool, idtmp, NULL);
1840             gate->storage_class |= STCtemp | STCctfe | STCvolatile;
1841             gate->semantic(sc);
1842 
1843             Expression *ae = new DeclarationExp(loc, gate);
1844             eprefix = semantic(ae, sc);
1845         }
1846 
1847         for (ptrdiff_t i = start; i != end; i += step)
1848         {
1849             Expression *arg = (*arguments)[i];
1850 
1851             Parameter *parameter = (i >= (ptrdiff_t)nparams ? NULL : Parameter::getNth(tf->parameters, i));
1852             const bool isRef = (parameter && (parameter->storageClass & (STCref | STCout)));
1853             const bool isLazy = (parameter && (parameter->storageClass & STClazy));
1854 
1855             /* Skip lazy parameters
1856              */
1857             if (isLazy)
1858                 continue;
1859 
1860             /* Do we have a gate? Then we have a prefix and we're not yet past the last throwing arg.
1861              * Declare a temporary variable for this arg and append that declaration to 'eprefix',
1862              * which will implicitly take care of potential problem 2) for this arg.
1863              * 'eprefix' will therefore finally contain all args up to and including the last
1864              * potentially throwing arg, excluding all lazy parameters.
1865              */
1866             if (gate)
1867             {
1868                 const bool needsDtor = (!isRef && arg->type->needsDestruction() && i != lastthrow);
1869 
1870                 /* Declare temporary 'auto __pfx = arg' (needsDtor) or 'auto __pfy = arg' (!needsDtor)
1871                  */
1872                 VarDeclaration *tmp = copyToTemp(0,
1873                     needsDtor ? "__pfx" : "__pfy",
1874                     !isRef ? arg : arg->addressOf());
1875                 tmp->semantic(sc);
1876 
1877                 /* Modify the destructor so it only runs if gate==false, i.e.,
1878                  * only if there was a throw while constructing the args
1879                  */
1880                 if (!needsDtor)
1881                 {
1882                     if (tmp->edtor)
1883                     {
1884                         assert(i == lastthrow);
1885                         tmp->edtor = NULL;
1886                     }
1887                 }
1888                 else
1889                 {
1890                     // edtor => (__gate || edtor)
1891                     assert(tmp->edtor);
1892                     Expression *e = tmp->edtor;
1893                     e = new OrOrExp(e->loc, new VarExp(e->loc, gate), e);
1894                     tmp->edtor = semantic(e, sc);
1895                     //printf("edtor: %s\n", tmp->edtor->toChars());
1896                 }
1897 
1898                 // eprefix => (eprefix, auto __pfx/y = arg)
1899                 DeclarationExp *ae = new DeclarationExp(loc, tmp);
1900                 eprefix = Expression::combine(eprefix, semantic(ae, sc));
1901 
1902                 // arg => __pfx/y
1903                 arg = new VarExp(loc, tmp);
1904                 arg = semantic(arg, sc);
1905                 if (isRef)
1906                 {
1907                     arg = new PtrExp(loc, arg);
1908                     arg = semantic(arg, sc);
1909                 }
1910 
1911                 /* Last throwing arg? Then finalize eprefix => (eprefix, gate = true),
1912                  * i.e., disable the dtors right after constructing the last throwing arg.
1913                  * From now on, the callee will take care of destructing the args because
1914                  * the args are implicitly moved into function parameters.
1915                  *
1916                  * Set gate to null to let the next iterations know they don't need to
1917                  * append to eprefix anymore.
1918                  */
1919                 if (i == lastthrow)
1920                 {
1921                     Expression *e = new AssignExp(gate->loc, new VarExp(gate->loc, gate), new IntegerExp(gate->loc, 1, Type::tbool));
1922                     eprefix = Expression::combine(eprefix, semantic(e, sc));
1923                     gate = NULL;
1924                 }
1925             }
1926             else
1927             {
1928                 /* No gate, no prefix to append to.
1929                  * Handle problem 2) by calling the copy constructor for value structs
1930                  * (or static arrays of them) if appropriate.
1931                  */
1932                 Type *tv = arg->type->baseElemOf();
1933                 if (!isRef && tv->ty == Tstruct)
1934                     arg = doCopyOrMove(sc, arg);
1935             }
1936 
1937             (*arguments)[i] = arg;
1938         }
1939     }
1940     //if (eprefix) printf("eprefix: %s\n", eprefix->toChars());
1941 
1942     // If D linkage and variadic, add _arguments[] as first argument
1943     if (tf->linkage == LINKd && tf->varargs == 1)
1944     {
1945         assert(arguments->dim >= nparams);
1946 
1947         Parameters *args = new Parameters;
1948         args->setDim(arguments->dim - nparams);
1949         for (size_t i = 0; i < arguments->dim - nparams; i++)
1950         {
1951             Parameter *arg = new Parameter(STCin, (*arguments)[nparams + i]->type, NULL, NULL);
1952             (*args)[i] = arg;
1953         }
1954 
1955         TypeTuple *tup = new TypeTuple(args);
1956         Expression *e = new TypeidExp(loc, tup);
1957         e = semantic(e, sc);
1958         arguments->insert(0, e);
1959     }
1960 
1961     Type *tret = tf->next;
1962     if (isCtorCall)
1963     {
1964         //printf("[%s] fd = %s %s, %d %d %d\n", loc.toChars(), fd->toChars(), fd->type->toChars(),
1965         //    wildmatch, tf->isWild(), fd->isolateReturn());
1966         if (!tthis)
1967         {
1968             assert(sc->intypeof || global.errors);
1969             tthis = fd->isThis()->type->addMod(fd->type->mod);
1970         }
1971         if (tf->isWild() && !fd->isolateReturn())
1972         {
1973             if (wildmatch)
1974                 tret = tret->substWildTo(wildmatch);
1975             int offset;
1976             if (!tret->implicitConvTo(tthis) &&
1977                 !(MODimplicitConv(tret->mod, tthis->mod) && tret->isBaseOf(tthis, &offset) && offset == 0))
1978             {
1979                 const char* s1 = tret ->isNaked() ? " mutable" : tret ->modToChars();
1980                 const char* s2 = tthis->isNaked() ? " mutable" : tthis->modToChars();
1981                 ::error(loc, "inout constructor %s creates%s object, not%s",
1982                         fd->toPrettyChars(), s1, s2);
1983                 err = true;
1984             }
1985         }
1986         tret = tthis;
1987     }
1988     else if (wildmatch && tret)
1989     {
1990         /* Adjust function return type based on wildmatch
1991          */
1992         //printf("wildmatch = x%x, tret = %s\n", wildmatch, tret->toChars());
1993         tret = tret->substWildTo(wildmatch);
1994     }
1995     *prettype = tret;
1996     *peprefix = eprefix;
1997     return (err || olderrors != global.errors);
1998 }
1999 
2000 /******************************** Expression **************************/
2001 
Expression(Loc loc,TOK op,int size)2002 Expression::Expression(Loc loc, TOK op, int size)
2003 {
2004     //printf("Expression::Expression(op = %d) this = %p\n", op, this);
2005     this->loc = loc;
2006     this->op = op;
2007     this->size = (unsigned char)size;
2008     this->parens = 0;
2009     type = NULL;
2010 }
2011 
_init()2012 void Expression::_init()
2013 {
2014     CTFEExp::cantexp = new CTFEExp(TOKcantexp);
2015     CTFEExp::voidexp = new CTFEExp(TOKvoidexp);
2016     CTFEExp::breakexp = new CTFEExp(TOKbreak);
2017     CTFEExp::continueexp = new CTFEExp(TOKcontinue);
2018     CTFEExp::gotoexp = new CTFEExp(TOKgoto);
2019 }
2020 
syntaxCopy()2021 Expression *Expression::syntaxCopy()
2022 {
2023     //printf("Expression::syntaxCopy()\n");
2024     //print();
2025     return copy();
2026 }
2027 
2028 /*********************************
2029  * Does *not* do a deep copy.
2030  */
2031 
copy()2032 Expression *Expression::copy()
2033 {
2034     Expression *e;
2035     if (!size)
2036     {
2037         assert(0);
2038     }
2039     void *pe = mem.xmalloc(size);
2040     //printf("Expression::copy(op = %d) e = %p\n", op, pe);
2041     e = (Expression *)memcpy(pe, (void *)this, size);
2042     return e;
2043 }
2044 
print()2045 void Expression::print()
2046 {
2047     fprintf(stderr, "%s\n", toChars());
2048     fflush(stderr);
2049 }
2050 
toChars()2051 const char *Expression::toChars()
2052 {
2053     OutBuffer buf;
2054     HdrGenState hgs;
2055     toCBuffer(this, &buf, &hgs);
2056     return buf.extractString();
2057 }
2058 
error(const char * format,...)2059 void Expression::error(const char *format, ...) const
2060 {
2061     if (type != Type::terror)
2062     {
2063         va_list ap;
2064         va_start(ap, format);
2065         ::verror(loc, format, ap);
2066         va_end( ap );
2067     }
2068 }
2069 
warning(const char * format,...)2070 void Expression::warning(const char *format, ...) const
2071 {
2072     if (type != Type::terror)
2073     {
2074         va_list ap;
2075         va_start(ap, format);
2076         ::vwarning(loc, format, ap);
2077         va_end( ap );
2078     }
2079 }
2080 
deprecation(const char * format,...)2081 void Expression::deprecation(const char *format, ...) const
2082 {
2083     if (type != Type::terror)
2084     {
2085         va_list ap;
2086         va_start(ap, format);
2087         ::vdeprecation(loc, format, ap);
2088         va_end( ap );
2089     }
2090 }
2091 
2092 /**********************************
2093  * Combine e1 and e2 by CommaExp if both are not NULL.
2094  */
combine(Expression * e1,Expression * e2)2095 Expression *Expression::combine(Expression *e1, Expression *e2)
2096 {
2097     if (e1)
2098     {
2099         if (e2)
2100         {
2101             e1 = new CommaExp(e1->loc, e1, e2);
2102             e1->type = e2->type;
2103         }
2104     }
2105     else
2106         e1 = e2;
2107     return e1;
2108 }
2109 
2110 /**********************************
2111  * If 'e' is a tree of commas, returns the leftmost expression
2112  * by stripping off it from the tree. The remained part of the tree
2113  * is returned via *pe0.
2114  * Otherwise 'e' is directly returned and *pe0 is set to NULL.
2115  */
extractLast(Expression * e,Expression ** pe0)2116 Expression *Expression::extractLast(Expression *e, Expression **pe0)
2117 {
2118     if (e->op != TOKcomma)
2119     {
2120         *pe0 = NULL;
2121         return e;
2122     }
2123 
2124     CommaExp *ce = (CommaExp *)e;
2125     if (ce->e2->op != TOKcomma)
2126     {
2127         *pe0 = ce->e1;
2128         return ce->e2;
2129     }
2130     else
2131     {
2132         *pe0 = e;
2133 
2134         Expression **pce = &ce->e2;
2135         while (((CommaExp *)(*pce))->e2->op == TOKcomma)
2136         {
2137             pce = &((CommaExp *)(*pce))->e2;
2138         }
2139         assert((*pce)->op == TOKcomma);
2140         ce = (CommaExp *)(*pce);
2141         *pce = ce->e1;
2142 
2143         return ce->e2;
2144     }
2145 }
2146 
toInteger()2147 dinteger_t Expression::toInteger()
2148 {
2149     //printf("Expression %s\n", Token::toChars(op));
2150     error("integer constant expression expected instead of %s", toChars());
2151     return 0;
2152 }
2153 
toUInteger()2154 uinteger_t Expression::toUInteger()
2155 {
2156     //printf("Expression %s\n", Token::toChars(op));
2157     return (uinteger_t)toInteger();
2158 }
2159 
toReal()2160 real_t Expression::toReal()
2161 {
2162     error("floating point constant expression expected instead of %s", toChars());
2163     return CTFloat::zero;
2164 }
2165 
toImaginary()2166 real_t Expression::toImaginary()
2167 {
2168     error("floating point constant expression expected instead of %s", toChars());
2169     return CTFloat::zero;
2170 }
2171 
toComplex()2172 complex_t Expression::toComplex()
2173 {
2174     error("floating point constant expression expected instead of %s", toChars());
2175     return complex_t(CTFloat::zero);
2176 }
2177 
toStringExp()2178 StringExp *Expression::toStringExp()
2179 {
2180     return NULL;
2181 }
2182 
toTupleExp()2183 TupleExp *Expression::toTupleExp()
2184 {
2185     return NULL;
2186 }
2187 
2188 /***************************************
2189  * Return !=0 if expression is an lvalue.
2190  */
2191 
isLvalue()2192 bool Expression::isLvalue()
2193 {
2194     return false;
2195 }
2196 
2197 /*******************************
2198  * Give error if we're not an lvalue.
2199  * If we can, convert expression to be an lvalue.
2200  */
2201 
toLvalue(Scope *,Expression * e)2202 Expression *Expression::toLvalue(Scope *, Expression *e)
2203 {
2204     if (!e)
2205         e = this;
2206     else if (!loc.filename)
2207         loc = e->loc;
2208 
2209     if (e->op == TOKtype)
2210         error("%s '%s' is a type, not an lvalue", e->type->kind(), e->type->toChars());
2211     else
2212         error("%s is not an lvalue", e->toChars());
2213 
2214     return new ErrorExp();
2215 }
2216 
2217 /***************************************
2218  * Parameters:
2219  *      sc:     scope
2220  *      flag:   1: do not issue error message for invalid modification
2221  * Returns:
2222  *      0:      is not modifiable
2223  *      1:      is modifiable in default == being related to type->isMutable()
2224  *      2:      is modifiable, because this is a part of initializing.
2225  */
2226 
checkModifiable(Scope *,int)2227 int Expression::checkModifiable(Scope *, int)
2228 {
2229     return type ? 1 : 0;    // default modifiable
2230 }
2231 
modifiableLvalue(Scope * sc,Expression * e)2232 Expression *Expression::modifiableLvalue(Scope *sc, Expression *e)
2233 {
2234     //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars());
2235 
2236     // See if this expression is a modifiable lvalue (i.e. not const)
2237     if (checkModifiable(sc) == 1)
2238     {
2239         assert(type);
2240         if (!type->isMutable())
2241         {
2242             error("cannot modify %s expression %s", MODtoChars(type->mod), toChars());
2243             return new ErrorExp();
2244         }
2245         else if (!type->isAssignable())
2246         {
2247             error("cannot modify struct %s %s with immutable members", toChars(), type->toChars());
2248             return new ErrorExp();
2249         }
2250     }
2251     return toLvalue(sc, e);
2252 }
2253 
2254 /****************************************
2255  * Check that the expression has a valid type.
2256  * If not, generates an error "... has no type".
2257  * Returns:
2258  *      true if the expression is not valid.
2259  * Note:
2260  *      When this function returns true, `checkValue()` should also return true.
2261  */
checkType()2262 bool Expression::checkType()
2263 {
2264     return false;
2265 }
2266 
2267 /****************************************
2268  * Check that the expression has a valid value.
2269  * If not, generates an error "... has no value".
2270  * Returns:
2271  *      true if the expression is not valid or has void type.
2272  */
checkValue()2273 bool Expression::checkValue()
2274 {
2275     if (type && type->toBasetype()->ty == Tvoid)
2276     {
2277         error("expression %s is void and has no value", toChars());
2278         //print(); halt();
2279         if (!global.gag)
2280             type = Type::terror;
2281         return true;
2282     }
2283     return false;
2284 }
2285 
checkScalar()2286 bool Expression::checkScalar()
2287 {
2288     if (op == TOKerror)
2289         return true;
2290     if (type->toBasetype()->ty == Terror)
2291         return true;
2292     if (!type->isscalar())
2293     {
2294         error("'%s' is not a scalar, it is a %s", toChars(), type->toChars());
2295         return true;
2296     }
2297     return checkValue();
2298 }
2299 
checkNoBool()2300 bool Expression::checkNoBool()
2301 {
2302     if (op == TOKerror)
2303         return true;
2304     if (type->toBasetype()->ty == Terror)
2305         return true;
2306     if (type->toBasetype()->ty == Tbool)
2307     {
2308         error("operation not allowed on bool '%s'", toChars());
2309         return true;
2310     }
2311     return false;
2312 }
2313 
checkIntegral()2314 bool Expression::checkIntegral()
2315 {
2316     if (op == TOKerror)
2317         return true;
2318     if (type->toBasetype()->ty == Terror)
2319         return true;
2320     if (!type->isintegral())
2321     {
2322         error("'%s' is not of integral type, it is a %s", toChars(), type->toChars());
2323         return true;
2324     }
2325     return checkValue();
2326 }
2327 
checkArithmetic()2328 bool Expression::checkArithmetic()
2329 {
2330     if (op == TOKerror)
2331         return true;
2332     if (type->toBasetype()->ty == Terror)
2333         return true;
2334     if (!type->isintegral() && !type->isfloating())
2335     {
2336         error("'%s' is not of arithmetic type, it is a %s", toChars(), type->toChars());
2337         return true;
2338     }
2339     return checkValue();
2340 }
2341 
checkDeprecated(Scope * sc,Dsymbol * s)2342 void Expression::checkDeprecated(Scope *sc, Dsymbol *s)
2343 {
2344     s->checkDeprecated(loc, sc);
2345 }
2346 
2347 /*********************************************
2348  * Calling function f.
2349  * Check the purity, i.e. if we're in a pure function
2350  * we can only call other pure functions.
2351  * Returns true if error occurs.
2352  */
checkPurity(Scope * sc,FuncDeclaration * f)2353 bool Expression::checkPurity(Scope *sc, FuncDeclaration *f)
2354 {
2355     if (!sc->func)
2356         return false;
2357     if (sc->func == f)
2358         return false;
2359     if (sc->intypeof == 1)
2360         return false;
2361     if (sc->flags & (SCOPEctfe | SCOPEdebug))
2362         return false;
2363 
2364     /* Given:
2365      * void f() {
2366      *   pure void g() {
2367      *     /+pure+/ void h() {
2368      *       /+pure+/ void i() { }
2369      *     }
2370      *   }
2371      * }
2372      * g() can call h() but not f()
2373      * i() can call h() and g() but not f()
2374      */
2375 
2376     // Find the closest pure parent of the calling function
2377     FuncDeclaration *outerfunc = sc->func;
2378     FuncDeclaration *calledparent = f;
2379 
2380     if (outerfunc->isInstantiated())
2381     {
2382         // The attributes of outerfunc should be inferred from the call of f.
2383     }
2384     else if (f->isInstantiated())
2385     {
2386         // The attributes of f are inferred from its body.
2387     }
2388     else if (f->isFuncLiteralDeclaration())
2389     {
2390         // The attributes of f are always inferred in its declared place.
2391     }
2392     else
2393     {
2394         /* Today, static local functions are impure by default, but they cannot
2395          * violate purity of enclosing functions.
2396          *
2397          *  auto foo() pure {      // non instantiated funciton
2398          *    static auto bar() {  // static, without pure attribute
2399          *      impureFunc();      // impure call
2400          *      // Although impureFunc is called inside bar, f(= impureFunc)
2401          *      // is not callable inside pure outerfunc(= foo <- bar).
2402          *    }
2403          *
2404          *    bar();
2405          *    // Although bar is called inside foo, f(= bar) is callable
2406          *    // bacause calledparent(= foo) is same with outerfunc(= foo).
2407          *  }
2408          */
2409 
2410         while (outerfunc->toParent2() &&
2411                outerfunc->isPureBypassingInference() == PUREimpure &&
2412                outerfunc->toParent2()->isFuncDeclaration())
2413         {
2414             outerfunc = outerfunc->toParent2()->isFuncDeclaration();
2415             if (outerfunc->type->ty == Terror)
2416                 return true;
2417         }
2418         while (calledparent->toParent2() &&
2419                calledparent->isPureBypassingInference() == PUREimpure &&
2420                calledparent->toParent2()->isFuncDeclaration())
2421         {
2422             calledparent = calledparent->toParent2()->isFuncDeclaration();
2423             if (calledparent->type->ty == Terror)
2424                 return true;
2425         }
2426     }
2427 
2428     // If the caller has a pure parent, then either the called func must be pure,
2429     // OR, they must have the same pure parent.
2430     if (!f->isPure() && calledparent != outerfunc)
2431     {
2432         FuncDeclaration *ff = outerfunc;
2433         if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
2434         {
2435             error("pure %s '%s' cannot call impure %s '%s'",
2436                 ff->kind(), ff->toPrettyChars(), f->kind(), f->toPrettyChars());
2437             return true;
2438         }
2439     }
2440     return false;
2441 }
2442 
2443 /*******************************************
2444  * Accessing variable v.
2445  * Check for purity and safety violations.
2446  * Returns true if error occurs.
2447  */
checkPurity(Scope * sc,VarDeclaration * v)2448 bool Expression::checkPurity(Scope *sc, VarDeclaration *v)
2449 {
2450     //printf("v = %s %s\n", v->type->toChars(), v->toChars());
2451 
2452     /* Look for purity and safety violations when accessing variable v
2453      * from current function.
2454      */
2455     if (!sc->func)
2456         return false;
2457     if (sc->intypeof == 1)
2458         return false;   // allow violations inside typeof(expression)
2459     if (sc->flags & (SCOPEctfe | SCOPEdebug))
2460         return false;   // allow violations inside compile-time evaluated expressions and debug conditionals
2461     if (v->ident == Id::ctfe)
2462         return false;   // magic variable never violates pure and safe
2463     if (v->isImmutable())
2464         return false;   // always safe and pure to access immutables...
2465     if (v->isConst() && !v->isRef() && (v->isDataseg() || v->isParameter()) &&
2466         v->type->implicitConvTo(v->type->immutableOf()))
2467         return false;   // or const global/parameter values which have no mutable indirections
2468     if (v->storage_class & STCmanifest)
2469         return false;   // ...or manifest constants
2470 
2471     bool err = false;
2472     if (v->isDataseg())
2473     {
2474         // Bugzilla 7533: Accessing implicit generated __gate is pure.
2475         if (v->ident == Id::gate)
2476             return false;
2477 
2478         /* Accessing global mutable state.
2479          * Therefore, this function and all its immediately enclosing
2480          * functions must be pure.
2481          */
2482         /* Today, static local functions are impure by default, but they cannot
2483          * violate purity of enclosing functions.
2484          *
2485          *  auto foo() pure {      // non instantiated funciton
2486          *    static auto bar() {  // static, without pure attribute
2487          *      globalData++;      // impure access
2488          *      // Although globalData is accessed inside bar,
2489          *      // it is not accessible inside pure foo.
2490          *    }
2491          *  }
2492          */
2493         for (Dsymbol *s = sc->func; s; s = s->toParent2())
2494         {
2495             FuncDeclaration *ff = s->isFuncDeclaration();
2496             if (!ff)
2497                 break;
2498             if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
2499             {
2500                 error("pure %s '%s' cannot access mutable static data '%s'",
2501                     ff->kind(), ff->toPrettyChars(), v->toChars());
2502                 err = true;
2503                 break;
2504             }
2505             /* If the enclosing is an instantiated function or a lambda, its
2506              * attribute inference result is preferred.
2507              */
2508             if (ff->isInstantiated())
2509                 break;
2510             if (ff->isFuncLiteralDeclaration())
2511                 break;
2512         }
2513     }
2514     else
2515     {
2516         /* Given:
2517          * void f() {
2518          *   int fx;
2519          *   pure void g() {
2520          *     int gx;
2521          *     /+pure+/ void h() {
2522          *       int hx;
2523          *       /+pure+/ void i() { }
2524          *     }
2525          *   }
2526          * }
2527          * i() can modify hx and gx but not fx
2528          */
2529 
2530         Dsymbol *vparent = v->toParent2();
2531         for (Dsymbol *s = sc->func; !err && s; s = s->toParent2())
2532         {
2533             if (s == vparent)
2534                 break;
2535 
2536             if (AggregateDeclaration *ad = s->isAggregateDeclaration())
2537             {
2538                 if (ad->isNested())
2539                     continue;
2540                 break;
2541             }
2542             FuncDeclaration *ff = s->isFuncDeclaration();
2543             if (!ff)
2544                 break;
2545             if (ff->isNested() || ff->isThis())
2546             {
2547                 if (ff->type->isImmutable() ||
2548                     (ff->type->isShared() && !MODimplicitConv(ff->type->mod, v->type->mod)))
2549                 {
2550                     OutBuffer ffbuf;
2551                     OutBuffer vbuf;
2552                     MODMatchToBuffer(&ffbuf, ff->type->mod, v->type->mod);
2553                     MODMatchToBuffer(&vbuf, v->type->mod, ff->type->mod);
2554                     error("%s%s '%s' cannot access %sdata '%s'",
2555                         ffbuf.peekString(), ff->kind(), ff->toPrettyChars(), vbuf.peekString(), v->toChars());
2556                     err = true;
2557                     break;
2558                 }
2559                 continue;
2560             }
2561             break;
2562         }
2563     }
2564 
2565     /* Do not allow safe functions to access __gshared data
2566      */
2567     if (v->storage_class & STCgshared)
2568     {
2569         if (sc->func->setUnsafe())
2570         {
2571             error("safe %s '%s' cannot access __gshared data '%s'",
2572                 sc->func->kind(), sc->func->toChars(), v->toChars());
2573             err = true;
2574         }
2575     }
2576 
2577     return err;
2578 }
2579 
2580 /*********************************************
2581  * Calling function f.
2582  * Check the safety, i.e. if we're in a @safe function
2583  * we can only call @safe or @trusted functions.
2584  * Returns true if error occurs.
2585  */
checkSafety(Scope * sc,FuncDeclaration * f)2586 bool Expression::checkSafety(Scope *sc, FuncDeclaration *f)
2587 {
2588     if (!sc->func)
2589         return false;
2590     if (sc->func == f)
2591         return false;
2592     if (sc->intypeof == 1)
2593         return false;
2594     if (sc->flags & SCOPEctfe)
2595         return false;
2596 
2597     if (!f->isSafe() && !f->isTrusted())
2598     {
2599         if (sc->flags & SCOPEcompile ? sc->func->isSafeBypassingInference() : sc->func->setUnsafe())
2600         {
2601             if (loc.linnum == 0)  // e.g. implicitly generated dtor
2602                 loc = sc->func->loc;
2603 
2604             error("@safe %s '%s' cannot call @system %s '%s'",
2605                 sc->func->kind(), sc->func->toPrettyChars(), f->kind(), f->toPrettyChars());
2606             return true;
2607         }
2608     }
2609     return false;
2610 }
2611 
2612 /*********************************************
2613  * Calling function f.
2614  * Check the @nogc-ness, i.e. if we're in a @nogc function
2615  * we can only call other @nogc functions.
2616  * Returns true if error occurs.
2617  */
checkNogc(Scope * sc,FuncDeclaration * f)2618 bool Expression::checkNogc(Scope *sc, FuncDeclaration *f)
2619 {
2620     if (!sc->func)
2621         return false;
2622     if (sc->func == f)
2623         return false;
2624     if (sc->intypeof == 1)
2625         return false;
2626     if (sc->flags & SCOPEctfe)
2627         return false;
2628 
2629     if (!f->isNogc())
2630     {
2631         if (sc->flags & SCOPEcompile ? sc->func->isNogcBypassingInference() : sc->func->setGC())
2632         {
2633             if (loc.linnum == 0)  // e.g. implicitly generated dtor
2634                 loc = sc->func->loc;
2635 
2636             error("@nogc %s '%s' cannot call non-@nogc %s '%s'",
2637                 sc->func->kind(), sc->func->toPrettyChars(), f->kind(), f->toPrettyChars());
2638             return true;
2639         }
2640     }
2641     return false;
2642 }
2643 
2644 /********************************************
2645  * Check that the postblit is callable if t is an array of structs.
2646  * Returns true if error happens.
2647  */
checkPostblit(Scope * sc,Type * t)2648 bool Expression::checkPostblit(Scope *sc, Type *t)
2649 {
2650     t = t->baseElemOf();
2651     if (t->ty == Tstruct)
2652     {
2653         if (global.params.useTypeInfo && Type::dtypeinfo)
2654         {
2655             // Bugzilla 11395: Require TypeInfo generation for array concatenation
2656             semanticTypeInfo(sc, t);
2657         }
2658 
2659         StructDeclaration *sd = ((TypeStruct *)t)->sym;
2660         if (sd->postblit)
2661         {
2662             if (sd->postblit->storage_class & STCdisable)
2663             {
2664                 sd->error(loc, "is not copyable because it is annotated with @disable");
2665                 return true;
2666             }
2667             //checkDeprecated(sc, sd->postblit);        // necessary?
2668             checkPurity(sc, sd->postblit);
2669             checkSafety(sc, sd->postblit);
2670             checkNogc(sc, sd->postblit);
2671             //checkAccess(sd, loc, sc, sd->postblit);   // necessary?
2672             return false;
2673         }
2674     }
2675     return false;
2676 }
2677 
checkRightThis(Scope * sc)2678 bool Expression::checkRightThis(Scope *sc)
2679 {
2680     if (op == TOKerror)
2681         return true;
2682     if (op == TOKvar && type->ty != Terror)
2683     {
2684         VarExp *ve = (VarExp *)this;
2685         if (isNeedThisScope(sc, ve->var))
2686         {
2687             //printf("checkRightThis sc->intypeof = %d, ad = %p, func = %p, fdthis = %p\n",
2688             //        sc->intypeof, sc->getStructClassScope(), func, fdthis);
2689             error("need 'this' for '%s' of type '%s'", ve->var->toChars(), ve->var->type->toChars());
2690             return true;
2691         }
2692     }
2693     return false;
2694 }
2695 
2696 /*******************************
2697  * Check whether the expression allows RMW operations, error with rmw operator diagnostic if not.
2698  * ex is the RHS expression, or NULL if ++/-- is used (for diagnostics)
2699  * Returns true if error occurs.
2700  */
checkReadModifyWrite(TOK rmwOp,Expression * ex)2701 bool Expression::checkReadModifyWrite(TOK rmwOp, Expression *ex)
2702 {
2703     //printf("Expression::checkReadModifyWrite() %s %s", toChars(), ex ? ex->toChars() : "");
2704     if (!type || !type->isShared())
2705         return false;
2706 
2707     // atomicOp uses opAssign (+=/-=) rather than opOp (++/--) for the CT string literal.
2708     switch (rmwOp)
2709     {
2710         case TOKplusplus:
2711         case TOKpreplusplus:
2712             rmwOp = TOKaddass;
2713             break;
2714 
2715         case TOKminusminus:
2716         case TOKpreminusminus:
2717             rmwOp = TOKminass;
2718             break;
2719 
2720         default:
2721             break;
2722     }
2723 
2724     deprecation("read-modify-write operations are not allowed for shared variables. "
2725                 "Use core.atomic.atomicOp!\"%s\"(%s, %s) instead.",
2726                 Token::tochars[rmwOp], toChars(), ex ? ex->toChars() : "1");
2727     return false;
2728 
2729     // note: enable when deprecation becomes an error.
2730     // return true;
2731 }
2732 
2733 /*****************************
2734  * If expression can be tested for true or false,
2735  * returns the modified expression.
2736  * Otherwise returns ErrorExp.
2737  */
toBoolean(Scope * sc)2738 Expression *Expression::toBoolean(Scope *sc)
2739 {
2740     // Default is 'yes' - do nothing
2741     Expression *e = this;
2742     Type *t = type;
2743     Type *tb = type->toBasetype();
2744     Type *att = NULL;
2745 Lagain:
2746     // Structs can be converted to bool using opCast(bool)()
2747     if (tb->ty == Tstruct)
2748     {
2749         AggregateDeclaration *ad = ((TypeStruct *)tb)->sym;
2750         /* Don't really need to check for opCast first, but by doing so we
2751          * get better error messages if it isn't there.
2752          */
2753         Dsymbol *fd = search_function(ad, Id::_cast);
2754         if (fd)
2755         {
2756             e = new CastExp(loc, e, Type::tbool);
2757             e = semantic(e, sc);
2758             return e;
2759         }
2760 
2761         // Forward to aliasthis.
2762         if (ad->aliasthis && tb != att)
2763         {
2764             if (!att && tb->checkAliasThisRec())
2765                 att = tb;
2766             e = resolveAliasThis(sc, e);
2767             t = e->type;
2768             tb = e->type->toBasetype();
2769             goto Lagain;
2770         }
2771     }
2772 
2773     if (!t->isBoolean())
2774     {
2775         if (tb != Type::terror)
2776             error("expression %s of type %s does not have a boolean value", toChars(), t->toChars());
2777         return new ErrorExp();
2778     }
2779     return e;
2780 }
2781 
2782 /******************************
2783  * Take address of expression.
2784  */
2785 
addressOf()2786 Expression *Expression::addressOf()
2787 {
2788     //printf("Expression::addressOf()\n");
2789     Expression *e = new AddrExp(loc, this);
2790     e->type = type->pointerTo();
2791     return e;
2792 }
2793 
2794 /******************************
2795  * If this is a reference, dereference it.
2796  */
2797 
deref()2798 Expression *Expression::deref()
2799 {
2800     //printf("Expression::deref()\n");
2801     // type could be null if forward referencing an 'auto' variable
2802     if (type && type->ty == Treference)
2803     {
2804         Expression *e = new PtrExp(loc, this);
2805         e->type = ((TypeReference *)type)->next;
2806         return e;
2807     }
2808     return this;
2809 }
2810 
2811 /********************************
2812  * Does this expression statically evaluate to a boolean 'result' (true or false)?
2813  */
isBool(bool)2814 bool Expression::isBool(bool)
2815 {
2816     return false;
2817 }
2818 
2819 /****************************************
2820  * Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__ to loc.
2821  */
2822 
resolveLoc(Loc,Scope *)2823 Expression *Expression::resolveLoc(Loc, Scope *)
2824 {
2825     return this;
2826 }
2827 
arraySyntaxCopy(Expressions * exps)2828 Expressions *Expression::arraySyntaxCopy(Expressions *exps)
2829 {
2830     Expressions *a = NULL;
2831     if (exps)
2832     {
2833         a = new Expressions();
2834         a->setDim(exps->dim);
2835         for (size_t i = 0; i < a->dim; i++)
2836         {
2837             Expression *e = (*exps)[i];
2838             (*a)[i] = e ? e->syntaxCopy() : NULL;
2839         }
2840     }
2841     return a;
2842 }
2843 
2844 /************************************************
2845  * Destructors are attached to VarDeclarations.
2846  * Hence, if expression returns a temp that needs a destructor,
2847  * make sure and create a VarDeclaration for that temp.
2848  */
2849 
addDtorHook(Scope *)2850 Expression *Expression::addDtorHook(Scope *)
2851 {
2852     return this;
2853 }
2854 
2855 /******************************** IntegerExp **************************/
2856 
IntegerExp(Loc loc,dinteger_t value,Type * type)2857 IntegerExp::IntegerExp(Loc loc, dinteger_t value, Type *type)
2858         : Expression(loc, TOKint64, sizeof(IntegerExp))
2859 {
2860     //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : "");
2861     assert(type);
2862     if (!type->isscalar())
2863     {
2864         //printf("%s, loc = %d\n", toChars(), loc.linnum);
2865         if (type->ty != Terror)
2866             error("integral constant must be scalar type, not %s", type->toChars());
2867         type = Type::terror;
2868     }
2869     this->type = type;
2870     setInteger(value);
2871 }
2872 
IntegerExp(dinteger_t value)2873 IntegerExp::IntegerExp(dinteger_t value)
2874         : Expression(Loc(), TOKint64, sizeof(IntegerExp))
2875 {
2876     this->type = Type::tint32;
2877     this->value = (d_int32) value;
2878 }
2879 
create(Loc loc,dinteger_t value,Type * type)2880 IntegerExp *IntegerExp::create(Loc loc, dinteger_t value, Type *type)
2881 {
2882     return new IntegerExp(loc, value, type);
2883 }
2884 
equals(RootObject * o)2885 bool IntegerExp::equals(RootObject *o)
2886 {
2887     if (this == o)
2888         return true;
2889     if (((Expression *)o)->op == TOKint64)
2890     {
2891         IntegerExp *ne = (IntegerExp *)o;
2892         if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
2893             value == ne->value)
2894         {
2895             return true;
2896         }
2897     }
2898     return false;
2899 }
2900 
setInteger(dinteger_t value)2901 void IntegerExp::setInteger(dinteger_t value)
2902 {
2903     this->value = value;
2904     normalize();
2905 }
2906 
normalize()2907 void IntegerExp::normalize()
2908 {
2909     /* 'Normalize' the value of the integer to be in range of the type
2910      */
2911     switch (type->toBasetype()->ty)
2912     {
2913         case Tbool:         value = (value != 0);           break;
2914         case Tint8:         value = (d_int8)  value;        break;
2915         case Tchar:
2916         case Tuns8:         value = (d_uns8)  value;        break;
2917         case Tint16:        value = (d_int16) value;        break;
2918         case Twchar:
2919         case Tuns16:        value = (d_uns16) value;        break;
2920         case Tint32:        value = (d_int32) value;        break;
2921         case Tdchar:
2922         case Tuns32:        value = (d_uns32) value;        break;
2923         case Tint64:        value = (d_int64) value;        break;
2924         case Tuns64:        value = (d_uns64) value;        break;
2925         case Tpointer:
2926             if (Target::ptrsize == 8)
2927                 value = (d_uns64) value;
2928             else if (Target::ptrsize == 4)
2929                 value = (d_uns32) value;
2930             else if (Target::ptrsize == 2)
2931                 value = (d_uns16) value;
2932             else
2933                 assert(0);
2934             break;
2935         default:
2936             break;
2937     }
2938 }
2939 
toInteger()2940 dinteger_t IntegerExp::toInteger()
2941 {
2942     normalize();   // necessary until we fix all the paints of 'type'
2943     return value;
2944 }
2945 
toReal()2946 real_t IntegerExp::toReal()
2947 {
2948     normalize();   // necessary until we fix all the paints of 'type'
2949     Type *t = type->toBasetype();
2950     if (t->ty == Tuns64)
2951         return ldouble((d_uns64)value);
2952     else
2953         return ldouble((d_int64)value);
2954 }
2955 
toImaginary()2956 real_t IntegerExp::toImaginary()
2957 {
2958     return CTFloat::zero;
2959 }
2960 
toComplex()2961 complex_t IntegerExp::toComplex()
2962 {
2963     return (complex_t)toReal();
2964 }
2965 
isBool(bool result)2966 bool IntegerExp::isBool(bool result)
2967 {
2968     bool r = toInteger() != 0;
2969     return result ? r : !r;
2970 }
2971 
toLvalue(Scope *,Expression * e)2972 Expression *IntegerExp::toLvalue(Scope *, Expression *e)
2973 {
2974     if (!e)
2975         e = this;
2976     else if (!loc.filename)
2977         loc = e->loc;
2978     e->error("constant %s is not an lvalue", e->toChars());
2979     return new ErrorExp();
2980 }
2981 
2982 /******************************** ErrorExp **************************/
2983 
2984 /* Use this expression for error recovery.
2985  * It should behave as a 'sink' to prevent further cascaded error messages.
2986  */
2987 
ErrorExp()2988 ErrorExp::ErrorExp()
2989     : Expression(Loc(), TOKerror, sizeof(ErrorExp))
2990 {
2991     type = Type::terror;
2992 }
2993 
toLvalue(Scope *,Expression *)2994 Expression *ErrorExp::toLvalue(Scope *, Expression *)
2995 {
2996     return this;
2997 }
2998 
2999 /******************************** RealExp **************************/
3000 
RealExp(Loc loc,real_t value,Type * type)3001 RealExp::RealExp(Loc loc, real_t value, Type *type)
3002         : Expression(loc, TOKfloat64, sizeof(RealExp))
3003 {
3004     //printf("RealExp::RealExp(%Lg)\n", value);
3005     this->value = value;
3006     this->type = type;
3007 }
3008 
create(Loc loc,real_t value,Type * type)3009 RealExp *RealExp::create(Loc loc, real_t value, Type *type)
3010 {
3011     return new RealExp(loc, value,type);
3012 }
3013 
toInteger()3014 dinteger_t RealExp::toInteger()
3015 {
3016     return (sinteger_t) toReal();
3017 }
3018 
toUInteger()3019 uinteger_t RealExp::toUInteger()
3020 {
3021     return (uinteger_t) toReal();
3022 }
3023 
toReal()3024 real_t RealExp::toReal()
3025 {
3026     return type->isreal() ? value : CTFloat::zero;
3027 }
3028 
toImaginary()3029 real_t RealExp::toImaginary()
3030 {
3031     return type->isreal() ? CTFloat::zero : value;
3032 }
3033 
toComplex()3034 complex_t RealExp::toComplex()
3035 {
3036     return complex_t(toReal(), toImaginary());
3037 }
3038 
3039 /********************************
3040  * Test to see if two reals are the same.
3041  * Regard NaN's as equivalent.
3042  * Regard +0 and -0 as different.
3043  */
3044 
RealEquals(real_t x1,real_t x2)3045 int RealEquals(real_t x1, real_t x2)
3046 {
3047     return (CTFloat::isNaN(x1) && CTFloat::isNaN(x2)) ||
3048         CTFloat::isIdentical(x1, x2);
3049 }
3050 
equals(RootObject * o)3051 bool RealExp::equals(RootObject *o)
3052 {
3053     if (this == o)
3054         return true;
3055     if (((Expression *)o)->op == TOKfloat64)
3056     {
3057         RealExp *ne = (RealExp *)o;
3058         if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
3059             RealEquals(value, ne->value))
3060         {
3061             return true;
3062         }
3063     }
3064     return false;
3065 }
3066 
isBool(bool result)3067 bool RealExp::isBool(bool result)
3068 {
3069     return result ? (bool)value : !(bool)value;
3070 }
3071 
3072 /******************************** ComplexExp **************************/
3073 
ComplexExp(Loc loc,complex_t value,Type * type)3074 ComplexExp::ComplexExp(Loc loc, complex_t value, Type *type)
3075         : Expression(loc, TOKcomplex80, sizeof(ComplexExp)), value(value)
3076 {
3077     this->type = type;
3078     //printf("ComplexExp::ComplexExp(%s)\n", toChars());
3079 }
3080 
create(Loc loc,complex_t value,Type * type)3081 ComplexExp *ComplexExp::create(Loc loc, complex_t value, Type *type)
3082 {
3083     return new ComplexExp(loc, value, type);
3084 }
3085 
toInteger()3086 dinteger_t ComplexExp::toInteger()
3087 {
3088     return (sinteger_t) toReal();
3089 }
3090 
toUInteger()3091 uinteger_t ComplexExp::toUInteger()
3092 {
3093     return (uinteger_t) toReal();
3094 }
3095 
toReal()3096 real_t ComplexExp::toReal()
3097 {
3098     return creall(value);
3099 }
3100 
toImaginary()3101 real_t ComplexExp::toImaginary()
3102 {
3103     return cimagl(value);
3104 }
3105 
toComplex()3106 complex_t ComplexExp::toComplex()
3107 {
3108     return value;
3109 }
3110 
equals(RootObject * o)3111 bool ComplexExp::equals(RootObject *o)
3112 {
3113     if (this == o)
3114         return true;
3115     if (((Expression *)o)->op == TOKcomplex80)
3116     {
3117         ComplexExp *ne = (ComplexExp *)o;
3118         if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
3119             RealEquals(creall(value), creall(ne->value)) &&
3120             RealEquals(cimagl(value), cimagl(ne->value)))
3121         {
3122             return true;
3123         }
3124     }
3125     return false;
3126 }
3127 
isBool(bool result)3128 bool ComplexExp::isBool(bool result)
3129 {
3130     if (result)
3131         return (bool)(value);
3132     else
3133         return !value;
3134 }
3135 
3136 /******************************** IdentifierExp **************************/
3137 
IdentifierExp(Loc loc,Identifier * ident)3138 IdentifierExp::IdentifierExp(Loc loc, Identifier *ident)
3139         : Expression(loc, TOKidentifier, sizeof(IdentifierExp))
3140 {
3141     this->ident = ident;
3142 }
3143 
create(Loc loc,Identifier * ident)3144 IdentifierExp *IdentifierExp::create(Loc loc, Identifier *ident)
3145 {
3146     return new IdentifierExp(loc, ident);
3147 }
3148 
isLvalue()3149 bool IdentifierExp::isLvalue()
3150 {
3151     return true;
3152 }
3153 
toLvalue(Scope *,Expression *)3154 Expression *IdentifierExp::toLvalue(Scope *, Expression *)
3155 {
3156     return this;
3157 }
3158 
3159 /******************************** DollarExp **************************/
3160 
DollarExp(Loc loc)3161 DollarExp::DollarExp(Loc loc)
3162         : IdentifierExp(loc, Id::dollar)
3163 {
3164 }
3165 
3166 /******************************** DsymbolExp **************************/
3167 
DsymbolExp(Loc loc,Dsymbol * s,bool hasOverloads)3168 DsymbolExp::DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads)
3169         : Expression(loc, TOKdsymbol, sizeof(DsymbolExp))
3170 {
3171     this->s = s;
3172     this->hasOverloads = hasOverloads;
3173 }
3174 
3175 /****************************************
3176  * Resolve a symbol `s` and wraps it in an expression object.
3177  * Params:
3178  *      hasOverloads = works if the aliased symbol is a function.
3179  *          true:  it's overloaded and will be resolved later.
3180  *          false: it's exact function symbol.
3181  */
resolve(Loc loc,Scope * sc,Dsymbol * s,bool hasOverloads)3182 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads)
3183 {
3184 Lagain:
3185     Expression *e;
3186 
3187     //printf("DsymbolExp:: %p '%s' is a symbol\n", this, toChars());
3188     //printf("s = '%s', s->kind = '%s'\n", s->toChars(), s->kind());
3189     Dsymbol *olds = s;
3190     Declaration *d = s->isDeclaration();
3191     if (d && (d->storage_class & STCtemplateparameter))
3192     {
3193         s = s->toAlias();
3194     }
3195     else
3196     {
3197         if (!s->isFuncDeclaration())        // functions are checked after overloading
3198             s->checkDeprecated(loc, sc);
3199 
3200         // Bugzilla 12023: if 's' is a tuple variable, the tuple is returned.
3201         s = s->toAlias();
3202 
3203         //printf("s = '%s', s->kind = '%s', s->needThis() = %p\n", s->toChars(), s->kind(), s->needThis());
3204         if (s != olds && !s->isFuncDeclaration())
3205             s->checkDeprecated(loc, sc);
3206     }
3207 
3208     if (EnumMember *em = s->isEnumMember())
3209     {
3210         return em->getVarExp(loc, sc);
3211     }
3212     if (VarDeclaration *v = s->isVarDeclaration())
3213     {
3214         //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
3215         if (!v->type ||                    // during variable type inference
3216             (!v->type->deco && v->inuse))  // during variable type semantic
3217         {
3218             if (v->inuse)    // variable type depends on the variable itself
3219                 ::error(loc, "circular reference to %s '%s'", v->kind(), v->toPrettyChars());
3220             else             // variable type cannot be determined
3221                 ::error(loc, "forward reference to %s '%s'", v->kind(), v->toPrettyChars());
3222             return new ErrorExp();
3223         }
3224         if (v->type->ty == Terror)
3225             return new ErrorExp();
3226 
3227         if ((v->storage_class & STCmanifest) && v->_init)
3228         {
3229             if (v->inuse)
3230             {
3231                 ::error(loc, "circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
3232                 return new ErrorExp();
3233             }
3234 
3235             e = v->expandInitializer(loc);
3236             v->inuse++;
3237             e = semantic(e, sc);
3238             v->inuse--;
3239             return e;
3240         }
3241 
3242         // Change the ancestor lambdas to delegate before hasThis(sc) call.
3243         if (v->checkNestedReference(sc, loc))
3244             return new ErrorExp();
3245 
3246         if (v->needThis() && hasThis(sc))
3247             e = new DotVarExp(loc, new ThisExp(loc), v);
3248         else
3249             e = new VarExp(loc, v);
3250         e = semantic(e, sc);
3251         return e;
3252     }
3253     if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
3254     {
3255         //printf("'%s' is a function literal\n", fld->toChars());
3256         e = new FuncExp(loc, fld);
3257         return semantic(e, sc);
3258     }
3259     if (FuncDeclaration *f = s->isFuncDeclaration())
3260     {
3261         f = f->toAliasFunc();
3262         if (!f->functionSemantic())
3263             return new ErrorExp();
3264 
3265         if (!hasOverloads && f->checkForwardRef(loc))
3266             return new ErrorExp();
3267 
3268         FuncDeclaration *fd = s->isFuncDeclaration();
3269         fd->type = f->type;
3270         return new VarExp(loc, fd, hasOverloads);
3271     }
3272     if (OverDeclaration *od = s->isOverDeclaration())
3273     {
3274         e = new VarExp(loc, od, true);
3275         e->type = Type::tvoid;
3276         return e;
3277     }
3278     if (OverloadSet *o = s->isOverloadSet())
3279     {
3280         //printf("'%s' is an overload set\n", o->toChars());
3281         return new OverExp(loc, o);
3282     }
3283 
3284     if (Import *imp = s->isImport())
3285     {
3286         if (!imp->pkg)
3287         {
3288             ::error(loc, "forward reference of import %s", imp->toChars());
3289             return new ErrorExp();
3290         }
3291         ScopeExp *ie = new ScopeExp(loc, imp->pkg);
3292         return semantic(ie, sc);
3293     }
3294     if (Package *pkg = s->isPackage())
3295     {
3296         ScopeExp *ie = new ScopeExp(loc, pkg);
3297         return semantic(ie, sc);
3298     }
3299     if (Module *mod = s->isModule())
3300     {
3301         ScopeExp *ie = new ScopeExp(loc, mod);
3302         return semantic(ie, sc);
3303     }
3304 
3305     if (Nspace *ns = s->isNspace())
3306     {
3307         ScopeExp *ie = new ScopeExp(loc, ns);
3308         return semantic(ie, sc);
3309     }
3310 
3311     if (Type *t = s->getType())
3312     {
3313         return semantic(new TypeExp(loc, t), sc);
3314     }
3315 
3316     if (TupleDeclaration *tup = s->isTupleDeclaration())
3317     {
3318         if (tup->needThis() && hasThis(sc))
3319             e = new DotVarExp(loc, new ThisExp(loc), tup);
3320         else
3321             e = new TupleExp(loc, tup);
3322         e = semantic(e, sc);
3323         return e;
3324     }
3325 
3326     if (TemplateInstance *ti = s->isTemplateInstance())
3327     {
3328         ti->semantic(sc);
3329         if (!ti->inst || ti->errors)
3330             return new ErrorExp();
3331         s = ti->toAlias();
3332         if (!s->isTemplateInstance())
3333             goto Lagain;
3334         e = new ScopeExp(loc, ti);
3335         e = semantic(e, sc);
3336         return e;
3337     }
3338     if (TemplateDeclaration *td = s->isTemplateDeclaration())
3339     {
3340         Dsymbol *p = td->toParent2();
3341         FuncDeclaration *fdthis = hasThis(sc);
3342         AggregateDeclaration *ad = p ? p->isAggregateDeclaration() : NULL;
3343         if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad &&
3344             (td->_scope->stc & STCstatic) == 0)
3345         {
3346             e = new DotTemplateExp(loc, new ThisExp(loc), td);
3347         }
3348         else
3349             e = new TemplateExp(loc, td);
3350         e = semantic(e, sc);
3351         return e;
3352     }
3353 
3354     ::error(loc, "%s '%s' is not a variable", s->kind(), s->toChars());
3355     return new ErrorExp();
3356 }
3357 
isLvalue()3358 bool DsymbolExp::isLvalue()
3359 {
3360     return true;
3361 }
3362 
toLvalue(Scope *,Expression *)3363 Expression *DsymbolExp::toLvalue(Scope *, Expression *)
3364 {
3365     return this;
3366 }
3367 
3368 /******************************** ThisExp **************************/
3369 
ThisExp(Loc loc)3370 ThisExp::ThisExp(Loc loc)
3371         : Expression(loc, TOKthis, sizeof(ThisExp))
3372 {
3373     //printf("ThisExp::ThisExp() loc = %d\n", loc.linnum);
3374     var = NULL;
3375 }
3376 
isBool(bool result)3377 bool ThisExp::isBool(bool result)
3378 {
3379     return result ? true : false;
3380 }
3381 
isLvalue()3382 bool ThisExp::isLvalue()
3383 {
3384     // Class `this` should be an rvalue; struct `this` should be an lvalue.
3385     return type->toBasetype()->ty != Tclass;
3386 }
3387 
toLvalue(Scope * sc,Expression * e)3388 Expression *ThisExp::toLvalue(Scope *sc, Expression *e)
3389 {
3390     if (type->toBasetype()->ty == Tclass)
3391     {
3392         // Class `this` is an rvalue; struct `this` is an lvalue.
3393         return Expression::toLvalue(sc, e);
3394     }
3395     return this;
3396 }
3397 
3398 /******************************** SuperExp **************************/
3399 
SuperExp(Loc loc)3400 SuperExp::SuperExp(Loc loc)
3401         : ThisExp(loc)
3402 {
3403     op = TOKsuper;
3404 }
3405 
3406 /******************************** NullExp **************************/
3407 
NullExp(Loc loc,Type * type)3408 NullExp::NullExp(Loc loc, Type *type)
3409         : Expression(loc, TOKnull, sizeof(NullExp))
3410 {
3411     committed = 0;
3412     this->type = type;
3413 }
3414 
equals(RootObject * o)3415 bool NullExp::equals(RootObject *o)
3416 {
3417     if (o && o->dyncast() == DYNCAST_EXPRESSION)
3418     {
3419         Expression *e = (Expression *)o;
3420         if (e->op == TOKnull &&
3421             type->equals(e->type))
3422         {
3423             return true;
3424         }
3425     }
3426     return false;
3427 }
3428 
isBool(bool result)3429 bool NullExp::isBool(bool result)
3430 {
3431     return result ? false : true;
3432 }
3433 
toStringExp()3434 StringExp *NullExp::toStringExp()
3435 {
3436     if (implicitConvTo(Type::tstring))
3437     {
3438         StringExp *se = new StringExp(loc, (char*)mem.xcalloc(1, 1), 0);
3439         se->type = Type::tstring;
3440         return se;
3441     }
3442     return NULL;
3443 }
3444 
3445 /******************************** StringExp **************************/
3446 
StringExp(Loc loc,char * string)3447 StringExp::StringExp(Loc loc, char *string)
3448         : Expression(loc, TOKstring, sizeof(StringExp))
3449 {
3450     this->string = string;
3451     this->len = strlen(string);
3452     this->sz = 1;
3453     this->committed = 0;
3454     this->postfix = 0;
3455     this->ownedByCtfe = OWNEDcode;
3456 }
3457 
StringExp(Loc loc,void * string,size_t len)3458 StringExp::StringExp(Loc loc, void *string, size_t len)
3459         : Expression(loc, TOKstring, sizeof(StringExp))
3460 {
3461     this->string = string;
3462     this->len = len;
3463     this->sz = 1;
3464     this->committed = 0;
3465     this->postfix = 0;
3466     this->ownedByCtfe = OWNEDcode;
3467 }
3468 
StringExp(Loc loc,void * string,size_t len,utf8_t postfix)3469 StringExp::StringExp(Loc loc, void *string, size_t len, utf8_t postfix)
3470         : Expression(loc, TOKstring, sizeof(StringExp))
3471 {
3472     this->string = string;
3473     this->len = len;
3474     this->sz = 1;
3475     this->committed = 0;
3476     this->postfix = postfix;
3477     this->ownedByCtfe = OWNEDcode;
3478 }
3479 
create(Loc loc,char * s)3480 StringExp *StringExp::create(Loc loc, char *s)
3481 {
3482     return new StringExp(loc, s);
3483 }
3484 
create(Loc loc,void * string,size_t len)3485 StringExp *StringExp::create(Loc loc, void *string, size_t len)
3486 {
3487     return new StringExp(loc, string, len);
3488 }
3489 
equals(RootObject * o)3490 bool StringExp::equals(RootObject *o)
3491 {
3492     //printf("StringExp::equals('%s') %s\n", o->toChars(), toChars());
3493     if (o && o->dyncast() == DYNCAST_EXPRESSION)
3494     {
3495         Expression *e = (Expression *)o;
3496         if (e->op == TOKstring)
3497         {
3498             return compare(o) == 0;
3499         }
3500     }
3501     return false;
3502 }
3503 
3504 /**********************************
3505  * Return the number of code units the string would be if it were re-encoded
3506  * as tynto.
3507  * Params:
3508  *      tynto = code unit type of the target encoding
3509  * Returns:
3510  *      number of code units
3511  */
3512 
numberOfCodeUnits(int tynto)3513 size_t StringExp::numberOfCodeUnits(int tynto) const
3514 {
3515     int encSize;
3516     switch (tynto)
3517     {
3518         case 0:      return len;
3519         case Tchar:  encSize = 1; break;
3520         case Twchar: encSize = 2; break;
3521         case Tdchar: encSize = 4; break;
3522         default:
3523             assert(0);
3524     }
3525     if (sz == encSize)
3526         return len;
3527 
3528     size_t result = 0;
3529     dchar_t c;
3530 
3531     switch (sz)
3532     {
3533         case 1:
3534             for (size_t u = 0; u < len;)
3535             {
3536                 if (const char *p = utf_decodeChar((utf8_t *)string, len, &u, &c))
3537                 {
3538                     error("%s", p);
3539                     return 0;
3540                 }
3541                 result += utf_codeLength(encSize, c);
3542             }
3543             break;
3544 
3545         case 2:
3546             for (size_t u = 0; u < len;)
3547             {
3548                 if (const char *p = utf_decodeWchar((utf16_t *)string, len, &u, &c))
3549                 {
3550                     error("%s", p);
3551                     return 0;
3552                 }
3553                 result += utf_codeLength(encSize, c);
3554             }
3555             break;
3556 
3557         case 4:
3558             for (size_t u = 0; u < len;)
3559             {
3560                 c = *((utf32_t *)((char *)string + u));
3561                 u += 4;
3562                 result += utf_codeLength(encSize, c);
3563             }
3564             break;
3565 
3566         default:
3567             assert(0);
3568     }
3569     return result;
3570 }
3571 
3572 /**********************************************
3573  * Write the contents of the string to dest.
3574  * Use numberOfCodeUnits() to determine size of result.
3575  * Params:
3576  *  dest = destination
3577  *  tyto = encoding type of the result
3578  *  zero = add terminating 0
3579  */
writeTo(void * dest,bool zero,int tyto)3580 void StringExp::writeTo(void *dest, bool zero, int tyto) const
3581 {
3582     int encSize;
3583     switch (tyto)
3584     {
3585         case 0:      encSize = sz; break;
3586         case Tchar:  encSize = 1; break;
3587         case Twchar: encSize = 2; break;
3588         case Tdchar: encSize = 4; break;
3589         default:
3590             assert(0);
3591     }
3592     if (sz == encSize)
3593     {
3594         memcpy(dest, string, len * sz);
3595         if (zero)
3596             memset((char *)dest + len * sz, 0, sz);
3597     }
3598     else
3599         assert(0);
3600 }
3601 
3602 /**************************************************
3603  * If the string data is UTF-8 and can be accessed directly,
3604  * return a pointer to it.
3605  * Do not assume a terminating 0.
3606  * Returns:
3607  *  pointer to string data if possible, null if not
3608  */
toPtr()3609 char *StringExp::toPtr()
3610 {
3611     return (sz == 1) ? (char*)string : NULL;
3612 }
3613 
toStringExp()3614 StringExp *StringExp::toStringExp()
3615 {
3616     return this;
3617 }
3618 
3619 /****************************************
3620  * Convert string to char[].
3621  */
3622 
toUTF8(Scope * sc)3623 StringExp *StringExp::toUTF8(Scope *sc)
3624 {
3625     if (sz != 1)
3626     {   // Convert to UTF-8 string
3627         committed = 0;
3628         Expression *e = castTo(sc, Type::tchar->arrayOf());
3629         e = e->optimize(WANTvalue);
3630         assert(e->op == TOKstring);
3631         StringExp *se = (StringExp *)e;
3632         assert(se->sz == 1);
3633         return se;
3634     }
3635     return this;
3636 }
3637 
compare(RootObject * obj)3638 int StringExp::compare(RootObject *obj)
3639 {
3640     //printf("StringExp::compare()\n");
3641     // Used to sort case statement expressions so we can do an efficient lookup
3642     StringExp *se2 = (StringExp *)(obj);
3643 
3644     // This is a kludge so isExpression() in template.c will return 5
3645     // for StringExp's.
3646     if (!se2)
3647         return 5;
3648 
3649     assert(se2->op == TOKstring);
3650 
3651     size_t len1 = len;
3652     size_t len2 = se2->len;
3653 
3654     //printf("sz = %d, len1 = %d, len2 = %d\n", sz, (int)len1, (int)len2);
3655     if (len1 == len2)
3656     {
3657         switch (sz)
3658         {
3659             case 1:
3660                 return memcmp((char *)string, (char *)se2->string, len1);
3661 
3662             case 2:
3663             {
3664                 d_uns16 *s1 = (d_uns16 *)string;
3665                 d_uns16 *s2 = (d_uns16 *)se2->string;
3666 
3667                 for (size_t u = 0; u < len; u++)
3668                 {
3669                     if (s1[u] != s2[u])
3670                         return s1[u] - s2[u];
3671                 }
3672             }
3673             break;
3674 
3675             case 4:
3676             {
3677                 d_uns32 *s1 = (d_uns32 *)string;
3678                 d_uns32 *s2 = (d_uns32 *)se2->string;
3679 
3680                 for (size_t u = 0; u < len; u++)
3681                 {
3682                     if (s1[u] != s2[u])
3683                         return s1[u] - s2[u];
3684                 }
3685             }
3686             break;
3687 
3688             default:
3689                 assert(0);
3690         }
3691     }
3692     return (int)(len1 - len2);
3693 }
3694 
isBool(bool result)3695 bool StringExp::isBool(bool result)
3696 {
3697     return result ? true : false;
3698 }
3699 
3700 
isLvalue()3701 bool StringExp::isLvalue()
3702 {
3703     /* string literal is rvalue in default, but
3704      * conversion to reference of static array is only allowed.
3705      */
3706     return (type && type->toBasetype()->ty == Tsarray);
3707 }
3708 
toLvalue(Scope * sc,Expression * e)3709 Expression *StringExp::toLvalue(Scope *sc, Expression *e)
3710 {
3711     //printf("StringExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL);
3712     return (type && type->toBasetype()->ty == Tsarray)
3713             ? this : Expression::toLvalue(sc, e);
3714 }
3715 
modifiableLvalue(Scope *,Expression *)3716 Expression *StringExp::modifiableLvalue(Scope *, Expression *)
3717 {
3718     error("cannot modify string literal %s", toChars());
3719     return new ErrorExp();
3720 }
3721 
charAt(uinteger_t i)3722 unsigned StringExp::charAt(uinteger_t i) const
3723 {   unsigned value;
3724 
3725     switch (sz)
3726     {
3727         case 1:
3728             value = ((utf8_t *)string)[(size_t)i];
3729             break;
3730 
3731         case 2:
3732             value = ((unsigned short *)string)[(size_t)i];
3733             break;
3734 
3735         case 4:
3736             value = ((unsigned int *)string)[(size_t)i];
3737             break;
3738 
3739         default:
3740             assert(0);
3741             break;
3742     }
3743     return value;
3744 }
3745 
3746 /************************ ArrayLiteralExp ************************************/
3747 
3748 // [ e1, e2, e3, ... ]
3749 
ArrayLiteralExp(Loc loc,Type * type,Expressions * elements)3750 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expressions *elements)
3751     : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
3752 {
3753     this->basis = NULL;
3754     this->type = type;
3755     this->elements = elements;
3756     this->ownedByCtfe = OWNEDcode;
3757 }
3758 
ArrayLiteralExp(Loc loc,Type * type,Expression * e)3759 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *e)
3760     : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
3761 {
3762     this->basis = NULL;
3763     this->type = type;
3764     elements = new Expressions;
3765     elements->push(e);
3766     this->ownedByCtfe = OWNEDcode;
3767 }
3768 
ArrayLiteralExp(Loc loc,Type * type,Expression * basis,Expressions * elements)3769 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements)
3770     : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
3771 {
3772     this->basis = basis;
3773     this->type = type;
3774     this->elements = elements;
3775     this->ownedByCtfe = OWNEDcode;
3776 }
3777 
create(Loc loc,Expressions * elements)3778 ArrayLiteralExp *ArrayLiteralExp::create(Loc loc, Expressions *elements)
3779 {
3780     return new ArrayLiteralExp(loc, NULL, elements);
3781 }
3782 
equals(RootObject * o)3783 bool ArrayLiteralExp::equals(RootObject *o)
3784 {
3785     if (this == o)
3786         return true;
3787     if (o && o->dyncast() == DYNCAST_EXPRESSION &&
3788         ((Expression *)o)->op == TOKarrayliteral)
3789     {
3790         ArrayLiteralExp *ae = (ArrayLiteralExp *)o;
3791         if (elements->dim != ae->elements->dim)
3792             return false;
3793         if (elements->dim == 0 &&
3794             !type->equals(ae->type))
3795         {
3796             return false;
3797         }
3798         for (size_t i = 0; i < elements->dim; i++)
3799         {
3800             Expression *e1 = (*elements)[i];
3801             Expression *e2 = (*ae->elements)[i];
3802             if (!e1)
3803                 e1 = basis;
3804             if (!e2)
3805                 e2 = basis;
3806             if (e1 != e2 &&
3807                 (!e1 || !e2 || !e1->equals(e2)))
3808                 return false;
3809         }
3810         return true;
3811     }
3812     return false;
3813 }
3814 
syntaxCopy()3815 Expression *ArrayLiteralExp::syntaxCopy()
3816 {
3817     return new ArrayLiteralExp(loc,
3818         NULL,
3819         basis ? basis->syntaxCopy() : NULL,
3820         arraySyntaxCopy(elements));
3821 }
3822 
getElement(d_size_t i)3823 Expression *ArrayLiteralExp::getElement(d_size_t i)
3824 {
3825     Expression *el = (*elements)[i];
3826     if (!el)
3827         el = basis;
3828     return el;
3829 }
3830 
appendArrayLiteral(Expressions * elems,ArrayLiteralExp * ale)3831 static void appendArrayLiteral(Expressions *elems, ArrayLiteralExp *ale)
3832 {
3833     if (!ale->elements)
3834         return;
3835     size_t d = elems->dim;
3836     elems->append(ale->elements);
3837     for (size_t i = d; i < elems->dim; i++)
3838     {
3839         Expression *el = (*elems)[i];
3840         if (!el)
3841             (*elems)[i] = ale->basis;
3842     }
3843 }
3844 
3845 /* Copy element `Expressions` in the parameters when they're `ArrayLiteralExp`s.
3846  * Params:
3847  *      e1  = If it's ArrayLiteralExp, its `elements` will be copied.
3848  *            Otherwise, `e1` itself will be pushed into the new `Expressions`.
3849  *      e2  = If it's not `null`, it will be pushed/appended to the new
3850  *            `Expressions` by the same way with `e1`.
3851  * Returns:
3852  *      Newly allocated `Expressions`. Note that it points to the original
3853  *      `Expression` values in e1 and e2.
3854  */
copyElements(Expression * e1,Expression * e2)3855 Expressions* ArrayLiteralExp::copyElements(Expression *e1, Expression *e2)
3856 {
3857     Expressions *elems = new Expressions();
3858 
3859     if (e1->op == TOKarrayliteral)
3860         appendArrayLiteral(elems, (ArrayLiteralExp *)e1);
3861     else
3862         elems->push(e1);
3863 
3864     if (e2)
3865     {
3866         if (e2->op == TOKarrayliteral)
3867             appendArrayLiteral(elems, (ArrayLiteralExp *)e2);
3868         else
3869             elems->push(e2);
3870     }
3871 
3872     return elems;
3873 }
3874 
isBool(bool result)3875 bool ArrayLiteralExp::isBool(bool result)
3876 {
3877     size_t dim = elements ? elements->dim : 0;
3878     return result ? (dim != 0) : (dim == 0);
3879 }
3880 
toStringExp()3881 StringExp *ArrayLiteralExp::toStringExp()
3882 {
3883     TY telem = type->nextOf()->toBasetype()->ty;
3884 
3885     if (telem == Tchar || telem == Twchar || telem == Tdchar ||
3886         (telem == Tvoid && (!elements || elements->dim == 0)))
3887     {
3888         unsigned char sz = 1;
3889         if (telem == Twchar) sz = 2;
3890         else if (telem == Tdchar) sz = 4;
3891 
3892         OutBuffer buf;
3893         if (elements)
3894         {
3895             for (size_t i = 0; i < elements->dim; ++i)
3896             {
3897                 Expression *ch = getElement(i);
3898                 if (ch->op != TOKint64)
3899                     return NULL;
3900                 if (sz == 1)
3901                     buf.writeByte((unsigned)ch->toInteger());
3902                 else if (sz == 2)
3903                     buf.writeword((unsigned)ch->toInteger());
3904                 else
3905                     buf.write4((unsigned)ch->toInteger());
3906             }
3907         }
3908         char prefix;
3909              if (sz == 1) { prefix = 'c'; buf.writeByte(0); }
3910         else if (sz == 2) { prefix = 'w'; buf.writeword(0); }
3911         else              { prefix = 'd'; buf.write4(0); }
3912 
3913         const size_t len = buf.offset / sz - 1;
3914         StringExp *se = new StringExp(loc, buf.extractData(), len, prefix);
3915         se->sz = sz;
3916         se->type = type;
3917         return se;
3918     }
3919     return NULL;
3920 }
3921 
3922 /************************ AssocArrayLiteralExp ************************************/
3923 
3924 // [ key0 : value0, key1 : value1, ... ]
3925 
AssocArrayLiteralExp(Loc loc,Expressions * keys,Expressions * values)3926 AssocArrayLiteralExp::AssocArrayLiteralExp(Loc loc,
3927                 Expressions *keys, Expressions *values)
3928     : Expression(loc, TOKassocarrayliteral, sizeof(AssocArrayLiteralExp))
3929 {
3930     assert(keys->dim == values->dim);
3931     this->keys = keys;
3932     this->values = values;
3933     this->ownedByCtfe = OWNEDcode;
3934 }
3935 
equals(RootObject * o)3936 bool AssocArrayLiteralExp::equals(RootObject *o)
3937 {
3938     if (this == o)
3939         return true;
3940     if (o && o->dyncast() == DYNCAST_EXPRESSION &&
3941         ((Expression *)o)->op == TOKassocarrayliteral)
3942     {
3943         AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)o;
3944         if (keys->dim != ae->keys->dim)
3945             return false;
3946         size_t count = 0;
3947         for (size_t i = 0; i < keys->dim; i++)
3948         {
3949             for (size_t j = 0; j < ae->keys->dim; j++)
3950             {
3951                 if ((*keys)[i]->equals((*ae->keys)[j]))
3952                 {
3953                     if (!(*values)[i]->equals((*ae->values)[j]))
3954                         return false;
3955                     ++count;
3956                 }
3957             }
3958         }
3959         return count == keys->dim;
3960     }
3961     return false;
3962 }
3963 
syntaxCopy()3964 Expression *AssocArrayLiteralExp::syntaxCopy()
3965 {
3966     return new AssocArrayLiteralExp(loc,
3967         arraySyntaxCopy(keys), arraySyntaxCopy(values));
3968 }
3969 
isBool(bool result)3970 bool AssocArrayLiteralExp::isBool(bool result)
3971 {
3972     size_t dim = keys->dim;
3973     return result ? (dim != 0) : (dim == 0);
3974 }
3975 
3976 /************************ StructLiteralExp ************************************/
3977 
3978 // sd( e1, e2, e3, ... )
3979 
StructLiteralExp(Loc loc,StructDeclaration * sd,Expressions * elements,Type * stype)3980 StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype)
3981     : Expression(loc, TOKstructliteral, sizeof(StructLiteralExp))
3982 {
3983     this->sd = sd;
3984     if (!elements)
3985         elements = new Expressions();
3986     this->elements = elements;
3987     this->stype = stype;
3988     this->useStaticInit = false;
3989     this->sym = NULL;
3990     this->ownedByCtfe = OWNEDcode;
3991     this->origin = this;
3992     this->stageflags = 0;
3993     this->inlinecopy = NULL;
3994     //printf("StructLiteralExp::StructLiteralExp(%s)\n", toChars());
3995 }
3996 
create(Loc loc,StructDeclaration * sd,void * elements,Type * stype)3997 StructLiteralExp *StructLiteralExp::create(Loc loc, StructDeclaration *sd, void *elements, Type *stype)
3998 {
3999     return new StructLiteralExp(loc, sd, (Expressions *)elements, stype);
4000 }
4001 
equals(RootObject * o)4002 bool StructLiteralExp::equals(RootObject *o)
4003 {
4004     if (this == o)
4005         return true;
4006     if (o && o->dyncast() == DYNCAST_EXPRESSION &&
4007         ((Expression *)o)->op == TOKstructliteral)
4008     {
4009         StructLiteralExp *se = (StructLiteralExp *)o;
4010         if (!type->equals(se->type))
4011             return false;
4012         if (elements->dim != se->elements->dim)
4013             return false;
4014         for (size_t i = 0; i < elements->dim; i++)
4015         {
4016             Expression *e1 = (*elements)[i];
4017             Expression *e2 = (*se->elements)[i];
4018             if (e1 != e2 &&
4019                 (!e1 || !e2 || !e1->equals(e2)))
4020                 return false;
4021         }
4022         return true;
4023     }
4024     return false;
4025 }
4026 
syntaxCopy()4027 Expression *StructLiteralExp::syntaxCopy()
4028 {
4029     StructLiteralExp *exp = new StructLiteralExp(loc, sd, arraySyntaxCopy(elements), type ? type : stype);
4030     exp->origin = this;
4031     return exp;
4032 }
4033 
addDtorHook(Scope * sc)4034 Expression *StructLiteralExp::addDtorHook(Scope *sc)
4035 {
4036     /* If struct requires a destructor, rewrite as:
4037      *    (S tmp = S()),tmp
4038      * so that the destructor can be hung on tmp.
4039      */
4040     if (sd->dtor && sc->func)
4041     {
4042         /* Make an identifier for the temporary of the form:
4043          *   __sl%s%d, where %s is the struct name
4044          */
4045         const size_t len = 10;
4046         char buf[len + 1];
4047         buf[len] = 0;
4048         strcpy(buf, "__sl");
4049         strncat(buf, sd->ident->toChars(), len - 4 - 1);
4050         assert(buf[len] == 0);
4051 
4052         VarDeclaration *tmp = copyToTemp(0, buf, this);
4053         Expression *ae = new DeclarationExp(loc, tmp);
4054         Expression *e = new CommaExp(loc, ae, new VarExp(loc, tmp));
4055         e = semantic(e, sc);
4056         return e;
4057     }
4058     return this;
4059 }
4060 
4061 /**************************************
4062  * Gets expression at offset of type.
4063  * Returns NULL if not found.
4064  */
4065 
getField(Type * type,unsigned offset)4066 Expression *StructLiteralExp::getField(Type *type, unsigned offset)
4067 {
4068     //printf("StructLiteralExp::getField(this = %s, type = %s, offset = %u)\n",
4069     //  /*toChars()*/"", type->toChars(), offset);
4070     Expression *e = NULL;
4071     int i = getFieldIndex(type, offset);
4072 
4073     if (i != -1)
4074     {
4075         //printf("\ti = %d\n", i);
4076         if (i == (int)sd->fields.dim - 1 && sd->isNested())
4077             return NULL;
4078 
4079         assert(i < (int)elements->dim);
4080         e = (*elements)[i];
4081         if (e)
4082         {
4083             //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars());
4084 
4085             /* If type is a static array, and e is an initializer for that array,
4086              * then the field initializer should be an array literal of e.
4087              */
4088             if (e->type->castMod(0) != type->castMod(0) && type->ty == Tsarray)
4089             {   TypeSArray *tsa = (TypeSArray *)type;
4090                 size_t length = (size_t)tsa->dim->toInteger();
4091                 Expressions *z = new Expressions;
4092                 z->setDim(length);
4093                 for (size_t q = 0; q < length; ++q)
4094                     (*z)[q] = e->copy();
4095                 e = new ArrayLiteralExp(loc, type, z);
4096             }
4097             else
4098             {
4099                 e = e->copy();
4100                 e->type = type;
4101             }
4102             if (useStaticInit && e->op == TOKstructliteral &&
4103                 e->type->needsNested())
4104             {
4105                 StructLiteralExp *se = (StructLiteralExp *)e;
4106                 se->useStaticInit = true;
4107             }
4108         }
4109     }
4110     return e;
4111 }
4112 
4113 /************************************
4114  * Get index of field.
4115  * Returns -1 if not found.
4116  */
4117 
getFieldIndex(Type * type,unsigned offset)4118 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset)
4119 {
4120     /* Find which field offset is by looking at the field offsets
4121      */
4122     if (elements->dim)
4123     {
4124         for (size_t i = 0; i < sd->fields.dim; i++)
4125         {
4126             VarDeclaration *v = sd->fields[i];
4127 
4128             if (offset == v->offset &&
4129                 type->size() == v->type->size())
4130             {
4131                 /* context field might not be filled. */
4132                 if (i == sd->fields.dim - 1 && sd->isNested())
4133                     return (int)i;
4134                 Expression *e = (*elements)[i];
4135                 if (e)
4136                 {
4137                     return (int)i;
4138                 }
4139                 break;
4140             }
4141         }
4142     }
4143     return -1;
4144 }
4145 
4146 /************************ TypeDotIdExp ************************************/
4147 
4148 /* Things like:
4149  *      int.size
4150  *      foo.size
4151  *      (foo).size
4152  *      cast(foo).size
4153  */
4154 
typeDotIdExp(Loc loc,Type * type,Identifier * ident)4155 DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident)
4156 {
4157     return new DotIdExp(loc, new TypeExp(loc, type), ident);
4158 }
4159 
4160 
4161 /************************************************************/
4162 
4163 // Mainly just a placeholder
4164 
TypeExp(Loc loc,Type * type)4165 TypeExp::TypeExp(Loc loc, Type *type)
4166     : Expression(loc, TOKtype, sizeof(TypeExp))
4167 {
4168     //printf("TypeExp::TypeExp(%s)\n", type->toChars());
4169     this->type = type;
4170 }
4171 
syntaxCopy()4172 Expression *TypeExp::syntaxCopy()
4173 {
4174     return new TypeExp(loc, type->syntaxCopy());
4175 }
4176 
checkType()4177 bool TypeExp::checkType()
4178 {
4179     error("type %s is not an expression", toChars());
4180     return true;
4181 }
4182 
checkValue()4183 bool TypeExp::checkValue()
4184 {
4185     error("type %s has no value", toChars());
4186     return true;
4187 }
4188 
4189 /************************************************************/
4190 
4191 /***********************************************************
4192  * Mainly just a placeholder of
4193  *  Package, Module, Nspace, and TemplateInstance (including TemplateMixin)
4194  *
4195  * A template instance that requires IFTI:
4196  *      foo!tiargs(fargs)       // foo!tiargs
4197  * is left until CallExp::semantic() or resolveProperties()
4198  */
ScopeExp(Loc loc,ScopeDsymbol * sds)4199 ScopeExp::ScopeExp(Loc loc, ScopeDsymbol *sds)
4200     : Expression(loc, TOKscope, sizeof(ScopeExp))
4201 {
4202     //printf("ScopeExp::ScopeExp(sds = '%s')\n", sds->toChars());
4203     //static int count; if (++count == 38) *(char*)0=0;
4204     this->sds = sds;
4205     assert(!sds->isTemplateDeclaration());   // instead, you should use TemplateExp
4206 }
4207 
syntaxCopy()4208 Expression *ScopeExp::syntaxCopy()
4209 {
4210     return new ScopeExp(loc, (ScopeDsymbol *)sds->syntaxCopy(NULL));
4211 }
4212 
checkType()4213 bool ScopeExp::checkType()
4214 {
4215     if (sds->isPackage())
4216     {
4217         error("%s %s has no type", sds->kind(), sds->toChars());
4218         return true;
4219     }
4220     if (TemplateInstance *ti = sds->isTemplateInstance())
4221     {
4222         //assert(ti->needsTypeInference(sc));
4223         if (ti->tempdecl &&
4224             ti->semantictiargsdone &&
4225             ti->semanticRun == PASSinit)
4226         {
4227             error("partial %s %s has no type", sds->kind(), toChars());
4228             return true;
4229         }
4230     }
4231     return false;
4232 }
4233 
checkValue()4234 bool ScopeExp::checkValue()
4235 {
4236     error("%s %s has no value", sds->kind(), sds->toChars());
4237     return true;
4238 }
4239 
4240 /********************** TemplateExp **************************************/
4241 
4242 // Mainly just a placeholder
4243 
TemplateExp(Loc loc,TemplateDeclaration * td,FuncDeclaration * fd)4244 TemplateExp::TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd)
4245     : Expression(loc, TOKtemplate, sizeof(TemplateExp))
4246 {
4247     //printf("TemplateExp(): %s\n", td->toChars());
4248     this->td = td;
4249     this->fd = fd;
4250 }
4251 
checkType()4252 bool TemplateExp::checkType()
4253 {
4254     error("%s %s has no type", td->kind(), toChars());
4255     return true;
4256 }
4257 
checkValue()4258 bool TemplateExp::checkValue()
4259 {
4260     error("%s %s has no value", td->kind(), toChars());
4261     return true;
4262 }
4263 
isLvalue()4264 bool TemplateExp::isLvalue()
4265 {
4266     return fd != NULL;
4267 }
4268 
toLvalue(Scope * sc,Expression * e)4269 Expression *TemplateExp::toLvalue(Scope *sc, Expression *e)
4270 {
4271     if (!fd)
4272         return Expression::toLvalue(sc, e);
4273 
4274     assert(sc);
4275     return resolve(loc, sc, fd, true);
4276 }
4277 
4278 /********************** NewExp **************************************/
4279 
4280 /* thisexp.new(newargs) newtype(arguments) */
4281 
NewExp(Loc loc,Expression * thisexp,Expressions * newargs,Type * newtype,Expressions * arguments)4282 NewExp::NewExp(Loc loc, Expression *thisexp, Expressions *newargs,
4283         Type *newtype, Expressions *arguments)
4284     : Expression(loc, TOKnew, sizeof(NewExp))
4285 {
4286     this->thisexp = thisexp;
4287     this->newargs = newargs;
4288     this->newtype = newtype;
4289     this->arguments = arguments;
4290     argprefix = NULL;
4291     member = NULL;
4292     allocator = NULL;
4293     onstack = 0;
4294 }
4295 
create(Loc loc,Expression * thisexp,Expressions * newargs,Type * newtype,Expressions * arguments)4296 NewExp *NewExp::create(Loc loc, Expression *thisexp, Expressions *newargs,
4297         Type *newtype, Expressions *arguments)
4298 {
4299     return new NewExp(loc, thisexp, newargs, newtype, arguments);
4300 }
4301 
syntaxCopy()4302 Expression *NewExp::syntaxCopy()
4303 {
4304     return new NewExp(loc,
4305         thisexp ? thisexp->syntaxCopy() : NULL,
4306         arraySyntaxCopy(newargs),
4307         newtype->syntaxCopy(), arraySyntaxCopy(arguments));
4308 }
4309 
4310 /********************** NewAnonClassExp **************************************/
4311 
NewAnonClassExp(Loc loc,Expression * thisexp,Expressions * newargs,ClassDeclaration * cd,Expressions * arguments)4312 NewAnonClassExp::NewAnonClassExp(Loc loc, Expression *thisexp,
4313         Expressions *newargs, ClassDeclaration *cd, Expressions *arguments)
4314     : Expression(loc, TOKnewanonclass, sizeof(NewAnonClassExp))
4315 {
4316     this->thisexp = thisexp;
4317     this->newargs = newargs;
4318     this->cd = cd;
4319     this->arguments = arguments;
4320 }
4321 
syntaxCopy()4322 Expression *NewAnonClassExp::syntaxCopy()
4323 {
4324     return new NewAnonClassExp(loc,
4325         thisexp ? thisexp->syntaxCopy() : NULL,
4326         arraySyntaxCopy(newargs),
4327         (ClassDeclaration *)cd->syntaxCopy(NULL),
4328         arraySyntaxCopy(arguments));
4329 }
4330 
4331 /********************** SymbolExp **************************************/
4332 
SymbolExp(Loc loc,TOK op,int size,Declaration * var,bool hasOverloads)4333 SymbolExp::SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads)
4334     : Expression(loc, op, size)
4335 {
4336     assert(var);
4337     this->var = var;
4338     this->hasOverloads = hasOverloads;
4339 }
4340 
4341 /********************** SymOffExp **************************************/
4342 
SymOffExp(Loc loc,Declaration * var,dinteger_t offset,bool hasOverloads)4343 SymOffExp::SymOffExp(Loc loc, Declaration *var, dinteger_t offset, bool hasOverloads)
4344     : SymbolExp(loc, TOKsymoff, sizeof(SymOffExp), var,
4345                 var->isVarDeclaration() ? false : hasOverloads)
4346 {
4347     if (VarDeclaration *v = var->isVarDeclaration())
4348     {
4349         // FIXME: This error report will never be handled anyone.
4350         // It should be done before the SymOffExp construction.
4351         if (v->needThis())
4352             ::error(loc, "need 'this' for address of %s", v->toChars());
4353     }
4354     this->offset = offset;
4355 }
4356 
isBool(bool result)4357 bool SymOffExp::isBool(bool result)
4358 {
4359     return result ? true : false;
4360 }
4361 
4362 /******************************** VarExp **************************/
4363 
VarExp(Loc loc,Declaration * var,bool hasOverloads)4364 VarExp::VarExp(Loc loc, Declaration *var, bool hasOverloads)
4365     : SymbolExp(loc, TOKvar, sizeof(VarExp), var,
4366                 var->isVarDeclaration() ? false : hasOverloads)
4367 {
4368     //printf("VarExp(this = %p, '%s', loc = %s)\n", this, var->toChars(), loc.toChars());
4369     //if (strcmp(var->ident->toChars(), "func") == 0) halt();
4370     this->type = var->type;
4371 }
4372 
create(Loc loc,Declaration * var,bool hasOverloads)4373 VarExp *VarExp::create(Loc loc, Declaration *var, bool hasOverloads)
4374 {
4375     return new VarExp(loc, var, hasOverloads);
4376 }
4377 
equals(RootObject * o)4378 bool VarExp::equals(RootObject *o)
4379 {
4380     if (this == o)
4381         return true;
4382     if (((Expression *)o)->op == TOKvar)
4383     {
4384         VarExp *ne = (VarExp *)o;
4385         if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
4386             var == ne->var)
4387         {
4388             return true;
4389         }
4390     }
4391     return false;
4392 }
4393 
isLvalue()4394 bool VarExp::isLvalue()
4395 {
4396     if (var->storage_class & (STClazy | STCrvalue | STCmanifest))
4397         return false;
4398     return true;
4399 }
4400 
toLvalue(Scope *,Expression *)4401 Expression *VarExp::toLvalue(Scope *, Expression *)
4402 {
4403     if (var->storage_class & STCmanifest)
4404     {
4405         error("manifest constant '%s' is not lvalue", var->toChars());
4406         return new ErrorExp();
4407     }
4408     if (var->storage_class & STClazy)
4409     {
4410         error("lazy variables cannot be lvalues");
4411         return new ErrorExp();
4412     }
4413     if (var->ident == Id::ctfe)
4414     {
4415         error("compiler-generated variable __ctfe is not an lvalue");
4416         return new ErrorExp();
4417     }
4418     if (var->ident == Id::dollar)   // Bugzilla 13574
4419     {
4420         error("'$' is not an lvalue");
4421         return new ErrorExp();
4422     }
4423     return this;
4424 }
4425 
checkModifiable(Scope * sc,int flag)4426 int VarExp::checkModifiable(Scope *sc, int flag)
4427 {
4428     //printf("VarExp::checkModifiable %s", toChars());
4429     assert(type);
4430     return var->checkModify(loc, sc, type, NULL, flag);
4431 }
4432 
modifiableLvalue(Scope * sc,Expression * e)4433 Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e)
4434 {
4435     //printf("VarExp::modifiableLvalue('%s')\n", var->toChars());
4436     if (var->storage_class & STCmanifest)
4437     {
4438         error("cannot modify manifest constant '%s'", toChars());
4439         return new ErrorExp();
4440     }
4441     // See if this expression is a modifiable lvalue (i.e. not const)
4442     return Expression::modifiableLvalue(sc, e);
4443 }
4444 
4445 
4446 /******************************** OverExp **************************/
4447 
OverExp(Loc loc,OverloadSet * s)4448 OverExp::OverExp(Loc loc, OverloadSet *s)
4449         : Expression(loc, TOKoverloadset, sizeof(OverExp))
4450 {
4451     //printf("OverExp(this = %p, '%s')\n", this, var->toChars());
4452     vars = s;
4453     type = Type::tvoid;
4454 }
4455 
isLvalue()4456 bool OverExp::isLvalue()
4457 {
4458     return true;
4459 }
4460 
toLvalue(Scope *,Expression *)4461 Expression *OverExp::toLvalue(Scope *, Expression *)
4462 {
4463     return this;
4464 }
4465 
4466 /******************************** TupleExp **************************/
4467 
TupleExp(Loc loc,Expression * e0,Expressions * exps)4468 TupleExp::TupleExp(Loc loc, Expression *e0, Expressions *exps)
4469         : Expression(loc, TOKtuple, sizeof(TupleExp))
4470 {
4471     //printf("TupleExp(this = %p)\n", this);
4472     this->e0 = e0;
4473     this->exps = exps;
4474 }
4475 
TupleExp(Loc loc,Expressions * exps)4476 TupleExp::TupleExp(Loc loc, Expressions *exps)
4477         : Expression(loc, TOKtuple, sizeof(TupleExp))
4478 {
4479     //printf("TupleExp(this = %p)\n", this);
4480     this->e0 = NULL;
4481     this->exps = exps;
4482 }
4483 
TupleExp(Loc loc,TupleDeclaration * tup)4484 TupleExp::TupleExp(Loc loc, TupleDeclaration *tup)
4485         : Expression(loc, TOKtuple, sizeof(TupleExp))
4486 {
4487     this->e0 = NULL;
4488     this->exps = new Expressions();
4489 
4490     this->exps->reserve(tup->objects->dim);
4491     for (size_t i = 0; i < tup->objects->dim; i++)
4492     {   RootObject *o = (*tup->objects)[i];
4493         if (Dsymbol *s = getDsymbol(o))
4494         {
4495             /* If tuple element represents a symbol, translate to DsymbolExp
4496              * to supply implicit 'this' if needed later.
4497              */
4498             Expression *e = new DsymbolExp(loc, s);
4499             this->exps->push(e);
4500         }
4501         else if (o->dyncast() == DYNCAST_EXPRESSION)
4502         {
4503             Expression *e = ((Expression *)o)->copy();
4504             e->loc = loc;    // Bugzilla 15669
4505             this->exps->push(e);
4506         }
4507         else if (o->dyncast() == DYNCAST_TYPE)
4508         {
4509             Type *t = (Type *)o;
4510             Expression *e = new TypeExp(loc, t);
4511             this->exps->push(e);
4512         }
4513         else
4514         {
4515             error("%s is not an expression", o->toChars());
4516         }
4517     }
4518 }
4519 
equals(RootObject * o)4520 bool TupleExp::equals(RootObject *o)
4521 {
4522     if (this == o)
4523         return true;
4524     if (((Expression *)o)->op == TOKtuple)
4525     {
4526         TupleExp *te = (TupleExp *)o;
4527         if (exps->dim != te->exps->dim)
4528             return false;
4529         if ((e0 && !e0->equals(te->e0)) || (!e0 && te->e0))
4530             return false;
4531         for (size_t i = 0; i < exps->dim; i++)
4532         {
4533             Expression *e1 = (*exps)[i];
4534             Expression *e2 = (*te->exps)[i];
4535             if (!e1->equals(e2))
4536                 return false;
4537         }
4538         return true;
4539     }
4540     return false;
4541 }
4542 
syntaxCopy()4543 Expression *TupleExp::syntaxCopy()
4544 {
4545     return new TupleExp(loc, e0 ? e0->syntaxCopy() : NULL, arraySyntaxCopy(exps));
4546 }
4547 
toTupleExp()4548 TupleExp *TupleExp::toTupleExp()
4549 {
4550     return this;
4551 }
4552 
4553 /******************************** FuncExp *********************************/
4554 
FuncExp(Loc loc,Dsymbol * s)4555 FuncExp::FuncExp(Loc loc, Dsymbol *s)
4556         : Expression(loc, TOKfunction, sizeof(FuncExp))
4557 {
4558     this->td = s->isTemplateDeclaration();
4559     this->fd = s->isFuncLiteralDeclaration();
4560     if (td)
4561     {
4562         assert(td->literal);
4563         assert(td->members && td->members->dim == 1);
4564         fd = (*td->members)[0]->isFuncLiteralDeclaration();
4565     }
4566     tok = fd->tok;  // save original kind of function/delegate/(infer)
4567     assert(fd->fbody);
4568 }
4569 
equals(RootObject * o)4570 bool FuncExp::equals(RootObject *o)
4571 {
4572     if (this == o)
4573         return true;
4574     if (o->dyncast() != DYNCAST_EXPRESSION)
4575         return false;
4576     if (((Expression *)o)->op == TOKfunction)
4577     {
4578         FuncExp *fe = (FuncExp *)o;
4579         return fd == fe->fd;
4580     }
4581     return false;
4582 }
4583 
genIdent(Scope * sc)4584 void FuncExp::genIdent(Scope *sc)
4585 {
4586     if (fd->ident == Id::empty)
4587     {
4588         const char *s;
4589         if (fd->fes)                        s = "__foreachbody";
4590         else if (fd->tok == TOKreserved)    s = "__lambda";
4591         else if (fd->tok == TOKdelegate)    s = "__dgliteral";
4592         else                                s = "__funcliteral";
4593 
4594         DsymbolTable *symtab;
4595         if (FuncDeclaration *func = sc->parent->isFuncDeclaration())
4596         {
4597             if (func->localsymtab == NULL)
4598             {
4599                 // Inside template constraint, symtab is not set yet.
4600                 // Initialize it lazily.
4601                 func->localsymtab = new DsymbolTable();
4602             }
4603             symtab = func->localsymtab;
4604         }
4605         else
4606         {
4607             ScopeDsymbol *sds = sc->parent->isScopeDsymbol();
4608             if (!sds->symtab)
4609             {
4610                 // Inside template constraint, symtab may not be set yet.
4611                 // Initialize it lazily.
4612                 assert(sds->isTemplateInstance());
4613                 sds->symtab = new DsymbolTable();
4614             }
4615             symtab = sds->symtab;
4616         }
4617         assert(symtab);
4618         int num = (int)dmd_aaLen(symtab->tab) + 1;
4619         Identifier *id = Identifier::generateId(s, num);
4620         fd->ident = id;
4621         if (td) td->ident = id;
4622         symtab->insert(td ? (Dsymbol *)td : (Dsymbol *)fd);
4623     }
4624 }
4625 
syntaxCopy()4626 Expression *FuncExp::syntaxCopy()
4627 {
4628     if (td)
4629         return new FuncExp(loc, td->syntaxCopy(NULL));
4630     else if (fd->semanticRun == PASSinit)
4631         return new FuncExp(loc, fd->syntaxCopy(NULL));
4632     else    // Bugzilla 13481: Prevent multiple semantic analysis of lambda body.
4633         return new FuncExp(loc, fd);
4634 }
4635 
matchType(Type * to,Scope * sc,FuncExp ** presult,int flag)4636 MATCH FuncExp::matchType(Type *to, Scope *sc, FuncExp **presult, int flag)
4637 {
4638     //printf("FuncExp::matchType('%s'), to=%s\n", type ? type->toChars() : "null", to->toChars());
4639     if (presult)
4640         *presult = NULL;
4641 
4642     TypeFunction *tof = NULL;
4643     if (to->ty == Tdelegate)
4644     {
4645         if (tok == TOKfunction)
4646         {
4647             if (!flag)
4648                 error("cannot match function literal to delegate type '%s'", to->toChars());
4649             return MATCHnomatch;
4650         }
4651         tof = (TypeFunction *)to->nextOf();
4652     }
4653     else if (to->ty == Tpointer && to->nextOf()->ty == Tfunction)
4654     {
4655         if (tok == TOKdelegate)
4656         {
4657             if (!flag)
4658                 error("cannot match delegate literal to function pointer type '%s'", to->toChars());
4659             return MATCHnomatch;
4660         }
4661         tof = (TypeFunction *)to->nextOf();
4662     }
4663 
4664     if (td)
4665     {
4666         if (!tof)
4667         {
4668         L1:
4669             if (!flag)
4670                 error("cannot infer parameter types from %s", to->toChars());
4671             return MATCHnomatch;
4672         }
4673 
4674         // Parameter types inference from 'tof'
4675         assert(td->_scope);
4676         TypeFunction *tf = (TypeFunction *)fd->type;
4677         //printf("\ttof = %s\n", tof->toChars());
4678         //printf("\ttf  = %s\n", tf->toChars());
4679         size_t dim = Parameter::dim(tf->parameters);
4680 
4681         if (Parameter::dim(tof->parameters) != dim ||
4682             tof->varargs != tf->varargs)
4683             goto L1;
4684 
4685         Objects *tiargs = new Objects();
4686         tiargs->reserve(td->parameters->dim);
4687 
4688         for (size_t i = 0; i < td->parameters->dim; i++)
4689         {
4690             TemplateParameter *tp = (*td->parameters)[i];
4691             size_t u = 0;
4692             for (; u < dim; u++)
4693             {
4694                 Parameter *p = Parameter::getNth(tf->parameters, u);
4695                 if (p->type->ty == Tident &&
4696                     ((TypeIdentifier *)p->type)->ident == tp->ident)
4697                 {
4698                     break;
4699                 }
4700             }
4701             assert(u < dim);
4702             Parameter *pto = Parameter::getNth(tof->parameters, u);
4703             Type *t = pto->type;
4704             if (t->ty == Terror)
4705                 goto L1;
4706             tiargs->push(t);
4707         }
4708 
4709         // Set target of return type inference
4710         if (!tf->next && tof->next)
4711             fd->treq = to;
4712 
4713         TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
4714         Expression *ex = new ScopeExp(loc, ti);
4715         ex = ::semantic(ex, td->_scope);
4716 
4717         // Reset inference target for the later re-semantic
4718         fd->treq = NULL;
4719 
4720         if (ex->op == TOKerror)
4721             return MATCHnomatch;
4722         if (ex->op != TOKfunction)
4723             goto L1;
4724         return ((FuncExp *)ex)->matchType(to, sc, presult, flag);
4725     }
4726 
4727     if (!tof || !tof->next)
4728         return MATCHnomatch;
4729 
4730     assert(type && type != Type::tvoid);
4731     TypeFunction *tfx = (TypeFunction *)fd->type;
4732     bool convertMatch = (type->ty != to->ty);
4733 
4734     if (fd->inferRetType && tfx->next->implicitConvTo(tof->next) == MATCHconvert)
4735     {
4736         /* If return type is inferred and covariant return,
4737          * tweak return statements to required return type.
4738          *
4739          * interface I {}
4740          * class C : Object, I{}
4741          *
4742          * I delegate() dg = delegate() { return new class C(); }
4743          */
4744         convertMatch = true;
4745 
4746         TypeFunction *tfy = new TypeFunction(tfx->parameters, tof->next, tfx->varargs, tfx->linkage, STCundefined);
4747         tfy->mod = tfx->mod;
4748         tfy->isnothrow  = tfx->isnothrow;
4749         tfy->isnogc     = tfx->isnogc;
4750         tfy->purity     = tfx->purity;
4751         tfy->isproperty = tfx->isproperty;
4752         tfy->isref      = tfx->isref;
4753         tfy->iswild     = tfx->iswild;
4754         tfy->deco = tfy->merge()->deco;
4755 
4756         tfx = tfy;
4757     }
4758 
4759     Type *tx;
4760     if (tok == TOKdelegate ||
4761         (tok == TOKreserved && (type->ty == Tdelegate ||
4762                                 (type->ty == Tpointer && to->ty == Tdelegate))))
4763     {
4764         // Allow conversion from implicit function pointer to delegate
4765         tx = new TypeDelegate(tfx);
4766         tx->deco = tx->merge()->deco;
4767     }
4768     else
4769     {
4770         assert(tok == TOKfunction ||
4771                (tok == TOKreserved && type->ty == Tpointer));
4772         tx = tfx->pointerTo();
4773     }
4774     //printf("\ttx = %s, to = %s\n", tx->toChars(), to->toChars());
4775 
4776     MATCH m = tx->implicitConvTo(to);
4777     if (m > MATCHnomatch)
4778     {
4779         // MATCHexact:      exact type match
4780         // MATCHconst:      covairiant type match (eg. attributes difference)
4781         // MATCHconvert:    context conversion
4782         m = convertMatch ? MATCHconvert : tx->equals(to) ? MATCHexact : MATCHconst;
4783 
4784         if (presult)
4785         {
4786             (*presult) = (FuncExp *)copy();
4787             (*presult)->type = to;
4788 
4789             // Bugzilla 12508: Tweak function body for covariant returns.
4790             (*presult)->fd->modifyReturns(sc, tof->next);
4791         }
4792     }
4793     else if (!flag)
4794     {
4795         error("cannot implicitly convert expression (%s) of type %s to %s",
4796                 toChars(), tx->toChars(), to->toChars());
4797     }
4798     return m;
4799 }
4800 
toChars()4801 const char *FuncExp::toChars()
4802 {
4803     return fd->toChars();
4804 }
4805 
checkType()4806 bool FuncExp::checkType()
4807 {
4808     if (td)
4809     {
4810         error("template lambda has no type");
4811         return true;
4812     }
4813     return false;
4814 }
4815 
checkValue()4816 bool FuncExp::checkValue()
4817 {
4818     if (td)
4819     {
4820         error("template lambda has no value");
4821         return true;
4822     }
4823     return false;
4824 }
4825 
4826 /******************************** DeclarationExp **************************/
4827 
DeclarationExp(Loc loc,Dsymbol * declaration)4828 DeclarationExp::DeclarationExp(Loc loc, Dsymbol *declaration)
4829         : Expression(loc, TOKdeclaration, sizeof(DeclarationExp))
4830 {
4831     this->declaration = declaration;
4832 }
4833 
syntaxCopy()4834 Expression *DeclarationExp::syntaxCopy()
4835 {
4836     return new DeclarationExp(loc, declaration->syntaxCopy(NULL));
4837 }
4838 
hasCode()4839 bool DeclarationExp::hasCode()
4840 {
4841     if (VarDeclaration *vd = declaration->isVarDeclaration())
4842     {
4843         return !(vd->storage_class & (STCmanifest | STCstatic));
4844     }
4845     return false;
4846 }
4847 
4848 /************************ TypeidExp ************************************/
4849 
4850 /*
4851  *      typeid(int)
4852  */
4853 
TypeidExp(Loc loc,RootObject * o)4854 TypeidExp::TypeidExp(Loc loc, RootObject *o)
4855     : Expression(loc, TOKtypeid, sizeof(TypeidExp))
4856 {
4857     this->obj = o;
4858 }
4859 
syntaxCopy()4860 Expression *TypeidExp::syntaxCopy()
4861 {
4862     return new TypeidExp(loc, objectSyntaxCopy(obj));
4863 }
4864 
4865 /************************ TraitsExp ************************************/
4866 /*
4867  *      __traits(identifier, args...)
4868  */
4869 
TraitsExp(Loc loc,Identifier * ident,Objects * args)4870 TraitsExp::TraitsExp(Loc loc, Identifier *ident, Objects *args)
4871     : Expression(loc, TOKtraits, sizeof(TraitsExp))
4872 {
4873     this->ident = ident;
4874     this->args = args;
4875 }
4876 
syntaxCopy()4877 Expression *TraitsExp::syntaxCopy()
4878 {
4879     return new TraitsExp(loc, ident, TemplateInstance::arraySyntaxCopy(args));
4880 }
4881 
4882 /************************************************************/
4883 
HaltExp(Loc loc)4884 HaltExp::HaltExp(Loc loc)
4885         : Expression(loc, TOKhalt, sizeof(HaltExp))
4886 {
4887 }
4888 
4889 /************************************************************/
4890 
IsExp(Loc loc,Type * targ,Identifier * id,TOK tok,Type * tspec,TOK tok2,TemplateParameters * parameters)4891 IsExp::IsExp(Loc loc, Type *targ, Identifier *id, TOK tok,
4892         Type *tspec, TOK tok2, TemplateParameters *parameters)
4893         : Expression(loc, TOKis, sizeof(IsExp))
4894 {
4895     this->targ = targ;
4896     this->id = id;
4897     this->tok = tok;
4898     this->tspec = tspec;
4899     this->tok2 = tok2;
4900     this->parameters = parameters;
4901 }
4902 
syntaxCopy()4903 Expression *IsExp::syntaxCopy()
4904 {
4905     // This section is identical to that in TemplateDeclaration::syntaxCopy()
4906     TemplateParameters *p = NULL;
4907     if (parameters)
4908     {
4909         p = new TemplateParameters();
4910         p->setDim(parameters->dim);
4911         for (size_t i = 0; i < p->dim; i++)
4912             (*p)[i] = (*parameters)[i]->syntaxCopy();
4913     }
4914     return new IsExp(loc,
4915         targ->syntaxCopy(),
4916         id,
4917         tok,
4918         tspec ? tspec->syntaxCopy() : NULL,
4919         tok2,
4920         p);
4921 }
4922 
4923 void unSpeculative(Scope *sc, RootObject *o);
4924 
4925 /************************************************************/
4926 
UnaExp(Loc loc,TOK op,int size,Expression * e1)4927 UnaExp::UnaExp(Loc loc, TOK op, int size, Expression *e1)
4928         : Expression(loc, op, size)
4929 {
4930     this->e1 = e1;
4931     this->att1 = NULL;
4932 }
4933 
syntaxCopy()4934 Expression *UnaExp::syntaxCopy()
4935 {
4936     UnaExp *e = (UnaExp *)copy();
4937     e->type = NULL;
4938     e->e1 = e->e1->syntaxCopy();
4939     return e;
4940 }
4941 
4942 /********************************
4943  * The type for a unary expression is incompatible.
4944  * Print error message.
4945  * Returns:
4946  *  ErrorExp
4947  */
incompatibleTypes()4948 Expression *UnaExp::incompatibleTypes()
4949 {
4950     if (e1->type->toBasetype() == Type::terror)
4951         return e1;
4952 
4953     if (e1->op == TOKtype)
4954     {
4955         error("incompatible type for (%s(%s)): cannot use '%s' with types",
4956               Token::toChars(op), e1->toChars(), Token::toChars(op));
4957     }
4958     else
4959     {
4960         error("incompatible type for (%s(%s)): '%s'",
4961               Token::toChars(op), e1->toChars(), e1->type->toChars());
4962     }
4963     return new ErrorExp();
4964 }
4965 
resolveLoc(Loc loc,Scope * sc)4966 Expression *UnaExp::resolveLoc(Loc loc, Scope *sc)
4967 {
4968     e1 = e1->resolveLoc(loc, sc);
4969     return this;
4970 }
4971 
4972 /************************************************************/
4973 
BinExp(Loc loc,TOK op,int size,Expression * e1,Expression * e2)4974 BinExp::BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2)
4975         : Expression(loc, op, size)
4976 {
4977     this->e1 = e1;
4978     this->e2 = e2;
4979 
4980     this->att1 = NULL;
4981     this->att2 = NULL;
4982 }
4983 
syntaxCopy()4984 Expression *BinExp::syntaxCopy()
4985 {
4986     BinExp *e = (BinExp *)copy();
4987     e->type = NULL;
4988     e->e1 = e->e1->syntaxCopy();
4989     e->e2 = e->e2->syntaxCopy();
4990     return e;
4991 }
4992 
checkOpAssignTypes(Scope * sc)4993 Expression *BinExp::checkOpAssignTypes(Scope *sc)
4994 {
4995     // At that point t1 and t2 are the merged types. type is the original type of the lhs.
4996     Type *t1 = e1->type;
4997     Type *t2 = e2->type;
4998 
4999     // T opAssign floating yields a floating. Prevent truncating conversions (float to int).
5000     // See issue 3841.
5001     // Should we also prevent double to float (type->isfloating() && type->size() < t2 ->size()) ?
5002     if (op == TOKaddass || op == TOKminass ||
5003         op == TOKmulass || op == TOKdivass || op == TOKmodass ||
5004         op == TOKpowass)
5005     {
5006         if ((type->isintegral() && t2->isfloating()))
5007         {
5008             warning("%s %s %s is performing truncating conversion",
5009                     type->toChars(), Token::toChars(op), t2->toChars());
5010         }
5011     }
5012 
5013     // generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary
5014     if (op == TOKmulass || op == TOKdivass || op == TOKmodass)
5015     {
5016         // Any multiplication by an imaginary or complex number yields a complex result.
5017         // r *= c, i*=c, r*=i, i*=i are all forbidden operations.
5018         const char *opstr = Token::toChars(op);
5019         if (t1->isreal() && t2->iscomplex())
5020         {
5021             error("%s %s %s is undefined. Did you mean %s %s %s.re ?",
5022                 t1->toChars(), opstr, t2->toChars(),
5023                 t1->toChars(), opstr, t2->toChars());
5024             return new ErrorExp();
5025         }
5026         else if (t1->isimaginary() && t2->iscomplex())
5027         {
5028             error("%s %s %s is undefined. Did you mean %s %s %s.im ?",
5029                 t1->toChars(), opstr, t2->toChars(),
5030                 t1->toChars(), opstr, t2->toChars());
5031             return new ErrorExp();
5032         }
5033         else if ((t1->isreal() || t1->isimaginary()) &&
5034             t2->isimaginary())
5035         {
5036             error("%s %s %s is an undefined operation", t1->toChars(), opstr, t2->toChars());
5037             return new ErrorExp();
5038         }
5039     }
5040 
5041     // generate an error if this is a nonsensical += or -=, eg real += imaginary
5042     if (op == TOKaddass || op == TOKminass)
5043     {
5044         // Addition or subtraction of a real and an imaginary is a complex result.
5045         // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations.
5046         if ((t1->isreal() && (t2->isimaginary() || t2->iscomplex())) ||
5047             (t1->isimaginary() && (t2->isreal() || t2->iscomplex())))
5048         {
5049             error("%s %s %s is undefined (result is complex)",
5050                 t1->toChars(), Token::toChars(op), t2->toChars());
5051             return new ErrorExp();
5052         }
5053         if (type->isreal() || type->isimaginary())
5054         {
5055             assert(global.errors || t2->isfloating());
5056             e2 = e2->castTo(sc, t1);
5057         }
5058     }
5059 
5060     if (op == TOKmulass)
5061     {
5062         if (t2->isfloating())
5063         {
5064             if (t1->isreal())
5065             {
5066                 if (t2->isimaginary() || t2->iscomplex())
5067                 {
5068                     e2 = e2->castTo(sc, t1);
5069                 }
5070             }
5071             else if (t1->isimaginary())
5072             {
5073                 if (t2->isimaginary() || t2->iscomplex())
5074                 {
5075                     switch (t1->ty)
5076                     {
5077                         case Timaginary32: t2 = Type::tfloat32; break;
5078                         case Timaginary64: t2 = Type::tfloat64; break;
5079                         case Timaginary80: t2 = Type::tfloat80; break;
5080                         default:
5081                             assert(0);
5082                     }
5083                     e2 = e2->castTo(sc, t2);
5084                 }
5085             }
5086         }
5087     }
5088     else if (op == TOKdivass)
5089     {
5090         if (t2->isimaginary())
5091         {
5092             if (t1->isreal())
5093             {
5094                 // x/iv = i(-x/v)
5095                 // Therefore, the result is 0
5096                 e2 = new CommaExp(loc, e2, new RealExp(loc, CTFloat::zero, t1));
5097                 e2->type = t1;
5098                 Expression *e = new AssignExp(loc, e1, e2);
5099                 e->type = t1;
5100                 return e;
5101             }
5102             else if (t1->isimaginary())
5103             {
5104                 Type *t3;
5105                 switch (t1->ty)
5106                 {
5107                     case Timaginary32: t3 = Type::tfloat32; break;
5108                     case Timaginary64: t3 = Type::tfloat64; break;
5109                     case Timaginary80: t3 = Type::tfloat80; break;
5110                     default:
5111                         assert(0);
5112                 }
5113                 e2 = e2->castTo(sc, t3);
5114                 Expression *e = new AssignExp(loc, e1, e2);
5115                 e->type = t1;
5116                 return e;
5117             }
5118         }
5119     }
5120     else if (op == TOKmodass)
5121     {
5122         if (t2->iscomplex())
5123         {
5124             error("cannot perform modulo complex arithmetic");
5125             return new ErrorExp();
5126         }
5127     }
5128     return this;
5129 }
5130 
5131 /********************************
5132  * The types for a binary expression are incompatible.
5133  * Print error message.
5134  * Returns:
5135  *  ErrorExp
5136  */
incompatibleTypes()5137 Expression *BinExp::incompatibleTypes()
5138 {
5139     if (e1->type->toBasetype() == Type::terror)
5140         return e1;
5141     if (e2->type->toBasetype() == Type::terror)
5142         return e2;
5143 
5144     // CondExp uses 'a ? b : c' but we're comparing 'b : c'
5145     TOK thisOp = (op == TOKquestion) ? TOKcolon : op;
5146     if (e1->op == TOKtype || e2->op == TOKtype)
5147     {
5148         error("incompatible types for ((%s) %s (%s)): cannot use '%s' with types",
5149             e1->toChars(), Token::toChars(thisOp), e2->toChars(), Token::toChars(op));
5150     }
5151     else
5152     {
5153         error("incompatible types for ((%s) %s (%s)): '%s' and '%s'",
5154             e1->toChars(), Token::toChars(thisOp), e2->toChars(),
5155             e1->type->toChars(), e2->type->toChars());
5156     }
5157     return new ErrorExp();
5158 }
5159 
checkIntegralBin()5160 bool BinExp::checkIntegralBin()
5161 {
5162     bool r1 = e1->checkIntegral();
5163     bool r2 = e2->checkIntegral();
5164     return (r1 || r2);
5165 }
5166 
checkArithmeticBin()5167 bool BinExp::checkArithmeticBin()
5168 {
5169     bool r1 = e1->checkArithmetic();
5170     bool r2 = e2->checkArithmetic();
5171     return (r1 || r2);
5172 }
5173 
5174 /********************** BinAssignExp **************************************/
5175 
BinAssignExp(Loc loc,TOK op,int size,Expression * e1,Expression * e2)5176 BinAssignExp::BinAssignExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2)
5177         : BinExp(loc, op, size, e1, e2)
5178 {
5179 }
5180 
isLvalue()5181 bool BinAssignExp::isLvalue()
5182 {
5183     return true;
5184 }
5185 
toLvalue(Scope *,Expression *)5186 Expression *BinAssignExp::toLvalue(Scope *, Expression *)
5187 {
5188     // Lvalue-ness will be handled in glue layer.
5189     return this;
5190 }
5191 
modifiableLvalue(Scope * sc,Expression *)5192 Expression *BinAssignExp::modifiableLvalue(Scope *sc, Expression *)
5193 {
5194     // should check e1->checkModifiable() ?
5195     return toLvalue(sc, this);
5196 }
5197 
5198 /************************************************************/
5199 
CompileExp(Loc loc,Expression * e)5200 CompileExp::CompileExp(Loc loc, Expression *e)
5201         : UnaExp(loc, TOKmixin, sizeof(CompileExp), e)
5202 {
5203 }
5204 
5205 /************************************************************/
5206 
ImportExp(Loc loc,Expression * e)5207 ImportExp::ImportExp(Loc loc, Expression *e)
5208         : UnaExp(loc, TOKimport, sizeof(ImportExp), e)
5209 {
5210 }
5211 
5212 /************************************************************/
5213 
AssertExp(Loc loc,Expression * e,Expression * msg)5214 AssertExp::AssertExp(Loc loc, Expression *e, Expression *msg)
5215         : UnaExp(loc, TOKassert, sizeof(AssertExp), e)
5216 {
5217     this->msg = msg;
5218 }
5219 
syntaxCopy()5220 Expression *AssertExp::syntaxCopy()
5221 {
5222     return new AssertExp(loc, e1->syntaxCopy(), msg ? msg->syntaxCopy() : NULL);
5223 }
5224 
5225 /************************************************************/
5226 
DotIdExp(Loc loc,Expression * e,Identifier * ident)5227 DotIdExp::DotIdExp(Loc loc, Expression *e, Identifier *ident)
5228         : UnaExp(loc, TOKdotid, sizeof(DotIdExp), e)
5229 {
5230     this->ident = ident;
5231     this->wantsym = false;
5232     this->noderef = false;
5233 }
5234 
create(Loc loc,Expression * e,Identifier * ident)5235 DotIdExp *DotIdExp::create(Loc loc, Expression *e, Identifier *ident)
5236 {
5237     return new DotIdExp(loc, e, ident);
5238 }
5239 
5240 /********************** DotTemplateExp ***********************************/
5241 
5242 // Mainly just a placeholder
5243 
DotTemplateExp(Loc loc,Expression * e,TemplateDeclaration * td)5244 DotTemplateExp::DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td)
5245         : UnaExp(loc, TOKdottd, sizeof(DotTemplateExp), e)
5246 
5247 {
5248     this->td = td;
5249 }
5250 
checkType()5251 bool DotTemplateExp::checkType()
5252 {
5253     error("%s %s has no type", td->kind(), toChars());
5254     return true;
5255 }
5256 
checkValue()5257 bool DotTemplateExp::checkValue()
5258 {
5259     error("%s %s has no value", td->kind(), toChars());
5260     return true;
5261 }
5262 
5263 /************************************************************/
5264 
DotVarExp(Loc loc,Expression * e,Declaration * var,bool hasOverloads)5265 DotVarExp::DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads)
5266         : UnaExp(loc, TOKdotvar, sizeof(DotVarExp), e)
5267 {
5268     //printf("DotVarExp()\n");
5269     this->var = var;
5270     this->hasOverloads = var->isVarDeclaration() ? false : hasOverloads;
5271 }
5272 
isLvalue()5273 bool DotVarExp::isLvalue()
5274 {
5275     return true;
5276 }
5277 
toLvalue(Scope *,Expression *)5278 Expression *DotVarExp::toLvalue(Scope *, Expression *)
5279 {
5280     //printf("DotVarExp::toLvalue(%s)\n", toChars());
5281     return this;
5282 }
5283 
5284 /***********************************************
5285  * Mark variable v as modified if it is inside a constructor that var
5286  * is a field in.
5287  */
modifyFieldVar(Loc loc,Scope * sc,VarDeclaration * var,Expression * e1)5288 int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1)
5289 {
5290     //printf("modifyFieldVar(var = %s)\n", var->toChars());
5291     Dsymbol *s = sc->func;
5292     while (1)
5293     {
5294         FuncDeclaration *fd = NULL;
5295         if (s)
5296             fd = s->isFuncDeclaration();
5297         if (fd &&
5298             ((fd->isCtorDeclaration() && var->isField()) ||
5299              (fd->isStaticCtorDeclaration() && !var->isField())) &&
5300             fd->toParent2() == var->toParent2() &&
5301             (!e1 || e1->op == TOKthis)
5302            )
5303         {
5304             bool result = true;
5305 
5306             var->ctorinit = true;
5307             //printf("setting ctorinit\n");
5308 
5309             if (var->isField() && sc->fieldinit && !sc->intypeof)
5310             {
5311                 assert(e1);
5312                 bool mustInit = ((var->storage_class & STCnodefaultctor) != 0 ||
5313                                  var->type->needsNested());
5314 
5315                 size_t dim = sc->fieldinit_dim;
5316                 AggregateDeclaration *ad = fd->isMember2();
5317                 assert(ad);
5318                 size_t i;
5319                 for (i = 0; i < dim; i++)   // same as findFieldIndexByName in ctfeexp.c ?
5320                 {
5321                     if (ad->fields[i] == var)
5322                         break;
5323                 }
5324                 assert(i < dim);
5325                 unsigned fi = sc->fieldinit[i];
5326 
5327                 if (fi & CSXthis_ctor)
5328                 {
5329                     if (var->type->isMutable() && e1->type->isMutable())
5330                         result = false;
5331                     else
5332                     {
5333                         const char *modStr = !var->type->isMutable() ? MODtoChars(var->type->mod) : MODtoChars(e1->type->mod);
5334                         ::error(loc, "%s field '%s' initialized multiple times", modStr, var->toChars());
5335                     }
5336                 }
5337                 else if (sc->noctor || (fi & CSXlabel))
5338                 {
5339                     if (!mustInit && var->type->isMutable() && e1->type->isMutable())
5340                         result = false;
5341                     else
5342                     {
5343                         const char *modStr = !var->type->isMutable() ? MODtoChars(var->type->mod) : MODtoChars(e1->type->mod);
5344                         ::error(loc, "%s field '%s' initialization is not allowed in loops or after labels", modStr, var->toChars());
5345                     }
5346                 }
5347                 sc->fieldinit[i] |= CSXthis_ctor;
5348                 if (var->overlapped) // Bugzilla 15258
5349                 {
5350                     for (size_t j = 0; j < ad->fields.dim; j++)
5351                     {
5352                         VarDeclaration *v = ad->fields[j];
5353                         if (v == var || !var->isOverlappedWith(v))
5354                             continue;
5355                         v->ctorinit = true;
5356                         sc->fieldinit[j] = CSXthis_ctor;
5357                     }
5358                 }
5359             }
5360             else if (fd != sc->func)
5361             {
5362                 if (var->type->isMutable())
5363                     result = false;
5364                 else if (sc->func->fes)
5365                 {
5366                     const char *p = var->isField() ? "field" : var->kind();
5367                     ::error(loc, "%s %s '%s' initialization is not allowed in foreach loop",
5368                         MODtoChars(var->type->mod), p, var->toChars());
5369                 }
5370                 else
5371                 {
5372                     const char *p = var->isField() ? "field" : var->kind();
5373                     ::error(loc, "%s %s '%s' initialization is not allowed in nested function '%s'",
5374                         MODtoChars(var->type->mod), p, var->toChars(), sc->func->toChars());
5375                 }
5376             }
5377             return result;
5378         }
5379         else
5380         {
5381             if (s)
5382             {
5383                 s = s->toParent2();
5384                 continue;
5385             }
5386         }
5387         break;
5388     }
5389     return false;
5390 }
5391 
checkModifiable(Scope * sc,int flag)5392 int DotVarExp::checkModifiable(Scope *sc, int flag)
5393 {
5394     //printf("DotVarExp::checkModifiable %s %s\n", toChars(), type->toChars());
5395     if (checkUnsafeAccess(sc, this, false, !flag))
5396         return 2;
5397 
5398     if (e1->op == TOKthis)
5399         return var->checkModify(loc, sc, type, e1, flag);
5400 
5401     //printf("\te1 = %s\n", e1->toChars());
5402     return e1->checkModifiable(sc, flag);
5403 }
5404 
modifiableLvalue(Scope * sc,Expression * e)5405 Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e)
5406 {
5407     return Expression::modifiableLvalue(sc, e);
5408 }
5409 
5410 /************************************************************/
5411 
5412 /* Things like:
5413  *      foo.bar!(args)
5414  */
5415 
DotTemplateInstanceExp(Loc loc,Expression * e,Identifier * name,Objects * tiargs)5416 DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs)
5417         : UnaExp(loc, TOKdotti, sizeof(DotTemplateInstanceExp), e)
5418 {
5419     //printf("DotTemplateInstanceExp()\n");
5420     this->ti = new TemplateInstance(loc, name);
5421     this->ti->tiargs = tiargs;
5422 }
5423 
DotTemplateInstanceExp(Loc loc,Expression * e,TemplateInstance * ti)5424 DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti)
5425         : UnaExp(loc, TOKdotti, sizeof(DotTemplateInstanceExp), e)
5426 {
5427     this->ti = ti;
5428 }
5429 
syntaxCopy()5430 Expression *DotTemplateInstanceExp::syntaxCopy()
5431 {
5432     return new DotTemplateInstanceExp(loc,
5433         e1->syntaxCopy(),
5434         ti->name,
5435         TemplateInstance::arraySyntaxCopy(ti->tiargs));
5436 }
5437 
findTempDecl(Scope * sc)5438 bool DotTemplateInstanceExp::findTempDecl(Scope *sc)
5439 {
5440     if (ti->tempdecl)
5441         return true;
5442 
5443     Expression *e = new DotIdExp(loc, e1, ti->name);
5444     e = semantic(e, sc);
5445     if (e->op == TOKdot)
5446         e = ((DotExp *)e)->e2;
5447 
5448     Dsymbol *s = NULL;
5449     switch (e->op)
5450     {
5451         case TOKoverloadset:    s = ((OverExp *)e)->vars;       break;
5452         case TOKdottd:          s = ((DotTemplateExp *)e)->td;  break;
5453         case TOKscope:          s = ((ScopeExp *)e)->sds;       break;
5454         case TOKdotvar:         s = ((DotVarExp *)e)->var;      break;
5455         case TOKvar:            s = ((VarExp *)e)->var;         break;
5456         default:                return false;
5457     }
5458     return ti->updateTempDecl(sc, s);
5459 }
5460 
5461 /************************************************************/
5462 
DelegateExp(Loc loc,Expression * e,FuncDeclaration * f,bool hasOverloads)5463 DelegateExp::DelegateExp(Loc loc, Expression *e, FuncDeclaration *f, bool hasOverloads)
5464         : UnaExp(loc, TOKdelegate, sizeof(DelegateExp), e)
5465 {
5466     this->func = f;
5467     this->hasOverloads = hasOverloads;
5468 }
5469 
5470 /************************************************************/
5471 
DotTypeExp(Loc loc,Expression * e,Dsymbol * s)5472 DotTypeExp::DotTypeExp(Loc loc, Expression *e, Dsymbol *s)
5473         : UnaExp(loc, TOKdottype, sizeof(DotTypeExp), e)
5474 {
5475     this->sym = s;
5476     this->type = NULL;
5477 }
5478 
5479 /************************************************************/
5480 
CallExp(Loc loc,Expression * e,Expressions * exps)5481 CallExp::CallExp(Loc loc, Expression *e, Expressions *exps)
5482         : UnaExp(loc, TOKcall, sizeof(CallExp), e)
5483 {
5484     this->arguments = exps;
5485     this->f = NULL;
5486     this->directcall = false;
5487 }
5488 
CallExp(Loc loc,Expression * e)5489 CallExp::CallExp(Loc loc, Expression *e)
5490         : UnaExp(loc, TOKcall, sizeof(CallExp), e)
5491 {
5492     this->arguments = NULL;
5493     this->f = NULL;
5494     this->directcall = false;
5495 }
5496 
CallExp(Loc loc,Expression * e,Expression * earg1)5497 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1)
5498         : UnaExp(loc, TOKcall, sizeof(CallExp), e)
5499 {
5500     Expressions *arguments = new Expressions();
5501     if (earg1)
5502     {
5503         arguments->setDim(1);
5504         (*arguments)[0] = earg1;
5505     }
5506     this->arguments = arguments;
5507     this->f = NULL;
5508     this->directcall = false;
5509 }
5510 
CallExp(Loc loc,Expression * e,Expression * earg1,Expression * earg2)5511 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2)
5512         : UnaExp(loc, TOKcall, sizeof(CallExp), e)
5513 {
5514     Expressions *arguments = new Expressions();
5515     arguments->setDim(2);
5516     (*arguments)[0] = earg1;
5517     (*arguments)[1] = earg2;
5518 
5519     this->arguments = arguments;
5520     this->f = NULL;
5521     this->directcall = false;
5522 }
5523 
create(Loc loc,Expression * e,Expressions * exps)5524 CallExp *CallExp::create(Loc loc, Expression *e, Expressions *exps)
5525 {
5526     return new CallExp(loc, e, exps);
5527 }
5528 
create(Loc loc,Expression * e)5529 CallExp *CallExp::create(Loc loc, Expression *e)
5530 {
5531     return new CallExp(loc, e);
5532 }
5533 
create(Loc loc,Expression * e,Expression * earg1)5534 CallExp *CallExp::create(Loc loc, Expression *e, Expression *earg1)
5535 {
5536     return new CallExp(loc, e, earg1);
5537 }
5538 
syntaxCopy()5539 Expression *CallExp::syntaxCopy()
5540 {
5541     return new CallExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
5542 }
5543 
isLvalue()5544 bool CallExp::isLvalue()
5545 {
5546     Type *tb = e1->type->toBasetype();
5547     if (tb->ty == Tdelegate || tb->ty == Tpointer)
5548         tb = tb->nextOf();
5549     if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref)
5550     {
5551         if (e1->op == TOKdotvar)
5552             if (((DotVarExp *)e1)->var->isCtorDeclaration())
5553                 return false;
5554         return true;               // function returns a reference
5555     }
5556     return false;
5557 }
5558 
toLvalue(Scope * sc,Expression * e)5559 Expression *CallExp::toLvalue(Scope *sc, Expression *e)
5560 {
5561     if (isLvalue())
5562         return this;
5563     return Expression::toLvalue(sc, e);
5564 }
5565 
addDtorHook(Scope * sc)5566 Expression *CallExp::addDtorHook(Scope *sc)
5567 {
5568     /* Only need to add dtor hook if it's a type that needs destruction.
5569      * Use same logic as VarDeclaration::callScopeDtor()
5570      */
5571 
5572     if (e1->type && e1->type->ty == Tfunction)
5573     {
5574         TypeFunction *tf = (TypeFunction *)e1->type;
5575         if (tf->isref)
5576             return this;
5577     }
5578 
5579     Type *tv = type->baseElemOf();
5580     if (tv->ty == Tstruct)
5581     {
5582         TypeStruct *ts = (TypeStruct *)tv;
5583         StructDeclaration *sd = ts->sym;
5584         if (sd->dtor)
5585         {
5586             /* Type needs destruction, so declare a tmp
5587              * which the back end will recognize and call dtor on
5588              */
5589             VarDeclaration *tmp = copyToTemp(0, "__tmpfordtor", this);
5590             DeclarationExp *de = new DeclarationExp(loc, tmp);
5591             VarExp *ve = new VarExp(loc, tmp);
5592             Expression *e = new CommaExp(loc, de, ve);
5593             e = semantic(e, sc);
5594             return e;
5595         }
5596     }
5597     return this;
5598 }
5599 
5600 FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL)
5601 {
5602     if (e->op == TOKaddress)
5603     {
5604         Expression *ae1 = ((AddrExp *)e)->e1;
5605         if (ae1->op == TOKvar)
5606         {
5607             VarExp *ve = (VarExp *)ae1;
5608             if (hasOverloads)
5609                 *hasOverloads = ve->hasOverloads;
5610             return ve->var->isFuncDeclaration();
5611         }
5612         if (ae1->op == TOKdotvar)
5613         {
5614             DotVarExp *dve = (DotVarExp *)ae1;
5615             if (hasOverloads)
5616                 *hasOverloads = dve->hasOverloads;
5617             return dve->var->isFuncDeclaration();
5618         }
5619     }
5620     else
5621     {
5622         if (e->op == TOKsymoff)
5623         {
5624             SymOffExp *soe = (SymOffExp *)e;
5625             if (hasOverloads)
5626                 *hasOverloads = soe->hasOverloads;
5627             return soe->var->isFuncDeclaration();
5628         }
5629         if (e->op == TOKdelegate)
5630         {
5631             DelegateExp *dge = (DelegateExp *)e;
5632             if (hasOverloads)
5633                 *hasOverloads = dge->hasOverloads;
5634             return dge->func->isFuncDeclaration();
5635         }
5636     }
5637     return NULL;
5638 }
5639 
5640 /************************************************************/
5641 
AddrExp(Loc loc,Expression * e)5642 AddrExp::AddrExp(Loc loc, Expression *e)
5643         : UnaExp(loc, TOKaddress, sizeof(AddrExp), e)
5644 {
5645 }
5646 
AddrExp(Loc loc,Expression * e,Type * t)5647 AddrExp::AddrExp(Loc loc, Expression *e, Type *t)
5648         : UnaExp(loc, TOKaddress, sizeof(AddrExp), e)
5649 {
5650     type = t;
5651 }
5652 
5653 /************************************************************/
5654 
PtrExp(Loc loc,Expression * e)5655 PtrExp::PtrExp(Loc loc, Expression *e)
5656         : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
5657 {
5658 //    if (e->type)
5659 //      type = ((TypePointer *)e->type)->next;
5660 }
5661 
PtrExp(Loc loc,Expression * e,Type * t)5662 PtrExp::PtrExp(Loc loc, Expression *e, Type *t)
5663         : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
5664 {
5665     type = t;
5666 }
5667 
isLvalue()5668 bool PtrExp::isLvalue()
5669 {
5670     return true;
5671 }
5672 
toLvalue(Scope *,Expression *)5673 Expression *PtrExp::toLvalue(Scope *, Expression *)
5674 {
5675     return this;
5676 }
5677 
checkModifiable(Scope * sc,int flag)5678 int PtrExp::checkModifiable(Scope *sc, int flag)
5679 {
5680     if (e1->op == TOKsymoff)
5681     {   SymOffExp *se = (SymOffExp *)e1;
5682         return se->var->checkModify(loc, sc, type, NULL, flag);
5683     }
5684     else if (e1->op == TOKaddress)
5685     {
5686         AddrExp *ae = (AddrExp *)e1;
5687         return ae->e1->checkModifiable(sc, flag);
5688     }
5689     return 1;
5690 }
5691 
modifiableLvalue(Scope * sc,Expression * e)5692 Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e)
5693 {
5694     //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars());
5695     return Expression::modifiableLvalue(sc, e);
5696 }
5697 
5698 /************************************************************/
5699 
NegExp(Loc loc,Expression * e)5700 NegExp::NegExp(Loc loc, Expression *e)
5701         : UnaExp(loc, TOKneg, sizeof(NegExp), e)
5702 {
5703 }
5704 
5705 /************************************************************/
5706 
UAddExp(Loc loc,Expression * e)5707 UAddExp::UAddExp(Loc loc, Expression *e)
5708         : UnaExp(loc, TOKuadd, sizeof(UAddExp), e)
5709 {
5710 }
5711 
5712 /************************************************************/
5713 
ComExp(Loc loc,Expression * e)5714 ComExp::ComExp(Loc loc, Expression *e)
5715         : UnaExp(loc, TOKtilde, sizeof(ComExp), e)
5716 {
5717 }
5718 
5719 /************************************************************/
5720 
NotExp(Loc loc,Expression * e)5721 NotExp::NotExp(Loc loc, Expression *e)
5722         : UnaExp(loc, TOKnot, sizeof(NotExp), e)
5723 {
5724 }
5725 
5726 /************************************************************/
5727 
DeleteExp(Loc loc,Expression * e,bool isRAII)5728 DeleteExp::DeleteExp(Loc loc, Expression *e, bool isRAII)
5729         : UnaExp(loc, TOKdelete, sizeof(DeleteExp), e)
5730 {
5731     this->isRAII = isRAII;
5732 }
5733 
toBoolean(Scope *)5734 Expression *DeleteExp::toBoolean(Scope *)
5735 {
5736     error("delete does not give a boolean result");
5737     return new ErrorExp();
5738 }
5739 
5740 /************************************************************/
5741 
CastExp(Loc loc,Expression * e,Type * t)5742 CastExp::CastExp(Loc loc, Expression *e, Type *t)
5743         : UnaExp(loc, TOKcast, sizeof(CastExp), e)
5744 {
5745     this->to = t;
5746     this->mod = (unsigned char)~0;
5747 }
5748 
5749 /* For cast(const) and cast(immutable)
5750  */
CastExp(Loc loc,Expression * e,unsigned char mod)5751 CastExp::CastExp(Loc loc, Expression *e, unsigned char mod)
5752         : UnaExp(loc, TOKcast, sizeof(CastExp), e)
5753 {
5754     this->to = NULL;
5755     this->mod = mod;
5756 }
5757 
syntaxCopy()5758 Expression *CastExp::syntaxCopy()
5759 {
5760     return to ? new CastExp(loc, e1->syntaxCopy(), to->syntaxCopy())
5761               : new CastExp(loc, e1->syntaxCopy(), mod);
5762 }
5763 
5764 /************************************************************/
5765 
VectorExp(Loc loc,Expression * e,Type * t)5766 VectorExp::VectorExp(Loc loc, Expression *e, Type *t)
5767         : UnaExp(loc, TOKvector, sizeof(VectorExp), e)
5768 {
5769     assert(t->ty == Tvector);
5770     to = (TypeVector *)t;
5771     dim = ~0;
5772     ownedByCtfe = OWNEDcode;
5773 }
5774 
create(Loc loc,Expression * e,Type * t)5775 VectorExp *VectorExp::create(Loc loc, Expression *e, Type *t)
5776 {
5777     return new VectorExp(loc, e, t);
5778 }
5779 
syntaxCopy()5780 Expression *VectorExp::syntaxCopy()
5781 {
5782     return new VectorExp(loc, e1->syntaxCopy(), to->syntaxCopy());
5783 }
5784 
5785 /************************************************************/
5786 
VectorArrayExp(Loc loc,Expression * e1)5787 VectorArrayExp::VectorArrayExp(Loc loc, Expression *e1)
5788         : UnaExp(loc, TOKvectorarray, sizeof(VectorArrayExp), e1)
5789 {
5790 }
5791 
isLvalue()5792 bool VectorArrayExp::isLvalue()
5793 {
5794     return e1->isLvalue();
5795 }
5796 
toLvalue(Scope * sc,Expression * e)5797 Expression *VectorArrayExp::toLvalue(Scope *sc, Expression *e)
5798 {
5799     e1 = e1->toLvalue(sc, e);
5800     return this;
5801 }
5802 
5803 /************************************************************/
5804 
SliceExp(Loc loc,Expression * e1,IntervalExp * ie)5805 SliceExp::SliceExp(Loc loc, Expression *e1, IntervalExp *ie)
5806         : UnaExp(loc, TOKslice, sizeof(SliceExp), e1)
5807 {
5808     this->upr = ie ? ie->upr : NULL;
5809     this->lwr = ie ? ie->lwr : NULL;
5810     lengthVar = NULL;
5811     upperIsInBounds = false;
5812     lowerIsLessThanUpper = false;
5813     arrayop = false;
5814 }
5815 
SliceExp(Loc loc,Expression * e1,Expression * lwr,Expression * upr)5816 SliceExp::SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr)
5817         : UnaExp(loc, TOKslice, sizeof(SliceExp), e1)
5818 {
5819     this->upr = upr;
5820     this->lwr = lwr;
5821     lengthVar = NULL;
5822     upperIsInBounds = false;
5823     lowerIsLessThanUpper = false;
5824     arrayop = false;
5825 }
5826 
syntaxCopy()5827 Expression *SliceExp::syntaxCopy()
5828 {
5829     SliceExp *se = new SliceExp(loc, e1->syntaxCopy(),
5830         lwr ? lwr->syntaxCopy() : NULL,
5831         upr ? upr->syntaxCopy() : NULL);
5832     se->lengthVar = this->lengthVar;    // bug7871
5833     return se;
5834 }
5835 
checkModifiable(Scope * sc,int flag)5836 int SliceExp::checkModifiable(Scope *sc, int flag)
5837 {
5838     //printf("SliceExp::checkModifiable %s\n", toChars());
5839     if (e1->type->ty == Tsarray ||
5840         (e1->op == TOKindex && e1->type->ty != Tarray) ||
5841         e1->op == TOKslice)
5842     {
5843         return e1->checkModifiable(sc, flag);
5844     }
5845     return 1;
5846 }
5847 
isLvalue()5848 bool SliceExp::isLvalue()
5849 {
5850     /* slice expression is rvalue in default, but
5851      * conversion to reference of static array is only allowed.
5852      */
5853     return (type && type->toBasetype()->ty == Tsarray);
5854 }
5855 
toLvalue(Scope * sc,Expression * e)5856 Expression *SliceExp::toLvalue(Scope *sc, Expression *e)
5857 {
5858     //printf("SliceExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL);
5859     return (type && type->toBasetype()->ty == Tsarray)
5860             ? this : Expression::toLvalue(sc, e);
5861 }
5862 
modifiableLvalue(Scope *,Expression *)5863 Expression *SliceExp::modifiableLvalue(Scope *, Expression *)
5864 {
5865     error("slice expression %s is not a modifiable lvalue", toChars());
5866     return this;
5867 }
5868 
isBool(bool result)5869 bool SliceExp::isBool(bool result)
5870 {
5871     return e1->isBool(result);
5872 }
5873 
5874 /********************** ArrayLength **************************************/
5875 
ArrayLengthExp(Loc loc,Expression * e1)5876 ArrayLengthExp::ArrayLengthExp(Loc loc, Expression *e1)
5877         : UnaExp(loc, TOKarraylength, sizeof(ArrayLengthExp), e1)
5878 {
5879 }
5880 
opAssignToOp(Loc loc,TOK op,Expression * e1,Expression * e2)5881 Expression *opAssignToOp(Loc loc, TOK op, Expression *e1, Expression *e2)
5882 {   Expression *e;
5883 
5884     switch (op)
5885     {
5886         case TOKaddass:   e = new AddExp(loc, e1, e2);  break;
5887         case TOKminass:   e = new MinExp(loc, e1, e2);  break;
5888         case TOKmulass:   e = new MulExp(loc, e1, e2);  break;
5889         case TOKdivass:   e = new DivExp(loc, e1, e2);  break;
5890         case TOKmodass:   e = new ModExp(loc, e1, e2);  break;
5891         case TOKandass:   e = new AndExp(loc, e1, e2);  break;
5892         case TOKorass:    e = new OrExp (loc, e1, e2);  break;
5893         case TOKxorass:   e = new XorExp(loc, e1, e2);  break;
5894         case TOKshlass:   e = new ShlExp(loc, e1, e2);  break;
5895         case TOKshrass:   e = new ShrExp(loc, e1, e2);  break;
5896         case TOKushrass:  e = new UshrExp(loc, e1, e2); break;
5897         default:        assert(0);
5898     }
5899     return e;
5900 }
5901 
5902 /*********************
5903  * Rewrite:
5904  *    array.length op= e2
5905  * as:
5906  *    array.length = array.length op e2
5907  * or:
5908  *    auto tmp = &array;
5909  *    (*tmp).length = (*tmp).length op e2
5910  */
5911 
rewriteOpAssign(BinExp * exp)5912 Expression *ArrayLengthExp::rewriteOpAssign(BinExp *exp)
5913 {
5914     Expression *e;
5915 
5916     assert(exp->e1->op == TOKarraylength);
5917     ArrayLengthExp *ale = (ArrayLengthExp *)exp->e1;
5918     if (ale->e1->op == TOKvar)
5919     {
5920         e = opAssignToOp(exp->loc, exp->op, ale, exp->e2);
5921         e = new AssignExp(exp->loc, ale->syntaxCopy(), e);
5922     }
5923     else
5924     {
5925         /*    auto tmp = &array;
5926          *    (*tmp).length = (*tmp).length op e2
5927          */
5928         VarDeclaration *tmp = copyToTemp(0, "__arraylength", new AddrExp(ale->loc, ale->e1));
5929 
5930         Expression *e1 = new ArrayLengthExp(ale->loc, new PtrExp(ale->loc, new VarExp(ale->loc, tmp)));
5931         Expression *elvalue = e1->syntaxCopy();
5932         e = opAssignToOp(exp->loc, exp->op, e1, exp->e2);
5933         e = new AssignExp(exp->loc, elvalue, e);
5934         e = new CommaExp(exp->loc, new DeclarationExp(ale->loc, tmp), e);
5935     }
5936     return e;
5937 }
5938 
5939 /*********************** IntervalExp ********************************/
5940 
5941 // Mainly just a placeholder
5942 
IntervalExp(Loc loc,Expression * lwr,Expression * upr)5943 IntervalExp::IntervalExp(Loc loc, Expression *lwr, Expression *upr)
5944         : Expression(loc, TOKinterval, sizeof(IntervalExp))
5945 {
5946     this->lwr = lwr;
5947     this->upr = upr;
5948 }
5949 
syntaxCopy()5950 Expression *IntervalExp::syntaxCopy()
5951 {
5952     return new IntervalExp(loc, lwr->syntaxCopy(), upr->syntaxCopy());
5953 }
5954 
5955 /********************** DelegatePtrExp **************************************/
5956 
DelegatePtrExp(Loc loc,Expression * e1)5957 DelegatePtrExp::DelegatePtrExp(Loc loc, Expression *e1)
5958         : UnaExp(loc, TOKdelegateptr, sizeof(DelegatePtrExp), e1)
5959 {
5960 }
5961 
isLvalue()5962 bool DelegatePtrExp::isLvalue()
5963 {
5964     return e1->isLvalue();
5965 }
5966 
toLvalue(Scope * sc,Expression * e)5967 Expression *DelegatePtrExp::toLvalue(Scope *sc, Expression *e)
5968 {
5969     e1 = e1->toLvalue(sc, e);
5970     return this;
5971 }
5972 
modifiableLvalue(Scope * sc,Expression * e)5973 Expression *DelegatePtrExp::modifiableLvalue(Scope *sc, Expression *e)
5974 {
5975     if (sc->func->setUnsafe())
5976     {
5977         error("cannot modify delegate pointer in @safe code %s", toChars());
5978         return new ErrorExp();
5979     }
5980     return Expression::modifiableLvalue(sc, e);
5981 }
5982 
5983 /********************** DelegateFuncptrExp **************************************/
5984 
DelegateFuncptrExp(Loc loc,Expression * e1)5985 DelegateFuncptrExp::DelegateFuncptrExp(Loc loc, Expression *e1)
5986         : UnaExp(loc, TOKdelegatefuncptr, sizeof(DelegateFuncptrExp), e1)
5987 {
5988 }
5989 
isLvalue()5990 bool DelegateFuncptrExp::isLvalue()
5991 {
5992     return e1->isLvalue();
5993 }
5994 
toLvalue(Scope * sc,Expression * e)5995 Expression *DelegateFuncptrExp::toLvalue(Scope *sc, Expression *e)
5996 {
5997     e1 = e1->toLvalue(sc, e);
5998     return this;
5999 }
6000 
modifiableLvalue(Scope * sc,Expression * e)6001 Expression *DelegateFuncptrExp::modifiableLvalue(Scope *sc, Expression *e)
6002 {
6003     if (sc->func->setUnsafe())
6004     {
6005         error("cannot modify delegate function pointer in @safe code %s", toChars());
6006         return new ErrorExp();
6007     }
6008     return Expression::modifiableLvalue(sc, e);
6009 }
6010 
6011 /*********************** ArrayExp *************************************/
6012 
6013 // e1 [ i1, i2, i3, ... ]
6014 
ArrayExp(Loc loc,Expression * e1,Expression * index)6015 ArrayExp::ArrayExp(Loc loc, Expression *e1, Expression *index)
6016         : UnaExp(loc, TOKarray, sizeof(ArrayExp), e1)
6017 {
6018     arguments = new Expressions();
6019     if (index)
6020         arguments->push(index);
6021     lengthVar = NULL;
6022     currentDimension = 0;
6023 }
6024 
ArrayExp(Loc loc,Expression * e1,Expressions * args)6025 ArrayExp::ArrayExp(Loc loc, Expression *e1, Expressions *args)
6026         : UnaExp(loc, TOKarray, sizeof(ArrayExp), e1)
6027 {
6028     arguments = args;
6029     lengthVar = NULL;
6030     currentDimension = 0;
6031 }
6032 
syntaxCopy()6033 Expression *ArrayExp::syntaxCopy()
6034 {
6035     ArrayExp *ae = new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
6036     ae->lengthVar = this->lengthVar;    // bug7871
6037     return ae;
6038 }
6039 
isLvalue()6040 bool ArrayExp::isLvalue()
6041 {
6042     if (type && type->toBasetype()->ty == Tvoid)
6043         return false;
6044     return true;
6045 }
6046 
toLvalue(Scope *,Expression *)6047 Expression *ArrayExp::toLvalue(Scope *, Expression *)
6048 {
6049     if (type && type->toBasetype()->ty == Tvoid)
6050         error("voids have no value");
6051     return this;
6052 }
6053 
6054 /************************* DotExp ***********************************/
6055 
DotExp(Loc loc,Expression * e1,Expression * e2)6056 DotExp::DotExp(Loc loc, Expression *e1, Expression *e2)
6057         : BinExp(loc, TOKdot, sizeof(DotExp), e1, e2)
6058 {
6059 }
6060 
6061 /************************* CommaExp ***********************************/
6062 
CommaExp(Loc loc,Expression * e1,Expression * e2,bool generated)6063 CommaExp::CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated)
6064         : BinExp(loc, TOKcomma, sizeof(CommaExp), e1, e2)
6065 {
6066     isGenerated = generated;
6067     allowCommaExp = generated;
6068 }
6069 
isLvalue()6070 bool CommaExp::isLvalue()
6071 {
6072     return e2->isLvalue();
6073 }
6074 
toLvalue(Scope * sc,Expression *)6075 Expression *CommaExp::toLvalue(Scope *sc, Expression *)
6076 {
6077     e2 = e2->toLvalue(sc, NULL);
6078     return this;
6079 }
6080 
checkModifiable(Scope * sc,int flag)6081 int CommaExp::checkModifiable(Scope *sc, int flag)
6082 {
6083     return e2->checkModifiable(sc, flag);
6084 }
6085 
modifiableLvalue(Scope * sc,Expression * e)6086 Expression *CommaExp::modifiableLvalue(Scope *sc, Expression *e)
6087 {
6088     e2 = e2->modifiableLvalue(sc, e);
6089     return this;
6090 }
6091 
isBool(bool result)6092 bool CommaExp::isBool(bool result)
6093 {
6094     return e2->isBool(result);
6095 }
6096 
toBoolean(Scope * sc)6097 Expression *CommaExp::toBoolean(Scope *sc)
6098 {
6099     Expression *ex2 = e2->toBoolean(sc);
6100     if (ex2->op == TOKerror)
6101         return ex2;
6102     e2 = ex2;
6103     type = e2->type;
6104     return this;
6105 }
6106 
addDtorHook(Scope * sc)6107 Expression *CommaExp::addDtorHook(Scope *sc)
6108 {
6109     e2 = e2->addDtorHook(sc);
6110     return this;
6111 }
6112 
6113 /************************** IndexExp **********************************/
6114 
6115 // e1 [ e2 ]
6116 
IndexExp(Loc loc,Expression * e1,Expression * e2)6117 IndexExp::IndexExp(Loc loc, Expression *e1, Expression *e2)
6118         : BinExp(loc, TOKindex, sizeof(IndexExp), e1, e2)
6119 {
6120     //printf("IndexExp::IndexExp('%s')\n", toChars());
6121     lengthVar = NULL;
6122     modifiable = false;     // assume it is an rvalue
6123     indexIsInBounds = false;
6124 }
6125 
syntaxCopy()6126 Expression *IndexExp::syntaxCopy()
6127 {
6128     IndexExp *ie = new IndexExp(loc, e1->syntaxCopy(), e2->syntaxCopy());
6129     ie->lengthVar = this->lengthVar;    // bug7871
6130     return ie;
6131 }
6132 
isLvalue()6133 bool IndexExp::isLvalue()
6134 {
6135     return true;
6136 }
6137 
toLvalue(Scope *,Expression *)6138 Expression *IndexExp::toLvalue(Scope *, Expression *)
6139 {
6140     return this;
6141 }
6142 
checkModifiable(Scope * sc,int flag)6143 int IndexExp::checkModifiable(Scope *sc, int flag)
6144 {
6145     if (e1->type->ty == Tsarray ||
6146         e1->type->ty == Taarray ||
6147         (e1->op == TOKindex && e1->type->ty != Tarray) ||
6148         e1->op == TOKslice)
6149     {
6150         return e1->checkModifiable(sc, flag);
6151     }
6152     return 1;
6153 }
6154 
modifiableLvalue(Scope * sc,Expression * e)6155 Expression *IndexExp::modifiableLvalue(Scope *sc, Expression *e)
6156 {
6157     //printf("IndexExp::modifiableLvalue(%s)\n", toChars());
6158     Expression *ex = markSettingAAElem();
6159     if (ex->op == TOKerror)
6160         return ex;
6161 
6162     return Expression::modifiableLvalue(sc, e);
6163 }
6164 
markSettingAAElem()6165 Expression *IndexExp::markSettingAAElem()
6166 {
6167     if (e1->type->toBasetype()->ty == Taarray)
6168     {
6169         Type *t2b = e2->type->toBasetype();
6170         if (t2b->ty == Tarray && t2b->nextOf()->isMutable())
6171         {
6172             error("associative arrays can only be assigned values with immutable keys, not %s", e2->type->toChars());
6173             return new ErrorExp();
6174         }
6175         modifiable = true;
6176 
6177         if (e1->op == TOKindex)
6178         {
6179             Expression *ex = ((IndexExp *)e1)->markSettingAAElem();
6180             if (ex->op == TOKerror)
6181                 return ex;
6182             assert(ex == e1);
6183         }
6184     }
6185     return this;
6186 }
6187 
6188 /************************* PostExp ***********************************/
6189 
PostExp(TOK op,Loc loc,Expression * e)6190 PostExp::PostExp(TOK op, Loc loc, Expression *e)
6191         : BinExp(loc, op, sizeof(PostExp), e,
6192           new IntegerExp(loc, 1, Type::tint32))
6193 {
6194 }
6195 
6196 /************************* PreExp ***********************************/
6197 
PreExp(TOK op,Loc loc,Expression * e)6198 PreExp::PreExp(TOK op, Loc loc, Expression *e)
6199         : UnaExp(loc, op, sizeof(PreExp), e)
6200 {
6201 }
6202 
6203 /************************************************************/
6204 
6205 /* op can be TOKassign, TOKconstruct, or TOKblit */
6206 
AssignExp(Loc loc,Expression * e1,Expression * e2)6207 AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2)
6208         : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2)
6209 {
6210     memset = 0;
6211 }
6212 
isLvalue()6213 bool AssignExp::isLvalue()
6214 {
6215     // Array-op 'x[] = y[]' should make an rvalue.
6216     // Setting array length 'x.length = v' should make an rvalue.
6217     if (e1->op == TOKslice ||
6218         e1->op == TOKarraylength)
6219     {
6220         return false;
6221     }
6222     return true;
6223 }
6224 
toLvalue(Scope * sc,Expression * ex)6225 Expression *AssignExp::toLvalue(Scope *sc, Expression *ex)
6226 {
6227     if (e1->op == TOKslice ||
6228         e1->op == TOKarraylength)
6229     {
6230         return Expression::toLvalue(sc, ex);
6231     }
6232 
6233     /* In front-end level, AssignExp should make an lvalue of e1.
6234      * Taking the address of e1 will be handled in low level layer,
6235      * so this function does nothing.
6236      */
6237     return this;
6238 }
6239 
toBoolean(Scope *)6240 Expression *AssignExp::toBoolean(Scope *)
6241 {
6242     // Things like:
6243     //  if (a = b) ...
6244     // are usually mistakes.
6245 
6246     error("assignment cannot be used as a condition, perhaps == was meant?");
6247     return new ErrorExp();
6248 }
6249 
6250 /************************************************************/
6251 
ConstructExp(Loc loc,Expression * e1,Expression * e2)6252 ConstructExp::ConstructExp(Loc loc, Expression *e1, Expression *e2)
6253     : AssignExp(loc, e1, e2)
6254 {
6255     op = TOKconstruct;
6256 }
6257 
ConstructExp(Loc loc,VarDeclaration * v,Expression * e2)6258 ConstructExp::ConstructExp(Loc loc, VarDeclaration *v, Expression *e2)
6259     : AssignExp(loc, new VarExp(loc, v), e2)
6260 {
6261     assert(v->type && e1->type);
6262     op = TOKconstruct;
6263 
6264     if (v->storage_class & (STCref | STCout))
6265         memset |= referenceInit;
6266 }
6267 
6268 /************************************************************/
6269 
BlitExp(Loc loc,Expression * e1,Expression * e2)6270 BlitExp::BlitExp(Loc loc, Expression *e1, Expression *e2)
6271     : AssignExp(loc, e1, e2)
6272 {
6273     op = TOKblit;
6274 }
6275 
BlitExp(Loc loc,VarDeclaration * v,Expression * e2)6276 BlitExp::BlitExp(Loc loc, VarDeclaration *v, Expression *e2)
6277     : AssignExp(loc, new VarExp(loc, v), e2)
6278 {
6279     assert(v->type && e1->type);
6280     op = TOKblit;
6281 
6282     if (v->storage_class & (STCref | STCout))
6283         memset |= referenceInit;
6284 }
6285 
6286 /************************************************************/
6287 
AddAssignExp(Loc loc,Expression * e1,Expression * e2)6288 AddAssignExp::AddAssignExp(Loc loc, Expression *e1, Expression *e2)
6289         : BinAssignExp(loc, TOKaddass, sizeof(AddAssignExp), e1, e2)
6290 {
6291 }
6292 
6293 /************************************************************/
6294 
MinAssignExp(Loc loc,Expression * e1,Expression * e2)6295 MinAssignExp::MinAssignExp(Loc loc, Expression *e1, Expression *e2)
6296         : BinAssignExp(loc, TOKminass, sizeof(MinAssignExp), e1, e2)
6297 {
6298 }
6299 
6300 /************************************************************/
6301 
CatAssignExp(Loc loc,Expression * e1,Expression * e2)6302 CatAssignExp::CatAssignExp(Loc loc, Expression *e1, Expression *e2)
6303         : BinAssignExp(loc, TOKcatass, sizeof(CatAssignExp), e1, e2)
6304 {
6305 }
6306 
6307 /************************************************************/
6308 
MulAssignExp(Loc loc,Expression * e1,Expression * e2)6309 MulAssignExp::MulAssignExp(Loc loc, Expression *e1, Expression *e2)
6310         : BinAssignExp(loc, TOKmulass, sizeof(MulAssignExp), e1, e2)
6311 {
6312 }
6313 
6314 /************************************************************/
6315 
DivAssignExp(Loc loc,Expression * e1,Expression * e2)6316 DivAssignExp::DivAssignExp(Loc loc, Expression *e1, Expression *e2)
6317         : BinAssignExp(loc, TOKdivass, sizeof(DivAssignExp), e1, e2)
6318 {
6319 }
6320 
6321 /************************************************************/
6322 
ModAssignExp(Loc loc,Expression * e1,Expression * e2)6323 ModAssignExp::ModAssignExp(Loc loc, Expression *e1, Expression *e2)
6324         : BinAssignExp(loc, TOKmodass, sizeof(ModAssignExp), e1, e2)
6325 {
6326 }
6327 
6328 /************************************************************/
6329 
ShlAssignExp(Loc loc,Expression * e1,Expression * e2)6330 ShlAssignExp::ShlAssignExp(Loc loc, Expression *e1, Expression *e2)
6331         : BinAssignExp(loc, TOKshlass, sizeof(ShlAssignExp), e1, e2)
6332 {
6333 }
6334 
6335 /************************************************************/
6336 
ShrAssignExp(Loc loc,Expression * e1,Expression * e2)6337 ShrAssignExp::ShrAssignExp(Loc loc, Expression *e1, Expression *e2)
6338         : BinAssignExp(loc, TOKshrass, sizeof(ShrAssignExp), e1, e2)
6339 {
6340 }
6341 
6342 /************************************************************/
6343 
UshrAssignExp(Loc loc,Expression * e1,Expression * e2)6344 UshrAssignExp::UshrAssignExp(Loc loc, Expression *e1, Expression *e2)
6345         : BinAssignExp(loc, TOKushrass, sizeof(UshrAssignExp), e1, e2)
6346 {
6347 }
6348 
6349 /************************************************************/
6350 
AndAssignExp(Loc loc,Expression * e1,Expression * e2)6351 AndAssignExp::AndAssignExp(Loc loc, Expression *e1, Expression *e2)
6352         : BinAssignExp(loc, TOKandass, sizeof(AndAssignExp), e1, e2)
6353 {
6354 }
6355 
6356 /************************************************************/
6357 
OrAssignExp(Loc loc,Expression * e1,Expression * e2)6358 OrAssignExp::OrAssignExp(Loc loc, Expression *e1, Expression *e2)
6359         : BinAssignExp(loc, TOKorass, sizeof(OrAssignExp), e1, e2)
6360 {
6361 }
6362 
6363 /************************************************************/
6364 
XorAssignExp(Loc loc,Expression * e1,Expression * e2)6365 XorAssignExp::XorAssignExp(Loc loc, Expression *e1, Expression *e2)
6366         : BinAssignExp(loc, TOKxorass, sizeof(XorAssignExp), e1, e2)
6367 {
6368 }
6369 
6370 /***************** PowAssignExp *******************************************/
6371 
PowAssignExp(Loc loc,Expression * e1,Expression * e2)6372 PowAssignExp::PowAssignExp(Loc loc, Expression *e1, Expression *e2)
6373         : BinAssignExp(loc, TOKpowass, sizeof(PowAssignExp), e1, e2)
6374 {
6375 }
6376 
6377 /************************* AddExp *****************************/
6378 
AddExp(Loc loc,Expression * e1,Expression * e2)6379 AddExp::AddExp(Loc loc, Expression *e1, Expression *e2)
6380         : BinExp(loc, TOKadd, sizeof(AddExp), e1, e2)
6381 {
6382 }
6383 
6384 /************************************************************/
6385 
MinExp(Loc loc,Expression * e1,Expression * e2)6386 MinExp::MinExp(Loc loc, Expression *e1, Expression *e2)
6387         : BinExp(loc, TOKmin, sizeof(MinExp), e1, e2)
6388 {
6389 }
6390 
6391 /************************* CatExp *****************************/
6392 
CatExp(Loc loc,Expression * e1,Expression * e2)6393 CatExp::CatExp(Loc loc, Expression *e1, Expression *e2)
6394         : BinExp(loc, TOKcat, sizeof(CatExp), e1, e2)
6395 {
6396 }
6397 
6398 /************************************************************/
6399 
MulExp(Loc loc,Expression * e1,Expression * e2)6400 MulExp::MulExp(Loc loc, Expression *e1, Expression *e2)
6401         : BinExp(loc, TOKmul, sizeof(MulExp), e1, e2)
6402 {
6403 }
6404 
6405 /************************************************************/
6406 
DivExp(Loc loc,Expression * e1,Expression * e2)6407 DivExp::DivExp(Loc loc, Expression *e1, Expression *e2)
6408         : BinExp(loc, TOKdiv, sizeof(DivExp), e1, e2)
6409 {
6410 }
6411 
6412 /************************************************************/
6413 
ModExp(Loc loc,Expression * e1,Expression * e2)6414 ModExp::ModExp(Loc loc, Expression *e1, Expression *e2)
6415         : BinExp(loc, TOKmod, sizeof(ModExp), e1, e2)
6416 {
6417 }
6418 
6419 /************************************************************/
6420 
PowExp(Loc loc,Expression * e1,Expression * e2)6421 PowExp::PowExp(Loc loc, Expression *e1, Expression *e2)
6422         : BinExp(loc, TOKpow, sizeof(PowExp), e1, e2)
6423 {
6424 }
6425 
6426 /************************************************************/
6427 
ShlExp(Loc loc,Expression * e1,Expression * e2)6428 ShlExp::ShlExp(Loc loc, Expression *e1, Expression *e2)
6429         : BinExp(loc, TOKshl, sizeof(ShlExp), e1, e2)
6430 {
6431 }
6432 
6433 /************************************************************/
6434 
ShrExp(Loc loc,Expression * e1,Expression * e2)6435 ShrExp::ShrExp(Loc loc, Expression *e1, Expression *e2)
6436         : BinExp(loc, TOKshr, sizeof(ShrExp), e1, e2)
6437 {
6438 }
6439 
6440 /************************************************************/
6441 
UshrExp(Loc loc,Expression * e1,Expression * e2)6442 UshrExp::UshrExp(Loc loc, Expression *e1, Expression *e2)
6443         : BinExp(loc, TOKushr, sizeof(UshrExp), e1, e2)
6444 {
6445 }
6446 
6447 /************************************************************/
6448 
AndExp(Loc loc,Expression * e1,Expression * e2)6449 AndExp::AndExp(Loc loc, Expression *e1, Expression *e2)
6450         : BinExp(loc, TOKand, sizeof(AndExp), e1, e2)
6451 {
6452 }
6453 
6454 /************************************************************/
6455 
OrExp(Loc loc,Expression * e1,Expression * e2)6456 OrExp::OrExp(Loc loc, Expression *e1, Expression *e2)
6457         : BinExp(loc, TOKor, sizeof(OrExp), e1, e2)
6458 {
6459 }
6460 
6461 /************************************************************/
6462 
XorExp(Loc loc,Expression * e1,Expression * e2)6463 XorExp::XorExp(Loc loc, Expression *e1, Expression *e2)
6464         : BinExp(loc, TOKxor, sizeof(XorExp), e1, e2)
6465 {
6466 }
6467 
6468 /************************************************************/
6469 
OrOrExp(Loc loc,Expression * e1,Expression * e2)6470 OrOrExp::OrOrExp(Loc loc, Expression *e1, Expression *e2)
6471         : BinExp(loc, TOKoror, sizeof(OrOrExp), e1, e2)
6472 {
6473 }
6474 
toBoolean(Scope * sc)6475 Expression *OrOrExp::toBoolean(Scope *sc)
6476 {
6477     Expression *ex2 = e2->toBoolean(sc);
6478     if (ex2->op == TOKerror)
6479         return ex2;
6480     e2 = ex2;
6481     return this;
6482 }
6483 
6484 /************************************************************/
6485 
AndAndExp(Loc loc,Expression * e1,Expression * e2)6486 AndAndExp::AndAndExp(Loc loc, Expression *e1, Expression *e2)
6487         : BinExp(loc, TOKandand, sizeof(AndAndExp), e1, e2)
6488 {
6489 }
6490 
toBoolean(Scope * sc)6491 Expression *AndAndExp::toBoolean(Scope *sc)
6492 {
6493     Expression *ex2 = e2->toBoolean(sc);
6494     if (ex2->op == TOKerror)
6495         return ex2;
6496     e2 = ex2;
6497     return this;
6498 }
6499 
6500 /************************************************************/
6501 
InExp(Loc loc,Expression * e1,Expression * e2)6502 InExp::InExp(Loc loc, Expression *e1, Expression *e2)
6503         : BinExp(loc, TOKin, sizeof(InExp), e1, e2)
6504 {
6505 }
6506 
6507 /************************************************************/
6508 
6509 /* This deletes the key e1 from the associative array e2
6510  */
6511 
RemoveExp(Loc loc,Expression * e1,Expression * e2)6512 RemoveExp::RemoveExp(Loc loc, Expression *e1, Expression *e2)
6513         : BinExp(loc, TOKremove, sizeof(RemoveExp), e1, e2)
6514 {
6515     type = Type::tbool;
6516 }
6517 
6518 /************************************************************/
6519 
CmpExp(TOK op,Loc loc,Expression * e1,Expression * e2)6520 CmpExp::CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2)
6521         : BinExp(loc, op, sizeof(CmpExp), e1, e2)
6522 {
6523 }
6524 
6525 /************************************************************/
6526 
EqualExp(TOK op,Loc loc,Expression * e1,Expression * e2)6527 EqualExp::EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2)
6528         : BinExp(loc, op, sizeof(EqualExp), e1, e2)
6529 {
6530     assert(op == TOKequal || op == TOKnotequal);
6531 }
6532 
6533 /************************************************************/
6534 
IdentityExp(TOK op,Loc loc,Expression * e1,Expression * e2)6535 IdentityExp::IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2)
6536         : BinExp(loc, op, sizeof(IdentityExp), e1, e2)
6537 {
6538 }
6539 
6540 /****************************************************************/
6541 
CondExp(Loc loc,Expression * econd,Expression * e1,Expression * e2)6542 CondExp::CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2)
6543         : BinExp(loc, TOKquestion, sizeof(CondExp), e1, e2)
6544 {
6545     this->econd = econd;
6546 }
6547 
syntaxCopy()6548 Expression *CondExp::syntaxCopy()
6549 {
6550     return new CondExp(loc, econd->syntaxCopy(), e1->syntaxCopy(), e2->syntaxCopy());
6551 }
6552 
hookDtors(Scope * sc)6553 void CondExp::hookDtors(Scope *sc)
6554 {
6555     class DtorVisitor : public StoppableVisitor
6556     {
6557     public:
6558         Scope *sc;
6559         CondExp *ce;
6560         VarDeclaration *vcond;
6561         bool isThen;
6562 
6563         DtorVisitor(Scope *sc, CondExp *ce)
6564         {
6565             this->sc = sc;
6566             this->ce = ce;
6567             this->vcond = NULL;
6568         }
6569 
6570         void visit(Expression *)
6571         {
6572             //printf("(e = %s)\n", e->toChars());
6573         }
6574 
6575         void visit(DeclarationExp *e)
6576         {
6577             VarDeclaration *v = e->declaration->isVarDeclaration();
6578             if (v && !v->isDataseg())
6579             {
6580                 if (v->_init)
6581                 {
6582                     ExpInitializer *ei = v->_init->isExpInitializer();
6583                     if (ei)
6584                         ei->exp->accept(this);
6585                 }
6586 
6587                 if (v->needsScopeDtor())
6588                 {
6589                     if (!vcond)
6590                     {
6591                         vcond = copyToTemp(STCvolatile, "__cond", ce->econd);
6592                         vcond->semantic(sc);
6593 
6594                         Expression *de = new DeclarationExp(ce->econd->loc, vcond);
6595                         de = semantic(de, sc);
6596 
6597                         Expression *ve = new VarExp(ce->econd->loc, vcond);
6598                         ce->econd = Expression::combine(de, ve);
6599                     }
6600 
6601                     //printf("\t++v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars());
6602                     Expression *ve = new VarExp(vcond->loc, vcond);
6603                     if (isThen)
6604                         v->edtor = new AndAndExp(v->edtor->loc, ve, v->edtor);
6605                     else
6606                         v->edtor = new OrOrExp(v->edtor->loc, ve, v->edtor);
6607                     v->edtor = semantic(v->edtor, sc);
6608                     //printf("\t--v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars());
6609                 }
6610             }
6611         }
6612     };
6613 
6614     DtorVisitor v(sc, this);
6615     //printf("+%s\n", toChars());
6616     v.isThen = true;    walkPostorder(e1, &v);
6617     v.isThen = false;   walkPostorder(e2, &v);
6618     //printf("-%s\n", toChars());
6619 }
6620 
isLvalue()6621 bool CondExp::isLvalue()
6622 {
6623     return e1->isLvalue() && e2->isLvalue();
6624 }
6625 
6626 
toLvalue(Scope * sc,Expression *)6627 Expression *CondExp::toLvalue(Scope *sc, Expression *)
6628 {
6629     // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)
6630     CondExp *e = (CondExp *)copy();
6631     e->e1 = e1->toLvalue(sc, NULL)->addressOf();
6632     e->e2 = e2->toLvalue(sc, NULL)->addressOf();
6633     e->type = type->pointerTo();
6634     return new PtrExp(loc, e, type);
6635 }
6636 
checkModifiable(Scope * sc,int flag)6637 int CondExp::checkModifiable(Scope *sc, int flag)
6638 {
6639     return e1->checkModifiable(sc, flag) && e2->checkModifiable(sc, flag);
6640 }
6641 
modifiableLvalue(Scope * sc,Expression *)6642 Expression *CondExp::modifiableLvalue(Scope *sc, Expression *)
6643 {
6644     //error("conditional expression %s is not a modifiable lvalue", toChars());
6645     e1 = e1->modifiableLvalue(sc, e1);
6646     e2 = e2->modifiableLvalue(sc, e2);
6647     return toLvalue(sc, this);
6648 }
6649 
toBoolean(Scope * sc)6650 Expression *CondExp::toBoolean(Scope *sc)
6651 {
6652     Expression *ex1 = e1->toBoolean(sc);
6653     Expression *ex2 = e2->toBoolean(sc);
6654     if (ex1->op == TOKerror)
6655         return ex1;
6656     if (ex2->op == TOKerror)
6657         return ex2;
6658     e1 = ex1;
6659     e2 = ex2;
6660     return this;
6661 }
6662 
6663 /****************************************************************/
6664 
DefaultInitExp(Loc loc,TOK subop,int size)6665 DefaultInitExp::DefaultInitExp(Loc loc, TOK subop, int size)
6666     : Expression(loc, TOKdefault, size)
6667 {
6668     this->subop = subop;
6669 }
6670 
6671 /****************************************************************/
6672 
FileInitExp(Loc loc,TOK tok)6673 FileInitExp::FileInitExp(Loc loc, TOK tok)
6674     : DefaultInitExp(loc, tok, sizeof(FileInitExp))
6675 {
6676 }
6677 
resolveLoc(Loc loc,Scope * sc)6678 Expression *FileInitExp::resolveLoc(Loc loc, Scope *sc)
6679 {
6680     //printf("FileInitExp::resolve() %s\n", toChars());
6681     const char *s = loc.filename ? loc.filename : sc->_module->ident->toChars();
6682     if (subop == TOKfilefullpath)
6683         s = FileName::combine(sc->_module->srcfilePath, s);
6684     Expression *e = new StringExp(loc, const_cast<char *>(s));
6685     e = semantic(e, sc);
6686     e = e->castTo(sc, type);
6687     return e;
6688 }
6689 
6690 /****************************************************************/
6691 
LineInitExp(Loc loc)6692 LineInitExp::LineInitExp(Loc loc)
6693     : DefaultInitExp(loc, TOKline, sizeof(LineInitExp))
6694 {
6695 }
6696 
resolveLoc(Loc loc,Scope * sc)6697 Expression *LineInitExp::resolveLoc(Loc loc, Scope *sc)
6698 {
6699     Expression *e = new IntegerExp(loc, loc.linnum, Type::tint32);
6700     e = e->castTo(sc, type);
6701     return e;
6702 }
6703 
6704 /****************************************************************/
6705 
ModuleInitExp(Loc loc)6706 ModuleInitExp::ModuleInitExp(Loc loc)
6707     : DefaultInitExp(loc, TOKmodulestring, sizeof(ModuleInitExp))
6708 {
6709 }
6710 
resolveLoc(Loc loc,Scope * sc)6711 Expression *ModuleInitExp::resolveLoc(Loc loc, Scope *sc)
6712 {
6713     const char *s;
6714     if (sc->callsc)
6715         s = sc->callsc->_module->toPrettyChars();
6716     else
6717         s = sc->_module->toPrettyChars();
6718     Expression *e = new StringExp(loc, const_cast<char *>(s));
6719     e = semantic(e, sc);
6720     e = e->castTo(sc, type);
6721     return e;
6722 }
6723 
6724 /****************************************************************/
6725 
FuncInitExp(Loc loc)6726 FuncInitExp::FuncInitExp(Loc loc)
6727     : DefaultInitExp(loc, TOKfuncstring, sizeof(FuncInitExp))
6728 {
6729 }
6730 
resolveLoc(Loc loc,Scope * sc)6731 Expression *FuncInitExp::resolveLoc(Loc loc, Scope *sc)
6732 {
6733     const char *s;
6734     if (sc->callsc && sc->callsc->func)
6735         s = sc->callsc->func->Dsymbol::toPrettyChars();
6736     else if (sc->func)
6737         s = sc->func->Dsymbol::toPrettyChars();
6738     else
6739         s = "";
6740     Expression *e = new StringExp(loc, const_cast<char *>(s));
6741     e = semantic(e, sc);
6742     e->type = Type::tstring;
6743     return e;
6744 }
6745 
6746 /****************************************************************/
6747 
PrettyFuncInitExp(Loc loc)6748 PrettyFuncInitExp::PrettyFuncInitExp(Loc loc)
6749     : DefaultInitExp(loc, TOKprettyfunc, sizeof(PrettyFuncInitExp))
6750 {
6751 }
6752 
resolveLoc(Loc loc,Scope * sc)6753 Expression *PrettyFuncInitExp::resolveLoc(Loc loc, Scope *sc)
6754 {
6755     FuncDeclaration *fd;
6756     if (sc->callsc && sc->callsc->func)
6757         fd = sc->callsc->func;
6758     else
6759         fd = sc->func;
6760 
6761     const char *s;
6762     if (fd)
6763     {
6764         const char *funcStr = fd->Dsymbol::toPrettyChars();
6765         OutBuffer buf;
6766         functionToBufferWithIdent((TypeFunction *)fd->type, &buf, funcStr);
6767         s = buf.extractString();
6768     }
6769     else
6770     {
6771         s = "";
6772     }
6773 
6774     Expression *e = new StringExp(loc, const_cast<char *>(s));
6775     e = semantic(e, sc);
6776     e->type = Type::tstring;
6777     return e;
6778 }
6779 
6780 /****************************************************************/
6781 
extractOpDollarSideEffect(Scope * sc,UnaExp * ue)6782 Expression *extractOpDollarSideEffect(Scope *sc, UnaExp *ue)
6783 {
6784     Expression *e0;
6785     Expression *e1 = Expression::extractLast(ue->e1, &e0);
6786     // Bugzilla 12585: Extract the side effect part if ue->e1 is comma.
6787 
6788     if (!isTrivialExp(e1))
6789     {
6790         /* Even if opDollar is needed, 'e1' should be evaluate only once. So
6791          * Rewrite:
6792          *      e1.opIndex( ... use of $ ... )
6793          *      e1.opSlice( ... use of $ ... )
6794          * as:
6795          *      (ref __dop = e1, __dop).opIndex( ... __dop.opDollar ...)
6796          *      (ref __dop = e1, __dop).opSlice( ... __dop.opDollar ...)
6797          */
6798         e1 = extractSideEffect(sc, "__dop", &e0, e1, false);
6799         assert(e1->op == TOKvar);
6800         VarExp *ve = (VarExp *)e1;
6801         ve->var->storage_class |= STCexptemp;     // lifetime limited to expression
6802     }
6803     ue->e1 = e1;
6804     return e0;
6805 }
6806 
6807 /**************************************
6808  * Runs semantic on ae->arguments. Declares temporary variables
6809  * if '$' was used.
6810  */
resolveOpDollar(Scope * sc,ArrayExp * ae,Expression ** pe0)6811 Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0)
6812 {
6813     assert(!ae->lengthVar);
6814 
6815     *pe0 = NULL;
6816 
6817     AggregateDeclaration *ad = isAggregate(ae->e1->type);
6818     Dsymbol *slice = search_function(ad, Id::slice);
6819     //printf("slice = %s %s\n", slice->kind(), slice->toChars());
6820 
6821     for (size_t i = 0; i < ae->arguments->dim; i++)
6822     {
6823         if (i == 0)
6824             *pe0 = extractOpDollarSideEffect(sc, ae);
6825 
6826         Expression *e = (*ae->arguments)[i];
6827         if (e->op == TOKinterval && !(slice && slice->isTemplateDeclaration()))
6828         {
6829         Lfallback:
6830             if (ae->arguments->dim == 1)
6831                 return NULL;
6832             ae->error("multi-dimensional slicing requires template opSlice");
6833             return new ErrorExp();
6834         }
6835         //printf("[%d] e = %s\n", i, e->toChars());
6836 
6837         // Create scope for '$' variable for this dimension
6838         ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, ae);
6839         sym->loc = ae->loc;
6840         sym->parent = sc->scopesym;
6841         sc = sc->push(sym);
6842         ae->lengthVar = NULL;       // Create it only if required
6843         ae->currentDimension = i;   // Dimension for $, if required
6844 
6845         e = semantic(e, sc);
6846         e = resolveProperties(sc, e);
6847 
6848         if (ae->lengthVar && sc->func)
6849         {
6850             // If $ was used, declare it now
6851             Expression *de = new DeclarationExp(ae->loc, ae->lengthVar);
6852             de = semantic(de, sc);
6853             *pe0 = Expression::combine(*pe0, de);
6854         }
6855         sc = sc->pop();
6856 
6857         if (e->op == TOKinterval)
6858         {
6859             IntervalExp *ie = (IntervalExp *)e;
6860 
6861             Objects *tiargs = new Objects();
6862             Expression *edim = new IntegerExp(ae->loc, i, Type::tsize_t);
6863             edim = semantic(edim, sc);
6864             tiargs->push(edim);
6865 
6866             Expressions *fargs = new Expressions();
6867             fargs->push(ie->lwr);
6868             fargs->push(ie->upr);
6869 
6870             unsigned xerrors = global.startGagging();
6871             sc = sc->push();
6872             FuncDeclaration *fslice = resolveFuncCall(ae->loc, sc, slice, tiargs, ae->e1->type, fargs, 1);
6873             sc = sc->pop();
6874             global.endGagging(xerrors);
6875             if (!fslice)
6876                 goto Lfallback;
6877 
6878             e = new DotTemplateInstanceExp(ae->loc, ae->e1, slice->ident, tiargs);
6879             e = new CallExp(ae->loc, e, fargs);
6880             e = semantic(e, sc);
6881         }
6882 
6883         if (!e->type)
6884         {
6885             ae->error("%s has no value", e->toChars());
6886             e = new ErrorExp();
6887         }
6888         if (e->op == TOKerror)
6889             return e;
6890 
6891         (*ae->arguments)[i] = e;
6892     }
6893 
6894     return ae;
6895 }
6896 
6897 /***********************************************************
6898  * Resolve `exp` as a compile-time known string.
6899  * Params:
6900  *  sc  = scope
6901  *  exp = Expression which expected as a string
6902  *  s   = What the string is expected for, will be used in error diagnostic.
6903  * Returns:
6904  *  String literal, or `null` if error happens.
6905  */
semanticString(Scope * sc,Expression * exp,const char * s)6906 StringExp *semanticString(Scope *sc, Expression *exp, const char *s)
6907 {
6908     sc = sc->startCTFE();
6909     exp = semantic(exp, sc);
6910     exp = resolveProperties(sc, exp);
6911     sc = sc->endCTFE();
6912 
6913     if (exp->op == TOKerror)
6914         return NULL;
6915 
6916     Expression *e = exp;
6917     if (exp->type->isString())
6918     {
6919         e = e->ctfeInterpret();
6920         if (e->op == TOKerror)
6921             return NULL;
6922     }
6923 
6924     StringExp *se = e->toStringExp();
6925     if (!se)
6926     {
6927         exp->error("string expected for %s, not (%s) of type %s",
6928             s, exp->toChars(), exp->type->toChars());
6929         return NULL;
6930     }
6931     return se;
6932 }
6933 
6934 /**************************************
6935  * Runs semantic on se->lwr and se->upr. Declares a temporary variable
6936  * if '$' was used.
6937  */
resolveOpDollar(Scope * sc,ArrayExp * ae,IntervalExp * ie,Expression ** pe0)6938 Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, IntervalExp *ie, Expression **pe0)
6939 {
6940     //assert(!ae->lengthVar);
6941     if (!ie)
6942         return ae;
6943 
6944     VarDeclaration *lengthVar = ae->lengthVar;
6945 
6946     // create scope for '$'
6947     ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, ae);
6948     sym->loc = ae->loc;
6949     sym->parent = sc->scopesym;
6950     sc = sc->push(sym);
6951 
6952     for (size_t i = 0; i < 2; ++i)
6953     {
6954         Expression *e = i == 0 ? ie->lwr : ie->upr;
6955         e = semantic(e, sc);
6956         e = resolveProperties(sc, e);
6957         if (!e->type)
6958         {
6959             ae->error("%s has no value", e->toChars());
6960             return new ErrorExp();
6961         }
6962         (i == 0 ? ie->lwr : ie->upr) = e;
6963     }
6964 
6965     if (lengthVar != ae->lengthVar && sc->func)
6966     {
6967         // If $ was used, declare it now
6968         Expression *de = new DeclarationExp(ae->loc, ae->lengthVar);
6969         de = semantic(de, sc);
6970         *pe0 = Expression::combine(*pe0, de);
6971     }
6972     sc = sc->pop();
6973 
6974     return ae;
6975 }
6976 
reorderSettingAAElem(Scope * sc)6977 Expression *BinExp::reorderSettingAAElem(Scope *sc)
6978 {
6979     BinExp *be = this;
6980 
6981     if (be->e1->op != TOKindex)
6982         return be;
6983     IndexExp *ie = (IndexExp *)be->e1;
6984     if (ie->e1->type->toBasetype()->ty != Taarray)
6985         return be;
6986 
6987     /* Fix evaluation order of setting AA element. (Bugzilla 3825)
6988      * Rewrite:
6989      *     aa[k1][k2][k3] op= val;
6990      * as:
6991      *     auto ref __aatmp = aa;
6992      *     auto ref __aakey3 = k1, __aakey2 = k2, __aakey1 = k3;
6993      *     auto ref __aaval = val;
6994      *     __aatmp[__aakey3][__aakey2][__aakey1] op= __aaval;  // assignment
6995      */
6996 
6997     Expression *e0 = NULL;
6998     while (1)
6999     {
7000         Expression *de = NULL;
7001         ie->e2 = extractSideEffect(sc, "__aakey", &de, ie->e2);
7002         e0 = Expression::combine(de, e0);
7003 
7004         Expression *ie1 = ie->e1;
7005         if (ie1->op != TOKindex ||
7006             ((IndexExp *)ie1)->e1->type->toBasetype()->ty != Taarray)
7007         {
7008             break;
7009         }
7010         ie = (IndexExp *)ie1;
7011     }
7012     assert(ie->e1->type->toBasetype()->ty == Taarray);
7013 
7014     Expression *de = NULL;
7015     ie->e1 = extractSideEffect(sc, "__aatmp", &de, ie->e1);
7016     e0 = Expression::combine(de, e0);
7017 
7018     be->e2 = extractSideEffect(sc, "__aaval", &e0, be->e2, true);
7019 
7020     //printf("-e0 = %s, be = %s\n", e0->toChars(), be->toChars());
7021     return Expression::combine(e0, be);
7022 }
7023