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