]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/dmd/expression.h
d: Merge upstream dmd 47ed0330f
[thirdparty/gcc.git] / gcc / d / dmd / expression.h
CommitLineData
b4c522fa
IB
1
2/* Compiler implementation of the D programming language
8e788ac6 3 * Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
b4c522fa
IB
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/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
23class Type;
24class TypeVector;
25struct Scope;
26class TupleDeclaration;
27class VarDeclaration;
28class FuncDeclaration;
29class FuncLiteralDeclaration;
30class Declaration;
31class CtorDeclaration;
32class NewDeclaration;
33class Dsymbol;
34class Import;
35class Module;
36class ScopeDsymbol;
37class Expression;
38class Declaration;
39class AggregateDeclaration;
40class StructDeclaration;
41class TemplateInstance;
42class TemplateDeclaration;
43class ClassDeclaration;
44class BinExp;
45class OverloadSet;
46class Initializer;
47class StringExp;
48class ArrayExp;
49class SliceExp;
50struct UnionExp;
51#ifdef IN_GCC
52typedef union tree_node Symbol;
53#else
54struct Symbol; // back end symbol
55#endif
56
57Expression *resolveProperties(Scope *sc, Expression *e);
58Expression *resolvePropertiesOnly(Scope *sc, Expression *e1);
59bool checkAccess(Loc loc, Scope *sc, Expression *e, Declaration *d);
60bool checkAccess(Loc loc, Scope *sc, Package *p);
61Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Dsymbol *d);
62Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid);
63void expandTuples(Expressions *exps);
64TupleDeclaration *isAliasThisTuple(Expression *e);
65int expandAliasThisTuples(Expressions *exps, size_t starti = 0);
66FuncDeclaration *hasThis(Scope *sc);
67Expression *fromConstInitializer(int result, Expression *e);
68bool arrayExpressionSemantic(Expressions *exps, Scope *sc, bool preserveErrors = false);
69TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s);
70Expression *valueNoDtor(Expression *e);
71int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1);
72Expression *resolveAliasThis(Scope *sc, Expression *e, bool gag = false);
73Expression *doCopyOrMove(Scope *sc, Expression *e);
74Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0);
75Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, IntervalExp *ie, Expression **pe0);
76Expression *integralPromotions(Expression *e, Scope *sc);
77bool discardValue(Expression *e);
78bool isTrivialExp(Expression *e);
79
80int isConst(Expression *e);
81Expression *toDelegate(Expression *e, Type* t, Scope *sc);
82AggregateDeclaration *isAggregate(Type *t);
83IntRange getIntRange(Expression *e);
84bool checkNonAssignmentArrayOp(Expression *e, bool suggestion = false);
85bool isUnaArrayOp(TOK op);
86bool isBinArrayOp(TOK op);
87bool isBinAssignArrayOp(TOK op);
88bool isArrayOpOperand(Expression *e);
89Expression *arrayOp(BinExp *e, Scope *sc);
90Expression *arrayOp(BinAssignExp *e, Scope *sc);
91bool hasSideEffect(Expression *e);
92bool canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow);
93Expression *Expression_optimize(Expression *e, int result, bool keepLvalue);
94MATCH implicitConvTo(Expression *e, Type *t);
95Expression *implicitCastTo(Expression *e, Scope *sc, Type *t);
96Expression *castTo(Expression *e, Scope *sc, Type *t);
97Expression *ctfeInterpret(Expression *);
98Expression *inlineCopy(Expression *e, Scope *sc);
99Expression *op_overload(Expression *e, Scope *sc);
100Type *toStaticArrayType(SliceExp *e);
101Expression *scaleFactor(BinExp *be, Scope *sc);
102Expression *typeCombine(BinExp *be, Scope *sc);
103Expression *inferType(Expression *e, Type *t, int flag = 0);
104Expression *semanticTraits(TraitsExp *e, Scope *sc);
105Type *getIndirection(Type *t);
106
107Expression *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 */
112Expression *ctfeInterpretForPragmaMsg(Expression *e);
113
114enum 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
124class Expression : public RootObject
125{
126public:
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();
5b74dd0a 160 virtual TupleExp *toTupleExp();
b4c522fa
IB
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
224class IntegerExp : public Expression
225{
226public:
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
245class ErrorExp : public Expression
246{
247public:
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
255class RealExp : public Expression
256{
257public:
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
272class ComplexExp : public Expression
273{
274public:
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
289class IdentifierExp : public Expression
290{
291public:
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
301class DollarExp : public IdentifierExp
302{
303public:
304 DollarExp(Loc loc);
305 void accept(Visitor *v) { v->visit(this); }
306};
307
308class DsymbolExp : public Expression
309{
310public:
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
320class ThisExp : public Expression
321{
322public:
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
333class SuperExp : public ThisExp
334{
335public:
336 SuperExp(Loc loc);
337
338 void accept(Visitor *v) { v->visit(this); }
339};
340
341class NullExp : public Expression
342{
343public:
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
353class StringExp : public Expression
354{
355public:
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
385class TupleExp : public Expression
386{
387public:
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);
5b74dd0a 401 TupleExp *toTupleExp();
b4c522fa
IB
402 Expression *syntaxCopy();
403 bool equals(RootObject *o);
404
405 void accept(Visitor *v) { v->visit(this); }
406};
407
408class ArrayLiteralExp : public Expression
409{
410public:
411 Expression *basis;
412 Expressions *elements;
413 OwnedBy ownedByCtfe;
414
255b2d91
IB
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);
b4c522fa
IB
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
429class AssocArrayLiteralExp : public Expression
430{
431public:
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
457class StructLiteralExp : public Expression
458{
459public:
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
495class DotIdExp;
496DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident);
497
498class TypeExp : public Expression
499{
500public:
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
508class ScopeExp : public Expression
509{
510public:
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
520class TemplateExp : public Expression
521{
522public:
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
534class NewExp : public Expression
535{
536public:
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
558class NewAnonClassExp : public Expression
559{
560public:
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
574class SymbolExp : public Expression
575{
576public:
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
586class SymOffExp : public SymbolExp
587{
588public:
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
599class VarExp : public SymbolExp
600{
601public:
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
616class OverExp : public Expression
617{
618public:
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
629class FuncExp : public Expression
630{
631public:
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.
653class DeclarationExp : public Expression
654{
655public:
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
666class TypeidExp : public Expression
667{
668public:
669 RootObject *obj;
670
671 TypeidExp(Loc loc, RootObject *obj);
672 Expression *syntaxCopy();
673 void accept(Visitor *v) { v->visit(this); }
674};
675
676class TraitsExp : public Expression
677{
678public:
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
687class HaltExp : public Expression
688{
689public:
690 HaltExp(Loc loc);
691
692 void accept(Visitor *v) { v->visit(this); }
693};
694
695class IsExp : public Expression
696{
697public:
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
716class UnaExp : public Expression
717{
718public:
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
730typedef UnionExp (*fp_t)(Loc loc, Type *, Expression *, Expression *);
731typedef int (*fp2_t)(Loc loc, TOK, Expression *, Expression *);
732
733class BinExp : public Expression
734{
735public:
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
754class BinAssignExp : public BinExp
755{
756public:
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
767class CompileExp : public UnaExp
768{
769public:
770 CompileExp(Loc loc, Expression *e);
771 void accept(Visitor *v) { v->visit(this); }
772};
773
774class ImportExp : public UnaExp
775{
776public:
777 ImportExp(Loc loc, Expression *e);
778 void accept(Visitor *v) { v->visit(this); }
779};
780
781class AssertExp : public UnaExp
782{
783public:
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
792class DotIdExp : public UnaExp
793{
794public:
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
804class DotTemplateExp : public UnaExp
805{
806public:
807 TemplateDeclaration *td;
808
809 DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td);
810 void accept(Visitor *v) { v->visit(this); }
811};
812
813class DotVarExp : public UnaExp
814{
815public:
816 Declaration *var;
817 bool hasOverloads;
818
819 DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads = true);
820 int checkModifiable(Scope *sc, int flag);
821 bool checkReadModifyWrite();
822 bool isLvalue();
823 Expression *toLvalue(Scope *sc, Expression *e);
824 Expression *modifiableLvalue(Scope *sc, Expression *e);
825 void accept(Visitor *v) { v->visit(this); }
826};
827
828class DotTemplateInstanceExp : public UnaExp
829{
830public:
831 TemplateInstance *ti;
832
833 DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs);
834 DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti);
835 Expression *syntaxCopy();
836 bool findTempDecl(Scope *sc);
837 void accept(Visitor *v) { v->visit(this); }
838};
839
840class DelegateExp : public UnaExp
841{
842public:
843 FuncDeclaration *func;
844 bool hasOverloads;
845
846 DelegateExp(Loc loc, Expression *e, FuncDeclaration *func, bool hasOverloads = true);
847
848 void accept(Visitor *v) { v->visit(this); }
849};
850
851class DotTypeExp : public UnaExp
852{
853public:
854 Dsymbol *sym; // symbol that represents a type
855
856 DotTypeExp(Loc loc, Expression *e, Dsymbol *sym);
857 void accept(Visitor *v) { v->visit(this); }
858};
859
860class CallExp : public UnaExp
861{
862public:
863 Expressions *arguments; // function arguments
864 FuncDeclaration *f; // symbol to call
865 bool directcall; // true if a virtual call is devirtualized
866 CallExp(Loc loc, Expression *e, Expressions *exps);
867 CallExp(Loc loc, Expression *e);
868 CallExp(Loc loc, Expression *e, Expression *earg1);
869 CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2);
870
871 static CallExp *create(Loc loc, Expression *e, Expressions *exps);
872 static CallExp *create(Loc loc, Expression *e);
873 static CallExp *create(Loc loc, Expression *e, Expression *earg1);
874
875 Expression *syntaxCopy();
876 bool isLvalue();
877 Expression *toLvalue(Scope *sc, Expression *e);
878 Expression *addDtorHook(Scope *sc);
879
880 void accept(Visitor *v) { v->visit(this); }
881};
882
883class AddrExp : public UnaExp
884{
885public:
886 AddrExp(Loc loc, Expression *e);
887 AddrExp(Loc loc, Expression *e, Type *t);
888
889 void accept(Visitor *v) { v->visit(this); }
890};
891
892class PtrExp : public UnaExp
893{
894public:
895 PtrExp(Loc loc, Expression *e);
896 PtrExp(Loc loc, Expression *e, Type *t);
897 int checkModifiable(Scope *sc, int flag);
898 bool isLvalue();
899 Expression *toLvalue(Scope *sc, Expression *e);
900 Expression *modifiableLvalue(Scope *sc, Expression *e);
901
902 void accept(Visitor *v) { v->visit(this); }
903};
904
905class NegExp : public UnaExp
906{
907public:
908 NegExp(Loc loc, Expression *e);
909
910 void accept(Visitor *v) { v->visit(this); }
911};
912
913class UAddExp : public UnaExp
914{
915public:
916 UAddExp(Loc loc, Expression *e);
917
918 void accept(Visitor *v) { v->visit(this); }
919};
920
921class ComExp : public UnaExp
922{
923public:
924 ComExp(Loc loc, Expression *e);
925
926 void accept(Visitor *v) { v->visit(this); }
927};
928
929class NotExp : public UnaExp
930{
931public:
932 NotExp(Loc loc, Expression *e);
933 void accept(Visitor *v) { v->visit(this); }
934};
935
936class DeleteExp : public UnaExp
937{
938public:
939 bool isRAII;
940 DeleteExp(Loc loc, Expression *e, bool isRAII);
941 Expression *toBoolean(Scope *sc);
942 void accept(Visitor *v) { v->visit(this); }
943};
944
945class CastExp : public UnaExp
946{
947public:
948 // Possible to cast to one type while painting to another type
949 Type *to; // type to cast to
950 unsigned char mod; // MODxxxxx
951
952 CastExp(Loc loc, Expression *e, Type *t);
953 CastExp(Loc loc, Expression *e, unsigned char mod);
954 Expression *syntaxCopy();
955
956 void accept(Visitor *v) { v->visit(this); }
957};
958
959class VectorExp : public UnaExp
960{
961public:
962 TypeVector *to; // the target vector type before semantic()
963 unsigned dim; // number of elements in the vector
b9da0278 964 OwnedBy ownedByCtfe;
b4c522fa
IB
965
966 VectorExp(Loc loc, Expression *e, Type *t);
967 static VectorExp *create(Loc loc, Expression *e, Type *t);
968 Expression *syntaxCopy();
969 void accept(Visitor *v) { v->visit(this); }
970};
971
b9da0278
IB
972class VectorArrayExp : public UnaExp
973{
974public:
975 VectorArrayExp(Loc loc, Expression *e1);
976 bool isLvalue();
977 Expression *toLvalue(Scope *sc, Expression *e);
978 void accept(Visitor *v) { v->visit(this); }
979};
980
b4c522fa
IB
981class SliceExp : public UnaExp
982{
983public:
984 Expression *upr; // NULL if implicit 0
985 Expression *lwr; // NULL if implicit [length - 1]
986 VarDeclaration *lengthVar;
987 bool upperIsInBounds; // true if upr <= e1.length
988 bool lowerIsLessThanUpper; // true if lwr <= upr
989 bool arrayop; // an array operation, rather than a slice
990
991 SliceExp(Loc loc, Expression *e1, IntervalExp *ie);
992 SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr);
993 Expression *syntaxCopy();
994 int checkModifiable(Scope *sc, int flag);
995 bool isLvalue();
996 Expression *toLvalue(Scope *sc, Expression *e);
997 Expression *modifiableLvalue(Scope *sc, Expression *e);
998 bool isBool(bool result);
999
1000 void accept(Visitor *v) { v->visit(this); }
1001};
1002
1003class ArrayLengthExp : public UnaExp
1004{
1005public:
1006 ArrayLengthExp(Loc loc, Expression *e1);
1007
1008 static Expression *rewriteOpAssign(BinExp *exp);
1009 void accept(Visitor *v) { v->visit(this); }
1010};
1011
1012class IntervalExp : public Expression
1013{
1014public:
1015 Expression *lwr;
1016 Expression *upr;
1017
1018 IntervalExp(Loc loc, Expression *lwr, Expression *upr);
1019 Expression *syntaxCopy();
1020 void accept(Visitor *v) { v->visit(this); }
1021};
1022
1023class DelegatePtrExp : public UnaExp
1024{
1025public:
1026 DelegatePtrExp(Loc loc, Expression *e1);
1027 bool isLvalue();
1028 Expression *toLvalue(Scope *sc, Expression *e);
1029 Expression *modifiableLvalue(Scope *sc, Expression *e);
1030 void accept(Visitor *v) { v->visit(this); }
1031};
1032
1033class DelegateFuncptrExp : public UnaExp
1034{
1035public:
1036 DelegateFuncptrExp(Loc loc, Expression *e1);
1037 bool isLvalue();
1038 Expression *toLvalue(Scope *sc, Expression *e);
1039 Expression *modifiableLvalue(Scope *sc, Expression *e);
1040 void accept(Visitor *v) { v->visit(this); }
1041};
1042
1043// e1[a0,a1,a2,a3,...]
1044
1045class ArrayExp : public UnaExp
1046{
1047public:
1048 Expressions *arguments; // Array of Expression's
1049 size_t currentDimension; // for opDollar
1050 VarDeclaration *lengthVar;
1051
1052 ArrayExp(Loc loc, Expression *e1, Expression *index = NULL);
1053 ArrayExp(Loc loc, Expression *e1, Expressions *args);
1054 Expression *syntaxCopy();
1055 bool isLvalue();
1056 Expression *toLvalue(Scope *sc, Expression *e);
1057
1058 void accept(Visitor *v) { v->visit(this); }
1059};
1060
1061/****************************************************************/
1062
1063class DotExp : public BinExp
1064{
1065public:
1066 DotExp(Loc loc, Expression *e1, Expression *e2);
1067 void accept(Visitor *v) { v->visit(this); }
1068};
1069
1070class CommaExp : public BinExp
1071{
1072public:
1073 bool isGenerated;
1074 bool allowCommaExp;
1075 CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated = true);
1076 int checkModifiable(Scope *sc, int flag);
1077 bool isLvalue();
1078 Expression *toLvalue(Scope *sc, Expression *e);
1079 Expression *modifiableLvalue(Scope *sc, Expression *e);
1080 bool isBool(bool result);
1081 Expression *toBoolean(Scope *sc);
1082 Expression *addDtorHook(Scope *sc);
1083 void accept(Visitor *v) { v->visit(this); }
1084};
1085
1086class IndexExp : public BinExp
1087{
1088public:
1089 VarDeclaration *lengthVar;
1090 bool modifiable;
1091 bool indexIsInBounds; // true if 0 <= e2 && e2 <= e1.length - 1
1092
1093 IndexExp(Loc loc, Expression *e1, Expression *e2);
1094 Expression *syntaxCopy();
1095 int checkModifiable(Scope *sc, int flag);
1096 bool isLvalue();
1097 Expression *toLvalue(Scope *sc, Expression *e);
1098 Expression *modifiableLvalue(Scope *sc, Expression *e);
1099
1100 Expression *markSettingAAElem();
1101
1102 void accept(Visitor *v) { v->visit(this); }
1103};
1104
1105/* For both i++ and i--
1106 */
1107class PostExp : public BinExp
1108{
1109public:
1110 PostExp(TOK op, Loc loc, Expression *e);
1111 void accept(Visitor *v) { v->visit(this); }
1112};
1113
1114/* For both ++i and --i
1115 */
1116class PreExp : public UnaExp
1117{
1118public:
1119 PreExp(TOK op, Loc loc, Expression *e);
1120 void accept(Visitor *v) { v->visit(this); }
1121};
1122
1123enum MemorySet
1124{
1125 blockAssign = 1, // setting the contents of an array
1126 referenceInit = 2 // setting the reference of STCref variable
1127};
1128
1129class AssignExp : public BinExp
1130{
1131public:
1132 int memset; // combination of MemorySet flags
1133
1134 AssignExp(Loc loc, Expression *e1, Expression *e2);
1135 bool isLvalue();
1136 Expression *toLvalue(Scope *sc, Expression *ex);
1137 Expression *toBoolean(Scope *sc);
1138
1139 void accept(Visitor *v) { v->visit(this); }
1140};
1141
1142class ConstructExp : public AssignExp
1143{
1144public:
1145 ConstructExp(Loc loc, Expression *e1, Expression *e2);
1146 ConstructExp(Loc loc, VarDeclaration *v, Expression *e2);
1147 void accept(Visitor *v) { v->visit(this); }
1148};
1149
1150class BlitExp : public AssignExp
1151{
1152public:
1153 BlitExp(Loc loc, Expression *e1, Expression *e2);
1154 BlitExp(Loc loc, VarDeclaration *v, Expression *e2);
1155 void accept(Visitor *v) { v->visit(this); }
1156};
1157
1158class AddAssignExp : public BinAssignExp
1159{
1160public:
1161 AddAssignExp(Loc loc, Expression *e1, Expression *e2);
1162 void accept(Visitor *v) { v->visit(this); }
1163};
1164
1165class MinAssignExp : public BinAssignExp
1166{
1167public:
1168 MinAssignExp(Loc loc, Expression *e1, Expression *e2);
1169 void accept(Visitor *v) { v->visit(this); }
1170};
1171
1172class MulAssignExp : public BinAssignExp
1173{
1174public:
1175 MulAssignExp(Loc loc, Expression *e1, Expression *e2);
1176 void accept(Visitor *v) { v->visit(this); }
1177};
1178
1179class DivAssignExp : public BinAssignExp
1180{
1181public:
1182 DivAssignExp(Loc loc, Expression *e1, Expression *e2);
1183 void accept(Visitor *v) { v->visit(this); }
1184};
1185
1186class ModAssignExp : public BinAssignExp
1187{
1188public:
1189 ModAssignExp(Loc loc, Expression *e1, Expression *e2);
1190 void accept(Visitor *v) { v->visit(this); }
1191};
1192
1193class AndAssignExp : public BinAssignExp
1194{
1195public:
1196 AndAssignExp(Loc loc, Expression *e1, Expression *e2);
1197 void accept(Visitor *v) { v->visit(this); }
1198};
1199
1200class OrAssignExp : public BinAssignExp
1201{
1202public:
1203 OrAssignExp(Loc loc, Expression *e1, Expression *e2);
1204 void accept(Visitor *v) { v->visit(this); }
1205};
1206
1207class XorAssignExp : public BinAssignExp
1208{
1209public:
1210 XorAssignExp(Loc loc, Expression *e1, Expression *e2);
1211 void accept(Visitor *v) { v->visit(this); }
1212};
1213
1214class PowAssignExp : public BinAssignExp
1215{
1216public:
1217 PowAssignExp(Loc loc, Expression *e1, Expression *e2);
1218 void accept(Visitor *v) { v->visit(this); }
1219};
1220
1221class ShlAssignExp : public BinAssignExp
1222{
1223public:
1224 ShlAssignExp(Loc loc, Expression *e1, Expression *e2);
1225 void accept(Visitor *v) { v->visit(this); }
1226};
1227
1228class ShrAssignExp : public BinAssignExp
1229{
1230public:
1231 ShrAssignExp(Loc loc, Expression *e1, Expression *e2);
1232 void accept(Visitor *v) { v->visit(this); }
1233};
1234
1235class UshrAssignExp : public BinAssignExp
1236{
1237public:
1238 UshrAssignExp(Loc loc, Expression *e1, Expression *e2);
1239 void accept(Visitor *v) { v->visit(this); }
1240};
1241
1242class CatAssignExp : public BinAssignExp
1243{
1244public:
1245 CatAssignExp(Loc loc, Expression *e1, Expression *e2);
1246 void accept(Visitor *v) { v->visit(this); }
1247};
1248
1249class AddExp : public BinExp
1250{
1251public:
1252 AddExp(Loc loc, Expression *e1, Expression *e2);
1253
1254 void accept(Visitor *v) { v->visit(this); }
1255};
1256
1257class MinExp : public BinExp
1258{
1259public:
1260 MinExp(Loc loc, Expression *e1, Expression *e2);
1261
1262 void accept(Visitor *v) { v->visit(this); }
1263};
1264
1265class CatExp : public BinExp
1266{
1267public:
1268 CatExp(Loc loc, Expression *e1, Expression *e2);
1269
1270 void accept(Visitor *v) { v->visit(this); }
1271};
1272
1273class MulExp : public BinExp
1274{
1275public:
1276 MulExp(Loc loc, Expression *e1, Expression *e2);
1277
1278 void accept(Visitor *v) { v->visit(this); }
1279};
1280
1281class DivExp : public BinExp
1282{
1283public:
1284 DivExp(Loc loc, Expression *e1, Expression *e2);
1285
1286 void accept(Visitor *v) { v->visit(this); }
1287};
1288
1289class ModExp : public BinExp
1290{
1291public:
1292 ModExp(Loc loc, Expression *e1, Expression *e2);
1293
1294 void accept(Visitor *v) { v->visit(this); }
1295};
1296
1297class PowExp : public BinExp
1298{
1299public:
1300 PowExp(Loc loc, Expression *e1, Expression *e2);
1301
1302 void accept(Visitor *v) { v->visit(this); }
1303};
1304
1305class ShlExp : public BinExp
1306{
1307public:
1308 ShlExp(Loc loc, Expression *e1, Expression *e2);
1309
1310 void accept(Visitor *v) { v->visit(this); }
1311};
1312
1313class ShrExp : public BinExp
1314{
1315public:
1316 ShrExp(Loc loc, Expression *e1, Expression *e2);
1317
1318 void accept(Visitor *v) { v->visit(this); }
1319};
1320
1321class UshrExp : public BinExp
1322{
1323public:
1324 UshrExp(Loc loc, Expression *e1, Expression *e2);
1325
1326 void accept(Visitor *v) { v->visit(this); }
1327};
1328
1329class AndExp : public BinExp
1330{
1331public:
1332 AndExp(Loc loc, Expression *e1, Expression *e2);
1333
1334 void accept(Visitor *v) { v->visit(this); }
1335};
1336
1337class OrExp : public BinExp
1338{
1339public:
1340 OrExp(Loc loc, Expression *e1, Expression *e2);
1341
1342 void accept(Visitor *v) { v->visit(this); }
1343};
1344
1345class XorExp : public BinExp
1346{
1347public:
1348 XorExp(Loc loc, Expression *e1, Expression *e2);
1349
1350 void accept(Visitor *v) { v->visit(this); }
1351};
1352
1353class OrOrExp : public BinExp
1354{
1355public:
1356 OrOrExp(Loc loc, Expression *e1, Expression *e2);
1357 Expression *toBoolean(Scope *sc);
1358 void accept(Visitor *v) { v->visit(this); }
1359};
1360
1361class AndAndExp : public BinExp
1362{
1363public:
1364 AndAndExp(Loc loc, Expression *e1, Expression *e2);
1365 Expression *toBoolean(Scope *sc);
1366 void accept(Visitor *v) { v->visit(this); }
1367};
1368
1369class CmpExp : public BinExp
1370{
1371public:
1372 CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1373
1374 void accept(Visitor *v) { v->visit(this); }
1375};
1376
1377class InExp : public BinExp
1378{
1379public:
1380 InExp(Loc loc, Expression *e1, Expression *e2);
1381
1382 void accept(Visitor *v) { v->visit(this); }
1383};
1384
1385class RemoveExp : public BinExp
1386{
1387public:
1388 RemoveExp(Loc loc, Expression *e1, Expression *e2);
1389 void accept(Visitor *v) { v->visit(this); }
1390};
1391
1392// == and !=
1393
1394class EqualExp : public BinExp
1395{
1396public:
1397 EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1398
1399 void accept(Visitor *v) { v->visit(this); }
1400};
1401
1402// is and !is
1403
1404class IdentityExp : public BinExp
1405{
1406public:
1407 IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1408 void accept(Visitor *v) { v->visit(this); }
1409};
1410
1411/****************************************************************/
1412
1413class CondExp : public BinExp
1414{
1415public:
1416 Expression *econd;
1417
1418 CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2);
1419 Expression *syntaxCopy();
1420 int checkModifiable(Scope *sc, int flag);
1421 bool isLvalue();
1422 Expression *toLvalue(Scope *sc, Expression *e);
1423 Expression *modifiableLvalue(Scope *sc, Expression *e);
1424 Expression *toBoolean(Scope *sc);
1425 void hookDtors(Scope *sc);
1426
1427 void accept(Visitor *v) { v->visit(this); }
1428};
1429
1430/****************************************************************/
1431
1432class DefaultInitExp : public Expression
1433{
1434public:
1435 TOK subop; // which of the derived classes this is
1436
1437 DefaultInitExp(Loc loc, TOK subop, int size);
1438 void accept(Visitor *v) { v->visit(this); }
1439};
1440
1441class FileInitExp : public DefaultInitExp
1442{
1443public:
1444 FileInitExp(Loc loc, TOK tok);
1445 Expression *resolveLoc(Loc loc, Scope *sc);
1446 void accept(Visitor *v) { v->visit(this); }
1447};
1448
1449class LineInitExp : public DefaultInitExp
1450{
1451public:
1452 LineInitExp(Loc loc);
1453 Expression *resolveLoc(Loc loc, Scope *sc);
1454 void accept(Visitor *v) { v->visit(this); }
1455};
1456
1457class ModuleInitExp : public DefaultInitExp
1458{
1459public:
1460 ModuleInitExp(Loc loc);
1461 Expression *resolveLoc(Loc loc, Scope *sc);
1462 void accept(Visitor *v) { v->visit(this); }
1463};
1464
1465class FuncInitExp : public DefaultInitExp
1466{
1467public:
1468 FuncInitExp(Loc loc);
1469 Expression *resolveLoc(Loc loc, Scope *sc);
1470 void accept(Visitor *v) { v->visit(this); }
1471};
1472
1473class PrettyFuncInitExp : public DefaultInitExp
1474{
1475public:
1476 PrettyFuncInitExp(Loc loc);
1477 Expression *resolveLoc(Loc loc, Scope *sc);
1478 void accept(Visitor *v) { v->visit(this); }
1479};
1480
1481/****************************************************************/
1482
1483/* A type meant as a union of all the Expression types,
1484 * to serve essentially as a Variant that will sit on the stack
1485 * during CTFE to reduce memory consumption.
1486 */
1487struct UnionExp
1488{
1489 UnionExp() { } // yes, default constructor does nothing
1490
1491 UnionExp(Expression *e)
1492 {
1493 memcpy(this, (void *)e, e->size);
1494 }
1495
1496 /* Extract pointer to Expression
1497 */
1498 Expression *exp() { return (Expression *)&u; }
1499
1500 /* Convert to an allocated Expression
1501 */
1502 Expression *copy();
1503
1504private:
f9ab59ff
IB
1505 // Ensure that the union is suitably aligned.
1506#if defined(__GNUC__) || defined(__clang__)
1507 __attribute__((aligned(8)))
1508#elif defined(_MSC_VER)
1509 __declspec(align(8))
1510#elif defined(__DMC__)
1511 #pragma pack(8)
1512#endif
b4c522fa
IB
1513 union
1514 {
1515 char exp [sizeof(Expression)];
1516 char integerexp[sizeof(IntegerExp)];
1517 char errorexp [sizeof(ErrorExp)];
1518 char realexp [sizeof(RealExp)];
1519 char complexexp[sizeof(ComplexExp)];
1520 char symoffexp [sizeof(SymOffExp)];
1521 char stringexp [sizeof(StringExp)];
1522 char arrayliteralexp [sizeof(ArrayLiteralExp)];
1523 char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];
1524 char structliteralexp [sizeof(StructLiteralExp)];
1525 char nullexp [sizeof(NullExp)];
1526 char dotvarexp [sizeof(DotVarExp)];
1527 char addrexp [sizeof(AddrExp)];
1528 char indexexp [sizeof(IndexExp)];
1529 char sliceexp [sizeof(SliceExp)];
b9da0278 1530 char vectorexp [sizeof(VectorExp)];
b4c522fa 1531 } u;
f9ab59ff
IB
1532#if defined(__DMC__)
1533 #pragma pack()
1534#endif
b4c522fa
IB
1535};
1536
1537/****************************************************************/
1538
1539/* Special values used by the interpreter
1540 */
1541
1542Expression *expType(Type *type, Expression *e);
1543
1544UnionExp Neg(Type *type, Expression *e1);
1545UnionExp Com(Type *type, Expression *e1);
1546UnionExp Not(Type *type, Expression *e1);
1547UnionExp Bool(Type *type, Expression *e1);
1548UnionExp Cast(Loc loc, Type *type, Type *to, Expression *e1);
1549UnionExp ArrayLength(Type *type, Expression *e1);
1550UnionExp Ptr(Type *type, Expression *e1);
1551
1552UnionExp Add(Loc loc, Type *type, Expression *e1, Expression *e2);
1553UnionExp Min(Loc loc, Type *type, Expression *e1, Expression *e2);
1554UnionExp Mul(Loc loc, Type *type, Expression *e1, Expression *e2);
1555UnionExp Div(Loc loc, Type *type, Expression *e1, Expression *e2);
1556UnionExp Mod(Loc loc, Type *type, Expression *e1, Expression *e2);
1557UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2);
1558UnionExp Shl(Loc loc, Type *type, Expression *e1, Expression *e2);
1559UnionExp Shr(Loc loc, Type *type, Expression *e1, Expression *e2);
1560UnionExp Ushr(Loc loc, Type *type, Expression *e1, Expression *e2);
1561UnionExp And(Loc loc, Type *type, Expression *e1, Expression *e2);
1562UnionExp Or(Loc loc, Type *type, Expression *e1, Expression *e2);
1563UnionExp Xor(Loc loc, Type *type, Expression *e1, Expression *e2);
1564UnionExp Index(Type *type, Expression *e1, Expression *e2);
1565UnionExp Cat(Type *type, Expression *e1, Expression *e2);
1566
1567UnionExp Equal(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1568UnionExp Cmp(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1569UnionExp Identity(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1570
1571UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr);
1572
1573// Const-folding functions used by CTFE
1574
1575void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *newval, size_t firstIndex);
1576void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, size_t firstIndex);
1577void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, size_t firstIndex);
1578
1579int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len);
1580int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len);