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