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