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