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