]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/expression.h
Add D front-end, libphobos library, and D2 testsuite.
[thirdparty/gcc.git] / gcc / d / dmd / expression.h
1
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 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, Expressions *elements);
414 ArrayLiteralExp(Loc loc, Expression *e);
415 ArrayLiteralExp(Loc loc, 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
963 VectorExp(Loc loc, Expression *e, Type *t);
964 static VectorExp *create(Loc loc, Expression *e, Type *t);
965 Expression *syntaxCopy();
966 void accept(Visitor *v) { v->visit(this); }
967 };
968
969 class SliceExp : public UnaExp
970 {
971 public:
972 Expression *upr; // NULL if implicit 0
973 Expression *lwr; // NULL if implicit [length - 1]
974 VarDeclaration *lengthVar;
975 bool upperIsInBounds; // true if upr <= e1.length
976 bool lowerIsLessThanUpper; // true if lwr <= upr
977 bool arrayop; // an array operation, rather than a slice
978
979 SliceExp(Loc loc, Expression *e1, IntervalExp *ie);
980 SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr);
981 Expression *syntaxCopy();
982 int checkModifiable(Scope *sc, int flag);
983 bool isLvalue();
984 Expression *toLvalue(Scope *sc, Expression *e);
985 Expression *modifiableLvalue(Scope *sc, Expression *e);
986 bool isBool(bool result);
987
988 void accept(Visitor *v) { v->visit(this); }
989 };
990
991 class ArrayLengthExp : public UnaExp
992 {
993 public:
994 ArrayLengthExp(Loc loc, Expression *e1);
995
996 static Expression *rewriteOpAssign(BinExp *exp);
997 void accept(Visitor *v) { v->visit(this); }
998 };
999
1000 class IntervalExp : public Expression
1001 {
1002 public:
1003 Expression *lwr;
1004 Expression *upr;
1005
1006 IntervalExp(Loc loc, Expression *lwr, Expression *upr);
1007 Expression *syntaxCopy();
1008 void accept(Visitor *v) { v->visit(this); }
1009 };
1010
1011 class DelegatePtrExp : public UnaExp
1012 {
1013 public:
1014 DelegatePtrExp(Loc loc, Expression *e1);
1015 bool isLvalue();
1016 Expression *toLvalue(Scope *sc, Expression *e);
1017 Expression *modifiableLvalue(Scope *sc, Expression *e);
1018 void accept(Visitor *v) { v->visit(this); }
1019 };
1020
1021 class DelegateFuncptrExp : public UnaExp
1022 {
1023 public:
1024 DelegateFuncptrExp(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 // e1[a0,a1,a2,a3,...]
1032
1033 class ArrayExp : public UnaExp
1034 {
1035 public:
1036 Expressions *arguments; // Array of Expression's
1037 size_t currentDimension; // for opDollar
1038 VarDeclaration *lengthVar;
1039
1040 ArrayExp(Loc loc, Expression *e1, Expression *index = NULL);
1041 ArrayExp(Loc loc, Expression *e1, Expressions *args);
1042 Expression *syntaxCopy();
1043 bool isLvalue();
1044 Expression *toLvalue(Scope *sc, Expression *e);
1045
1046 void accept(Visitor *v) { v->visit(this); }
1047 };
1048
1049 /****************************************************************/
1050
1051 class DotExp : public BinExp
1052 {
1053 public:
1054 DotExp(Loc loc, Expression *e1, Expression *e2);
1055 void accept(Visitor *v) { v->visit(this); }
1056 };
1057
1058 class CommaExp : public BinExp
1059 {
1060 public:
1061 bool isGenerated;
1062 bool allowCommaExp;
1063 CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated = true);
1064 int checkModifiable(Scope *sc, int flag);
1065 bool isLvalue();
1066 Expression *toLvalue(Scope *sc, Expression *e);
1067 Expression *modifiableLvalue(Scope *sc, Expression *e);
1068 bool isBool(bool result);
1069 Expression *toBoolean(Scope *sc);
1070 Expression *addDtorHook(Scope *sc);
1071 void accept(Visitor *v) { v->visit(this); }
1072 };
1073
1074 class IndexExp : public BinExp
1075 {
1076 public:
1077 VarDeclaration *lengthVar;
1078 bool modifiable;
1079 bool indexIsInBounds; // true if 0 <= e2 && e2 <= e1.length - 1
1080
1081 IndexExp(Loc loc, Expression *e1, Expression *e2);
1082 Expression *syntaxCopy();
1083 int checkModifiable(Scope *sc, int flag);
1084 bool isLvalue();
1085 Expression *toLvalue(Scope *sc, Expression *e);
1086 Expression *modifiableLvalue(Scope *sc, Expression *e);
1087
1088 Expression *markSettingAAElem();
1089
1090 void accept(Visitor *v) { v->visit(this); }
1091 };
1092
1093 /* For both i++ and i--
1094 */
1095 class PostExp : public BinExp
1096 {
1097 public:
1098 PostExp(TOK op, Loc loc, Expression *e);
1099 void accept(Visitor *v) { v->visit(this); }
1100 };
1101
1102 /* For both ++i and --i
1103 */
1104 class PreExp : public UnaExp
1105 {
1106 public:
1107 PreExp(TOK op, Loc loc, Expression *e);
1108 void accept(Visitor *v) { v->visit(this); }
1109 };
1110
1111 enum MemorySet
1112 {
1113 blockAssign = 1, // setting the contents of an array
1114 referenceInit = 2 // setting the reference of STCref variable
1115 };
1116
1117 class AssignExp : public BinExp
1118 {
1119 public:
1120 int memset; // combination of MemorySet flags
1121
1122 AssignExp(Loc loc, Expression *e1, Expression *e2);
1123 bool isLvalue();
1124 Expression *toLvalue(Scope *sc, Expression *ex);
1125 Expression *toBoolean(Scope *sc);
1126
1127 void accept(Visitor *v) { v->visit(this); }
1128 };
1129
1130 class ConstructExp : public AssignExp
1131 {
1132 public:
1133 ConstructExp(Loc loc, Expression *e1, Expression *e2);
1134 ConstructExp(Loc loc, VarDeclaration *v, Expression *e2);
1135 void accept(Visitor *v) { v->visit(this); }
1136 };
1137
1138 class BlitExp : public AssignExp
1139 {
1140 public:
1141 BlitExp(Loc loc, Expression *e1, Expression *e2);
1142 BlitExp(Loc loc, VarDeclaration *v, Expression *e2);
1143 void accept(Visitor *v) { v->visit(this); }
1144 };
1145
1146 class AddAssignExp : public BinAssignExp
1147 {
1148 public:
1149 AddAssignExp(Loc loc, Expression *e1, Expression *e2);
1150 void accept(Visitor *v) { v->visit(this); }
1151 };
1152
1153 class MinAssignExp : public BinAssignExp
1154 {
1155 public:
1156 MinAssignExp(Loc loc, Expression *e1, Expression *e2);
1157 void accept(Visitor *v) { v->visit(this); }
1158 };
1159
1160 class MulAssignExp : public BinAssignExp
1161 {
1162 public:
1163 MulAssignExp(Loc loc, Expression *e1, Expression *e2);
1164 void accept(Visitor *v) { v->visit(this); }
1165 };
1166
1167 class DivAssignExp : public BinAssignExp
1168 {
1169 public:
1170 DivAssignExp(Loc loc, Expression *e1, Expression *e2);
1171 void accept(Visitor *v) { v->visit(this); }
1172 };
1173
1174 class ModAssignExp : public BinAssignExp
1175 {
1176 public:
1177 ModAssignExp(Loc loc, Expression *e1, Expression *e2);
1178 void accept(Visitor *v) { v->visit(this); }
1179 };
1180
1181 class AndAssignExp : public BinAssignExp
1182 {
1183 public:
1184 AndAssignExp(Loc loc, Expression *e1, Expression *e2);
1185 void accept(Visitor *v) { v->visit(this); }
1186 };
1187
1188 class OrAssignExp : public BinAssignExp
1189 {
1190 public:
1191 OrAssignExp(Loc loc, Expression *e1, Expression *e2);
1192 void accept(Visitor *v) { v->visit(this); }
1193 };
1194
1195 class XorAssignExp : public BinAssignExp
1196 {
1197 public:
1198 XorAssignExp(Loc loc, Expression *e1, Expression *e2);
1199 void accept(Visitor *v) { v->visit(this); }
1200 };
1201
1202 class PowAssignExp : public BinAssignExp
1203 {
1204 public:
1205 PowAssignExp(Loc loc, Expression *e1, Expression *e2);
1206 void accept(Visitor *v) { v->visit(this); }
1207 };
1208
1209 class ShlAssignExp : public BinAssignExp
1210 {
1211 public:
1212 ShlAssignExp(Loc loc, Expression *e1, Expression *e2);
1213 void accept(Visitor *v) { v->visit(this); }
1214 };
1215
1216 class ShrAssignExp : public BinAssignExp
1217 {
1218 public:
1219 ShrAssignExp(Loc loc, Expression *e1, Expression *e2);
1220 void accept(Visitor *v) { v->visit(this); }
1221 };
1222
1223 class UshrAssignExp : public BinAssignExp
1224 {
1225 public:
1226 UshrAssignExp(Loc loc, Expression *e1, Expression *e2);
1227 void accept(Visitor *v) { v->visit(this); }
1228 };
1229
1230 class CatAssignExp : public BinAssignExp
1231 {
1232 public:
1233 CatAssignExp(Loc loc, Expression *e1, Expression *e2);
1234 void accept(Visitor *v) { v->visit(this); }
1235 };
1236
1237 class AddExp : public BinExp
1238 {
1239 public:
1240 AddExp(Loc loc, Expression *e1, Expression *e2);
1241
1242 void accept(Visitor *v) { v->visit(this); }
1243 };
1244
1245 class MinExp : public BinExp
1246 {
1247 public:
1248 MinExp(Loc loc, Expression *e1, Expression *e2);
1249
1250 void accept(Visitor *v) { v->visit(this); }
1251 };
1252
1253 class CatExp : public BinExp
1254 {
1255 public:
1256 CatExp(Loc loc, Expression *e1, Expression *e2);
1257
1258 void accept(Visitor *v) { v->visit(this); }
1259 };
1260
1261 class MulExp : public BinExp
1262 {
1263 public:
1264 MulExp(Loc loc, Expression *e1, Expression *e2);
1265
1266 void accept(Visitor *v) { v->visit(this); }
1267 };
1268
1269 class DivExp : public BinExp
1270 {
1271 public:
1272 DivExp(Loc loc, Expression *e1, Expression *e2);
1273
1274 void accept(Visitor *v) { v->visit(this); }
1275 };
1276
1277 class ModExp : public BinExp
1278 {
1279 public:
1280 ModExp(Loc loc, Expression *e1, Expression *e2);
1281
1282 void accept(Visitor *v) { v->visit(this); }
1283 };
1284
1285 class PowExp : public BinExp
1286 {
1287 public:
1288 PowExp(Loc loc, Expression *e1, Expression *e2);
1289
1290 void accept(Visitor *v) { v->visit(this); }
1291 };
1292
1293 class ShlExp : public BinExp
1294 {
1295 public:
1296 ShlExp(Loc loc, Expression *e1, Expression *e2);
1297
1298 void accept(Visitor *v) { v->visit(this); }
1299 };
1300
1301 class ShrExp : public BinExp
1302 {
1303 public:
1304 ShrExp(Loc loc, Expression *e1, Expression *e2);
1305
1306 void accept(Visitor *v) { v->visit(this); }
1307 };
1308
1309 class UshrExp : public BinExp
1310 {
1311 public:
1312 UshrExp(Loc loc, Expression *e1, Expression *e2);
1313
1314 void accept(Visitor *v) { v->visit(this); }
1315 };
1316
1317 class AndExp : public BinExp
1318 {
1319 public:
1320 AndExp(Loc loc, Expression *e1, Expression *e2);
1321
1322 void accept(Visitor *v) { v->visit(this); }
1323 };
1324
1325 class OrExp : public BinExp
1326 {
1327 public:
1328 OrExp(Loc loc, Expression *e1, Expression *e2);
1329
1330 void accept(Visitor *v) { v->visit(this); }
1331 };
1332
1333 class XorExp : public BinExp
1334 {
1335 public:
1336 XorExp(Loc loc, Expression *e1, Expression *e2);
1337
1338 void accept(Visitor *v) { v->visit(this); }
1339 };
1340
1341 class OrOrExp : public BinExp
1342 {
1343 public:
1344 OrOrExp(Loc loc, Expression *e1, Expression *e2);
1345 Expression *toBoolean(Scope *sc);
1346 void accept(Visitor *v) { v->visit(this); }
1347 };
1348
1349 class AndAndExp : public BinExp
1350 {
1351 public:
1352 AndAndExp(Loc loc, Expression *e1, Expression *e2);
1353 Expression *toBoolean(Scope *sc);
1354 void accept(Visitor *v) { v->visit(this); }
1355 };
1356
1357 class CmpExp : public BinExp
1358 {
1359 public:
1360 CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1361
1362 void accept(Visitor *v) { v->visit(this); }
1363 };
1364
1365 class InExp : public BinExp
1366 {
1367 public:
1368 InExp(Loc loc, Expression *e1, Expression *e2);
1369
1370 void accept(Visitor *v) { v->visit(this); }
1371 };
1372
1373 class RemoveExp : public BinExp
1374 {
1375 public:
1376 RemoveExp(Loc loc, Expression *e1, Expression *e2);
1377 void accept(Visitor *v) { v->visit(this); }
1378 };
1379
1380 // == and !=
1381
1382 class EqualExp : public BinExp
1383 {
1384 public:
1385 EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1386
1387 void accept(Visitor *v) { v->visit(this); }
1388 };
1389
1390 // is and !is
1391
1392 class IdentityExp : public BinExp
1393 {
1394 public:
1395 IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1396 void accept(Visitor *v) { v->visit(this); }
1397 };
1398
1399 /****************************************************************/
1400
1401 class CondExp : public BinExp
1402 {
1403 public:
1404 Expression *econd;
1405
1406 CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2);
1407 Expression *syntaxCopy();
1408 int checkModifiable(Scope *sc, int flag);
1409 bool isLvalue();
1410 Expression *toLvalue(Scope *sc, Expression *e);
1411 Expression *modifiableLvalue(Scope *sc, Expression *e);
1412 Expression *toBoolean(Scope *sc);
1413 void hookDtors(Scope *sc);
1414
1415 void accept(Visitor *v) { v->visit(this); }
1416 };
1417
1418 /****************************************************************/
1419
1420 class DefaultInitExp : public Expression
1421 {
1422 public:
1423 TOK subop; // which of the derived classes this is
1424
1425 DefaultInitExp(Loc loc, TOK subop, int size);
1426 void accept(Visitor *v) { v->visit(this); }
1427 };
1428
1429 class FileInitExp : public DefaultInitExp
1430 {
1431 public:
1432 FileInitExp(Loc loc, TOK tok);
1433 Expression *resolveLoc(Loc loc, Scope *sc);
1434 void accept(Visitor *v) { v->visit(this); }
1435 };
1436
1437 class LineInitExp : public DefaultInitExp
1438 {
1439 public:
1440 LineInitExp(Loc loc);
1441 Expression *resolveLoc(Loc loc, Scope *sc);
1442 void accept(Visitor *v) { v->visit(this); }
1443 };
1444
1445 class ModuleInitExp : public DefaultInitExp
1446 {
1447 public:
1448 ModuleInitExp(Loc loc);
1449 Expression *resolveLoc(Loc loc, Scope *sc);
1450 void accept(Visitor *v) { v->visit(this); }
1451 };
1452
1453 class FuncInitExp : public DefaultInitExp
1454 {
1455 public:
1456 FuncInitExp(Loc loc);
1457 Expression *resolveLoc(Loc loc, Scope *sc);
1458 void accept(Visitor *v) { v->visit(this); }
1459 };
1460
1461 class PrettyFuncInitExp : public DefaultInitExp
1462 {
1463 public:
1464 PrettyFuncInitExp(Loc loc);
1465 Expression *resolveLoc(Loc loc, Scope *sc);
1466 void accept(Visitor *v) { v->visit(this); }
1467 };
1468
1469 /****************************************************************/
1470
1471 /* A type meant as a union of all the Expression types,
1472 * to serve essentially as a Variant that will sit on the stack
1473 * during CTFE to reduce memory consumption.
1474 */
1475 struct UnionExp
1476 {
1477 UnionExp() { } // yes, default constructor does nothing
1478
1479 UnionExp(Expression *e)
1480 {
1481 memcpy(this, (void *)e, e->size);
1482 }
1483
1484 /* Extract pointer to Expression
1485 */
1486 Expression *exp() { return (Expression *)&u; }
1487
1488 /* Convert to an allocated Expression
1489 */
1490 Expression *copy();
1491
1492 private:
1493 union
1494 {
1495 char exp [sizeof(Expression)];
1496 char integerexp[sizeof(IntegerExp)];
1497 char errorexp [sizeof(ErrorExp)];
1498 char realexp [sizeof(RealExp)];
1499 char complexexp[sizeof(ComplexExp)];
1500 char symoffexp [sizeof(SymOffExp)];
1501 char stringexp [sizeof(StringExp)];
1502 char arrayliteralexp [sizeof(ArrayLiteralExp)];
1503 char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];
1504 char structliteralexp [sizeof(StructLiteralExp)];
1505 char nullexp [sizeof(NullExp)];
1506 char dotvarexp [sizeof(DotVarExp)];
1507 char addrexp [sizeof(AddrExp)];
1508 char indexexp [sizeof(IndexExp)];
1509 char sliceexp [sizeof(SliceExp)];
1510
1511 // Ensure that the union is suitably aligned.
1512 real_t for_alignment_only;
1513 } u;
1514 };
1515
1516 /****************************************************************/
1517
1518 /* Special values used by the interpreter
1519 */
1520
1521 Expression *expType(Type *type, Expression *e);
1522
1523 UnionExp Neg(Type *type, Expression *e1);
1524 UnionExp Com(Type *type, Expression *e1);
1525 UnionExp Not(Type *type, Expression *e1);
1526 UnionExp Bool(Type *type, Expression *e1);
1527 UnionExp Cast(Loc loc, Type *type, Type *to, Expression *e1);
1528 UnionExp ArrayLength(Type *type, Expression *e1);
1529 UnionExp Ptr(Type *type, Expression *e1);
1530
1531 UnionExp Add(Loc loc, Type *type, Expression *e1, Expression *e2);
1532 UnionExp Min(Loc loc, Type *type, Expression *e1, Expression *e2);
1533 UnionExp Mul(Loc loc, Type *type, Expression *e1, Expression *e2);
1534 UnionExp Div(Loc loc, Type *type, Expression *e1, Expression *e2);
1535 UnionExp Mod(Loc loc, Type *type, Expression *e1, Expression *e2);
1536 UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2);
1537 UnionExp Shl(Loc loc, Type *type, Expression *e1, Expression *e2);
1538 UnionExp Shr(Loc loc, Type *type, Expression *e1, Expression *e2);
1539 UnionExp Ushr(Loc loc, Type *type, Expression *e1, Expression *e2);
1540 UnionExp And(Loc loc, Type *type, Expression *e1, Expression *e2);
1541 UnionExp Or(Loc loc, Type *type, Expression *e1, Expression *e2);
1542 UnionExp Xor(Loc loc, Type *type, Expression *e1, Expression *e2);
1543 UnionExp Index(Type *type, Expression *e1, Expression *e2);
1544 UnionExp Cat(Type *type, Expression *e1, Expression *e2);
1545
1546 UnionExp Equal(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1547 UnionExp Cmp(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1548 UnionExp Identity(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1549
1550 UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr);
1551
1552 // Const-folding functions used by CTFE
1553
1554 void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *newval, size_t firstIndex);
1555 void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, size_t firstIndex);
1556 void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, size_t firstIndex);
1557
1558 int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len);
1559 int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len);