expression.h revision 1.1 1
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/dlang/dmd/blob/master/src/dmd/expression.h
9 */
10
11 #pragma once
12
13 #include "complex_t.h"
14 #include "globals.h"
15 #include "identifier.h"
16 #include "arraytypes.h"
17 #include "intrange.h"
18 #include "visitor.h"
19 #include "tokens.h"
20
21 #include "root/rmem.h"
22
23 class Type;
24 class TypeVector;
25 struct Scope;
26 class TupleDeclaration;
27 class VarDeclaration;
28 class FuncDeclaration;
29 class FuncLiteralDeclaration;
30 class Declaration;
31 class CtorDeclaration;
32 class NewDeclaration;
33 class Dsymbol;
34 class Import;
35 class Module;
36 class ScopeDsymbol;
37 class Expression;
38 class Declaration;
39 class AggregateDeclaration;
40 class StructDeclaration;
41 class TemplateInstance;
42 class TemplateDeclaration;
43 class ClassDeclaration;
44 class BinExp;
45 class OverloadSet;
46 class Initializer;
47 class StringExp;
48 class ArrayExp;
49 class SliceExp;
50 struct UnionExp;
51 #ifdef IN_GCC
52 typedef union tree_node Symbol;
53 #else
54 struct Symbol; // back end symbol
55 #endif
56
57 Expression *resolveProperties(Scope *sc, Expression *e);
58 Expression *resolvePropertiesOnly(Scope *sc, Expression *e1);
59 bool checkAccess(Loc loc, Scope *sc, Expression *e, Declaration *d);
60 bool checkAccess(Loc loc, Scope *sc, Package *p);
61 Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Dsymbol *d);
62 Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid);
63 void expandTuples(Expressions *exps);
64 TupleDeclaration *isAliasThisTuple(Expression *e);
65 int expandAliasThisTuples(Expressions *exps, size_t starti = 0);
66 FuncDeclaration *hasThis(Scope *sc);
67 Expression *fromConstInitializer(int result, Expression *e);
68 bool arrayExpressionSemantic(Expressions *exps, Scope *sc, bool preserveErrors = false);
69 TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s);
70 Expression *valueNoDtor(Expression *e);
71 int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1);
72 Expression *resolveAliasThis(Scope *sc, Expression *e, bool gag = false);
73 Expression *doCopyOrMove(Scope *sc, Expression *e);
74 Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0);
75 Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, IntervalExp *ie, Expression **pe0);
76 Expression *integralPromotions(Expression *e, Scope *sc);
77 bool discardValue(Expression *e);
78 bool isTrivialExp(Expression *e);
79
80 int isConst(Expression *e);
81 Expression *toDelegate(Expression *e, Type* t, Scope *sc);
82 AggregateDeclaration *isAggregate(Type *t);
83 IntRange getIntRange(Expression *e);
84 bool checkNonAssignmentArrayOp(Expression *e, bool suggestion = false);
85 bool isUnaArrayOp(TOK op);
86 bool isBinArrayOp(TOK op);
87 bool isBinAssignArrayOp(TOK op);
88 bool isArrayOpOperand(Expression *e);
89 Expression *arrayOp(BinExp *e, Scope *sc);
90 Expression *arrayOp(BinAssignExp *e, Scope *sc);
91 bool hasSideEffect(Expression *e);
92 bool canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow);
93 Expression *Expression_optimize(Expression *e, int result, bool keepLvalue);
94 MATCH implicitConvTo(Expression *e, Type *t);
95 Expression *implicitCastTo(Expression *e, Scope *sc, Type *t);
96 Expression *castTo(Expression *e, Scope *sc, Type *t);
97 Expression *ctfeInterpret(Expression *);
98 Expression *inlineCopy(Expression *e, Scope *sc);
99 Expression *op_overload(Expression *e, Scope *sc);
100 Type *toStaticArrayType(SliceExp *e);
101 Expression *scaleFactor(BinExp *be, Scope *sc);
102 Expression *typeCombine(BinExp *be, Scope *sc);
103 Expression *inferType(Expression *e, Type *t, int flag = 0);
104 Expression *semanticTraits(TraitsExp *e, Scope *sc);
105 Type *getIndirection(Type *t);
106
107 Expression *checkGC(Scope *sc, Expression *e);
108
109 /* Run CTFE on the expression, but allow the expression to be a TypeExp
110 * or a tuple containing a TypeExp. (This is required by pragma(msg)).
111 */
112 Expression *ctfeInterpretForPragmaMsg(Expression *e);
113
114 enum OwnedBy
115 {
116 OWNEDcode, // normal code expression in AST
117 OWNEDctfe, // value expression for CTFE
118 OWNEDcache // constant value cached for CTFE
119 };
120
121 #define WANTvalue 0 // default
122 #define WANTexpand 1 // expand const/immutable variables if possible
123
124 class Expression : public RootObject
125 {
126 public:
127 Loc loc; // file location
128 Type *type; // !=NULL means that semantic() has been run
129 TOK op; // to minimize use of dynamic_cast
130 unsigned char size; // # of bytes in Expression so we can copy() it
131 unsigned char parens; // if this is a parenthesized expression
132
133 Expression(Loc loc, TOK op, int size);
134 static void _init();
135 Expression *copy();
136 virtual Expression *syntaxCopy();
137
138 // kludge for template.isExpression()
139 int dyncast() const { return DYNCAST_EXPRESSION; }
140
141 void print();
142 const char *toChars();
143 void error(const char *format, ...) const;
144 void warning(const char *format, ...) const;
145 void deprecation(const char *format, ...) const;
146
147 // creates a single expression which is effectively (e1, e2)
148 // this new expression does not necessarily need to have valid D source code representation,
149 // for example, it may include declaration expressions
150 static Expression *combine(Expression *e1, Expression *e2);
151 static Expression *extractLast(Expression *e, Expression **pe0);
152 static Expressions *arraySyntaxCopy(Expressions *exps);
153
154 virtual dinteger_t toInteger();
155 virtual uinteger_t toUInteger();
156 virtual real_t toReal();
157 virtual real_t toImaginary();
158 virtual complex_t toComplex();
159 virtual StringExp *toStringExp();
160 virtual bool isLvalue();
161 virtual Expression *toLvalue(Scope *sc, Expression *e);
162 virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
163 Expression *implicitCastTo(Scope *sc, Type *t)
164 {
165 return ::implicitCastTo(this, sc, t);
166 }
167 MATCH implicitConvTo(Type *t)
168 {
169 return ::implicitConvTo(this, t);
170 }
171 Expression *castTo(Scope *sc, Type *t)
172 {
173 return ::castTo(this, sc, t);
174 }
175 virtual Expression *resolveLoc(Loc loc, Scope *sc);
176 virtual bool checkType();
177 virtual bool checkValue();
178 bool checkScalar();
179 bool checkNoBool();
180 bool checkIntegral();
181 bool checkArithmetic();
182 void checkDeprecated(Scope *sc, Dsymbol *s);
183 bool checkPurity(Scope *sc, FuncDeclaration *f);
184 bool checkPurity(Scope *sc, VarDeclaration *v);
185 bool checkSafety(Scope *sc, FuncDeclaration *f);
186 bool checkNogc(Scope *sc, FuncDeclaration *f);
187 bool checkPostblit(Scope *sc, Type *t);
188 bool checkRightThis(Scope *sc);
189 bool checkReadModifyWrite(TOK rmwOp, Expression *ex = NULL);
190 virtual int checkModifiable(Scope *sc, int flag = 0);
191 virtual Expression *toBoolean(Scope *sc);
192 virtual Expression *addDtorHook(Scope *sc);
193 Expression *addressOf();
194 Expression *deref();
195
196 Expression *optimize(int result, bool keepLvalue = false)
197 {
198 return Expression_optimize(this, result, keepLvalue);
199 }
200
201 // Entry point for CTFE.
202 // A compile-time result is required. Give an error if not possible
203 Expression *ctfeInterpret()
204 {
205 return ::ctfeInterpret(this);
206 }
207
208 int isConst() { return ::isConst(this); }
209 virtual bool isBool(bool result);
210 Expression *op_overload(Scope *sc)
211 {
212 return ::op_overload(this, sc);
213 }
214
215 virtual bool hasCode()
216 {
217 return true;
218 }
219
220 virtual void accept(Visitor *v) { v->visit(this); }
221 };
222
223 class IntegerExp : public Expression
224 {
225 public:
226 dinteger_t value;
227
228 IntegerExp(Loc loc, dinteger_t value, Type *type);
229 IntegerExp(dinteger_t value);
230 static IntegerExp *create(Loc loc, dinteger_t value, Type *type);
231 bool equals(RootObject *o);
232 dinteger_t toInteger();
233 real_t toReal();
234 real_t toImaginary();
235 complex_t toComplex();
236 bool isBool(bool result);
237 Expression *toLvalue(Scope *sc, Expression *e);
238 void accept(Visitor *v) { v->visit(this); }
239 dinteger_t getInteger() { return value; }
240 void setInteger(dinteger_t value);
241 void normalize();
242 };
243
244 class ErrorExp : public Expression
245 {
246 public:
247 ErrorExp();
248 Expression *toLvalue(Scope *sc, Expression *e);
249 void accept(Visitor *v) { v->visit(this); }
250
251 static ErrorExp *errorexp; // handy shared value
252 };
253
254 class RealExp : public Expression
255 {
256 public:
257 real_t value;
258
259 RealExp(Loc loc, real_t value, Type *type);
260 static RealExp *create(Loc loc, real_t value, Type *type);
261 bool equals(RootObject *o);
262 dinteger_t toInteger();
263 uinteger_t toUInteger();
264 real_t toReal();
265 real_t toImaginary();
266 complex_t toComplex();
267 bool isBool(bool result);
268 void accept(Visitor *v) { v->visit(this); }
269 };
270
271 class ComplexExp : public Expression
272 {
273 public:
274 complex_t value;
275
276 ComplexExp(Loc loc, complex_t value, Type *type);
277 static ComplexExp *create(Loc loc, complex_t value, Type *type);
278 bool equals(RootObject *o);
279 dinteger_t toInteger();
280 uinteger_t toUInteger();
281 real_t toReal();
282 real_t toImaginary();
283 complex_t toComplex();
284 bool isBool(bool result);
285 void accept(Visitor *v) { v->visit(this); }
286 };
287
288 class IdentifierExp : public Expression
289 {
290 public:
291 Identifier *ident;
292
293 IdentifierExp(Loc loc, Identifier *ident);
294 static IdentifierExp *create(Loc loc, Identifier *ident);
295 bool isLvalue();
296 Expression *toLvalue(Scope *sc, Expression *e);
297 void accept(Visitor *v) { v->visit(this); }
298 };
299
300 class DollarExp : public IdentifierExp
301 {
302 public:
303 DollarExp(Loc loc);
304 void accept(Visitor *v) { v->visit(this); }
305 };
306
307 class DsymbolExp : public Expression
308 {
309 public:
310 Dsymbol *s;
311 bool hasOverloads;
312
313 DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads = true);
314 bool isLvalue();
315 Expression *toLvalue(Scope *sc, Expression *e);
316 void accept(Visitor *v) { v->visit(this); }
317 };
318
319 class ThisExp : public Expression
320 {
321 public:
322 VarDeclaration *var;
323
324 ThisExp(Loc loc);
325 bool isBool(bool result);
326 bool isLvalue();
327 Expression *toLvalue(Scope *sc, Expression *e);
328
329 void accept(Visitor *v) { v->visit(this); }
330 };
331
332 class SuperExp : public ThisExp
333 {
334 public:
335 SuperExp(Loc loc);
336
337 void accept(Visitor *v) { v->visit(this); }
338 };
339
340 class NullExp : public Expression
341 {
342 public:
343 unsigned char committed; // !=0 if type is committed
344
345 NullExp(Loc loc, Type *t = NULL);
346 bool equals(RootObject *o);
347 bool isBool(bool result);
348 StringExp *toStringExp();
349 void accept(Visitor *v) { v->visit(this); }
350 };
351
352 class StringExp : public Expression
353 {
354 public:
355 void *string; // char, wchar, or dchar data
356 size_t len; // number of chars, wchars, or dchars
357 unsigned char sz; // 1: char, 2: wchar, 4: dchar
358 unsigned char committed; // !=0 if type is committed
359 utf8_t postfix; // 'c', 'w', 'd'
360 OwnedBy ownedByCtfe;
361
362 StringExp(Loc loc, char *s);
363 StringExp(Loc loc, void *s, size_t len);
364 StringExp(Loc loc, void *s, size_t len, utf8_t postfix);
365 static StringExp *create(Loc loc, char *s);
366 static StringExp *create(Loc loc, void *s, size_t len);
367 bool equals(RootObject *o);
368 StringExp *toStringExp();
369 StringExp *toUTF8(Scope *sc);
370 int compare(RootObject *obj);
371 bool isBool(bool result);
372 bool isLvalue();
373 Expression *toLvalue(Scope *sc, Expression *e);
374 Expression *modifiableLvalue(Scope *sc, Expression *e);
375 unsigned charAt(uinteger_t i) const;
376 void accept(Visitor *v) { v->visit(this); }
377 size_t numberOfCodeUnits(int tynto = 0) const;
378 void writeTo(void* dest, bool zero, int tyto = 0) const;
379 char *toPtr();
380 };
381
382 // Tuple
383
384 class TupleExp : public Expression
385 {
386 public:
387 Expression *e0; // side-effect part
388 /* Tuple-field access may need to take out its side effect part.
389 * For example:
390 * foo().tupleof
391 * is rewritten as:
392 * (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...))
393 * The declaration of temporary variable __tup will be stored in TupleExp::e0.
394 */
395 Expressions *exps;
396
397 TupleExp(Loc loc, Expression *e0, Expressions *exps);
398 TupleExp(Loc loc, Expressions *exps);
399 TupleExp(Loc loc, TupleDeclaration *tup);
400 Expression *syntaxCopy();
401 bool equals(RootObject *o);
402
403 void accept(Visitor *v) { v->visit(this); }
404 };
405
406 class ArrayLiteralExp : public Expression
407 {
408 public:
409 Expression *basis;
410 Expressions *elements;
411 OwnedBy ownedByCtfe;
412
413 ArrayLiteralExp(Loc loc, Type *type, Expressions *elements);
414 ArrayLiteralExp(Loc loc, Type *type, Expression *e);
415 ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements);
416 static ArrayLiteralExp *create(Loc loc, Expressions *elements);
417 Expression *syntaxCopy();
418 bool equals(RootObject *o);
419 Expression *getElement(d_size_t i);
420 static Expressions* copyElements(Expression *e1, Expression *e2 = NULL);
421 bool isBool(bool result);
422 StringExp *toStringExp();
423
424 void accept(Visitor *v) { v->visit(this); }
425 };
426
427 class AssocArrayLiteralExp : public Expression
428 {
429 public:
430 Expressions *keys;
431 Expressions *values;
432 OwnedBy ownedByCtfe;
433
434 AssocArrayLiteralExp(Loc loc, Expressions *keys, Expressions *values);
435 bool equals(RootObject *o);
436 Expression *syntaxCopy();
437 bool isBool(bool result);
438
439 void accept(Visitor *v) { v->visit(this); }
440 };
441
442 // scrubReturnValue is running
443 #define stageScrub 0x1
444 // hasNonConstPointers is running
445 #define stageSearchPointers 0x2
446 // optimize is running
447 #define stageOptimize 0x4
448 // apply is running
449 #define stageApply 0x8
450 //inlineScan is running
451 #define stageInlineScan 0x10
452 // toCBuffer is running
453 #define stageToCBuffer 0x20
454
455 class StructLiteralExp : public Expression
456 {
457 public:
458 StructDeclaration *sd; // which aggregate this is for
459 Expressions *elements; // parallels sd->fields[] with NULL entries for fields to skip
460 Type *stype; // final type of result (can be different from sd's type)
461
462 bool useStaticInit; // if this is true, use the StructDeclaration's init symbol
463 Symbol *sym; // back end symbol to initialize with literal
464
465 OwnedBy ownedByCtfe;
466
467 // pointer to the origin instance of the expression.
468 // once a new expression is created, origin is set to 'this'.
469 // anytime when an expression copy is created, 'origin' pointer is set to
470 // 'origin' pointer value of the original expression.
471 StructLiteralExp *origin;
472
473 // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.
474 StructLiteralExp *inlinecopy;
475
476 // anytime when recursive function is calling, 'stageflags' marks with bit flag of
477 // current stage and unmarks before return from this function.
478 // 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
479 // (with infinite recursion) of this expression.
480 int stageflags;
481
482 StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype = NULL);
483 static StructLiteralExp *create(Loc loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
484 bool equals(RootObject *o);
485 Expression *syntaxCopy();
486 Expression *getField(Type *type, unsigned offset);
487 int getFieldIndex(Type *type, unsigned offset);
488 Expression *addDtorHook(Scope *sc);
489
490 void accept(Visitor *v) { v->visit(this); }
491 };
492
493 class DotIdExp;
494 DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident);
495
496 class TypeExp : public Expression
497 {
498 public:
499 TypeExp(Loc loc, Type *type);
500 Expression *syntaxCopy();
501 bool checkType();
502 bool checkValue();
503 void accept(Visitor *v) { v->visit(this); }
504 };
505
506 class ScopeExp : public Expression
507 {
508 public:
509 ScopeDsymbol *sds;
510
511 ScopeExp(Loc loc, ScopeDsymbol *sds);
512 Expression *syntaxCopy();
513 bool checkType();
514 bool checkValue();
515 void accept(Visitor *v) { v->visit(this); }
516 };
517
518 class TemplateExp : public Expression
519 {
520 public:
521 TemplateDeclaration *td;
522 FuncDeclaration *fd;
523
524 TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd = NULL);
525 bool isLvalue();
526 Expression *toLvalue(Scope *sc, Expression *e);
527 bool checkType();
528 bool checkValue();
529 void accept(Visitor *v) { v->visit(this); }
530 };
531
532 class NewExp : public Expression
533 {
534 public:
535 /* thisexp.new(newargs) newtype(arguments)
536 */
537 Expression *thisexp; // if !NULL, 'this' for class being allocated
538 Expressions *newargs; // Array of Expression's to call new operator
539 Type *newtype;
540 Expressions *arguments; // Array of Expression's
541
542 Expression *argprefix; // expression to be evaluated just before arguments[]
543
544 CtorDeclaration *member; // constructor function
545 NewDeclaration *allocator; // allocator function
546 int onstack; // allocate on stack
547
548 NewExp(Loc loc, Expression *thisexp, Expressions *newargs,
549 Type *newtype, Expressions *arguments);
550 static NewExp *create(Loc loc, Expression *thisexp, Expressions *newargs, Type *newtype, Expressions *arguments);
551 Expression *syntaxCopy();
552
553 void accept(Visitor *v) { v->visit(this); }
554 };
555
556 class NewAnonClassExp : public Expression
557 {
558 public:
559 /* thisexp.new(newargs) class baseclasses { } (arguments)
560 */
561 Expression *thisexp; // if !NULL, 'this' for class being allocated
562 Expressions *newargs; // Array of Expression's to call new operator
563 ClassDeclaration *cd; // class being instantiated
564 Expressions *arguments; // Array of Expression's to call class constructor
565
566 NewAnonClassExp(Loc loc, Expression *thisexp, Expressions *newargs,
567 ClassDeclaration *cd, Expressions *arguments);
568 Expression *syntaxCopy();
569 void accept(Visitor *v) { v->visit(this); }
570 };
571
572 class SymbolExp : public Expression
573 {
574 public:
575 Declaration *var;
576 bool hasOverloads;
577 SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads);
578
579 void accept(Visitor *v) { v->visit(this); }
580 };
581
582 // Offset from symbol
583
584 class SymOffExp : public SymbolExp
585 {
586 public:
587 dinteger_t offset;
588
589 SymOffExp(Loc loc, Declaration *var, dinteger_t offset, bool hasOverloads = true);
590 bool isBool(bool result);
591
592 void accept(Visitor *v) { v->visit(this); }
593 };
594
595 // Variable
596
597 class VarExp : public SymbolExp
598 {
599 public:
600 VarExp(Loc loc, Declaration *var, bool hasOverloads = true);
601 static VarExp *create(Loc loc, Declaration *var, bool hasOverloads = true);
602 bool equals(RootObject *o);
603 int checkModifiable(Scope *sc, int flag);
604 bool checkReadModifyWrite();
605 bool isLvalue();
606 Expression *toLvalue(Scope *sc, Expression *e);
607 Expression *modifiableLvalue(Scope *sc, Expression *e);
608
609 void accept(Visitor *v) { v->visit(this); }
610 };
611
612 // Overload Set
613
614 class OverExp : public Expression
615 {
616 public:
617 OverloadSet *vars;
618
619 OverExp(Loc loc, OverloadSet *s);
620 bool isLvalue();
621 Expression *toLvalue(Scope *sc, Expression *e);
622 void accept(Visitor *v) { v->visit(this); }
623 };
624
625 // Function/Delegate literal
626
627 class FuncExp : public Expression
628 {
629 public:
630 FuncLiteralDeclaration *fd;
631 TemplateDeclaration *td;
632 TOK tok;
633
634 FuncExp(Loc loc, Dsymbol *s);
635 bool equals(RootObject *o);
636 void genIdent(Scope *sc);
637 Expression *syntaxCopy();
638 MATCH matchType(Type *to, Scope *sc, FuncExp **pfe, int flag = 0);
639 const char *toChars();
640 bool checkType();
641 bool checkValue();
642
643 void accept(Visitor *v) { v->visit(this); }
644 };
645
646 // Declaration of a symbol
647
648 // D grammar allows declarations only as statements. However in AST representation
649 // it can be part of any expression. This is used, for example, during internal
650 // syntax re-writes to inject hidden symbols.
651 class DeclarationExp : public Expression
652 {
653 public:
654 Dsymbol *declaration;
655
656 DeclarationExp(Loc loc, Dsymbol *declaration);
657 Expression *syntaxCopy();
658
659 bool hasCode();
660
661 void accept(Visitor *v) { v->visit(this); }
662 };
663
664 class TypeidExp : public Expression
665 {
666 public:
667 RootObject *obj;
668
669 TypeidExp(Loc loc, RootObject *obj);
670 Expression *syntaxCopy();
671 void accept(Visitor *v) { v->visit(this); }
672 };
673
674 class TraitsExp : public Expression
675 {
676 public:
677 Identifier *ident;
678 Objects *args;
679
680 TraitsExp(Loc loc, Identifier *ident, Objects *args);
681 Expression *syntaxCopy();
682 void accept(Visitor *v) { v->visit(this); }
683 };
684
685 class HaltExp : public Expression
686 {
687 public:
688 HaltExp(Loc loc);
689
690 void accept(Visitor *v) { v->visit(this); }
691 };
692
693 class IsExp : public Expression
694 {
695 public:
696 /* is(targ id tok tspec)
697 * is(targ id == tok2)
698 */
699 Type *targ;
700 Identifier *id; // can be NULL
701 TOK tok; // ':' or '=='
702 Type *tspec; // can be NULL
703 TOK tok2; // 'struct', 'union', etc.
704 TemplateParameters *parameters;
705
706 IsExp(Loc loc, Type *targ, Identifier *id, TOK tok, Type *tspec,
707 TOK tok2, TemplateParameters *parameters);
708 Expression *syntaxCopy();
709 void accept(Visitor *v) { v->visit(this); }
710 };
711
712 /****************************************************************/
713
714 class UnaExp : public Expression
715 {
716 public:
717 Expression *e1;
718 Type *att1; // Save alias this type to detect recursion
719
720 UnaExp(Loc loc, TOK op, int size, Expression *e1);
721 Expression *syntaxCopy();
722 Expression *incompatibleTypes();
723 Expression *resolveLoc(Loc loc, Scope *sc);
724
725 void accept(Visitor *v) { v->visit(this); }
726 };
727
728 typedef UnionExp (*fp_t)(Loc loc, Type *, Expression *, Expression *);
729 typedef int (*fp2_t)(Loc loc, TOK, Expression *, Expression *);
730
731 class BinExp : public Expression
732 {
733 public:
734 Expression *e1;
735 Expression *e2;
736
737 Type *att1; // Save alias this type to detect recursion
738 Type *att2; // Save alias this type to detect recursion
739
740 BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2);
741 Expression *syntaxCopy();
742 Expression *incompatibleTypes();
743 Expression *checkOpAssignTypes(Scope *sc);
744 bool checkIntegralBin();
745 bool checkArithmeticBin();
746
747 Expression *reorderSettingAAElem(Scope *sc);
748
749 void accept(Visitor *v) { v->visit(this); }
750 };
751
752 class BinAssignExp : public BinExp
753 {
754 public:
755 BinAssignExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2);
756
757 bool isLvalue();
758 Expression *toLvalue(Scope *sc, Expression *ex);
759 Expression *modifiableLvalue(Scope *sc, Expression *e);
760 void accept(Visitor *v) { v->visit(this); }
761 };
762
763 /****************************************************************/
764
765 class CompileExp : public UnaExp
766 {
767 public:
768 CompileExp(Loc loc, Expression *e);
769 void accept(Visitor *v) { v->visit(this); }
770 };
771
772 class ImportExp : public UnaExp
773 {
774 public:
775 ImportExp(Loc loc, Expression *e);
776 void accept(Visitor *v) { v->visit(this); }
777 };
778
779 class AssertExp : public UnaExp
780 {
781 public:
782 Expression *msg;
783
784 AssertExp(Loc loc, Expression *e, Expression *msg = NULL);
785 Expression *syntaxCopy();
786
787 void accept(Visitor *v) { v->visit(this); }
788 };
789
790 class DotIdExp : public UnaExp
791 {
792 public:
793 Identifier *ident;
794 bool noderef; // true if the result of the expression will never be dereferenced
795 bool wantsym; // do not replace Symbol with its initializer during semantic()
796
797 DotIdExp(Loc loc, Expression *e, Identifier *ident);
798 static DotIdExp *create(Loc loc, Expression *e, Identifier *ident);
799 void accept(Visitor *v) { v->visit(this); }
800 };
801
802 class DotTemplateExp : public UnaExp
803 {
804 public:
805 TemplateDeclaration *td;
806
807 DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td);
808 void accept(Visitor *v) { v->visit(this); }
809 };
810
811 class DotVarExp : public UnaExp
812 {
813 public:
814 Declaration *var;
815 bool hasOverloads;
816
817 DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads = true);
818 int checkModifiable(Scope *sc, int flag);
819 bool checkReadModifyWrite();
820 bool isLvalue();
821 Expression *toLvalue(Scope *sc, Expression *e);
822 Expression *modifiableLvalue(Scope *sc, Expression *e);
823 void accept(Visitor *v) { v->visit(this); }
824 };
825
826 class DotTemplateInstanceExp : public UnaExp
827 {
828 public:
829 TemplateInstance *ti;
830
831 DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs);
832 DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti);
833 Expression *syntaxCopy();
834 bool findTempDecl(Scope *sc);
835 void accept(Visitor *v) { v->visit(this); }
836 };
837
838 class DelegateExp : public UnaExp
839 {
840 public:
841 FuncDeclaration *func;
842 bool hasOverloads;
843
844 DelegateExp(Loc loc, Expression *e, FuncDeclaration *func, bool hasOverloads = true);
845
846 void accept(Visitor *v) { v->visit(this); }
847 };
848
849 class DotTypeExp : public UnaExp
850 {
851 public:
852 Dsymbol *sym; // symbol that represents a type
853
854 DotTypeExp(Loc loc, Expression *e, Dsymbol *sym);
855 void accept(Visitor *v) { v->visit(this); }
856 };
857
858 class CallExp : public UnaExp
859 {
860 public:
861 Expressions *arguments; // function arguments
862 FuncDeclaration *f; // symbol to call
863 bool directcall; // true if a virtual call is devirtualized
864 CallExp(Loc loc, Expression *e, Expressions *exps);
865 CallExp(Loc loc, Expression *e);
866 CallExp(Loc loc, Expression *e, Expression *earg1);
867 CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2);
868
869 static CallExp *create(Loc loc, Expression *e, Expressions *exps);
870 static CallExp *create(Loc loc, Expression *e);
871 static CallExp *create(Loc loc, Expression *e, Expression *earg1);
872
873 Expression *syntaxCopy();
874 bool isLvalue();
875 Expression *toLvalue(Scope *sc, Expression *e);
876 Expression *addDtorHook(Scope *sc);
877
878 void accept(Visitor *v) { v->visit(this); }
879 };
880
881 class AddrExp : public UnaExp
882 {
883 public:
884 AddrExp(Loc loc, Expression *e);
885 AddrExp(Loc loc, Expression *e, Type *t);
886
887 void accept(Visitor *v) { v->visit(this); }
888 };
889
890 class PtrExp : public UnaExp
891 {
892 public:
893 PtrExp(Loc loc, Expression *e);
894 PtrExp(Loc loc, Expression *e, Type *t);
895 int checkModifiable(Scope *sc, int flag);
896 bool isLvalue();
897 Expression *toLvalue(Scope *sc, Expression *e);
898 Expression *modifiableLvalue(Scope *sc, Expression *e);
899
900 void accept(Visitor *v) { v->visit(this); }
901 };
902
903 class NegExp : public UnaExp
904 {
905 public:
906 NegExp(Loc loc, Expression *e);
907
908 void accept(Visitor *v) { v->visit(this); }
909 };
910
911 class UAddExp : public UnaExp
912 {
913 public:
914 UAddExp(Loc loc, Expression *e);
915
916 void accept(Visitor *v) { v->visit(this); }
917 };
918
919 class ComExp : public UnaExp
920 {
921 public:
922 ComExp(Loc loc, Expression *e);
923
924 void accept(Visitor *v) { v->visit(this); }
925 };
926
927 class NotExp : public UnaExp
928 {
929 public:
930 NotExp(Loc loc, Expression *e);
931 void accept(Visitor *v) { v->visit(this); }
932 };
933
934 class DeleteExp : public UnaExp
935 {
936 public:
937 bool isRAII;
938 DeleteExp(Loc loc, Expression *e, bool isRAII);
939 Expression *toBoolean(Scope *sc);
940 void accept(Visitor *v) { v->visit(this); }
941 };
942
943 class CastExp : public UnaExp
944 {
945 public:
946 // Possible to cast to one type while painting to another type
947 Type *to; // type to cast to
948 unsigned char mod; // MODxxxxx
949
950 CastExp(Loc loc, Expression *e, Type *t);
951 CastExp(Loc loc, Expression *e, unsigned char mod);
952 Expression *syntaxCopy();
953
954 void accept(Visitor *v) { v->visit(this); }
955 };
956
957 class VectorExp : public UnaExp
958 {
959 public:
960 TypeVector *to; // the target vector type before semantic()
961 unsigned dim; // number of elements in the vector
962 OwnedBy ownedByCtfe;
963
964 VectorExp(Loc loc, Expression *e, Type *t);
965 static VectorExp *create(Loc loc, Expression *e, Type *t);
966 Expression *syntaxCopy();
967 void accept(Visitor *v) { v->visit(this); }
968 };
969
970 class VectorArrayExp : public UnaExp
971 {
972 public:
973 VectorArrayExp(Loc loc, Expression *e1);
974 bool isLvalue();
975 Expression *toLvalue(Scope *sc, Expression *e);
976 void accept(Visitor *v) { v->visit(this); }
977 };
978
979 class SliceExp : public UnaExp
980 {
981 public:
982 Expression *upr; // NULL if implicit 0
983 Expression *lwr; // NULL if implicit [length - 1]
984 VarDeclaration *lengthVar;
985 bool upperIsInBounds; // true if upr <= e1.length
986 bool lowerIsLessThanUpper; // true if lwr <= upr
987 bool arrayop; // an array operation, rather than a slice
988
989 SliceExp(Loc loc, Expression *e1, IntervalExp *ie);
990 SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr);
991 Expression *syntaxCopy();
992 int checkModifiable(Scope *sc, int flag);
993 bool isLvalue();
994 Expression *toLvalue(Scope *sc, Expression *e);
995 Expression *modifiableLvalue(Scope *sc, Expression *e);
996 bool isBool(bool result);
997
998 void accept(Visitor *v) { v->visit(this); }
999 };
1000
1001 class ArrayLengthExp : public UnaExp
1002 {
1003 public:
1004 ArrayLengthExp(Loc loc, Expression *e1);
1005
1006 static Expression *rewriteOpAssign(BinExp *exp);
1007 void accept(Visitor *v) { v->visit(this); }
1008 };
1009
1010 class IntervalExp : public Expression
1011 {
1012 public:
1013 Expression *lwr;
1014 Expression *upr;
1015
1016 IntervalExp(Loc loc, Expression *lwr, Expression *upr);
1017 Expression *syntaxCopy();
1018 void accept(Visitor *v) { v->visit(this); }
1019 };
1020
1021 class DelegatePtrExp : public UnaExp
1022 {
1023 public:
1024 DelegatePtrExp(Loc loc, Expression *e1);
1025 bool isLvalue();
1026 Expression *toLvalue(Scope *sc, Expression *e);
1027 Expression *modifiableLvalue(Scope *sc, Expression *e);
1028 void accept(Visitor *v) { v->visit(this); }
1029 };
1030
1031 class DelegateFuncptrExp : public UnaExp
1032 {
1033 public:
1034 DelegateFuncptrExp(Loc loc, Expression *e1);
1035 bool isLvalue();
1036 Expression *toLvalue(Scope *sc, Expression *e);
1037 Expression *modifiableLvalue(Scope *sc, Expression *e);
1038 void accept(Visitor *v) { v->visit(this); }
1039 };
1040
1041 // e1[a0,a1,a2,a3,...]
1042
1043 class ArrayExp : public UnaExp
1044 {
1045 public:
1046 Expressions *arguments; // Array of Expression's
1047 size_t currentDimension; // for opDollar
1048 VarDeclaration *lengthVar;
1049
1050 ArrayExp(Loc loc, Expression *e1, Expression *index = NULL);
1051 ArrayExp(Loc loc, Expression *e1, Expressions *args);
1052 Expression *syntaxCopy();
1053 bool isLvalue();
1054 Expression *toLvalue(Scope *sc, Expression *e);
1055
1056 void accept(Visitor *v) { v->visit(this); }
1057 };
1058
1059 /****************************************************************/
1060
1061 class DotExp : public BinExp
1062 {
1063 public:
1064 DotExp(Loc loc, Expression *e1, Expression *e2);
1065 void accept(Visitor *v) { v->visit(this); }
1066 };
1067
1068 class CommaExp : public BinExp
1069 {
1070 public:
1071 bool isGenerated;
1072 bool allowCommaExp;
1073 CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated = true);
1074 int checkModifiable(Scope *sc, int flag);
1075 bool isLvalue();
1076 Expression *toLvalue(Scope *sc, Expression *e);
1077 Expression *modifiableLvalue(Scope *sc, Expression *e);
1078 bool isBool(bool result);
1079 Expression *toBoolean(Scope *sc);
1080 Expression *addDtorHook(Scope *sc);
1081 void accept(Visitor *v) { v->visit(this); }
1082 };
1083
1084 class IndexExp : public BinExp
1085 {
1086 public:
1087 VarDeclaration *lengthVar;
1088 bool modifiable;
1089 bool indexIsInBounds; // true if 0 <= e2 && e2 <= e1.length - 1
1090
1091 IndexExp(Loc loc, Expression *e1, Expression *e2);
1092 Expression *syntaxCopy();
1093 int checkModifiable(Scope *sc, int flag);
1094 bool isLvalue();
1095 Expression *toLvalue(Scope *sc, Expression *e);
1096 Expression *modifiableLvalue(Scope *sc, Expression *e);
1097
1098 Expression *markSettingAAElem();
1099
1100 void accept(Visitor *v) { v->visit(this); }
1101 };
1102
1103 /* For both i++ and i--
1104 */
1105 class PostExp : public BinExp
1106 {
1107 public:
1108 PostExp(TOK op, Loc loc, Expression *e);
1109 void accept(Visitor *v) { v->visit(this); }
1110 };
1111
1112 /* For both ++i and --i
1113 */
1114 class PreExp : public UnaExp
1115 {
1116 public:
1117 PreExp(TOK op, Loc loc, Expression *e);
1118 void accept(Visitor *v) { v->visit(this); }
1119 };
1120
1121 enum MemorySet
1122 {
1123 blockAssign = 1, // setting the contents of an array
1124 referenceInit = 2 // setting the reference of STCref variable
1125 };
1126
1127 class AssignExp : public BinExp
1128 {
1129 public:
1130 int memset; // combination of MemorySet flags
1131
1132 AssignExp(Loc loc, Expression *e1, Expression *e2);
1133 bool isLvalue();
1134 Expression *toLvalue(Scope *sc, Expression *ex);
1135 Expression *toBoolean(Scope *sc);
1136
1137 void accept(Visitor *v) { v->visit(this); }
1138 };
1139
1140 class ConstructExp : public AssignExp
1141 {
1142 public:
1143 ConstructExp(Loc loc, Expression *e1, Expression *e2);
1144 ConstructExp(Loc loc, VarDeclaration *v, Expression *e2);
1145 void accept(Visitor *v) { v->visit(this); }
1146 };
1147
1148 class BlitExp : public AssignExp
1149 {
1150 public:
1151 BlitExp(Loc loc, Expression *e1, Expression *e2);
1152 BlitExp(Loc loc, VarDeclaration *v, Expression *e2);
1153 void accept(Visitor *v) { v->visit(this); }
1154 };
1155
1156 class AddAssignExp : public BinAssignExp
1157 {
1158 public:
1159 AddAssignExp(Loc loc, Expression *e1, Expression *e2);
1160 void accept(Visitor *v) { v->visit(this); }
1161 };
1162
1163 class MinAssignExp : public BinAssignExp
1164 {
1165 public:
1166 MinAssignExp(Loc loc, Expression *e1, Expression *e2);
1167 void accept(Visitor *v) { v->visit(this); }
1168 };
1169
1170 class MulAssignExp : public BinAssignExp
1171 {
1172 public:
1173 MulAssignExp(Loc loc, Expression *e1, Expression *e2);
1174 void accept(Visitor *v) { v->visit(this); }
1175 };
1176
1177 class DivAssignExp : public BinAssignExp
1178 {
1179 public:
1180 DivAssignExp(Loc loc, Expression *e1, Expression *e2);
1181 void accept(Visitor *v) { v->visit(this); }
1182 };
1183
1184 class ModAssignExp : public BinAssignExp
1185 {
1186 public:
1187 ModAssignExp(Loc loc, Expression *e1, Expression *e2);
1188 void accept(Visitor *v) { v->visit(this); }
1189 };
1190
1191 class AndAssignExp : public BinAssignExp
1192 {
1193 public:
1194 AndAssignExp(Loc loc, Expression *e1, Expression *e2);
1195 void accept(Visitor *v) { v->visit(this); }
1196 };
1197
1198 class OrAssignExp : public BinAssignExp
1199 {
1200 public:
1201 OrAssignExp(Loc loc, Expression *e1, Expression *e2);
1202 void accept(Visitor *v) { v->visit(this); }
1203 };
1204
1205 class XorAssignExp : public BinAssignExp
1206 {
1207 public:
1208 XorAssignExp(Loc loc, Expression *e1, Expression *e2);
1209 void accept(Visitor *v) { v->visit(this); }
1210 };
1211
1212 class PowAssignExp : public BinAssignExp
1213 {
1214 public:
1215 PowAssignExp(Loc loc, Expression *e1, Expression *e2);
1216 void accept(Visitor *v) { v->visit(this); }
1217 };
1218
1219 class ShlAssignExp : public BinAssignExp
1220 {
1221 public:
1222 ShlAssignExp(Loc loc, Expression *e1, Expression *e2);
1223 void accept(Visitor *v) { v->visit(this); }
1224 };
1225
1226 class ShrAssignExp : public BinAssignExp
1227 {
1228 public:
1229 ShrAssignExp(Loc loc, Expression *e1, Expression *e2);
1230 void accept(Visitor *v) { v->visit(this); }
1231 };
1232
1233 class UshrAssignExp : public BinAssignExp
1234 {
1235 public:
1236 UshrAssignExp(Loc loc, Expression *e1, Expression *e2);
1237 void accept(Visitor *v) { v->visit(this); }
1238 };
1239
1240 class CatAssignExp : public BinAssignExp
1241 {
1242 public:
1243 CatAssignExp(Loc loc, Expression *e1, Expression *e2);
1244 void accept(Visitor *v) { v->visit(this); }
1245 };
1246
1247 class AddExp : public BinExp
1248 {
1249 public:
1250 AddExp(Loc loc, Expression *e1, Expression *e2);
1251
1252 void accept(Visitor *v) { v->visit(this); }
1253 };
1254
1255 class MinExp : public BinExp
1256 {
1257 public:
1258 MinExp(Loc loc, Expression *e1, Expression *e2);
1259
1260 void accept(Visitor *v) { v->visit(this); }
1261 };
1262
1263 class CatExp : public BinExp
1264 {
1265 public:
1266 CatExp(Loc loc, Expression *e1, Expression *e2);
1267
1268 void accept(Visitor *v) { v->visit(this); }
1269 };
1270
1271 class MulExp : public BinExp
1272 {
1273 public:
1274 MulExp(Loc loc, Expression *e1, Expression *e2);
1275
1276 void accept(Visitor *v) { v->visit(this); }
1277 };
1278
1279 class DivExp : public BinExp
1280 {
1281 public:
1282 DivExp(Loc loc, Expression *e1, Expression *e2);
1283
1284 void accept(Visitor *v) { v->visit(this); }
1285 };
1286
1287 class ModExp : public BinExp
1288 {
1289 public:
1290 ModExp(Loc loc, Expression *e1, Expression *e2);
1291
1292 void accept(Visitor *v) { v->visit(this); }
1293 };
1294
1295 class PowExp : public BinExp
1296 {
1297 public:
1298 PowExp(Loc loc, Expression *e1, Expression *e2);
1299
1300 void accept(Visitor *v) { v->visit(this); }
1301 };
1302
1303 class ShlExp : public BinExp
1304 {
1305 public:
1306 ShlExp(Loc loc, Expression *e1, Expression *e2);
1307
1308 void accept(Visitor *v) { v->visit(this); }
1309 };
1310
1311 class ShrExp : public BinExp
1312 {
1313 public:
1314 ShrExp(Loc loc, Expression *e1, Expression *e2);
1315
1316 void accept(Visitor *v) { v->visit(this); }
1317 };
1318
1319 class UshrExp : public BinExp
1320 {
1321 public:
1322 UshrExp(Loc loc, Expression *e1, Expression *e2);
1323
1324 void accept(Visitor *v) { v->visit(this); }
1325 };
1326
1327 class AndExp : public BinExp
1328 {
1329 public:
1330 AndExp(Loc loc, Expression *e1, Expression *e2);
1331
1332 void accept(Visitor *v) { v->visit(this); }
1333 };
1334
1335 class OrExp : public BinExp
1336 {
1337 public:
1338 OrExp(Loc loc, Expression *e1, Expression *e2);
1339
1340 void accept(Visitor *v) { v->visit(this); }
1341 };
1342
1343 class XorExp : public BinExp
1344 {
1345 public:
1346 XorExp(Loc loc, Expression *e1, Expression *e2);
1347
1348 void accept(Visitor *v) { v->visit(this); }
1349 };
1350
1351 class OrOrExp : public BinExp
1352 {
1353 public:
1354 OrOrExp(Loc loc, Expression *e1, Expression *e2);
1355 Expression *toBoolean(Scope *sc);
1356 void accept(Visitor *v) { v->visit(this); }
1357 };
1358
1359 class AndAndExp : public BinExp
1360 {
1361 public:
1362 AndAndExp(Loc loc, Expression *e1, Expression *e2);
1363 Expression *toBoolean(Scope *sc);
1364 void accept(Visitor *v) { v->visit(this); }
1365 };
1366
1367 class CmpExp : public BinExp
1368 {
1369 public:
1370 CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1371
1372 void accept(Visitor *v) { v->visit(this); }
1373 };
1374
1375 class InExp : public BinExp
1376 {
1377 public:
1378 InExp(Loc loc, Expression *e1, Expression *e2);
1379
1380 void accept(Visitor *v) { v->visit(this); }
1381 };
1382
1383 class RemoveExp : public BinExp
1384 {
1385 public:
1386 RemoveExp(Loc loc, Expression *e1, Expression *e2);
1387 void accept(Visitor *v) { v->visit(this); }
1388 };
1389
1390 // == and !=
1391
1392 class EqualExp : public BinExp
1393 {
1394 public:
1395 EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1396
1397 void accept(Visitor *v) { v->visit(this); }
1398 };
1399
1400 // is and !is
1401
1402 class IdentityExp : public BinExp
1403 {
1404 public:
1405 IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1406 void accept(Visitor *v) { v->visit(this); }
1407 };
1408
1409 /****************************************************************/
1410
1411 class CondExp : public BinExp
1412 {
1413 public:
1414 Expression *econd;
1415
1416 CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2);
1417 Expression *syntaxCopy();
1418 int checkModifiable(Scope *sc, int flag);
1419 bool isLvalue();
1420 Expression *toLvalue(Scope *sc, Expression *e);
1421 Expression *modifiableLvalue(Scope *sc, Expression *e);
1422 Expression *toBoolean(Scope *sc);
1423 void hookDtors(Scope *sc);
1424
1425 void accept(Visitor *v) { v->visit(this); }
1426 };
1427
1428 /****************************************************************/
1429
1430 class DefaultInitExp : public Expression
1431 {
1432 public:
1433 TOK subop; // which of the derived classes this is
1434
1435 DefaultInitExp(Loc loc, TOK subop, int size);
1436 void accept(Visitor *v) { v->visit(this); }
1437 };
1438
1439 class FileInitExp : public DefaultInitExp
1440 {
1441 public:
1442 FileInitExp(Loc loc, TOK tok);
1443 Expression *resolveLoc(Loc loc, Scope *sc);
1444 void accept(Visitor *v) { v->visit(this); }
1445 };
1446
1447 class LineInitExp : public DefaultInitExp
1448 {
1449 public:
1450 LineInitExp(Loc loc);
1451 Expression *resolveLoc(Loc loc, Scope *sc);
1452 void accept(Visitor *v) { v->visit(this); }
1453 };
1454
1455 class ModuleInitExp : public DefaultInitExp
1456 {
1457 public:
1458 ModuleInitExp(Loc loc);
1459 Expression *resolveLoc(Loc loc, Scope *sc);
1460 void accept(Visitor *v) { v->visit(this); }
1461 };
1462
1463 class FuncInitExp : public DefaultInitExp
1464 {
1465 public:
1466 FuncInitExp(Loc loc);
1467 Expression *resolveLoc(Loc loc, Scope *sc);
1468 void accept(Visitor *v) { v->visit(this); }
1469 };
1470
1471 class PrettyFuncInitExp : public DefaultInitExp
1472 {
1473 public:
1474 PrettyFuncInitExp(Loc loc);
1475 Expression *resolveLoc(Loc loc, Scope *sc);
1476 void accept(Visitor *v) { v->visit(this); }
1477 };
1478
1479 /****************************************************************/
1480
1481 /* A type meant as a union of all the Expression types,
1482 * to serve essentially as a Variant that will sit on the stack
1483 * during CTFE to reduce memory consumption.
1484 */
1485 struct UnionExp
1486 {
1487 UnionExp() { } // yes, default constructor does nothing
1488
1489 UnionExp(Expression *e)
1490 {
1491 memcpy(this, (void *)e, e->size);
1492 }
1493
1494 /* Extract pointer to Expression
1495 */
1496 Expression *exp() { return (Expression *)&u; }
1497
1498 /* Convert to an allocated Expression
1499 */
1500 Expression *copy();
1501
1502 private:
1503 // Ensure that the union is suitably aligned.
1504 #if defined(__GNUC__) || defined(__clang__)
1505 __attribute__((aligned(8)))
1506 #elif defined(_MSC_VER)
1507 __declspec(align(8))
1508 #elif defined(__DMC__)
1509 #pragma pack(8)
1510 #endif
1511 union
1512 {
1513 char exp [sizeof(Expression)];
1514 char integerexp[sizeof(IntegerExp)];
1515 char errorexp [sizeof(ErrorExp)];
1516 char realexp [sizeof(RealExp)];
1517 char complexexp[sizeof(ComplexExp)];
1518 char symoffexp [sizeof(SymOffExp)];
1519 char stringexp [sizeof(StringExp)];
1520 char arrayliteralexp [sizeof(ArrayLiteralExp)];
1521 char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];
1522 char structliteralexp [sizeof(StructLiteralExp)];
1523 char nullexp [sizeof(NullExp)];
1524 char dotvarexp [sizeof(DotVarExp)];
1525 char addrexp [sizeof(AddrExp)];
1526 char indexexp [sizeof(IndexExp)];
1527 char sliceexp [sizeof(SliceExp)];
1528 char vectorexp [sizeof(VectorExp)];
1529 } u;
1530 #if defined(__DMC__)
1531 #pragma pack()
1532 #endif
1533 };
1534
1535 /****************************************************************/
1536
1537 /* Special values used by the interpreter
1538 */
1539
1540 Expression *expType(Type *type, Expression *e);
1541
1542 UnionExp Neg(Type *type, Expression *e1);
1543 UnionExp Com(Type *type, Expression *e1);
1544 UnionExp Not(Type *type, Expression *e1);
1545 UnionExp Bool(Type *type, Expression *e1);
1546 UnionExp Cast(Loc loc, Type *type, Type *to, Expression *e1);
1547 UnionExp ArrayLength(Type *type, Expression *e1);
1548 UnionExp Ptr(Type *type, Expression *e1);
1549
1550 UnionExp Add(Loc loc, Type *type, Expression *e1, Expression *e2);
1551 UnionExp Min(Loc loc, Type *type, Expression *e1, Expression *e2);
1552 UnionExp Mul(Loc loc, Type *type, Expression *e1, Expression *e2);
1553 UnionExp Div(Loc loc, Type *type, Expression *e1, Expression *e2);
1554 UnionExp Mod(Loc loc, Type *type, Expression *e1, Expression *e2);
1555 UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2);
1556 UnionExp Shl(Loc loc, Type *type, Expression *e1, Expression *e2);
1557 UnionExp Shr(Loc loc, Type *type, Expression *e1, Expression *e2);
1558 UnionExp Ushr(Loc loc, Type *type, Expression *e1, Expression *e2);
1559 UnionExp And(Loc loc, Type *type, Expression *e1, Expression *e2);
1560 UnionExp Or(Loc loc, Type *type, Expression *e1, Expression *e2);
1561 UnionExp Xor(Loc loc, Type *type, Expression *e1, Expression *e2);
1562 UnionExp Index(Type *type, Expression *e1, Expression *e2);
1563 UnionExp Cat(Type *type, Expression *e1, Expression *e2);
1564
1565 UnionExp Equal(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1566 UnionExp Cmp(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1567 UnionExp Identity(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1568
1569 UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr);
1570
1571 // Const-folding functions used by CTFE
1572
1573 void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *newval, size_t firstIndex);
1574 void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, size_t firstIndex);
1575 void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, size_t firstIndex);
1576
1577 int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len);
1578 int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len);
1579