2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, December 2006
17 // Issues with using -include total.h (defines integer_t) and then complex.h fails...
28 #define integer_t dmd_integer_t
32 extern "C" char * __cdecl __locale_decpoint
;
38 #include "..\root\mem.h"
40 #include "../root/mem.h"
45 #include "expression.h"
50 #include "statement.h"
51 #include "declaration.h"
52 #include "aggregate.h"
61 Expression
*createTypeInfoArray(Scope
*sc
, Expression
*args
[], int dim
);
65 /**********************************
66 * Set operator precedence for each operator.
69 // Operator precedence - greater values are higher precedence
91 enum PREC precedence
[TOKMAX
];
95 precedence
[TOKdotvar
] = PREC_primary
;
96 precedence
[TOKimport
] = PREC_primary
;
97 precedence
[TOKidentifier
] = PREC_primary
;
98 precedence
[TOKthis
] = PREC_primary
;
99 precedence
[TOKsuper
] = PREC_primary
;
100 precedence
[TOKint64
] = PREC_primary
;
101 precedence
[TOKfloat64
] = PREC_primary
;
102 precedence
[TOKnull
] = PREC_primary
;
103 precedence
[TOKstring
] = PREC_primary
;
104 precedence
[TOKarrayliteral
] = PREC_primary
;
105 precedence
[TOKtypedot
] = PREC_primary
;
106 precedence
[TOKtypeid
] = PREC_primary
;
107 precedence
[TOKis
] = PREC_primary
;
108 precedence
[TOKassert
] = PREC_primary
;
109 precedence
[TOKfunction
] = PREC_primary
;
110 precedence
[TOKvar
] = PREC_primary
;
113 precedence
[TOKdotti
] = PREC_primary
;
114 precedence
[TOKdot
] = PREC_primary
;
115 // precedence[TOKarrow] = PREC_primary;
116 precedence
[TOKplusplus
] = PREC_primary
;
117 precedence
[TOKminusminus
] = PREC_primary
;
118 precedence
[TOKcall
] = PREC_primary
;
119 precedence
[TOKslice
] = PREC_primary
;
120 precedence
[TOKarray
] = PREC_primary
;
122 precedence
[TOKaddress
] = PREC_unary
;
123 precedence
[TOKstar
] = PREC_unary
;
124 precedence
[TOKneg
] = PREC_unary
;
125 precedence
[TOKuadd
] = PREC_unary
;
126 precedence
[TOKnot
] = PREC_unary
;
127 precedence
[TOKtobool
] = PREC_add
;
128 precedence
[TOKtilde
] = PREC_unary
;
129 precedence
[TOKdelete
] = PREC_unary
;
130 precedence
[TOKnew
] = PREC_unary
;
131 precedence
[TOKcast
] = PREC_unary
;
133 precedence
[TOKmul
] = PREC_mul
;
134 precedence
[TOKdiv
] = PREC_mul
;
135 precedence
[TOKmod
] = PREC_mul
;
137 precedence
[TOKadd
] = PREC_add
;
138 precedence
[TOKmin
] = PREC_add
;
139 precedence
[TOKcat
] = PREC_add
;
141 precedence
[TOKshl
] = PREC_shift
;
142 precedence
[TOKshr
] = PREC_shift
;
143 precedence
[TOKushr
] = PREC_shift
;
145 precedence
[TOKlt
] = PREC_rel
;
146 precedence
[TOKle
] = PREC_rel
;
147 precedence
[TOKgt
] = PREC_rel
;
148 precedence
[TOKge
] = PREC_rel
;
149 precedence
[TOKunord
] = PREC_rel
;
150 precedence
[TOKlg
] = PREC_rel
;
151 precedence
[TOKleg
] = PREC_rel
;
152 precedence
[TOKule
] = PREC_rel
;
153 precedence
[TOKul
] = PREC_rel
;
154 precedence
[TOKuge
] = PREC_rel
;
155 precedence
[TOKug
] = PREC_rel
;
156 precedence
[TOKue
] = PREC_rel
;
157 precedence
[TOKin
] = PREC_rel
;
159 precedence
[TOKequal
] = PREC_equal
;
160 precedence
[TOKnotequal
] = PREC_equal
;
161 precedence
[TOKidentity
] = PREC_equal
;
162 precedence
[TOKnotidentity
] = PREC_equal
;
164 precedence
[TOKand
] = PREC_and
;
166 precedence
[TOKxor
] = PREC_xor
;
168 precedence
[TOKor
] = PREC_or
;
170 precedence
[TOKandand
] = PREC_andand
;
172 precedence
[TOKoror
] = PREC_oror
;
174 precedence
[TOKquestion
] = PREC_cond
;
176 precedence
[TOKassign
] = PREC_assign
;
177 precedence
[TOKconstruct
] = PREC_assign
;
178 precedence
[TOKblit
] = PREC_assign
;
179 precedence
[TOKaddass
] = PREC_assign
;
180 precedence
[TOKminass
] = PREC_assign
;
181 precedence
[TOKcatass
] = PREC_assign
;
182 precedence
[TOKmulass
] = PREC_assign
;
183 precedence
[TOKdivass
] = PREC_assign
;
184 precedence
[TOKmodass
] = PREC_assign
;
185 precedence
[TOKshlass
] = PREC_assign
;
186 precedence
[TOKshrass
] = PREC_assign
;
187 precedence
[TOKushrass
] = PREC_assign
;
188 precedence
[TOKandass
] = PREC_assign
;
189 precedence
[TOKorass
] = PREC_assign
;
190 precedence
[TOKxorass
] = PREC_assign
;
192 precedence
[TOKcomma
] = PREC_expr
;
195 /*************************************************************
196 * Now that we have the right function f, we need to get the
197 * right 'this' pointer if f is in an outer class, but our
198 * existing 'this' pointer is in an inner class.
199 * This code is analogous to that used for variables
200 * in DotVarExp::semantic().
203 Expression
*getRightThis(Loc loc
, Scope
*sc
, AggregateDeclaration
*ad
, Expression
*e1
, Declaration
*var
)
206 Type
*t
= e1
->type
->toBasetype();
209 !(t
->ty
== Tpointer
&& t
->next
->ty
== Tstruct
&&
210 ((TypeStruct
*)t
->next
)->sym
== ad
)
212 !(t
->ty
== Tstruct
&&
213 ((TypeStruct
*)t
)->sym
== ad
)
216 ClassDeclaration
*cd
= ad
->isClassDeclaration();
217 ClassDeclaration
*tcd
= t
->isClassHandle();
220 !(tcd
== cd
|| cd
->isBaseOf(tcd
, NULL
))
223 if (tcd
&& tcd
->isNested())
224 { // Try again with outer scope
226 e1
= new DotVarExp(loc
, e1
, tcd
->vthis
);
227 e1
= e1
->semantic(sc
);
229 // Skip over nested functions, and get the enclosing
231 Dsymbol
*s
= tcd
->toParent();
232 while (s
&& s
->isFuncDeclaration())
233 { FuncDeclaration
*f
= s
->isFuncDeclaration();
236 e1
= new VarExp(loc
, f
->vthis
);
240 if (s
&& s
->isClassDeclaration())
241 e1
->type
= s
->isClassDeclaration()->type
;
242 e1
= e1
->semantic(sc
);
248 error("this for %s needs to be type %s not type %s",
249 var
->toChars(), ad
->toChars(), t
->toChars());
255 /*****************************************
256 * Determine if 'this' is available.
257 * If it is, return the FuncDeclaration that has it.
260 FuncDeclaration
*hasThis(Scope
*sc
)
261 { FuncDeclaration
*fd
;
262 FuncDeclaration
*fdthis
;
264 //printf("hasThis()\n");
265 fdthis
= sc
->parent
->isFuncDeclaration();
266 //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : "");
268 // Go upwards until we find the enclosing member function
279 Dsymbol
*parent
= fd
->parent
;
282 TemplateInstance
*ti
= parent
->isTemplateInstance();
289 fd
= fd
->parent
->isFuncDeclaration();
293 { //printf("test '%s'\n", fd->toChars());
301 return NULL
; // don't have 'this' available
305 /***************************************
306 * Pull out any properties.
309 Expression
*resolveProperties(Scope
*sc
, Expression
*e
)
311 //printf("resolveProperties(%s)\n", e->toChars());
314 Type
*t
= e
->type
->toBasetype();
316 if (t
->ty
== Tfunction
)
318 e
= new CallExp(e
->loc
, e
);
322 /* Look for e being a lazy parameter; rewrite as delegate call
324 else if (e
->op
== TOKvar
)
325 { VarExp
*ve
= (VarExp
*)e
;
327 if (ve
->var
->storage_class
& STClazy
)
329 e
= new CallExp(e
->loc
, e
);
334 else if (e
->op
== TOKdotexp
)
336 e
->error("expression has no value");
342 /******************************
343 * Perform semantic() on an array of Expressions.
346 void arrayExpressionSemantic(Expressions
*exps
, Scope
*sc
)
350 for (size_t i
= 0; i
< exps
->dim
; i
++)
351 { Expression
*e
= (Expression
*)exps
->data
[i
];
354 exps
->data
[i
] = (void *)e
;
359 /****************************************
363 void expandTuples(Expressions
*exps
)
365 //printf("expandTuples()\n");
368 for (size_t i
= 0; i
< exps
->dim
; i
++)
369 { Expression
*arg
= (Expression
*)exps
->data
[i
];
373 // Look for tuple with 0 members
374 if (arg
->op
== TOKtype
)
375 { TypeExp
*e
= (TypeExp
*)arg
;
376 if (e
->type
->toBasetype()->ty
== Ttuple
)
377 { TypeTuple
*tt
= (TypeTuple
*)e
->type
->toBasetype();
379 if (!tt
->arguments
|| tt
->arguments
->dim
== 0)
390 // Inline expand all the tuples
391 while (arg
->op
== TOKtuple
)
392 { TupleExp
*te
= (TupleExp
*)arg
;
394 exps
->remove(i
); // remove arg
395 exps
->insert(i
, te
->exps
); // replace with tuple contents
397 return; // empty tuple, no more arguments
398 arg
= (Expression
*)exps
->data
[i
];
404 /****************************************
405 * Preprocess arguments to function.
408 void preFunctionArguments(Loc loc
, Scope
*sc
, Expressions
*exps
)
414 for (size_t i
= 0; i
< exps
->dim
; i
++)
415 { Expression
*arg
= (Expression
*)exps
->data
[i
];
423 arg
->error("%s is not an expression", arg
->toChars());
424 arg
= new IntegerExp(arg
->loc
, 0, Type::tint32
);
427 arg
= resolveProperties(sc
, arg
);
428 exps
->data
[i
] = (void *) arg
;
432 if (arg
->type
->ty
== Tfunction
)
434 arg
= new AddrExp(arg
->loc
, arg
);
435 arg
= arg
->semantic(sc
);
436 exps
->data
[i
] = (void *) arg
;
444 /****************************************
445 * Now that we know the exact type of the function we're calling,
446 * the arguments[] need to be adjusted:
447 * 1) implicitly convert argument to the corresponding parameter type
448 * 2) add default arguments for any missing arguments
449 * 3) do default promotions on arguments corresponding to ...
450 * 4) add hidden _arguments[] argument
453 void functionArguments(Loc loc
, Scope
*sc
, TypeFunction
*tf
, Expressions
*arguments
)
459 //printf("functionArguments()\n");
461 size_t nargs
= arguments
? arguments
->dim
: 0;
462 size_t nparams
= Argument::dim(tf
->parameters
);
464 if (nargs
> nparams
&& tf
->varargs
== 0)
465 error(loc
, "expected %"PRIuSIZE
" arguments, not %"PRIuSIZE
, nparams
, nargs
);
467 n
= (nargs
> nparams
) ? nargs
: nparams
; // n = max(nargs, nparams)
470 for (size_t i
= 0; i
< n
; i
++)
475 arg
= (Expression
*)arguments
->data
[i
];
481 Argument
*p
= Argument::getNth(tf
->parameters
, i
);
487 if (tf
->varargs
== 2 && i
+ 1 == nparams
)
489 error(loc
, "expected %"PRIuSIZE
" arguments, not %"PRIuSIZE
, nparams
, nargs
);
492 arg
= p
->defaultArg
->copy();
493 arguments
->push(arg
);
497 if (tf
->varargs
== 2 && i
+ 1 == nparams
)
499 //printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars());
500 if (arg
->implicitConvTo(p
->type
))
502 if (nargs
!= nparams
)
503 error(loc
, "expected %"PRIuSIZE
" arguments, not %"PRIuSIZE
, nparams
, nargs
);
507 Type
*tb
= p
->type
->toBasetype();
508 Type
*tret
= p
->isLazyArray();
513 { // Create a static array variable v of type arg->type
515 /* GCC 4.0 does not like zero length arrays used like
516 this; pass a null array value instead. Could also
517 just make a one-element array. */
520 arg
= new NullExp(loc
);
525 char name
[10 + sizeof(idn
)*3 + 1];
526 sprintf(name
, "__arrayArg%d", ++idn
);
527 Identifier
*id
= Lexer::idPool(name
);
528 Type
*t
= new TypeSArray(tb
->next
, new IntegerExp(nargs
- i
));
529 t
= t
->semantic(loc
, sc
);
530 VarDeclaration
*v
= new VarDeclaration(loc
, t
, id
, new VoidInitializer(loc
));
532 v
->parent
= sc
->parent
;
535 Expression
*c
= new DeclarationExp(0, v
);
538 for (size_t u
= i
; u
< nargs
; u
++)
539 { Expression
*a
= (Expression
*)arguments
->data
[u
];
540 if (tret
&& !tb
->next
->equals(a
->type
))
541 a
= a
->toDelegate(sc
, tret
);
543 Expression
*e
= new VarExp(loc
, v
);
544 e
= new IndexExp(loc
, e
, new IntegerExp(u
+ 1 - nparams
));
545 e
= new AssignExp(loc
, e
, a
);
547 c
= new CommaExp(loc
, c
, e
);
551 arg
= new VarExp(loc
, v
);
553 arg
= new CommaExp(loc
, c
, arg
);
558 * new Tclass(arg0, arg1, ..., argn)
560 Expressions
*args
= new Expressions();
561 args
->setDim(nargs
- i
);
562 for (size_t u
= i
; u
< nargs
; u
++)
563 args
->data
[u
- i
] = arguments
->data
[u
];
564 arg
= new NewExp(loc
, NULL
, NULL
, p
->type
, args
);
569 { error(loc
, "not enough arguments");
574 arg
= arg
->semantic(sc
);
575 //printf("\targ = '%s'\n", arg->toChars());
576 arguments
->setDim(i
+ 1);
581 if (!(p
->storageClass
& STClazy
&& p
->type
->ty
== Tvoid
))
582 arg
= arg
->implicitCastTo(sc
, p
->type
);
583 if (p
->storageClass
& (STCout
| STCref
))
585 // BUG: should check that argument to ref is type 'invariant'
586 // BUG: assignments to ref should also be type 'invariant'
587 arg
= arg
->modifiableLvalue(sc
, arg
);
589 //if (arg->op == TOKslice)
590 //arg->error("cannot modify slice %s", arg->toChars());
593 // Convert static arrays to pointers
594 tb
= arg
->type
->toBasetype();
595 if (tb
->ty
== Tsarray
)
597 arg
= arg
->checkToPointer();
600 // Convert lazy argument to a delegate
601 if (p
->storageClass
& STClazy
)
603 arg
= arg
->toDelegate(sc
, p
->type
);
609 // If not D linkage, do promotions
610 if (tf
->linkage
!= LINKd
)
612 // Promote bytes, words, etc., to ints
613 arg
= arg
->integralPromotions(sc
);
615 // Promote floats to doubles
616 switch (arg
->type
->ty
)
619 arg
= arg
->castTo(sc
, Type::tfloat64
);
623 arg
= arg
->castTo(sc
, Type::timaginary64
);
628 // Convert static arrays to dynamic arrays
629 tb
= arg
->type
->toBasetype();
630 if (tb
->ty
== Tsarray
)
631 { TypeSArray
*ts
= (TypeSArray
*)tb
;
632 Type
*ta
= tb
->next
->arrayOf();
633 if (ts
->size(arg
->loc
) == 0)
634 { arg
= new NullExp(arg
->loc
);
638 arg
= arg
->castTo(sc
, ta
);
643 arg
= arg
->optimize(WANTvalue
);
644 arguments
->data
[i
] = (void *) arg
;
649 // If D linkage and variadic, add _arguments[] as first argument
650 if (tf
->linkage
== LINKd
&& tf
->varargs
== 1)
654 e
= createTypeInfoArray(sc
, (Expression
**)&arguments
->data
[nparams
],
655 arguments
->dim
- nparams
);
656 arguments
->insert(0, e
);
660 /**************************************************
661 * Write expression out to buf, but wrap it
662 * in ( ) if its precedence is less than pr.
665 void expToCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
, Expression
*e
, enum PREC pr
)
667 if (precedence
[e
->op
] < pr
)
670 e
->toCBuffer(buf
, hgs
);
674 e
->toCBuffer(buf
, hgs
);
677 /**************************************************
678 * Write out argument list to buf.
681 void argsToCBuffer(OutBuffer
*buf
, Expressions
*arguments
, HdrGenState
*hgs
)
685 for (size_t i
= 0; i
< arguments
->dim
; i
++)
686 { Expression
*arg
= (Expression
*)arguments
->data
[i
];
691 expToCBuffer(buf
, hgs
, arg
, PREC_assign
);
697 /**************************************************
698 * Write out argument types to buf.
701 void argExpTypesToCBuffer(OutBuffer
*buf
, Expressions
*arguments
, HdrGenState
*hgs
)
706 for (size_t i
= 0; i
< arguments
->dim
; i
++)
707 { Expression
*arg
= (Expression
*)arguments
->data
[i
];
712 arg
->type
->toCBuffer2(&argbuf
, hgs
, 0);
718 /******************************** Expression **************************/
720 Expression::Expression(Loc loc
, enum TOK op
, int size
)
729 Expression
*Expression::syntaxCopy()
731 //printf("Expression::syntaxCopy()\n");
736 /*********************************
737 * Does *not* do a deep copy.
740 Expression
*Expression::copy()
746 fprintf(stdmsg
, "No expression copy for: %s\n", toChars());
747 printf("op = %d\n", op
);
752 e
= (Expression
*)mem
.malloc(size
);
753 return (Expression
*)memcpy(e
, this, size
);
756 /**************************
757 * Semantically analyze Expression.
758 * Determine types, fold constants, etc.
761 Expression
*Expression::semantic(Scope
*sc
)
764 printf("Expression::semantic()\n");
767 type
= type
->semantic(loc
, sc
);
773 void Expression::print()
775 fprintf(stdmsg
, "%s\n", toChars());
779 char *Expression::toChars()
783 memset(&hgs
, 0, sizeof(hgs
));
784 buf
= new OutBuffer();
785 toCBuffer(buf
, &hgs
);
786 return buf
->toChars();
789 void Expression::error(const char *format
, ...)
792 va_start(ap
, format
);
793 ::verror(loc
, format
, ap
);
797 void Expression::rvalue()
799 if (type
&& type
->toBasetype()->ty
== Tvoid
)
800 { error("expression %s is void and has no value", toChars());
808 Expression
*Expression::combine(Expression
*e1
, Expression
*e2
)
814 e1
= new CommaExp(e1
->loc
, e1
, e2
);
823 integer_t
Expression::toInteger()
825 //printf("Expression %s\n", Token::toChars(op));
826 error("Integer constant expression expected instead of %s", toChars());
830 uinteger_t
Expression::toUInteger()
832 //printf("Expression %s\n", Token::toChars(op));
833 return (uinteger_t
)toInteger();
836 real_t
Expression::toReal()
838 error("Floating point constant expression expected instead of %s", toChars());
842 real_t
Expression::toImaginary()
844 error("Floating point constant expression expected instead of %s", toChars());
848 complex_t
Expression::toComplex()
850 error("Floating point constant expression expected instead of %s", toChars());
852 return complex_t(real_t(0)); // %% nicer
858 void Expression::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
860 buf
->writestring(Token::toChars(op
));
863 void Expression::toMangleBuffer(OutBuffer
*buf
)
865 error("expression %s is not a valid template value argument", toChars());
868 /*******************************
869 * Give error if we're not an lvalue.
870 * If we can, convert expression to be an lvalue.
873 Expression
*Expression::toLvalue(Scope
*sc
, Expression
*e
)
877 else if (!loc
.filename
)
879 error("%s is not an lvalue", e
->toChars());
883 Expression
*Expression::modifiableLvalue(Scope
*sc
, Expression
*e
)
885 // See if this expression is a modifiable lvalue (i.e. not const)
886 return toLvalue(sc
, e
);
889 /************************************
890 * Detect cases where pointers to the stack can 'escape' the
891 * lifetime of the stack frame.
894 void Expression::checkEscape()
898 void Expression::checkScalar()
900 if (!type
->isscalar())
901 error("'%s' is not a scalar, it is a %s", toChars(), type
->toChars());
904 void Expression::checkNoBool()
906 if (type
->toBasetype()->ty
== Tbool
)
907 error("operation not allowed on bool '%s'", toChars());
910 Expression
*Expression::checkIntegral()
912 if (!type
->isintegral())
913 { error("'%s' is not of integral type, it is a %s", toChars(), type
->toChars());
914 return new IntegerExp(0);
919 Expression
*Expression::checkArithmetic()
921 if (!type
->isintegral() && !type
->isfloating())
922 { error("'%s' is not of arithmetic type, it is a %s", toChars(), type
->toChars());
923 return new IntegerExp(0);
928 void Expression::checkDeprecated(Scope
*sc
, Dsymbol
*s
)
930 s
->checkDeprecated(loc
, sc
);
933 /********************************
934 * Check for expressions that have no use.
936 * flag 0 not going to use the result, so issue error message if no
938 * 1 the result of the expression is used, but still check
939 * for useless subexpressions
940 * 2 do not issue error messages, just return !=0 if expression
944 int Expression::checkSideEffect(int flag
)
947 { if (op
== TOKimport
)
949 error("%s has no effect", toChars());
952 error("%s has no effect in expression (%s)",
953 Token::toChars(op
), toChars());
958 /*****************************
959 * Check that expression can be tested for true or false.
962 Expression
*Expression::checkToBoolean()
964 // Default is 'yes' - do nothing
971 if (!type
->checkBoolean())
973 error("expression %s of type %s does not have a boolean value", toChars(), type
->toChars());
978 /****************************
981 Expression
*Expression::checkToPointer()
986 //printf("Expression::checkToPointer()\n");
989 // If C static array, convert to pointer
990 tb
= type
->toBasetype();
991 if (tb
->ty
== Tsarray
)
992 { TypeSArray
*ts
= (TypeSArray
*)tb
;
993 if (ts
->size(loc
) == 0)
994 e
= new NullExp(loc
);
996 e
= new AddrExp(loc
, this);
997 e
->type
= tb
->next
->pointerTo();
1002 /******************************
1003 * Take address of expression.
1006 Expression
*Expression::addressOf(Scope
*sc
)
1010 //printf("Expression::addressOf()\n");
1011 e
= toLvalue(sc
, NULL
);
1012 e
= new AddrExp(loc
, e
);
1013 e
->type
= type
->pointerTo();
1017 /******************************
1018 * If this is a reference, dereference it.
1021 Expression
*Expression::deref()
1023 //printf("Expression::deref()\n");
1024 if (type
->ty
== Treference
)
1027 e
= new PtrExp(loc
, this);
1028 e
->type
= type
->next
;
1034 /********************************
1035 * Does this expression statically evaluate to a boolean TRUE or FALSE?
1038 int Expression::isBool(int result
)
1043 /********************************
1044 * Does this expression result in either a 1 or a 0?
1047 int Expression::isBit()
1052 Expressions
*Expression::arraySyntaxCopy(Expressions
*exps
)
1053 { Expressions
*a
= NULL
;
1057 a
= new Expressions();
1058 a
->setDim(exps
->dim
);
1059 for (int i
= 0; i
< a
->dim
; i
++)
1060 { Expression
*e
= (Expression
*)exps
->data
[i
];
1062 e
= e
->syntaxCopy();
1069 /******************************** IntegerExp **************************/
1071 IntegerExp::IntegerExp(Loc loc
, integer_t value
, Type
*type
)
1072 : Expression(loc
, TOKint64
, sizeof(IntegerExp
))
1074 //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : "");
1075 if (type
&& !type
->isscalar())
1077 error("integral constant must be scalar type, not %s", type
->toChars());
1078 type
= Type::terror
;
1081 this->value
= value
;
1084 IntegerExp::IntegerExp(integer_t value
)
1085 : Expression(0, TOKint64
, sizeof(IntegerExp
))
1087 this->type
= Type::tint32
;
1088 this->value
= value
;
1091 int IntegerExp::equals(Object
*o
)
1095 (((Expression
*)o
)->op
== TOKint64
&&
1096 ((ne
= (IntegerExp
*)o
), type
->equals(ne
->type
)) &&
1097 value
== ne
->value
))
1102 char *IntegerExp::toChars()
1105 return Expression::toChars();
1107 static char buffer
[sizeof(value
) * 3 + 1];
1109 sprintf(buffer
, "%"PRIdMAX
, value
);
1114 integer_t
IntegerExp::toInteger()
1123 case Tbool
: value
= (value
!= 0); break;
1124 case Tint8
: value
= (d_int8
) value
; break;
1126 case Tuns8
: value
= (d_uns8
) value
; break;
1127 case Tint16
: value
= (d_int16
) value
; break;
1129 case Tuns16
: value
= (d_uns16
) value
; break;
1130 case Tint32
: value
= (d_int32
) value
; break;
1132 case Tuns32
: value
= (d_uns32
) value
; break;
1133 case Tint64
: value
= (d_int64
) value
; break;
1134 case Tuns64
: value
= (d_uns64
) value
; break;
1139 case 4: value
= (d_uns32
) value
; break;
1140 case 8: value
= (d_uns64
) value
; break;
1142 assert(PTRSIZE
== 4 || PTRSIZE
== 8);
1148 TypeEnum
*te
= (TypeEnum
*)t
;
1149 t
= te
->sym
->memtype
;
1155 TypeTypedef
*tt
= (TypeTypedef
*)t
;
1156 t
= tt
->sym
->basetype
;
1171 real_t
IntegerExp::toReal()
1176 t
= type
->toBasetype();
1177 if (t
->ty
== Tuns64
)
1178 return (real_t
)(d_uns64
)value
;
1180 return (real_t
)(d_int64
)value
;
1183 real_t
IntegerExp::toImaginary()
1188 complex_t
IntegerExp::toComplex()
1193 int IntegerExp::isBool(int result
)
1195 return result
? value
!= 0 : value
== 0;
1198 Expression
*IntegerExp::semantic(Scope
*sc
)
1202 // Determine what the type of this number is
1203 integer_t number
= value
;
1205 if (number
& 0x8000000000000000LL
)
1206 type
= Type::tuns64
;
1207 else if (number
& 0xFFFFFFFF80000000LL
)
1208 type
= Type::tint64
;
1210 type
= Type::tint32
;
1213 { type
= type
->semantic(loc
, sc
);
1218 Expression
*IntegerExp::toLvalue(Scope
*sc
, Expression
*e
)
1222 else if (!loc
.filename
)
1224 e
->error("constant %s is not an lvalue", e
->toChars());
1228 void IntegerExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
1230 integer_t v
= toInteger();
1239 { TypeEnum
*te
= (TypeEnum
*)t
;
1240 buf
->printf("cast(%s)", te
->sym
->toChars());
1241 t
= te
->sym
->memtype
;
1246 { TypeTypedef
*tt
= (TypeTypedef
*)t
;
1247 buf
->printf("cast(%s)", tt
->sym
->toChars());
1248 t
= tt
->sym
->basetype
;
1252 case Twchar
: // BUG: need to cast(wchar)
1253 case Tdchar
: // BUG: need to cast(dchar)
1254 if ((uinteger_t
)v
> 0xFF)
1256 buf
->printf("'\\U%08x'", v
);
1261 buf
->writestring("'\\''");
1262 else if (isprint(v
) && v
!= '\\')
1263 buf
->printf("'%c'", (int)v
);
1265 buf
->printf("'\\x%02x'", (int)v
);
1269 buf
->writestring("cast(byte)");
1273 buf
->writestring("cast(short)");
1278 buf
->printf("%d", (int)v
);
1282 buf
->writestring("cast(ubyte)");
1286 buf
->writestring("cast(ushort)");
1291 buf
->printf("%du", (unsigned)v
);
1295 buf
->printf("%"PRIdMAX
"L", v
);
1299 buf
->printf("%"PRIuMAX
"LU", v
);
1304 buf
->writestring((char *)(v
? "true" : "false"));
1308 buf
->writestring("cast(");
1309 buf
->writestring(t
->toChars());
1310 buf
->writeByte(')');
1320 else if (v
& 0x8000000000000000LL
)
1321 buf
->printf("0x%"PRIxMAX
, v
);
1323 buf
->printf("%"PRIdMAX
, v
);
1326 void IntegerExp::toMangleBuffer(OutBuffer
*buf
)
1328 if ((sinteger_t
)value
< 0)
1329 buf
->printf("N%"PRIdMAX
, -value
);
1331 buf
->printf("%"PRIdMAX
, value
);
1334 /******************************** RealExp **************************/
1336 RealExp::RealExp(Loc loc
, real_t value
, Type
*type
)
1337 : Expression(loc
, TOKfloat64
, sizeof(RealExp
))
1339 //printf("RealExp::RealExp(%Lg)\n", value);
1340 this->value
= value
;
1344 char *RealExp::toChars()
1346 char buffer
[sizeof(value
) * 3 + 8 + 1 + 1];
1349 value
.format(buffer
, sizeof(buffer
));
1350 if (type
->isimaginary())
1351 strcat(buffer
, "i");
1353 sprintf(buffer
, type
->isimaginary() ? "%Lgi" : "%Lg", value
);
1355 assert(strlen(buffer
) < sizeof(buffer
));
1356 return mem
.strdup(buffer
);
1359 integer_t
RealExp::toInteger()
1362 return (d_int64
) toReal().toInt();
1364 return (sinteger_t
) toReal();
1368 uinteger_t
RealExp::toUInteger()
1371 return (uinteger_t
) toReal().toInt();
1373 return (uinteger_t
) toReal();
1377 real_t
RealExp::toReal()
1379 return type
->isreal() ? value
: 0;
1382 real_t
RealExp::toImaginary()
1384 return type
->isreal() ? 0 : value
;
1387 complex_t
RealExp::toComplex()
1390 return toReal() + toImaginary() * I
;
1392 return complex_t(toReal(), toImaginary());
1396 /********************************
1397 * Test to see if two reals are the same.
1398 * Regard NaN's as equivalent.
1399 * Regard +0 and -0 as different.
1402 int RealEquals(real_t x1
, real_t x2
)
1405 return (isnan(x1
) && isnan(x2
)) ||
1406 /* In some cases, the REALPAD bytes get garbage in them,
1407 * so be sure and ignore them.
1409 memcmp(&x1
, &x2
, REALSIZE
- REALPAD
) == 0;
1411 return (x1
.isNan() && x2
.isNan()) || x1
.isIdenticalTo(x2
);
1415 int RealExp::equals(Object
*o
)
1419 (((Expression
*)o
)->op
== TOKfloat64
&&
1420 ((ne
= (RealExp
*)o
), type
->equals(ne
->type
)) &&
1421 RealEquals(value
, ne
->value
)
1428 Expression
*RealExp::semantic(Scope
*sc
)
1431 type
= Type::tfloat64
;
1433 type
= type
->semantic(loc
, sc
);
1437 int RealExp::isBool(int result
)
1440 return result
? (! value
.isZero()) : (value
.isZero());
1442 return result
? (value
!= 0)
1447 void floatToBuffer(OutBuffer
*buf
, Type
*type
, const real_t
& value
)
1449 /* In order to get an exact representation, try converting it
1450 * to decimal then back again. If it matches, use it.
1451 * If it doesn't, fall back to hex, which is
1456 real_t parsed_value
;
1458 value
.format(buffer
, sizeof(buffer
));
1459 parsed_value
= real_t::parse(buffer
, real_t::LongDouble
);
1460 if (parsed_value
.isIdenticalTo( value
))
1461 buf
->writestring(buffer
);
1464 value
.formatHex(buffer
, sizeof(buffer
));
1465 buf
->writestring(buffer
);
1468 sprintf(buffer
, "%Lg", value
);
1469 assert(strlen(buffer
) < sizeof(buffer
));
1470 #if _WIN32 && __DMC__
1471 char *save
= __locale_decpoint
;
1472 __locale_decpoint
= ".";
1473 real_t r
= strtold(buffer
, NULL
);
1474 __locale_decpoint
= save
;
1476 real_t r
= strtold(buffer
, NULL
);
1478 if (r
== value
) // if exact duplication
1479 buf
->writestring(buffer
);
1481 buf
->printf("%La", value
); // ensure exact duplication
1486 Type
*t
= type
->toBasetype();
1492 buf
->writeByte('F');
1498 buf
->writeByte('L');
1504 if (t
->isimaginary())
1505 buf
->writeByte('i');
1509 void RealExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
1511 floatToBuffer(buf
, type
, value
);
1514 void realToMangleBuffer(OutBuffer
*buf
, real_t value
)
1516 /* Rely on %A to get portable mangling.
1517 * Must munge result to get only identifier characters.
1519 * Possible values from %A => mangled result
1523 * -0X1.1BC18BA997B95P+79 => N11BC18BA997B95P79
1529 buf
->writestring("NAN"); // no -NAN bugs
1530 else if (value
.isInf())
1531 buf
->writestring(value
.isNegative()?"NINF":"INF");
1534 buf
->writestring("NAN"); // no -NAN bugs
1540 value
.formatHex(buffer
, sizeof(buffer
));
1541 int n
= strlen(buffer
);
1543 int n
= sprintf(buffer
, "%LA", value
);
1544 assert(n
> 0 && n
< sizeof(buffer
));
1546 for (int i
= 0; i
< n
; i
++)
1547 { char c
= buffer
[i
];
1552 buf
->writeByte('N');
1563 break; // skip leading 0X
1572 void RealExp::toMangleBuffer(OutBuffer
*buf
)
1574 buf
->writeByte('e');
1575 realToMangleBuffer(buf
, value
);
1579 /******************************** ComplexExp **************************/
1581 ComplexExp::ComplexExp(Loc loc
, complex_t value
, Type
*type
)
1582 : Expression(loc
, TOKcomplex80
, sizeof(ComplexExp
))
1584 this->value
= value
;
1586 //printf("ComplexExp::ComplexExp(%s)\n", toChars());
1589 char *ComplexExp::toChars()
1591 char buffer
[sizeof(value
) * 3 + 8 + 1];
1594 char buf1
[sizeof(value
) * 3 + 8 + 1];
1595 char buf2
[sizeof(value
) * 3 + 8 + 1];
1596 creall(value
).format(buf1
, sizeof(buf1
));
1597 cimagl(value
).format(buf2
, sizeof(buf2
));
1598 sprintf(buffer
, "(%s+%si)", buf1
, buf2
);
1600 sprintf(buffer
, "(%Lg+%Lgi)", creall(value
), cimagl(value
));
1601 assert(strlen(buffer
) < sizeof(buffer
));
1603 return mem
.strdup(buffer
);
1606 integer_t
ComplexExp::toInteger()
1609 return (d_int64
) toReal().toInt();
1611 return (sinteger_t
) toReal();
1615 uinteger_t
ComplexExp::toUInteger()
1618 return (uinteger_t
) toReal().toInt();
1620 return (uinteger_t
) toReal();
1624 real_t
ComplexExp::toReal()
1626 return creall(value
);
1629 real_t
ComplexExp::toImaginary()
1631 return cimagl(value
);
1634 complex_t
ComplexExp::toComplex()
1639 int ComplexExp::equals(Object
*o
)
1643 (((Expression
*)o
)->op
== TOKcomplex80
&&
1644 ((ne
= (ComplexExp
*)o
), type
->equals(ne
->type
)) &&
1646 RealEquals(creall(value
), creall(ne
->value
)) &&
1647 RealEquals(cimagl(value
), cimagl(ne
->value
))
1649 RealEquals(value
.re
, ne
->value
.re
) &&
1650 RealEquals(value
.im
, ne
->value
.im
)
1658 Expression
*ComplexExp::semantic(Scope
*sc
)
1661 type
= Type::tcomplex80
;
1663 type
= type
->semantic(loc
, sc
);
1667 int ComplexExp::isBool(int result
)
1670 return (bool)(value
);
1675 void ComplexExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
1681 char buf1
[sizeof(value
) * 3 + 8 + 1];
1682 char buf2
[sizeof(value
) * 3 + 8 + 1];
1683 creall(value
).format(buf1
, sizeof(buf1
));
1684 cimagl(value
).format(buf2
, sizeof(buf2
));
1685 buf
->printf("(%s+%si)", buf1
, buf2
);
1687 buf
->writeByte('(');
1688 floatToBuffer(buf
, type
, creall(value
));
1689 buf
->writeByte('+');
1690 floatToBuffer(buf
, type
, cimagl(value
));
1691 buf
->writestring("i)");
1695 void ComplexExp::toMangleBuffer(OutBuffer
*buf
)
1697 buf
->writeByte('c');
1698 real_t r
= toReal();
1699 realToMangleBuffer(buf
, r
);
1700 buf
->writeByte('c'); // separate the two
1702 realToMangleBuffer(buf
, r
);
1705 /******************************** IdentifierExp **************************/
1707 IdentifierExp::IdentifierExp(Loc loc
, Identifier
*ident
)
1708 : Expression(loc
, TOKidentifier
, sizeof(IdentifierExp
))
1710 this->ident
= ident
;
1713 Expression
*IdentifierExp::semantic(Scope
*sc
)
1719 printf("IdentifierExp::semantic('%s')\n", ident
->toChars());
1721 s
= sc
->search(loc
, ident
, &scopesym
);
1724 WithScopeSymbol
*withsym
;
1726 // See if it was a with class
1727 withsym
= scopesym
->isWithScopeSymbol();
1732 // Same as wthis.ident
1733 if (s
->needThis() || s
->isTemplateDeclaration())
1735 e
= new VarExp(loc
, withsym
->withstate
->wthis
);
1736 e
= new DotIdExp(loc
, e
, ident
);
1739 { Type
*t
= withsym
->withstate
->wthis
->type
;
1740 if (t
->ty
== Tpointer
)
1742 e
= new TypeDotIdExp(loc
, t
, ident
);
1747 if (!s
->parent
&& scopesym
->isArrayScopeSymbol())
1748 { // Kludge to run semantic() here because
1749 // ArrayScopeSymbol::search() doesn't have access to sc.
1752 // Look to see if f is really a function template
1753 FuncDeclaration
*f
= s
->isFuncDeclaration();
1755 { TemplateInstance
*ti
= f
->parent
->isTemplateInstance();
1758 !ti
->isTemplateMixin() &&
1759 (ti
->name
== f
->ident
||
1760 ti
->toAlias()->ident
== f
->ident
)
1762 ti
->tempdecl
&& ti
->tempdecl
->onemember
)
1764 TemplateDeclaration
*tempdecl
= ti
->tempdecl
;
1765 if (tempdecl
->overroot
) // if not start of overloaded list of TemplateDeclaration's
1766 tempdecl
= tempdecl
->overroot
; // then get the start
1767 e
= new TemplateExp(loc
, tempdecl
);
1768 e
= e
->semantic(sc
);
1772 e
= new DsymbolExp(loc
, s
);
1774 return e
->semantic(sc
);
1776 error("undefined identifier %s", ident
->toChars());
1777 type
= Type::terror
;
1781 char *IdentifierExp::toChars()
1783 return ident
->toChars();
1786 void IdentifierExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
1789 buf
->writestring(ident
->toHChars2());
1791 buf
->writestring(ident
->toChars());
1794 Expression
*IdentifierExp::toLvalue(Scope
*sc
, Expression
*e
)
1797 tym
= tybasic(e1
->ET
->Tty
);
1798 if (!(tyscalar(tym
) ||
1800 tym
== TYarray
&& e
->Eoper
== TOKaddr
))
1801 synerr(EM_lvalue
); // lvalue expected
1806 /******************************** DollarExp **************************/
1808 DollarExp::DollarExp(Loc loc
)
1809 : IdentifierExp(loc
, Id::dollar
)
1813 /******************************** DsymbolExp **************************/
1815 DsymbolExp::DsymbolExp(Loc loc
, Dsymbol
*s
)
1816 : Expression(loc
, TOKdsymbol
, sizeof(DsymbolExp
))
1821 Expression
*DsymbolExp::semantic(Scope
*sc
)
1824 printf("DsymbolExp::semantic('%s')\n", s
->toChars());
1832 FuncLiteralDeclaration
*fld
;
1834 ClassDeclaration
*cd
;
1835 ClassDeclaration
*thiscd
= NULL
;
1840 //printf("DsymbolExp:: %p '%s' is a symbol\n", this, toChars());
1841 //printf("s = '%s', s->kind = '%s'\n", s->toChars(), s->kind());
1844 if (!s
->isFuncDeclaration()) // functions are checked after overloading
1845 checkDeprecated(sc
, s
);
1847 //printf("s = '%s', s->kind = '%s', s->needThis() = %p\n", s->toChars(), s->kind(), s->needThis());
1848 if (!s
->isFuncDeclaration())
1849 checkDeprecated(sc
, s
);
1852 thiscd
= sc
->func
->parent
->isClassDeclaration();
1854 // BUG: This should happen after overload resolution for functions, not before
1857 if (hasThis(sc
) /*&& !s->isFuncDeclaration()*/)
1859 // Supply an implicit 'this', as in
1864 de
= new DotVarExp(loc
, new ThisExp(loc
), s
->isDeclaration());
1865 return de
->semantic(sc
);
1869 em
= s
->isEnumMember();
1872 e
= em
->value
->copy();
1873 e
= e
->semantic(sc
);
1876 v
= s
->isVarDeclaration();
1879 //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
1883 { error("forward reference of %s", v
->toChars());
1884 type
= Type::terror
;
1887 if (v
->isConst() && type
->toBasetype()->ty
!= Tsarray
)
1893 error("circular reference to '%s'", v
->toChars());
1894 type
= Type::tint32
;
1897 ExpInitializer
*ei
= v
->init
->isExpInitializer();
1900 e
= ei
->exp
->copy(); // make copy so we can change loc
1901 if (e
->op
== TOKstring
|| !e
->type
)
1902 e
= e
->semantic(sc
);
1903 e
= e
->implicitCastTo(sc
, type
);
1910 e
= type
->defaultInit();
1915 e
= new VarExp(loc
, v
);
1917 e
= e
->semantic(sc
);
1920 fld
= s
->isFuncLiteralDeclaration();
1922 { //printf("'%s' is a function literal\n", fld->toChars());
1923 e
= new FuncExp(loc
, fld
);
1924 return e
->semantic(sc
);
1926 f
= s
->isFuncDeclaration();
1928 { //printf("'%s' is a function\n", f->toChars());
1929 return new VarExp(loc
, f
);
1931 cd
= s
->isClassDeclaration();
1932 if (cd
&& thiscd
&& cd
->isBaseOf(thiscd
, NULL
) && sc
->func
->needThis())
1934 // We need to add an implicit 'this' if cd is this class or a base class.
1937 dte
= new DotTypeExp(loc
, new ThisExp(loc
), s
);
1938 return dte
->semantic(sc
);
1940 imp
= s
->isImport();
1945 ie
= new ScopeExp(loc
, imp
->pkg
);
1946 return ie
->semantic(sc
);
1948 pkg
= s
->isPackage();
1953 ie
= new ScopeExp(loc
, pkg
);
1954 return ie
->semantic(sc
);
1956 Module
*mod
= s
->isModule();
1961 ie
= new ScopeExp(loc
, mod
);
1962 return ie
->semantic(sc
);
1968 return new TypeExp(loc
, t
);
1971 TupleDeclaration
*tup
= s
->isTupleDeclaration();
1974 e
= new TupleExp(loc
, tup
);
1975 e
= e
->semantic(sc
);
1979 TemplateInstance
*ti
= s
->isTemplateInstance();
1980 if (ti
&& !global
.errors
)
1981 { if (!ti
->semanticdone
)
1983 s
= ti
->inst
->toAlias();
1984 if (!s
->isTemplateInstance())
1986 e
= new ScopeExp(loc
, ti
);
1987 e
= e
->semantic(sc
);
1991 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
1994 e
= new TemplateExp(loc
, td
);
1995 e
= e
->semantic(sc
);
2000 error("%s '%s' is not a variable", s
->kind(), s
->toChars());
2001 type
= Type::terror
;
2005 char *DsymbolExp::toChars()
2007 return s
->toChars();
2010 void DsymbolExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
2012 buf
->writestring(s
->toChars());
2015 Expression
*DsymbolExp::toLvalue(Scope
*sc
, Expression
*e
)
2018 tym
= tybasic(e1
->ET
->Tty
);
2019 if (!(tyscalar(tym
) ||
2021 tym
== TYarray
&& e
->Eoper
== TOKaddr
))
2022 synerr(EM_lvalue
); // lvalue expected
2027 /******************************** GetLoggerExp **************************/
2029 GetLoggerExp::GetLoggerExp(Loc loc
)
2030 : Expression(loc
, TOKlogger
, sizeof(GetLoggerExp
))
2034 Expression
*GetLoggerExp::semantic(Scope
*sc
)
2036 Expression
*log
= new DotIdExp(loc
, new IdentifierExp(loc
, Id::empty
), Id::__log
);
2037 return log
->semantic(sc
);
2040 void GetLoggerExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
2042 buf
->writestring("log");
2045 /******************************** ThisExp **************************/
2047 ThisExp::ThisExp(Loc loc
)
2048 : Expression(loc
, TOKthis
, sizeof(ThisExp
))
2053 Expression
*ThisExp::semantic(Scope
*sc
)
2054 { FuncDeclaration
*fd
;
2055 FuncDeclaration
*fdthis
;
2059 printf("ThisExp::semantic()\n");
2062 { //assert(global.errors || var);
2066 /* Special case for typeof(this) and typeof(super) since both
2067 * should work even if they are not inside a non-static member function
2071 // Find enclosing struct or class
2072 for (Dsymbol
*s
= sc
->parent
; 1; s
= s
->parent
)
2074 ClassDeclaration
*cd
;
2075 StructDeclaration
*sd
;
2079 error("%s is not in a struct or class scope", toChars());
2082 cd
= s
->isClassDeclaration();
2088 sd
= s
->isStructDeclaration();
2091 type
= sd
->type
->pointerTo();
2097 fdthis
= sc
->parent
->isFuncDeclaration();
2098 fd
= hasThis(sc
); // fd is the uplevel function with the 'this' variable
2104 assert(var
->parent
);
2106 var
->isVarDeclaration()->checkNestedReference(sc
, loc
);
2108 if (fd
!= fdthis
) // if nested
2110 fdthis
->getLevel(loc
, fd
);
2111 fd
->vthis
->nestedref
= 1;
2112 fd
->nestedFrameRef
= 1;
2115 sc
->callSuper
|= CSXthis
;
2119 error("'this' is only allowed in non-static member functions, not %s", sc
->parent
->toChars());
2120 type
= Type::tint32
;
2124 int ThisExp::isBool(int result
)
2126 return result
? TRUE
: FALSE
;
2129 void ThisExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
2131 buf
->writestring("this");
2134 Expression
*ThisExp::toLvalue(Scope
*sc
, Expression
*e
)
2139 /******************************** SuperExp **************************/
2141 SuperExp::SuperExp(Loc loc
)
2147 Expression
*SuperExp::semantic(Scope
*sc
)
2148 { FuncDeclaration
*fd
;
2149 FuncDeclaration
*fdthis
;
2150 ClassDeclaration
*cd
;
2154 printf("SuperExp::semantic('%s')\n", toChars());
2159 /* Special case for typeof(this) and typeof(super) since both
2160 * should work even if they are not inside a non-static member function
2164 // Find enclosing class
2165 for (Dsymbol
*s
= sc
->parent
; 1; s
= s
->parent
)
2167 ClassDeclaration
*cd
;
2171 error("%s is not in a class scope", toChars());
2174 cd
= s
->isClassDeclaration();
2179 { error("class %s has no 'super'", s
->toChars());
2188 fdthis
= sc
->parent
->isFuncDeclaration();
2194 assert(var
->parent
);
2197 while (s
&& s
->isTemplateInstance())
2200 cd
= s
->isClassDeclaration();
2201 //printf("parent is %s %s\n", fd->toParent()->kind(), fd->toParent()->toChars());
2206 error("no base class for %s", cd
->toChars());
2207 type
= fd
->vthis
->type
;
2211 type
= cd
->baseClass
->type
;
2214 var
->isVarDeclaration()->checkNestedReference(sc
, loc
);
2218 fdthis
->getLevel(loc
, fd
);
2219 fd
->vthis
->nestedref
= 1;
2220 fd
->nestedFrameRef
= 1;
2224 sc
->callSuper
|= CSXsuper
;
2229 error("'super' is only allowed in non-static class member functions");
2230 type
= Type::tint32
;
2234 void SuperExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
2236 buf
->writestring("super");
2240 /******************************** NullExp **************************/
2242 NullExp::NullExp(Loc loc
)
2243 : Expression(loc
, TOKnull
, sizeof(NullExp
))
2248 Expression
*NullExp::semantic(Scope
*sc
)
2251 printf("NullExp::semantic('%s')\n", toChars());
2253 // NULL is the same as (void *)0
2255 type
= Type::tvoid
->pointerTo();
2259 int NullExp::isBool(int result
)
2261 return result
? FALSE
: TRUE
;
2264 void NullExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
2266 buf
->writestring("null");
2269 void NullExp::toMangleBuffer(OutBuffer
*buf
)
2271 buf
->writeByte('n');
2274 /******************************** StringExp **************************/
2276 StringExp::StringExp(Loc loc
, char *string
)
2277 : Expression(loc
, TOKstring
, sizeof(StringExp
))
2279 this->string
= string
;
2280 this->len
= strlen(string
);
2282 this->committed
= 0;
2286 StringExp::StringExp(Loc loc
, void *string
, size_t len
)
2287 : Expression(loc
, TOKstring
, sizeof(StringExp
))
2289 this->string
= string
;
2292 this->committed
= 0;
2296 StringExp::StringExp(Loc loc
, void *string
, size_t len
, unsigned char postfix
)
2297 : Expression(loc
, TOKstring
, sizeof(StringExp
))
2299 this->string
= string
;
2302 this->committed
= 0;
2303 this->postfix
= postfix
;
2307 Expression
*StringExp::syntaxCopy()
2309 printf("StringExp::syntaxCopy() %s\n", toChars());
2314 int StringExp::equals(Object
*o
)
2316 //printf("StringExp::equals('%s')\n", o->toChars());
2317 if (o
&& o
->dyncast() == DYNCAST_EXPRESSION
)
2318 { Expression
*e
= (Expression
*)o
;
2320 if (e
->op
== TOKstring
)
2322 return compare(o
) == 0;
2328 char *StringExp::toChars()
2334 memset(&hgs
, 0, sizeof(hgs
));
2335 toCBuffer(&buf
, &hgs
);
2337 p
= (char *)buf
.data
;
2342 Expression
*StringExp::semantic(Scope
*sc
)
2345 printf("StringExp::semantic() %s\n", toChars());
2357 for (u
= 0; u
< len
;)
2359 p
= utf_decodeChar((unsigned char *)string
, len
, &u
, &c
);
2370 string
= buffer
.extractData();
2373 type
= new TypeSArray(Type::tdchar
, new IntegerExp(loc
, len
, Type::tindex
));
2378 for (u
= 0; u
< len
;)
2380 p
= utf_decodeChar((unsigned char *)string
, len
, &u
, &c
);
2386 { buffer
.writeUTF16(c
);
2392 buffer
.writeUTF16(0);
2393 string
= buffer
.extractData();
2396 type
= new TypeSArray(Type::twchar
, new IntegerExp(loc
, len
, Type::tindex
));
2403 type
= new TypeSArray(Type::tchar
, new IntegerExp(loc
, len
, Type::tindex
));
2406 type
= type
->semantic(loc
, sc
);
2411 /****************************************
2412 * Convert string to char[].
2415 StringExp
*StringExp::toUTF8(Scope
*sc
)
2418 { // Convert to UTF-8 string
2420 Expression
*e
= castTo(sc
, Type::tchar
->arrayOf());
2421 e
= e
->optimize(WANTvalue
);
2422 assert(e
->op
== TOKstring
);
2423 StringExp
*se
= (StringExp
*)e
;
2424 assert(se
->sz
== 1);
2430 int StringExp::compare(Object
*obj
)
2432 // Used to sort case statement expressions so we can do an efficient lookup
2433 StringExp
*se2
= (StringExp
*)(obj
);
2435 // This is a kludge so isExpression() in template.c will return 5
2440 assert(se2
->op
== TOKstring
);
2443 int len2
= se2
->len
;
2450 return strcmp((char *)string
, (char *)se2
->string
);
2454 d_wchar
*s1
= (d_wchar
*)string
;
2455 d_wchar
*s2
= (d_wchar
*)se2
->string
;
2457 for (u
= 0; u
< len
; u
++)
2460 return s1
[u
] - s2
[u
];
2466 d_dchar
*s1
= (d_dchar
*)string
;
2467 d_dchar
*s2
= (d_dchar
*)se2
->string
;
2469 for (u
= 0; u
< len
; u
++)
2472 return s1
[u
] - s2
[u
];
2484 int StringExp::isBool(int result
)
2486 return result
? TRUE
: FALSE
;
2489 unsigned StringExp::charAt(size_t i
)
2495 value
= ((unsigned char *)string
)[i
];
2499 value
= ((unsigned short *)string
)[i
];
2503 value
= ((unsigned int *)string
)[i
];
2513 void StringExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
2515 buf
->writeByte('"');
2516 for (size_t i
= 0; i
< len
; i
++)
2517 { unsigned c
= charAt(i
);
2524 buf
->writeByte('\\');
2527 { if (c
<= 0x7F && (isprint(c
) || hgs
->console
))
2530 buf
->printf("\\x%02x", c
);
2532 else if (c
<= 0xFFFF)
2533 buf
->printf("\\x%02x\\x%02x", c
& 0xFF, c
>> 8);
2535 buf
->printf("\\x%02x\\x%02x\\x%02x\\x%02x",
2536 c
& 0xFF, (c
>> 8) & 0xFF, (c
>> 16) & 0xFF, c
>> 24);
2540 buf
->writeByte('"');
2542 buf
->writeByte(postfix
);
2545 void StringExp::toMangleBuffer(OutBuffer
*buf
)
2554 /* Write string in UTF-8 format
2559 q
= (unsigned char *)string
;
2564 for (u
= 0; u
< len
; )
2566 p
= utf_decodeWchar((unsigned short *)string
, len
, &u
, &c
);
2577 for (u
= 0; u
< len
; u
++)
2579 c
= ((unsigned *)string
)[u
];
2580 if (!utf_isValidDchar(c
))
2581 error("invalid UCS-32 char \\U%08x", c
);
2592 buf
->printf("%d_", qlen
);
2593 for (size_t i
= 0; i
< qlen
; i
++)
2594 buf
->printf("%02x", q
[i
]);
2597 /************************ ArrayLiteralExp ************************************/
2599 // [ e1, e2, e3, ... ]
2601 ArrayLiteralExp::ArrayLiteralExp(Loc loc
, Expressions
*elements
)
2602 : Expression(loc
, TOKarrayliteral
, sizeof(ArrayLiteralExp
))
2604 this->elements
= elements
;
2607 ArrayLiteralExp::ArrayLiteralExp(Loc loc
, Expression
*e
)
2608 : Expression(loc
, TOKarrayliteral
, sizeof(ArrayLiteralExp
))
2610 elements
= new Expressions
;
2614 Expression
*ArrayLiteralExp::syntaxCopy()
2616 return new ArrayLiteralExp(loc
, arraySyntaxCopy(elements
));
2619 Expression
*ArrayLiteralExp::semantic(Scope
*sc
)
2624 printf("ArrayLiteralExp::semantic('%s')\n", toChars());
2629 // Run semantic() on each element
2630 for (int i
= 0; i
< elements
->dim
; i
++)
2631 { e
= (Expression
*)elements
->data
[i
];
2632 e
= e
->semantic(sc
);
2633 elements
->data
[i
] = (void *)e
;
2635 expandTuples(elements
);
2636 for (int i
= 0; i
< elements
->dim
; i
++)
2637 { e
= (Expression
*)elements
->data
[i
];
2640 error("%s has no value", e
->toChars());
2641 e
= resolveProperties(sc
, e
);
2643 unsigned char committed
= 1;
2644 if (e
->op
== TOKstring
)
2645 committed
= ((StringExp
*)e
)->committed
;
2649 // Convert any static arrays to dynamic arrays
2650 if (t0
->ty
== Tsarray
)
2652 t0
= t0
->next
->arrayOf();
2653 e
= e
->implicitCastTo(sc
, t0
);
2657 e
= e
->implicitCastTo(sc
, t0
);
2658 if (!committed
&& e
->op
== TOKstring
)
2659 { StringExp
*se
= (StringExp
*)e
;
2662 elements
->data
[i
] = (void *)e
;
2667 type
= new TypeSArray(t0
, new IntegerExp(elements
->dim
));
2668 type
= type
->semantic(loc
, sc
);
2672 int ArrayLiteralExp::checkSideEffect(int flag
)
2675 for (size_t i
= 0; i
< elements
->dim
; i
++)
2676 { Expression
*e
= (Expression
*)elements
->data
[i
];
2678 f
|= e
->checkSideEffect(2);
2680 if (flag
== 0 && f
== 0)
2681 Expression::checkSideEffect(0);
2685 int ArrayLiteralExp::isBool(int result
)
2687 size_t dim
= elements
? elements
->dim
: 0;
2688 return result
? (dim
!= 0) : (dim
== 0);
2691 void ArrayLiteralExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
2693 buf
->writeByte('[');
2694 argsToCBuffer(buf
, elements
, hgs
);
2695 buf
->writeByte(']');
2698 void ArrayLiteralExp::toMangleBuffer(OutBuffer
*buf
)
2700 size_t dim
= elements
? elements
->dim
: 0;
2701 buf
->printf("A%"PRIuSIZE
, dim
);
2702 for (size_t i
= 0; i
< dim
; i
++)
2703 { Expression
*e
= (Expression
*)elements
->data
[i
];
2704 e
->toMangleBuffer(buf
);
2708 /************************ AssocArrayLiteralExp ************************************/
2710 // [ key0 : value0, key1 : value1, ... ]
2712 AssocArrayLiteralExp::AssocArrayLiteralExp(Loc loc
,
2713 Expressions
*keys
, Expressions
*values
)
2714 : Expression(loc
, TOKassocarrayliteral
, sizeof(AssocArrayLiteralExp
))
2716 assert(keys
->dim
== values
->dim
);
2718 this->values
= values
;
2721 Expression
*AssocArrayLiteralExp::syntaxCopy()
2723 return new AssocArrayLiteralExp(loc
,
2724 arraySyntaxCopy(keys
), arraySyntaxCopy(values
));
2727 Expression
*AssocArrayLiteralExp::semantic(Scope
*sc
)
2730 Type
*tvalue
= NULL
;
2733 printf("AssocArrayLiteralExp::semantic('%s')\n", toChars());
2736 // Run semantic() on each element
2737 for (size_t i
= 0; i
< keys
->dim
; i
++)
2738 { Expression
*key
= (Expression
*)keys
->data
[i
];
2739 Expression
*value
= (Expression
*)values
->data
[i
];
2741 key
= key
->semantic(sc
);
2742 value
= value
->semantic(sc
);
2744 keys
->data
[i
] = (void *)key
;
2745 values
->data
[i
] = (void *)value
;
2748 expandTuples(values
);
2749 if (keys
->dim
!= values
->dim
)
2751 error("number of keys is %u, must match number of values %u", keys
->dim
, values
->dim
);
2755 for (size_t i
= 0; i
< keys
->dim
; i
++)
2756 { Expression
*key
= (Expression
*)keys
->data
[i
];
2757 Expression
*value
= (Expression
*)values
->data
[i
];
2760 error("%s has no value", key
->toChars());
2762 error("%s has no value", value
->toChars());
2763 key
= resolveProperties(sc
, key
);
2764 value
= resolveProperties(sc
, value
);
2769 key
= key
->implicitCastTo(sc
, tkey
);
2770 keys
->data
[i
] = (void *)key
;
2773 tvalue
= value
->type
;
2775 value
= value
->implicitCastTo(sc
, tvalue
);
2776 values
->data
[i
] = (void *)value
;
2782 tvalue
= Type::tvoid
;
2783 type
= new TypeAArray(tvalue
, tkey
);
2784 type
= type
->semantic(loc
, sc
);
2788 int AssocArrayLiteralExp::checkSideEffect(int flag
)
2791 for (size_t i
= 0; i
< keys
->dim
; i
++)
2792 { Expression
*key
= (Expression
*)keys
->data
[i
];
2793 Expression
*value
= (Expression
*)values
->data
[i
];
2795 f
|= key
->checkSideEffect(2);
2796 f
|= value
->checkSideEffect(2);
2798 if (flag
== 0 && f
== 0)
2799 Expression::checkSideEffect(0);
2803 int AssocArrayLiteralExp::isBool(int result
)
2805 size_t dim
= keys
->dim
;
2806 return result
? (dim
!= 0) : (dim
== 0);
2809 void AssocArrayLiteralExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
2811 buf
->writeByte('[');
2812 for (size_t i
= 0; i
< keys
->dim
; i
++)
2813 { Expression
*key
= (Expression
*)keys
->data
[i
];
2814 Expression
*value
= (Expression
*)values
->data
[i
];
2817 buf
->writeByte(',');
2818 expToCBuffer(buf
, hgs
, key
, PREC_assign
);
2819 buf
->writeByte(':');
2820 expToCBuffer(buf
, hgs
, value
, PREC_assign
);
2822 buf
->writeByte(']');
2825 void AssocArrayLiteralExp::toMangleBuffer(OutBuffer
*buf
)
2827 size_t dim
= keys
->dim
;
2828 buf
->printf("A%u", dim
);
2829 for (size_t i
= 0; i
< dim
; i
++)
2830 { Expression
*key
= (Expression
*)keys
->data
[i
];
2831 Expression
*value
= (Expression
*)values
->data
[i
];
2833 key
->toMangleBuffer(buf
);
2834 value
->toMangleBuffer(buf
);
2838 /************************ StructLiteralExp ************************************/
2840 // sd( e1, e2, e3, ... )
2842 StructLiteralExp::StructLiteralExp(Loc loc
, StructDeclaration
*sd
, Expressions
*elements
)
2843 : Expression(loc
, TOKstructliteral
, sizeof(StructLiteralExp
))
2846 this->elements
= elements
;
2849 this->fillHoles
= 1;
2852 Expression
*StructLiteralExp::syntaxCopy()
2854 return new StructLiteralExp(loc
, sd
, arraySyntaxCopy(elements
));
2857 Expression
*StructLiteralExp::semantic(Scope
*sc
)
2861 printf("StructLiteralExp::semantic('%s')\n", toChars());
2864 // Run semantic() on each element
2865 for (size_t i
= 0; i
< elements
->dim
; i
++)
2866 { e
= (Expression
*)elements
->data
[i
];
2869 e
= e
->semantic(sc
);
2870 elements
->data
[i
] = (void *)e
;
2872 expandTuples(elements
);
2874 for (size_t i
= 0; i
< elements
->dim
; i
++)
2875 { e
= (Expression
*)elements
->data
[i
];
2880 error("%s has no value", e
->toChars());
2881 e
= resolveProperties(sc
, e
);
2882 if (i
>= sd
->fields
.dim
)
2883 { error("more initializers than fields of %s", sd
->toChars());
2886 Dsymbol
*s
= (Dsymbol
*)sd
->fields
.data
[i
];
2887 VarDeclaration
*v
= s
->isVarDeclaration();
2889 if (v
->offset
< offset
)
2890 error("overlapping initialization for %s", v
->toChars());
2891 offset
= v
->offset
+ v
->type
->size();
2893 Type
*telem
= v
->type
;
2894 while (!e
->implicitConvTo(telem
) && telem
->toBasetype()->ty
== Tsarray
)
2895 { /* Static array initialization, as in:
2898 telem
= telem
->toBasetype()->nextOf();
2901 e
= e
->implicitCastTo(sc
, telem
);
2903 elements
->data
[i
] = (void *)e
;
2906 /* Fill out remainder of elements[] with default initializers for fields[]
2908 for (size_t i
= elements
->dim
; i
< sd
->fields
.dim
; i
++)
2909 { Dsymbol
*s
= (Dsymbol
*)sd
->fields
.data
[i
];
2910 VarDeclaration
*v
= s
->isVarDeclaration();
2913 if (v
->offset
< offset
)
2920 { e
= v
->init
->toExpression();
2922 error("cannot make expression out of initializer for %s", v
->toChars());
2925 { e
= v
->type
->defaultInit();
2928 offset
= v
->offset
+ v
->type
->size();
2937 /**************************************
2938 * Gets expression at offset of type.
2939 * Returns NULL if not found.
2942 Expression
*StructLiteralExp::getField(Type
*type
, unsigned offset
)
2943 { Expression
*e
= NULL
;
2944 int i
= getFieldIndex(type
, offset
);
2947 { e
= (Expression
*)elements
->data
[i
];
2957 /************************************
2958 * Get index of field.
2959 * Returns -1 if not found.
2962 int StructLiteralExp::getFieldIndex(Type
*type
, unsigned offset
)
2964 /* Find which field offset is by looking at the field offsets
2966 for (size_t i
= 0; i
< sd
->fields
.dim
; i
++)
2968 Dsymbol
*s
= (Dsymbol
*)sd
->fields
.data
[i
];
2969 VarDeclaration
*v
= s
->isVarDeclaration();
2972 if (offset
== v
->offset
&&
2973 type
->size() == v
->type
->size())
2974 { Expression
*e
= (Expression
*)elements
->data
[i
];
2986 Expression
*StructLiteralExp::toLvalue(Scope
*sc
, Expression
*e
)
2992 int StructLiteralExp::checkSideEffect(int flag
)
2995 for (size_t i
= 0; i
< elements
->dim
; i
++)
2996 { Expression
*e
= (Expression
*)elements
->data
[i
];
3000 f
|= e
->checkSideEffect(2);
3002 if (flag
== 0 && f
== 0)
3003 Expression::checkSideEffect(0);
3007 void StructLiteralExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3009 buf
->writestring(sd
->toChars());
3010 buf
->writeByte('(');
3011 argsToCBuffer(buf
, elements
, hgs
);
3012 buf
->writeByte(')');
3015 void StructLiteralExp::toMangleBuffer(OutBuffer
*buf
)
3017 size_t dim
= elements
? elements
->dim
: 0;
3018 buf
->printf("S%u", dim
);
3019 for (size_t i
= 0; i
< dim
; i
++)
3020 { Expression
*e
= (Expression
*)elements
->data
[i
];
3022 e
->toMangleBuffer(buf
);
3024 buf
->writeByte('v'); // 'v' for void
3028 /************************ TypeDotIdExp ************************************/
3037 TypeDotIdExp::TypeDotIdExp(Loc loc
, Type
*type
, Identifier
*ident
)
3038 : Expression(loc
, TOKtypedot
, sizeof(TypeDotIdExp
))
3041 this->ident
= ident
;
3044 Expression
*TypeDotIdExp::syntaxCopy()
3046 TypeDotIdExp
*te
= new TypeDotIdExp(loc
, type
->syntaxCopy(), ident
);
3050 Expression
*TypeDotIdExp::semantic(Scope
*sc
)
3054 printf("TypeDotIdExp::semantic()\n");
3056 e
= new DotIdExp(loc
, new TypeExp(loc
, type
), ident
);
3057 e
= e
->semantic(sc
);
3061 void TypeDotIdExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3063 buf
->writeByte('(');
3064 type
->toCBuffer(buf
, NULL
, hgs
);
3065 buf
->writeByte(')');
3066 buf
->writeByte('.');
3067 buf
->writestring(ident
->toChars());
3070 /************************************************************/
3072 // Mainly just a placeholder
3074 TypeExp::TypeExp(Loc loc
, Type
*type
)
3075 : Expression(loc
, TOKtype
, sizeof(TypeExp
))
3077 //printf("TypeExp::TypeExp(%s)\n", type->toChars());
3081 Expression
*TypeExp::semantic(Scope
*sc
)
3083 //printf("TypeExp::semantic(%s)\n", type->toChars());
3084 type
= type
->semantic(loc
, sc
);
3088 void TypeExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3090 type
->toCBuffer(buf
, NULL
, hgs
);
3093 /************************************************************/
3095 // Mainly just a placeholder
3097 ScopeExp::ScopeExp(Loc loc
, ScopeDsymbol
*pkg
)
3098 : Expression(loc
, TOKimport
, sizeof(ScopeExp
))
3100 //printf("ScopeExp::ScopeExp(pkg = '%s')\n", pkg->toChars());
3101 //static int count; if (++count == 38) *(char*)0=0;
3105 Expression
*ScopeExp::syntaxCopy()
3107 ScopeExp
*se
= new ScopeExp(loc
, (ScopeDsymbol
*)sds
->syntaxCopy(NULL
));
3111 Expression
*ScopeExp::semantic(Scope
*sc
)
3113 TemplateInstance
*ti
;
3117 printf("+ScopeExp::semantic('%s')\n", toChars());
3120 ti
= sds
->isTemplateInstance();
3121 if (ti
&& !global
.errors
)
3123 if (!ti
->semanticdone
)
3125 s
= ti
->inst
->toAlias();
3126 sds2
= s
->isScopeDsymbol();
3130 //printf("s = %s, '%s'\n", s->kind(), s->toChars());
3134 e
= new VarExp(loc
, ti
->withsym
->withstate
->wthis
);
3135 e
= new DotVarExp(loc
, e
, s
->isDeclaration());
3138 e
= new DsymbolExp(loc
, s
);
3139 e
= e
->semantic(sc
);
3140 //printf("-1ScopeExp::semantic()\n");
3148 //printf("sds = %s, '%s'\n", sds->kind(), sds->toChars());
3152 //printf("sds = %s, '%s'\n", sds->kind(), sds->toChars());
3153 //printf("\tparent = '%s'\n", sds->parent->toChars());
3157 //printf("-2ScopeExp::semantic() %s\n", toChars());
3161 void ScopeExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3163 if (sds
->isTemplateInstance())
3165 sds
->toCBuffer(buf
, hgs
);
3169 buf
->writestring(sds
->kind());
3170 buf
->writestring(" ");
3171 buf
->writestring(sds
->toChars());
3175 /********************** TemplateExp **************************************/
3177 // Mainly just a placeholder
3179 TemplateExp::TemplateExp(Loc loc
, TemplateDeclaration
*td
)
3180 : Expression(loc
, TOKtemplate
, sizeof(TemplateExp
))
3182 //printf("TemplateExp(): %s\n", td->toChars());
3186 void TemplateExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3188 buf
->writestring(td
->toChars());
3191 void TemplateExp::rvalue()
3193 error("template %s has no value", toChars());
3196 /********************** NewExp **************************************/
3198 NewExp::NewExp(Loc loc
, Expression
*thisexp
, Expressions
*newargs
,
3199 Type
*newtype
, Expressions
*arguments
)
3200 : Expression(loc
, TOKnew
, sizeof(NewExp
))
3202 this->thisexp
= thisexp
;
3203 this->newargs
= newargs
;
3204 this->newtype
= newtype
;
3205 this->arguments
= arguments
;
3211 Expression
*NewExp::syntaxCopy()
3213 return new NewExp(loc
,
3214 thisexp
? thisexp
->syntaxCopy() : NULL
,
3215 arraySyntaxCopy(newargs
),
3216 newtype
->syntaxCopy(), arraySyntaxCopy(arguments
));
3220 Expression
*NewExp::semantic(Scope
*sc
)
3223 ClassDeclaration
*cdthis
= NULL
;
3226 printf("NewExp::semantic() %s\n", toChars());
3228 printf("\tthisexp = %s\n", thisexp
->toChars());
3229 printf("\tnewtype: %s\n", newtype
->toChars());
3231 if (type
) // if semantic() already run
3236 { thisexp
= thisexp
->semantic(sc
);
3237 cdthis
= thisexp
->type
->isClassHandle();
3240 sc
= sc
->push(cdthis
);
3241 type
= newtype
->semantic(loc
, sc
);
3246 error("'this' for nested class must be a class type, not %s", thisexp
->type
->toChars());
3247 type
= newtype
->semantic(loc
, sc
);
3251 type
= newtype
->semantic(loc
, sc
);
3252 newtype
= type
; // in case type gets cast to something else
3253 tb
= type
->toBasetype();
3254 //printf("tb: %s, deco = %s\n", tb->toChars(), tb->deco);
3256 arrayExpressionSemantic(newargs
, sc
);
3257 preFunctionArguments(loc
, sc
, newargs
);
3258 arrayExpressionSemantic(arguments
, sc
);
3259 preFunctionArguments(loc
, sc
, arguments
);
3261 if (thisexp
&& tb
->ty
!= Tclass
)
3262 error("e.new is only for allocating nested classes, not %s", tb
->toChars());
3264 if (tb
->ty
== Tclass
)
3267 TypeClass
*tc
= (TypeClass
*)(tb
);
3268 ClassDeclaration
*cd
= tc
->sym
->isClassDeclaration();
3269 if (cd
->isInterfaceDeclaration())
3270 error("cannot create instance of interface %s", cd
->toChars());
3271 else if (cd
->isAbstract())
3272 { error("cannot create instance of abstract class %s", cd
->toChars());
3273 for (int i
= 0; i
< cd
->vtbl
.dim
; i
++)
3274 { FuncDeclaration
*fd
= ((Dsymbol
*)cd
->vtbl
.data
[i
])->isFuncDeclaration();
3275 if (fd
&& fd
->isAbstract())
3276 error("function %s is abstract", fd
->toChars());
3279 checkDeprecated(sc
, cd
);
3281 { /* We need a 'this' pointer for the nested class.
3282 * Ensure we have the right one.
3284 Dsymbol
*s
= cd
->toParent2();
3285 ClassDeclaration
*cdn
= s
->isClassDeclaration();
3287 //printf("isNested, cdn = %s\n", cdn ? cdn->toChars() : "null");
3292 // Supply an implicit 'this' and try again
3293 thisexp
= new ThisExp(loc
);
3294 for (Dsymbol
*sp
= sc
->parent
; 1; sp
= sp
->parent
)
3297 error("outer class %s 'this' needed to 'new' nested class %s", cdn
->toChars(), cd
->toChars());
3300 ClassDeclaration
*cdp
= sp
->isClassDeclaration();
3303 if (cdp
== cdn
|| cdn
->isBaseOf(cdp
, NULL
))
3305 // Add a '.outer' and try again
3306 thisexp
= new DotIdExp(loc
, thisexp
, Id::outer
);
3313 //printf("cdthis = %s\n", cdthis->toChars());
3314 if (cdthis
!= cdn
&& !cdn
->isBaseOf(cdthis
, NULL
))
3315 error("'this' for nested class must be of type %s, not %s", cdn
->toChars(), thisexp
->type
->toChars());
3320 for (Dsymbol
*sf
= sc
->func
; 1; sf
= sf
->toParent2()->isFuncDeclaration())
3324 error("outer class %s 'this' needed to 'new' nested class %s", cdn
->toChars(), cd
->toChars());
3327 printf("sf = %s\n", sf
->toChars());
3328 AggregateDeclaration
*ad
= sf
->isThis();
3329 if (ad
&& (ad
== cdn
|| cdn
->isBaseOf(ad
->isClassDeclaration(), NULL
)))
3336 error("e.new is only for allocating nested classes");
3339 error("e.new is only for allocating nested classes");
3341 FuncDeclaration
*f
= cd
->ctor
;
3345 f
= f
->overloadResolve(loc
, arguments
);
3346 checkDeprecated(sc
, f
);
3347 member
= f
->isCtorDeclaration();
3350 cd
->accessCheck(loc
, sc
, member
);
3352 tf
= (TypeFunction
*)f
->type
;
3356 arguments
= new Expressions();
3357 functionArguments(loc
, sc
, tf
, arguments
);
3361 if (arguments
&& arguments
->dim
)
3362 error("no constructor for %s", cd
->toChars());
3370 // Prepend the uint size argument to newargs[]
3371 e
= new IntegerExp(loc
, cd
->size(loc
), Type::tsize_t
);
3373 newargs
= new Expressions();
3376 f
= f
->overloadResolve(loc
, newargs
);
3377 allocator
= f
->isNewDeclaration();
3380 tf
= (TypeFunction
*)f
->type
;
3381 functionArguments(loc
, sc
, tf
, newargs
);
3385 if (newargs
&& newargs
->dim
)
3386 error("no allocator for %s", cd
->toChars());
3390 else if (tb
->ty
== Tstruct
)
3392 TypeStruct
*ts
= (TypeStruct
*)tb
;
3393 StructDeclaration
*sd
= ts
->sym
;
3394 FuncDeclaration
*f
= sd
->aggNew
;
3397 if (arguments
&& arguments
->dim
)
3398 error("no constructor for %s", type
->toChars());
3404 // Prepend the uint size argument to newargs[]
3405 e
= new IntegerExp(loc
, sd
->size(loc
), Type::tsize_t
);
3407 newargs
= new Expressions();
3410 f
= f
->overloadResolve(loc
, newargs
);
3411 allocator
= f
->isNewDeclaration();
3414 tf
= (TypeFunction
*)f
->type
;
3415 functionArguments(loc
, sc
, tf
, newargs
);
3417 e
= new VarExp(loc
, f
);
3418 e
= new CallExp(loc
, e
, newargs
);
3419 e
= e
->semantic(sc
);
3420 e
->type
= type
->pointerTo();
3424 type
= type
->pointerTo();
3426 else if (tb
->ty
== Tarray
&& (arguments
&& arguments
->dim
))
3428 for (size_t i
= 0; i
< arguments
->dim
; i
++)
3430 if (tb
->ty
!= Tarray
)
3431 { error("too many arguments for array");
3436 Expression
*arg
= (Expression
*)arguments
->data
[i
];
3437 arg
= resolveProperties(sc
, arg
);
3438 arg
= arg
->implicitCastTo(sc
, Type::tsize_t
);
3439 if (arg
->op
== TOKint64
&& (long long)arg
->toInteger() < 0)
3440 error("negative array index %s", arg
->toChars());
3441 arguments
->data
[i
] = (void *) arg
;
3442 tb
= tb
->next
->toBasetype();
3445 else if (tb
->isscalar())
3447 if (arguments
&& arguments
->dim
)
3448 error("no constructor for %s", type
->toChars());
3450 type
= type
->pointerTo();
3454 error("new can only create structs, dynamic arrays or class objects, not %s's", type
->toChars());
3455 type
= type
->pointerTo();
3458 //printf("NewExp: '%s'\n", toChars());
3459 //printf("NewExp:type '%s'\n", type->toChars());
3464 int NewExp::checkSideEffect(int flag
)
3469 void NewExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3473 { expToCBuffer(buf
, hgs
, thisexp
, PREC_primary
);
3474 buf
->writeByte('.');
3476 buf
->writestring("new ");
3477 if (newargs
&& newargs
->dim
)
3479 buf
->writeByte('(');
3480 argsToCBuffer(buf
, newargs
, hgs
);
3481 buf
->writeByte(')');
3483 newtype
->toCBuffer(buf
, NULL
, hgs
);
3484 if (arguments
&& arguments
->dim
)
3486 buf
->writeByte('(');
3487 argsToCBuffer(buf
, arguments
, hgs
);
3488 buf
->writeByte(')');
3492 /********************** NewAnonClassExp **************************************/
3494 NewAnonClassExp::NewAnonClassExp(Loc loc
, Expression
*thisexp
,
3495 Expressions
*newargs
, ClassDeclaration
*cd
, Expressions
*arguments
)
3496 : Expression(loc
, TOKnewanonclass
, sizeof(NewAnonClassExp
))
3498 this->thisexp
= thisexp
;
3499 this->newargs
= newargs
;
3501 this->arguments
= arguments
;
3504 Expression
*NewAnonClassExp::syntaxCopy()
3506 return new NewAnonClassExp(loc
,
3507 thisexp
? thisexp
->syntaxCopy() : NULL
,
3508 arraySyntaxCopy(newargs
),
3509 (ClassDeclaration
*)cd
->syntaxCopy(NULL
),
3510 arraySyntaxCopy(arguments
));
3514 Expression
*NewAnonClassExp::semantic(Scope
*sc
)
3517 printf("NewAnonClassExp::semantic() %s\n", toChars());
3518 //printf("type: %s\n", type->toChars());
3521 Expression
*d
= new DeclarationExp(loc
, cd
);
3522 d
= d
->semantic(sc
);
3524 Expression
*n
= new NewExp(loc
, thisexp
, newargs
, cd
->type
, arguments
);
3526 Expression
*c
= new CommaExp(loc
, d
, n
);
3527 return c
->semantic(sc
);
3530 int NewAnonClassExp::checkSideEffect(int flag
)
3535 void NewAnonClassExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3539 { expToCBuffer(buf
, hgs
, thisexp
, PREC_primary
);
3540 buf
->writeByte('.');
3542 buf
->writestring("new");
3543 if (newargs
&& newargs
->dim
)
3545 buf
->writeByte('(');
3546 argsToCBuffer(buf
, newargs
, hgs
);
3547 buf
->writeByte(')');
3549 buf
->writestring(" class ");
3550 if (arguments
&& arguments
->dim
)
3552 buf
->writeByte('(');
3553 argsToCBuffer(buf
, arguments
, hgs
);
3554 buf
->writeByte(')');
3556 //buf->writestring(" { }");
3559 cd
->toCBuffer(buf
, hgs
);
3563 /********************** SymOffExp **************************************/
3565 SymOffExp::SymOffExp(Loc loc
, Declaration
*var
, target_size_t offset
)
3566 : Expression(loc
, TOKsymoff
, sizeof(SymOffExp
))
3570 this->offset
= offset
;
3571 VarDeclaration
*v
= var
->isVarDeclaration();
3572 if (v
&& v
->needThis())
3573 error("need 'this' for address of %s", v
->toChars());
3576 Expression
*SymOffExp::semantic(Scope
*sc
)
3579 printf("SymOffExp::semantic('%s')\n", toChars());
3581 //var->semantic(sc);
3583 type
= var
->type
->pointerTo();
3584 VarDeclaration
*v
= var
->isVarDeclaration();
3586 v
->checkNestedReference(sc
, loc
);
3590 int SymOffExp::isBool(int result
)
3592 return result
? TRUE
: FALSE
;
3595 void SymOffExp::checkEscape()
3597 VarDeclaration
*v
= var
->isVarDeclaration();
3600 if (!v
->isDataseg())
3601 error("escaping reference to local variable %s", v
->toChars());
3605 void SymOffExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3608 buf
->printf("(& %s+%"PRIuTSIZE
")", var
->toChars(), offset
);
3610 buf
->printf("& %s", var
->toChars());
3613 /******************************** VarExp **************************/
3615 VarExp::VarExp(Loc loc
, Declaration
*var
)
3616 : Expression(loc
, TOKvar
, sizeof(VarExp
))
3618 //printf("VarExp(this = %p, '%s')\n", this, var->toChars());
3620 this->type
= var
->type
;
3623 int VarExp::equals(Object
*o
)
3627 (((Expression
*)o
)->op
== TOKvar
&&
3628 ((ne
= (VarExp
*)o
), type
->equals(ne
->type
)) &&
3634 Expression
*VarExp::semantic(Scope
*sc
)
3635 { FuncLiteralDeclaration
*fd
;
3638 printf("VarExp::semantic(%s)\n", toChars());
3643 if (var
->storage_class
& STClazy
)
3645 TypeFunction
*tf
= new TypeFunction(NULL
, type
, 0, LINKd
);
3646 type
= new TypeDelegate(tf
);
3647 type
= type
->semantic(loc
, sc
);
3652 VarDeclaration
*v
= var
->isVarDeclaration();
3655 if (v
->isConst() && type
->toBasetype()->ty
!= Tsarray
&& v
->init
)
3657 ExpInitializer
*ei
= v
->init
->isExpInitializer();
3660 //ei->exp->implicitCastTo(sc, type)->print();
3661 return ei
->exp
->implicitCastTo(sc
, type
);
3664 v
->checkNestedReference(sc
, loc
);
3667 else if ((fd
= var
->isFuncLiteralDeclaration()) != NULL
)
3669 e
= new FuncExp(loc
, fd
);
3677 char *VarExp::toChars()
3679 return var
->toChars();
3682 void VarExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3684 buf
->writestring(var
->toChars());
3687 void VarExp::checkEscape()
3689 VarDeclaration
*v
= var
->isVarDeclaration();
3691 { Type
*tb
= v
->type
->toBasetype();
3692 // if reference type
3693 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
|| tb
->ty
== Tclass
)
3695 if ((v
->isAuto() || v
->isScope()) && !v
->noauto
)
3696 error("escaping reference to auto local %s", v
->toChars());
3697 else if (v
->storage_class
& STCvariadic
)
3698 error("escaping reference to variadic parameter %s", v
->toChars());
3703 Expression
*VarExp::toLvalue(Scope
*sc
, Expression
*e
)
3706 tym
= tybasic(e1
->ET
->Tty
);
3707 if (!(tyscalar(tym
) ||
3709 tym
== TYarray
&& e
->Eoper
== TOKaddr
))
3710 synerr(EM_lvalue
); // lvalue expected
3712 if (var
->storage_class
& STClazy
)
3713 error("lazy variables cannot be lvalues");
3717 Expression
*VarExp::modifiableLvalue(Scope
*sc
, Expression
*e
)
3719 //printf("VarExp::modifiableLvalue('%s')\n", var->toChars());
3720 if (sc
->incontract
&& var
->isParameter())
3721 error("cannot modify parameter '%s' in contract", var
->toChars());
3723 if (type
&& type
->toBasetype()->ty
== Tsarray
)
3724 error("cannot change reference to static array '%s'", var
->toChars());
3726 VarDeclaration
*v
= var
->isVarDeclaration();
3727 if (v
&& v
->canassign
== 0 &&
3728 (var
->isConst() || (global
.params
.Dversion
> 1 && var
->isFinal())))
3729 error("cannot modify final variable '%s'", var
->toChars());
3731 // Also need this for non-null fields.
3734 if (var
->isCtorinit())
3735 { // It's only modifiable if inside the right constructor
3736 Dsymbol
*s
= sc
->func
;
3739 FuncDeclaration
*fd
= NULL
;
3741 fd
= s
->isFuncDeclaration();
3743 ((fd
->isCtorDeclaration() && var
->storage_class
& STCfield
) ||
3744 (fd
->isStaticCtorDeclaration() && !(var
->storage_class
& STCfield
))) &&
3745 fd
->toParent() == var
->toParent()
3748 VarDeclaration
*v
= var
->isVarDeclaration();
3751 //printf("setting ctorinit\n");
3756 { s
= s
->toParent2();
3761 const char *p
= var
->isStatic() ? "static " : "";
3762 error("can only initialize %sconst %s inside %sconstructor",
3763 p
, var
->toChars(), p
);
3770 // See if this expression is a modifiable lvalue (i.e. not const)
3771 return toLvalue(sc
, e
);
3775 /******************************** TupleExp **************************/
3777 TupleExp::TupleExp(Loc loc
, Expressions
*exps
)
3778 : Expression(loc
, TOKtuple
, sizeof(TupleExp
))
3780 //printf("TupleExp(this = %p)\n", this);
3786 TupleExp::TupleExp(Loc loc
, TupleDeclaration
*tup
)
3787 : Expression(loc
, TOKtuple
, sizeof(TupleExp
))
3789 exps
= new Expressions();
3792 exps
->reserve(tup
->objects
->dim
);
3793 for (size_t i
= 0; i
< tup
->objects
->dim
; i
++)
3794 { Object
*o
= (Object
*)tup
->objects
->data
[i
];
3795 if (o
->dyncast() == DYNCAST_EXPRESSION
)
3797 Expression
*e
= (Expression
*)o
;
3798 e
= e
->syntaxCopy();
3801 else if (o
->dyncast() == DYNCAST_DSYMBOL
)
3803 Dsymbol
*s
= (Dsymbol
*)o
;
3804 Expression
*e
= new DsymbolExp(loc
, s
);
3807 else if (o
->dyncast() == DYNCAST_TYPE
)
3809 Type
*t
= (Type
*)o
;
3810 Expression
*e
= new TypeExp(loc
, t
);
3815 error("%s is not an expression", o
->toChars());
3820 int TupleExp::equals(Object
*o
)
3825 if (((Expression
*)o
)->op
== TOKtuple
)
3827 TupleExp
*te
= (TupleExp
*)o
;
3828 if (exps
->dim
!= te
->exps
->dim
)
3830 for (size_t i
= 0; i
< exps
->dim
; i
++)
3831 { Expression
*e1
= (Expression
*)exps
->data
[i
];
3832 Expression
*e2
= (Expression
*)te
->exps
->data
[i
];
3834 if (!e1
->equals(e2
))
3842 Expression
*TupleExp::syntaxCopy()
3844 return new TupleExp(loc
, arraySyntaxCopy(exps
));
3847 Expression
*TupleExp::semantic(Scope
*sc
)
3850 printf("+TupleExp::semantic(%s)\n", toChars());
3855 // Run semantic() on each argument
3856 for (size_t i
= 0; i
< exps
->dim
; i
++)
3857 { Expression
*e
= (Expression
*)exps
->data
[i
];
3859 e
= e
->semantic(sc
);
3861 { error("%s has no value", e
->toChars());
3862 e
->type
= Type::terror
;
3864 exps
->data
[i
] = (void *)e
;
3868 if (0 && exps
->dim
== 1)
3870 return (Expression
*)exps
->data
[0];
3872 type
= new TypeTuple(exps
);
3873 //printf("-TupleExp::semantic(%s)\n", toChars());
3877 void TupleExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3879 buf
->writestring("tuple(");
3880 argsToCBuffer(buf
, exps
, hgs
);
3881 buf
->writeByte(')');
3884 int TupleExp::checkSideEffect(int flag
)
3887 for (int i
= 0; i
< exps
->dim
; i
++)
3888 { Expression
*e
= (Expression
*)exps
->data
[i
];
3890 f
|= e
->checkSideEffect(2);
3892 if (flag
== 0 && f
== 0)
3893 Expression::checkSideEffect(0);
3897 void TupleExp::checkEscape()
3899 for (size_t i
= 0; i
< exps
->dim
; i
++)
3900 { Expression
*e
= (Expression
*)exps
->data
[i
];
3905 /******************************** FuncExp *********************************/
3907 FuncExp::FuncExp(Loc loc
, FuncLiteralDeclaration
*fd
)
3908 : Expression(loc
, TOKfunction
, sizeof(FuncExp
))
3913 Expression
*FuncExp::syntaxCopy()
3915 return new FuncExp(loc
, (FuncLiteralDeclaration
*)fd
->syntaxCopy(NULL
));
3918 Expression
*FuncExp::semantic(Scope
*sc
)
3921 printf("FuncExp::semantic(%s)\n", toChars());
3926 fd
->parent
= sc
->parent
;
3929 if (!fd
->type
->next
)
3930 fd
->type
->next
= Type::terror
;
3939 if (!global
.errors
&& global
.params
.useInline
)
3944 // Type is a "delegate to" or "pointer to" the function literal
3947 type
= new TypeDelegate(fd
->type
);
3948 type
= type
->semantic(loc
, sc
);
3952 type
= fd
->type
->pointerTo();
3958 char *FuncExp::toChars()
3960 return fd
->toChars();
3963 void FuncExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
3965 buf
->writestring(fd
->toChars());
3969 /******************************** DeclarationExp **************************/
3971 DeclarationExp::DeclarationExp(Loc loc
, Dsymbol
*declaration
)
3972 : Expression(loc
, TOKdeclaration
, sizeof(DeclarationExp
))
3974 this->declaration
= declaration
;
3977 Expression
*DeclarationExp::syntaxCopy()
3979 return new DeclarationExp(loc
, declaration
->syntaxCopy(NULL
));
3982 Expression
*DeclarationExp::semantic(Scope
*sc
)
3988 printf("DeclarationExp::semantic() %s\n", toChars());
3991 /* This is here to support extern(linkage) declaration,
3992 * where the extern(linkage) winds up being an AttribDeclaration
3995 Dsymbol
*s
= declaration
;
3997 AttribDeclaration
*ad
= declaration
->isAttribDeclaration();
4000 if (ad
->decl
&& ad
->decl
->dim
== 1)
4001 s
= (Dsymbol
*)ad
->decl
->data
[0];
4004 if (s
->isVarDeclaration())
4005 { // Do semantic() on initializer first, so:
4008 declaration
->semantic(sc
);
4009 s
->parent
= sc
->parent
;
4012 //printf("inserting '%s' %p into sc = %p\n", s->toChars(), s, sc);
4013 // Insert into both local scope and function scope.
4014 // Must be unique in both.
4018 error("declaration %s is already defined", s
->toPrettyChars());
4020 { VarDeclaration
*v
= s
->isVarDeclaration();
4021 if ((s
->isFuncDeclaration() /*|| v && v->storage_class & STCstatic*/) &&
4022 !sc
->func
->localsymtab
->insert(s
))
4023 error("declaration %s is already defined in another scope in %s", s
->toPrettyChars(), sc
->func
->toChars());
4024 else if (!global
.params
.useDeprecated
)
4025 { // Disallow shadowing
4027 for (Scope
*scx
= sc
->enclosing
; scx
&& scx
->func
== sc
->func
; scx
= scx
->enclosing
)
4030 if (scx
->scopesym
&& scx
->scopesym
->symtab
&&
4031 (s2
= scx
->scopesym
->symtab
->lookup(s
->ident
)) != NULL
&&
4034 error("shadowing declaration %s is deprecated", s
->toPrettyChars());
4040 if (!s
->isVarDeclaration())
4042 declaration
->semantic(sc
);
4043 s
->parent
= sc
->parent
;
4047 declaration
->semantic2(sc
);
4050 declaration
->semantic3(sc
);
4052 if (!global
.errors
&& global
.params
.useInline
)
4053 declaration
->inlineScan();
4061 int DeclarationExp::checkSideEffect(int flag
)
4066 void DeclarationExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
4068 declaration
->toCBuffer(buf
, hgs
);
4072 /************************ TypeidExp ************************************/
4078 TypeidExp::TypeidExp(Loc loc
, Type
*typeidType
)
4079 : Expression(loc
, TOKtypeid
, sizeof(TypeidExp
))
4081 this->typeidType
= typeidType
;
4085 Expression
*TypeidExp::syntaxCopy()
4087 return new TypeidExp(loc
, typeidType
->syntaxCopy());
4091 Expression
*TypeidExp::semantic(Scope
*sc
)
4095 printf("TypeidExp::semantic()\n");
4097 typeidType
= typeidType
->semantic(loc
, sc
);
4098 e
= typeidType
->getTypeInfo(sc
);
4102 void TypeidExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
4104 buf
->writestring("typeid(");
4105 typeidType
->toCBuffer(buf
, NULL
, hgs
);
4106 buf
->writeByte(')');
4109 /************************************************************/
4111 HaltExp::HaltExp(Loc loc
)
4112 : Expression(loc
, TOKhalt
, sizeof(HaltExp
))
4116 Expression
*HaltExp::semantic(Scope
*sc
)
4119 printf("HaltExp::semantic()\n");
4125 int HaltExp::checkSideEffect(int flag
)
4130 void HaltExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
4132 buf
->writestring("halt");
4135 /************************************************************/
4137 IsExp::IsExp(Loc loc
, Type
*targ
, Identifier
*id
, enum TOK tok
,
4138 Type
*tspec
, enum TOK tok2
)
4139 : Expression(loc
, TOKis
, sizeof(IsExp
))
4144 this->tspec
= tspec
;
4148 Expression
*IsExp::syntaxCopy()
4150 return new IsExp(loc
,
4154 tspec
? tspec
->syntaxCopy() : NULL
,
4158 Expression
*IsExp::semantic(Scope
*sc
)
4161 //printf("IsExp::semantic()\n");
4162 if (id
&& !(sc
->flags
& SCOPEstaticif
))
4163 error("can only declare type aliases within static if conditionals");
4165 unsigned errors_save
= global
.errors
;
4167 global
.gag
++; // suppress printing of error messages
4168 targ
= targ
->semantic(loc
, sc
);
4170 unsigned gerrors
= global
.errors
;
4171 global
.errors
= errors_save
;
4173 if (gerrors
) // if any errors happened
4174 { // then condition is false
4177 else if (tok2
!= TOKreserved
)
4182 if (targ
->ty
!= Ttypedef
)
4184 tded
= ((TypeTypedef
*)targ
)->sym
->basetype
;
4188 if (targ
->ty
!= Tstruct
)
4190 if (((TypeStruct
*)targ
)->sym
->isUnionDeclaration())
4196 if (targ
->ty
!= Tstruct
)
4198 if (!((TypeStruct
*)targ
)->sym
->isUnionDeclaration())
4204 if (targ
->ty
!= Tclass
)
4206 if (((TypeClass
*)targ
)->sym
->isInterfaceDeclaration())
4212 if (targ
->ty
!= Tclass
)
4214 if (!((TypeClass
*)targ
)->sym
->isInterfaceDeclaration())
4220 // If class or interface, get the base class and interfaces
4221 if (targ
->ty
!= Tclass
)
4224 { ClassDeclaration
*cd
= ((TypeClass
*)targ
)->sym
;
4225 Arguments
*args
= new Arguments
;
4226 args
->reserve(cd
->baseclasses
.dim
);
4227 for (size_t i
= 0; i
< cd
->baseclasses
.dim
; i
++)
4228 { BaseClass
*b
= (BaseClass
*)cd
->baseclasses
.data
[i
];
4229 args
->push(new Argument(STCin
, b
->type
, NULL
, NULL
));
4231 tded
= new TypeTuple(args
);
4236 if (targ
->ty
!= Tenum
)
4238 tded
= ((TypeEnum
*)targ
)->sym
->memtype
;
4242 if (targ
->ty
!= Tdelegate
)
4244 tded
= targ
->next
; // the underlying function type
4248 { if (targ
->ty
!= Tfunction
)
4252 /* Generate tuple from function parameter types.
4254 assert(tded
->ty
== Tfunction
);
4255 Arguments
*params
= ((TypeFunction
*)tded
)->parameters
;
4256 size_t dim
= Argument::dim(params
);
4257 Arguments
*args
= new Arguments
;
4259 for (size_t i
= 0; i
< dim
; i
++)
4260 { Argument
*arg
= Argument::getNth(params
, i
);
4261 assert(arg
&& arg
->type
);
4262 args
->push(new Argument(arg
->storageClass
, arg
->type
, NULL
, NULL
));
4264 tded
= new TypeTuple(args
);
4268 /* Get the 'return type' for the function,
4269 * delegate, or pointer to function.
4271 if (targ
->ty
== Tfunction
)
4273 else if (targ
->ty
== Tdelegate
)
4274 tded
= targ
->next
->next
;
4275 else if (targ
->ty
== Tpointer
&& targ
->next
->ty
== Tfunction
)
4276 tded
= targ
->next
->next
;
4286 else if (id
&& tspec
)
4288 /* Evaluate to TRUE if targ matches tspec.
4289 * If TRUE, declare id as an alias for the specialized type.
4293 TemplateTypeParameter
tp(loc
, id
, NULL
, NULL
);
4295 TemplateParameters parameters
;
4296 parameters
.setDim(1);
4297 parameters
.data
[0] = (void *)&tp
;
4301 dedtypes
.data
[0] = NULL
;
4303 m
= targ
->deduceType(NULL
, tspec
, ¶meters
, &dedtypes
);
4304 if (m
== MATCHnomatch
||
4305 (m
!= MATCHexact
&& tok
== TOKequal
))
4309 assert(dedtypes
.dim
== 1);
4310 tded
= (Type
*)dedtypes
.data
[0];
4318 /* Declare id as an alias for type targ. Evaluate to TRUE
4325 /* Evaluate to TRUE if targ matches tspec
4327 tspec
= tspec
->semantic(loc
, sc
);
4328 //printf("targ = %s\n", targ->toChars());
4329 //printf("tspec = %s\n", tspec->toChars());
4330 if (tok
== TOKcolon
)
4331 { if (targ
->implicitConvTo(tspec
))
4337 { if (targ
->equals(tspec
))
4347 Dsymbol
*s
= new AliasDeclaration(loc
, id
, tded
);
4351 s
->addMember(sc
, sc
->sd
, 1);
4353 return new IntegerExp(1);
4356 return new IntegerExp(0);
4359 void IsExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
4361 buf
->writestring("is(");
4362 targ
->toCBuffer(buf
, id
, hgs
);
4363 if (tok2
!= TOKreserved
)
4365 buf
->printf(" %s %s", Token::toChars(tok
), Token::toChars(tok2
));
4369 if (tok
== TOKcolon
)
4370 buf
->writestring(" : ");
4372 buf
->writestring(" == ");
4373 tspec
->toCBuffer(buf
, NULL
, hgs
);
4377 { // First parameter is already output, so start with second
4378 for (int i
= 1; i
< parameters
->dim
; i
++)
4380 buf
->writeByte(',');
4381 TemplateParameter
*tp
= (TemplateParameter
*)parameters
->data
[i
];
4382 tp
->toCBuffer(buf
, hgs
);
4386 buf
->writeByte(')');
4390 /************************************************************/
4392 UnaExp::UnaExp(Loc loc
, enum TOK op
, int size
, Expression
*e1
)
4393 : Expression(loc
, op
, size
)
4398 Expression
*UnaExp::syntaxCopy()
4401 e
= (UnaExp
*)copy();
4403 e
->e1
= e
->e1
->syntaxCopy();
4407 Expression
*UnaExp::semantic(Scope
*sc
)
4410 printf("UnaExp::semantic('%s')\n", toChars());
4412 e1
= e1
->semantic(sc
);
4414 // error("%s has no value", e1->toChars());
4418 void UnaExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
4420 buf
->writestring(Token::toChars(op
));
4421 expToCBuffer(buf
, hgs
, e1
, precedence
[op
]);
4424 /************************************************************/
4426 BinExp::BinExp(Loc loc
, enum TOK op
, int size
, Expression
*e1
, Expression
*e2
)
4427 : Expression(loc
, op
, size
)
4433 Expression
*BinExp::syntaxCopy()
4436 e
= (BinExp
*)copy();
4438 e
->e1
= e
->e1
->syntaxCopy();
4439 e
->e2
= e
->e2
->syntaxCopy();
4443 Expression
*BinExp::semantic(Scope
*sc
)
4446 printf("BinExp::semantic('%s')\n", toChars());
4448 e1
= e1
->semantic(sc
);
4451 error("%s has no value", e1
->toChars());
4452 e1
->type
= Type::terror
;
4454 e2
= e2
->semantic(sc
);
4457 error("%s has no value", e2
->toChars());
4458 e2
->type
= Type::terror
;
4464 Expression
*BinExp::semanticp(Scope
*sc
)
4466 BinExp::semantic(sc
);
4467 e1
= resolveProperties(sc
, e1
);
4468 e2
= resolveProperties(sc
, e2
);
4472 /***************************
4473 * Common semantic routine for some xxxAssignExp's.
4476 Expression
*BinExp::commonSemanticAssign(Scope
*sc
)
4481 BinExp::semantic(sc
);
4482 e2
= resolveProperties(sc
, e2
);
4484 e
= op_overload(sc
);
4488 e1
= e1
->modifiableLvalue(sc
, e1
);
4491 if (type
->toBasetype()->ty
== Tbool
)
4493 error("operator not allowed on bool expression %s", toChars());
4496 e1
->checkArithmetic();
4497 e2
->checkArithmetic();
4499 if (op
== TOKmodass
&& e2
->type
->iscomplex())
4500 { error("cannot perform modulo complex arithmetic");
4501 return new IntegerExp(0);
4507 Expression
*BinExp::commonSemanticAssignIntegral(Scope
*sc
)
4512 BinExp::semantic(sc
);
4513 e2
= resolveProperties(sc
, e2
);
4515 e
= op_overload(sc
);
4519 e1
= e1
->modifiableLvalue(sc
, e1
);
4522 if (type
->toBasetype()->ty
== Tbool
)
4524 e2
= e2
->implicitCastTo(sc
, type
);
4528 e1
->checkIntegral();
4529 e2
->checkIntegral();
4534 int BinExp::checkSideEffect(int flag
)
4536 if (op
== TOKplusplus
||
4537 op
== TOKminusminus
||
4539 op
== TOKconstruct
||
4556 return Expression::checkSideEffect(flag
);
4559 void BinExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
4561 expToCBuffer(buf
, hgs
, e1
, precedence
[op
]);
4562 buf
->writeByte(' ');
4563 buf
->writestring(Token::toChars(op
));
4564 buf
->writeByte(' ');
4565 expToCBuffer(buf
, hgs
, e2
, (enum PREC
)(precedence
[op
] + 1));
4568 int BinExp::isunsigned()
4570 return e1
->type
->isunsigned() || e2
->type
->isunsigned();
4573 void BinExp::incompatibleTypes()
4575 error("incompatible types for ((%s) %s (%s)): '%s' and '%s'",
4576 e1
->toChars(), Token::toChars(op
), e2
->toChars(),
4577 e1
->type
->toChars(), e2
->type
->toChars());
4580 /************************************************************/
4582 CompileExp::CompileExp(Loc loc
, Expression
*e
)
4583 : UnaExp(loc
, TOKmixin
, sizeof(CompileExp
), e
)
4587 Expression
*CompileExp::semantic(Scope
*sc
)
4590 printf("CompileExp::semantic('%s')\n", toChars());
4592 UnaExp::semantic(sc
);
4593 e1
= resolveProperties(sc
, e1
);
4594 e1
= e1
->optimize(WANTvalue
| WANTinterpret
);
4595 if (e1
->op
!= TOKstring
)
4596 { error("argument to mixin must be a string, not (%s)", e1
->toChars());
4597 type
= Type::terror
;
4600 StringExp
*se
= (StringExp
*)e1
;
4601 se
= se
->toUTF8(sc
);
4602 Parser
p(sc
->module
, (unsigned char *)se
->string
, se
->len
, 0);
4605 Expression
*e
= p
.parseExpression();
4606 if (p
.token
.value
!= TOKeof
)
4607 error("incomplete mixin expression (%s)", se
->toChars());
4608 return e
->semantic(sc
);
4611 void CompileExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
4613 buf
->writestring("mixin(");
4614 expToCBuffer(buf
, hgs
, e1
, PREC_assign
);
4615 buf
->writeByte(')');
4618 /************************************************************/
4620 FileExp::FileExp(Loc loc
, Expression
*e
)
4621 : UnaExp(loc
, TOKmixin
, sizeof(FileExp
), e
)
4625 Expression
*FileExp::semantic(Scope
*sc
)
4630 printf("FileExp::semantic('%s')\n", toChars());
4632 UnaExp::semantic(sc
);
4633 e1
= resolveProperties(sc
, e1
);
4634 e1
= e1
->optimize(WANTvalue
);
4635 if (e1
->op
!= TOKstring
)
4636 { error("file name argument must be a string, not (%s)", e1
->toChars());
4639 se
= (StringExp
*)e1
;
4640 se
= se
->toUTF8(sc
);
4641 name
= (char *)se
->string
;
4643 if (!global
.params
.fileImppath
)
4644 { error("need -Jpath switch to import text file %s", name
);
4648 if (name
!= FileName::name(name
))
4649 { error("use -Jpath switch to provide path for filename %s", name
);
4653 name
= FileName::searchPath(global
.filePath
, name
, 0);
4655 { error("file %s cannot be found, check -Jpath", se
->toChars());
4659 if (global
.params
.verbose
)
4660 printf("file %s\t(%s)\n", se
->string
, name
);
4664 { error("cannot read file %s", f
.toChars());
4670 se
= new StringExp(loc
, f
.buffer
, f
.len
);
4674 return se
->semantic(sc
);
4677 se
= new StringExp(loc
, "");
4681 void FileExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
4683 buf
->writestring("import(");
4684 expToCBuffer(buf
, hgs
, e1
, PREC_assign
);
4685 buf
->writeByte(')');
4688 /************************************************************/
4690 AssertExp::AssertExp(Loc loc
, Expression
*e
, Expression
*msg
)
4691 : UnaExp(loc
, TOKassert
, sizeof(AssertExp
), e
)
4696 Expression
*AssertExp::syntaxCopy()
4698 AssertExp
*ae
= new AssertExp(loc
, e1
->syntaxCopy(),
4699 msg
? msg
->syntaxCopy() : NULL
);
4703 Expression
*AssertExp::semantic(Scope
*sc
)
4706 printf("AssertExp::semantic('%s')\n", toChars());
4708 UnaExp::semantic(sc
);
4709 e1
= resolveProperties(sc
, e1
);
4710 // BUG: see if we can do compile time elimination of the Assert
4711 e1
= e1
->optimize(WANTvalue
);
4712 e1
= e1
->checkToBoolean();
4715 msg
= msg
->semantic(sc
);
4716 msg
= resolveProperties(sc
, msg
);
4717 msg
= msg
->implicitCastTo(sc
, Type::tchar
->arrayOf());
4718 msg
= msg
->optimize(WANTvalue
);
4720 if (e1
->isBool(FALSE
))
4722 FuncDeclaration
*fd
= sc
->parent
->isFuncDeclaration();
4723 fd
->hasReturnExp
|= 4;
4725 if (!global
.params
.useAssert
)
4726 { Expression
*e
= new HaltExp(loc
);
4727 e
= e
->semantic(sc
);
4735 int AssertExp::checkSideEffect(int flag
)
4740 void AssertExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
4742 buf
->writestring("assert(");
4743 expToCBuffer(buf
, hgs
, e1
, PREC_assign
);
4746 buf
->writeByte(',');
4747 expToCBuffer(buf
, hgs
, msg
, PREC_assign
);
4749 buf
->writeByte(')');
4752 /************************************************************/
4754 DotIdExp::DotIdExp(Loc loc
, Expression
*e
, Identifier
*ident
)
4755 : UnaExp(loc
, TOKdot
, sizeof(DotIdExp
), e
)
4757 this->ident
= ident
;
4760 Expression
*DotIdExp::semantic(Scope
*sc
)
4766 printf("DotIdExp::semantic(this = %p, '%s')\n", this, toChars());
4767 //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op));
4770 //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; }
4773 /* Don't do semantic analysis if we'll be converting
4776 if (ident
== Id::stringof
)
4777 { char *s
= e1
->toChars();
4778 e
= new StringExp(loc
, s
, strlen(s
), 'c');
4779 e
= e
->semantic(sc
);
4784 /* Special case: rewrite this.id and super.id
4785 * to be classtype.id and baseclasstype.id
4786 * if we have no this pointer.
4788 if ((e1
->op
== TOKthis
|| e1
->op
== TOKsuper
) && !hasThis(sc
))
4789 { ClassDeclaration
*cd
;
4790 StructDeclaration
*sd
;
4791 AggregateDeclaration
*ad
;
4793 ad
= sc
->getStructClassScope();
4796 cd
= ad
->isClassDeclaration();
4799 if (e1
->op
== TOKthis
)
4801 e
= new TypeDotIdExp(loc
, cd
->type
, ident
);
4802 return e
->semantic(sc
);
4804 else if (cd
->baseClass
&& e1
->op
== TOKsuper
)
4806 e
= new TypeDotIdExp(loc
, cd
->baseClass
->type
, ident
);
4807 return e
->semantic(sc
);
4812 sd
= ad
->isStructDeclaration();
4815 if (e1
->op
== TOKthis
)
4817 e
= new TypeDotIdExp(loc
, sd
->type
, ident
);
4818 return e
->semantic(sc
);
4825 UnaExp::semantic(sc
);
4827 if (e1
->op
== TOKdotexp
)
4829 DotExp
*de
= (DotExp
*)e1
;
4835 e1
= resolveProperties(sc
, e1
);
4840 if (e1
->op
== TOKtuple
&& ident
== Id::length
)
4842 TupleExp
*te
= (TupleExp
*)e1
;
4843 e
= new IntegerExp(loc
, te
->exps
->dim
, Type::tsize_t
);
4847 if (eright
->op
== TOKimport
) // also used for template alias's
4850 ScopeExp
*ie
= (ScopeExp
*)eright
;
4852 s
= ie
->sds
->search(loc
, ident
, 0);
4856 checkDeprecated(sc
, s
);
4858 EnumMember
*em
= s
->isEnumMember();
4862 e
= e
->semantic(sc
);
4866 VarDeclaration
*v
= s
->isVarDeclaration();
4869 //printf("DotIdExp:: Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
4872 error("circular reference to '%s'", v
->toChars());
4873 type
= Type::tint32
;
4881 ExpInitializer
*ei
= v
->init
->isExpInitializer();
4884 //printf("\tei: %p (%s)\n", ei->exp, ei->exp->toChars());
4885 //ei->exp = ei->exp->semantic(sc);
4886 if (ei
->exp
->type
== type
)
4888 e
= ei
->exp
->copy(); // make copy so we can change loc
4894 else if (type
->isscalar())
4896 e
= type
->defaultInit();
4904 eleft
= new ThisExp(loc
);
4905 e
= new DotVarExp(loc
, eleft
, v
);
4906 e
= e
->semantic(sc
);
4910 e
= new VarExp(loc
, v
);
4912 { e
= new CommaExp(loc
, eleft
, e
);
4919 FuncDeclaration
*f
= s
->isFuncDeclaration();
4922 //printf("it's a function\n");
4926 eleft
= new ThisExp(loc
);
4927 e
= new DotVarExp(loc
, eleft
, f
);
4928 e
= e
->semantic(sc
);
4932 e
= new VarExp(loc
, f
);
4934 { e
= new CommaExp(loc
, eleft
, e
);
4941 Type
*t
= s
->getType();
4944 return new TypeExp(loc
, t
);
4947 TupleDeclaration
*tup
= s
->isTupleDeclaration();
4951 error("cannot have e.tuple");
4952 e
= new TupleExp(loc
, tup
);
4953 e
= e
->semantic(sc
);
4957 ScopeDsymbol
*sds
= s
->isScopeDsymbol();
4960 //printf("it's a ScopeDsymbol\n");
4961 e
= new ScopeExp(loc
, sds
);
4962 e
= e
->semantic(sc
);
4964 e
= new DotExp(loc
, eleft
, e
);
4968 Import
*imp
= s
->isImport();
4973 ie
= new ScopeExp(loc
, imp
->pkg
);
4974 return ie
->semantic(sc
);
4977 // BUG: handle other cases like in IdentifierExp::semantic()
4979 printf("s = '%s', kind = '%s'\n", s
->toChars(), s
->kind());
4983 else if (ident
== Id::stringof
)
4984 { char *s
= ie
->toChars();
4985 e
= new StringExp(loc
, s
, strlen(s
), 'c');
4986 e
= e
->semantic(sc
);
4989 error("undefined identifier %s", toChars());
4993 else if (e1
->type
->ty
== Tpointer
&&
4994 ident
!= Id::init
&& ident
!= Id::__sizeof
&&
4995 ident
!= Id::alignof
&& ident
!= Id::offsetof
&&
4996 ident
!= Id::mangleof
&& ident
!= Id::stringof
)
4998 e
= new PtrExp(loc
, e1
);
4999 e
->type
= e1
->type
->next
;
5000 return e
->type
->dotExp(sc
, e
, ident
);
5004 e
= e1
->type
->dotExp(sc
, e1
, ident
);
5005 e
= e
->semantic(sc
);
5010 void DotIdExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
5012 //printf("DotIdExp::toCBuffer()\n");
5013 expToCBuffer(buf
, hgs
, e1
, PREC_primary
);
5014 buf
->writeByte('.');
5015 buf
->writestring(ident
->toChars());
5018 /********************** DotTemplateExp ***********************************/
5020 // Mainly just a placeholder
5022 DotTemplateExp::DotTemplateExp(Loc loc
, Expression
*e
, TemplateDeclaration
*td
)
5023 : UnaExp(loc
, TOKdottd
, sizeof(DotTemplateExp
), e
)
5029 void DotTemplateExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
5031 expToCBuffer(buf
, hgs
, e1
, PREC_primary
);
5032 buf
->writeByte('.');
5033 buf
->writestring(td
->toChars());
5037 /************************************************************/
5039 DotVarExp::DotVarExp(Loc loc
, Expression
*e
, Declaration
*v
)
5040 : UnaExp(loc
, TOKdotvar
, sizeof(DotVarExp
), e
)
5042 //printf("DotVarExp()\n");
5046 Expression
*DotVarExp::semantic(Scope
*sc
)
5049 printf("DotVarExp::semantic('%s')\n", toChars());
5053 var
= var
->toAlias()->isDeclaration();
5055 TupleDeclaration
*tup
= var
->isTupleDeclaration();
5060 * tuple(e1.a, e1.b, e1.c)
5062 Expressions
*exps
= new Expressions
;
5064 exps
->reserve(tup
->objects
->dim
);
5065 for (size_t i
= 0; i
< tup
->objects
->dim
; i
++)
5066 { Object
*o
= (Object
*)tup
->objects
->data
[i
];
5067 if (o
->dyncast() != DYNCAST_EXPRESSION
)
5069 error("%s is not an expression", o
->toChars());
5073 Expression
*e
= (Expression
*)o
;
5074 if (e
->op
!= TOKdsymbol
)
5075 error("%s is not a member", e
->toChars());
5077 { DsymbolExp
*ve
= (DsymbolExp
*)e
;
5079 e
= new DotVarExp(loc
, e1
, ve
->s
->isDeclaration());
5084 Expression
*e
= new TupleExp(loc
, exps
);
5085 e
= e
->semantic(sc
);
5089 e1
= e1
->semantic(sc
);
5091 if (!type
&& global
.errors
)
5092 { // var is goofed up, just return 0
5093 return new IntegerExp(0);
5097 if (!var
->isFuncDeclaration()) // for functions, do checks after overload resolution
5099 AggregateDeclaration
*ad
= var
->toParent()->isAggregateDeclaration();
5100 e1
= getRightThis(loc
, sc
, ad
, e1
, var
);
5101 accessCheck(loc
, sc
, e1
, var
);
5104 //printf("-DotVarExp::semantic('%s')\n", toChars());
5108 Expression
*DotVarExp::toLvalue(Scope
*sc
, Expression
*e
)
5110 //printf("DotVarExp::toLvalue(%s)\n", toChars());
5114 Expression
*DotVarExp::modifiableLvalue(Scope
*sc
, Expression
*e
)
5116 //printf("DotVarExp::modifiableLvalue(%s)\n", toChars());
5118 // Also need this for non-null fields.
5119 VarDeclaration
*v
= var
->isVarDeclaration();
5120 if (v
) // When is it not a VarDeclaration?
5123 error("Just curious");
5125 if (var
->isCtorinit())
5126 { // It's only modifiable if inside the right constructor
5127 Dsymbol
*s
= sc
->func
;
5130 FuncDeclaration
*fd
= NULL
;
5132 fd
= s
->isFuncDeclaration();
5134 ((fd
->isCtorDeclaration() && var
->storage_class
& STCfield
) ||
5135 (fd
->isStaticCtorDeclaration() && !(var
->storage_class
& STCfield
))) &&
5136 fd
->toParent() == var
->toParent() &&
5140 VarDeclaration
*v
= var
->isVarDeclaration();
5143 //printf("setting ctorinit\n");
5148 { s
= s
->toParent2();
5153 const char *p
= var
->isStatic() ? "static " : "";
5154 error("can only initialize %sconst member %s inside %sconstructor",
5155 p
, var
->toChars(), p
);
5164 void DotVarExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
5166 expToCBuffer(buf
, hgs
, e1
, PREC_primary
);
5167 buf
->writeByte('.');
5168 buf
->writestring(var
->toChars());
5171 /************************************************************/
5177 DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc
, Expression
*e
, TemplateInstance
*ti
)
5178 : UnaExp(loc
, TOKdotti
, sizeof(DotTemplateInstanceExp
), e
)
5180 //printf("DotTemplateInstanceExp()\n");
5184 Expression
*DotTemplateInstanceExp::syntaxCopy()
5186 DotTemplateInstanceExp
*de
= new DotTemplateInstanceExp(loc
,
5188 (TemplateInstance
*)ti
->syntaxCopy(NULL
));
5192 Expression
*DotTemplateInstanceExp::semantic(Scope
*sc
)
5195 TemplateDeclaration
*td
;
5199 Expression
*eleft
= NULL
;
5203 printf("DotTemplateInstanceExp::semantic('%s')\n", toChars());
5207 e1
= e1
->semantic(sc
);
5210 t1
= t1
->toBasetype();
5212 if (e1
->op
== TOKdotexp
)
5213 { DotExp
*de
= (DotExp
*)e1
;
5221 if (eright
->op
== TOKimport
)
5223 s
= ((ScopeExp
*)eright
)->sds
;
5225 else if (e1
->op
== TOKtype
)
5227 s
= t1
->isClassHandle();
5229 { if (t1
->ty
== Tstruct
)
5230 s
= ((TypeStruct
*)t1
)->sym
;
5235 else if (t1
&& (t1
->ty
== Tstruct
|| t1
->ty
== Tclass
))
5237 s
= t1
->toDsymbol(sc
);
5240 else if (t1
&& t1
->ty
== Tpointer
)
5242 t1
= t1
->next
->toBasetype();
5243 if (t1
->ty
!= Tstruct
)
5245 s
= t1
->toDsymbol(sc
);
5251 error("template %s is not a member of %s", ti
->toChars(), e1
->toChars());
5257 s2
= s
->search(loc
, id
, 0);
5259 { error("template identifier %s is not a member of %s %s", id
->toChars(), s
->kind(), s
->ident
->toChars());
5265 td
= s
->isTemplateDeclaration();
5268 error("%s is not a template", id
->toChars());
5280 s
= ti
->inst
->toAlias();
5281 v
= s
->isDeclaration();
5283 { e
= new DotVarExp(loc
, eleft
, v
);
5284 e
= e
->semantic(sc
);
5289 e
= new ScopeExp(loc
, ti
);
5292 e
= new DotExp(loc
, eleft
, e
);
5294 e
= e
->semantic(sc
);
5298 return new IntegerExp(0);
5301 void DotTemplateInstanceExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
5303 expToCBuffer(buf
, hgs
, e1
, PREC_primary
);
5304 buf
->writeByte('.');
5305 ti
->toCBuffer(buf
, hgs
);
5308 /************************************************************/
5310 DelegateExp::DelegateExp(Loc loc
, Expression
*e
, FuncDeclaration
*f
)
5311 : UnaExp(loc
, TOKdelegate
, sizeof(DelegateExp
), e
)
5316 Expression
*DelegateExp::semantic(Scope
*sc
)
5319 printf("DelegateExp::semantic('%s')\n", toChars());
5323 e1
= e1
->semantic(sc
);
5324 type
= new TypeDelegate(func
->type
);
5325 type
= type
->semantic(loc
, sc
);
5326 AggregateDeclaration
*ad
= func
->toParent()->isAggregateDeclaration();
5327 if (func
->needThis())
5328 e1
= getRightThis(loc
, sc
, ad
, e1
, func
);
5333 void DelegateExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
5335 buf
->writeByte('&');
5336 if (!func
->isNested())
5338 expToCBuffer(buf
, hgs
, e1
, PREC_primary
);
5339 buf
->writeByte('.');
5341 buf
->writestring(func
->toChars());
5344 /************************************************************/
5346 DotTypeExp::DotTypeExp(Loc loc
, Expression
*e
, Dsymbol
*s
)
5347 : UnaExp(loc
, TOKdottype
, sizeof(DotTypeExp
), e
)
5350 this->type
= s
->getType();
5353 Expression
*DotTypeExp::semantic(Scope
*sc
)
5356 printf("DotTypeExp::semantic('%s')\n", toChars());
5358 UnaExp::semantic(sc
);
5362 void DotTypeExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
5364 expToCBuffer(buf
, hgs
, e1
, PREC_primary
);
5365 buf
->writeByte('.');
5366 buf
->writestring(sym
->toChars());
5369 /************************************************************/
5371 CallExp::CallExp(Loc loc
, Expression
*e
, Expressions
*exps
)
5372 : UnaExp(loc
, TOKcall
, sizeof(CallExp
), e
)
5374 this->arguments
= exps
;
5377 CallExp::CallExp(Loc loc
, Expression
*e
)
5378 : UnaExp(loc
, TOKcall
, sizeof(CallExp
), e
)
5380 this->arguments
= NULL
;
5383 CallExp::CallExp(Loc loc
, Expression
*e
, Expression
*earg1
)
5384 : UnaExp(loc
, TOKcall
, sizeof(CallExp
), e
)
5386 Expressions
*arguments
= new Expressions();
5387 arguments
->setDim(1);
5388 arguments
->data
[0] = (void *)earg1
;
5390 this->arguments
= arguments
;
5393 CallExp::CallExp(Loc loc
, Expression
*e
, Expression
*earg1
, Expression
*earg2
)
5394 : UnaExp(loc
, TOKcall
, sizeof(CallExp
), e
)
5396 Expressions
*arguments
= new Expressions();
5397 arguments
->setDim(2);
5398 arguments
->data
[0] = (void *)earg1
;
5399 arguments
->data
[1] = (void *)earg2
;
5401 this->arguments
= arguments
;
5404 Expression
*CallExp::syntaxCopy()
5406 return new CallExp(loc
, e1
->syntaxCopy(), arraySyntaxCopy(arguments
));
5410 Expression
*CallExp::semantic(Scope
*sc
)
5419 printf("CallExp::semantic() %s\n", toChars());
5422 return this; // semantic() already run
5424 if (arguments
&& arguments
->dim
)
5426 Expression
*earg
= (Expression
*)arguments
->data
[0];
5428 if (earg
->type
) earg
->type
->print();
5432 if (e1
->op
== TOKdelegate
)
5433 { DelegateExp
*de
= (DelegateExp
*)e1
;
5435 e1
= new DotVarExp(de
->loc
, de
->e1
, de
->func
);
5436 return semantic(sc
);
5440 * array.id(args) into id(array,args)
5441 * aa.remove(arg) into delete aa[arg]
5443 if (e1
->op
== TOKdot
)
5445 // BUG: we should handle array.a.b.c.e(args) too
5447 DotIdExp
*dotid
= (DotIdExp
*)(e1
);
5448 dotid
->e1
= dotid
->e1
->semantic(sc
);
5450 if (dotid
->e1
->type
)
5452 TY e1ty
= dotid
->e1
->type
->toBasetype()->ty
;
5453 if (e1ty
== Taarray
&& dotid
->ident
== Id::remove
)
5455 if (!arguments
|| arguments
->dim
!= 1)
5456 { error("expected key as argument to aa.remove()");
5459 Expression
*key
= (Expression
*)arguments
->data
[0];
5460 key
= key
->semantic(sc
);
5461 key
= resolveProperties(sc
, key
);
5464 TypeAArray
*taa
= (TypeAArray
*)dotid
->e1
->type
->toBasetype();
5465 key
= key
->implicitCastTo(sc
, taa
->index
);
5466 key
= key
->implicitCastTo(sc
, taa
->key
);
5468 return new RemoveExp(loc
, dotid
->e1
, key
);
5470 else if (e1ty
== Tarray
|| e1ty
== Tsarray
|| e1ty
== Taarray
)
5473 arguments
= new Expressions();
5474 arguments
->shift(dotid
->e1
);
5475 e1
= new IdentifierExp(dotid
->loc
, dotid
->ident
);
5483 if (e1
->op
== TOKthis
|| e1
->op
== TOKsuper
)
5485 // semantic() run later for these
5489 UnaExp::semantic(sc
);
5491 /* Look for e1 being a lazy parameter
5493 if (e1
->op
== TOKvar
)
5494 { VarExp
*ve
= (VarExp
*)e1
;
5496 if (ve
->var
->storage_class
& STClazy
)
5498 TypeFunction
*tf
= new TypeFunction(NULL
, ve
->var
->type
, 0, LINKd
);
5499 TypeDelegate
*t
= new TypeDelegate(tf
);
5500 ve
->type
= t
->semantic(loc
, sc
);
5504 if (e1
->op
== TOKimport
)
5505 { // Perhaps this should be moved to ScopeExp::semantic()
5506 ScopeExp
*se
= (ScopeExp
*)e1
;
5507 e1
= new DsymbolExp(loc
, se
->sds
);
5508 e1
= e1
->semantic(sc
);
5510 #if 1 // patch for #540 by Oskar Linde
5511 else if (e1
->op
== TOKdotexp
)
5513 DotExp
*de
= (DotExp
*) e1
;
5515 if (de
->e2
->op
== TOKimport
)
5516 { // This should *really* be moved to ScopeExp::semantic()
5517 ScopeExp
*se
= (ScopeExp
*)de
->e2
;
5518 de
->e2
= new DsymbolExp(loc
, se
->sds
);
5519 de
->e2
= de
->e2
->semantic(sc
);
5522 if (de
->e2
->op
== TOKtemplate
)
5523 { TemplateExp
*te
= (TemplateExp
*) de
->e2
;
5524 e1
= new DotTemplateExp(loc
,de
->e1
,te
->td
);
5530 if (e1
->op
== TOKcomma
)
5532 CommaExp
*ce
= (CommaExp
*)e1
;
5535 e1
->type
= ce
->type
;
5538 return ce
->semantic(sc
);
5543 t1
= e1
->type
->toBasetype();
5545 // Check for call operator overload
5547 { AggregateDeclaration
*ad
;
5549 if (t1
->ty
== Tstruct
)
5551 ad
= ((TypeStruct
*)t1
)->sym
;
5552 if (search_function(ad
, Id::call
))
5553 goto L1
; // overload of opCall, therefore it's a call
5555 if (e1
->op
!= TOKtype
)
5556 error("%s %s does not overload ()", ad
->kind(), ad
->toChars());
5557 /* It's a struct literal
5559 Expression
*e
= new StructLiteralExp(loc
, (StructDeclaration
*)ad
, arguments
);
5560 e
= e
->semantic(sc
);
5561 e
->type
= e1
->type
; // in case e1->type was a typedef
5564 else if (t1
->ty
== Tclass
)
5566 ad
= ((TypeClass
*)t1
)->sym
;
5569 // Rewrite as e1.call(arguments)
5570 Expression
*e
= new DotIdExp(loc
, e1
, Id::call
);
5571 e
= new CallExp(loc
, e
, arguments
);
5572 e
= e
->semantic(sc
);
5577 arrayExpressionSemantic(arguments
, sc
);
5578 preFunctionArguments(loc
, sc
, arguments
);
5580 if (e1
->op
== TOKdotvar
&& t1
->ty
== Tfunction
||
5584 DotTemplateExp
*dte
;
5585 AggregateDeclaration
*ad
;
5586 UnaExp
*ue
= (UnaExp
*)(e1
);
5588 if (e1
->op
== TOKdotvar
)
5589 { // Do overload resolution
5590 dve
= (DotVarExp
*)(e1
);
5592 f
= dve
->var
->isFuncDeclaration();
5594 f
= f
->overloadResolve(loc
, arguments
);
5596 ad
= f
->toParent()->isAggregateDeclaration();
5599 { dte
= (DotTemplateExp
*)(e1
);
5600 TemplateDeclaration
*td
= dte
->td
;
5603 // Should fix deduceFunctionTemplate() so it works on NULL argument
5604 arguments
= new Expressions();
5605 f
= td
->deduceFunctionTemplate(sc
, loc
, NULL
, arguments
);
5607 { type
= Type::terror
;
5610 ad
= td
->toParent()->isAggregateDeclaration();
5613 ue
->e1
= getRightThis(loc
, sc
, ad
, ue
->e1
, f
);
5615 checkDeprecated(sc
, f
);
5616 accessCheck(loc
, sc
, ue
->e1
, f
);
5619 VarExp
*ve
= new VarExp(loc
, f
);
5620 e1
= new CommaExp(loc
, ue
->e1
, ve
);
5625 if (e1
->op
== TOKdotvar
)
5628 e1
= new DotVarExp(loc
, dte
->e1
, f
);
5631 // See if we need to adjust the 'this' pointer
5632 AggregateDeclaration
*ad
= f
->isThis();
5633 ClassDeclaration
*cd
= ue
->e1
->type
->isClassHandle();
5634 if (ad
&& cd
&& ad
->isClassDeclaration() && ad
!= cd
&&
5635 ue
->e1
->op
!= TOKsuper
)
5637 ue
->e1
= ue
->e1
->castTo(sc
, ad
->type
); //new CastExp(loc, ue->e1, ad->type);
5638 ue
->e1
= ue
->e1
->semantic(sc
);
5643 else if (e1
->op
== TOKsuper
)
5645 // Base class constructor call
5646 ClassDeclaration
*cd
= NULL
;
5649 cd
= sc
->func
->toParent()->isClassDeclaration();
5650 if (!cd
|| !cd
->baseClass
|| !sc
->func
->isCtorDeclaration())
5652 error("super class constructor call must be in a constructor");
5653 type
= Type::terror
;
5658 f
= cd
->baseClass
->ctor
;
5660 { error("no super class constructor for %s", cd
->baseClass
->toChars());
5661 type
= Type::terror
;
5667 if (sc
->callSuper
& (CSXthis
| CSXsuper
))
5668 error("reference to this before super()");
5670 if (sc
->noctor
|| sc
->callSuper
& CSXlabel
)
5671 error("constructor calls not allowed in loops or after labels");
5672 if (sc
->callSuper
& (CSXsuper_ctor
| CSXthis_ctor
))
5673 error("multiple constructor calls");
5674 sc
->callSuper
|= CSXany_ctor
| CSXsuper_ctor
;
5676 f
= f
->overloadResolve(loc
, arguments
);
5677 checkDeprecated(sc
, f
);
5678 e1
= new DotVarExp(e1
->loc
, e1
, f
);
5679 e1
= e1
->semantic(sc
);
5684 else if (e1
->op
== TOKthis
)
5686 // same class constructor call
5687 ClassDeclaration
*cd
= NULL
;
5690 cd
= sc
->func
->toParent()->isClassDeclaration();
5691 if (!cd
|| !sc
->func
->isCtorDeclaration())
5693 error("class constructor call must be in a constructor");
5694 type
= Type::terror
;
5700 if (sc
->callSuper
& (CSXthis
| CSXsuper
))
5701 error("reference to this before super()");
5703 if (sc
->noctor
|| sc
->callSuper
& CSXlabel
)
5704 error("constructor calls not allowed in loops or after labels");
5705 if (sc
->callSuper
& (CSXsuper_ctor
| CSXthis_ctor
))
5706 error("multiple constructor calls");
5707 sc
->callSuper
|= CSXany_ctor
| CSXthis_ctor
;
5710 f
= f
->overloadResolve(loc
, arguments
);
5711 checkDeprecated(sc
, f
);
5712 e1
= new DotVarExp(e1
->loc
, e1
, f
);
5713 e1
= e1
->semantic(sc
);
5716 // BUG: this should really be done by checking the static
5719 error("cyclic constructor call");
5724 error("function expected before (), not '%s'", e1
->toChars());
5725 type
= Type::terror
;
5728 else if (t1
->ty
!= Tfunction
)
5730 if (t1
->ty
== Tdelegate
)
5732 assert(t1
->next
->ty
== Tfunction
);
5733 tf
= (TypeFunction
*)(t1
->next
);
5736 else if (t1
->ty
== Tpointer
&& t1
->next
->ty
== Tfunction
)
5739 e
= new PtrExp(loc
, e1
);
5744 else if (e1
->op
== TOKtemplate
)
5746 TemplateExp
*te
= (TemplateExp
*)e1
;
5747 f
= te
->td
->deduceFunctionTemplate(sc
, loc
, NULL
, arguments
);
5749 { type
= Type::terror
;
5752 if (f
->needThis() && hasThis(sc
))
5754 // Supply an implicit 'this', as in
5757 e1
= new DotTemplateExp(loc
, (new ThisExp(loc
))->semantic(sc
), te
->td
);
5761 e1
= new VarExp(loc
, f
);
5765 { error("function expected before (), not %s of type %s", e1
->toChars(), e1
->type
->toChars());
5766 type
= Type::terror
;
5770 else if (e1
->op
== TOKvar
)
5772 // Do overload resolution
5773 VarExp
*ve
= (VarExp
*)e1
;
5775 f
= ve
->var
->isFuncDeclaration();
5778 // Look to see if f is really a function template
5779 if (0 && !istemp
&& f
->parent
)
5780 { TemplateInstance
*ti
= f
->parent
->isTemplateInstance();
5783 (ti
->name
== f
->ident
||
5784 ti
->toAlias()->ident
== f
->ident
)
5788 /* This is so that one can refer to the enclosing
5789 * template, even if it has the same name as a member
5790 * of the template, if it has a !(arguments)
5792 TemplateDeclaration
*tempdecl
= ti
->tempdecl
;
5793 if (tempdecl
->overroot
) // if not start of overloaded list of TemplateDeclaration's
5794 tempdecl
= tempdecl
->overroot
; // then get the start
5795 e1
= new TemplateExp(loc
, tempdecl
);
5801 f
= f
->overloadResolve(loc
, arguments
);
5802 checkDeprecated(sc
, f
);
5804 if (f
->needThis() && hasThis(sc
))
5806 // Supply an implicit 'this', as in
5809 e1
= new DotVarExp(loc
, new ThisExp(loc
), f
);
5813 accessCheck(loc
, sc
, NULL
, f
);
5819 assert(t1
->ty
== Tfunction
);
5820 tf
= (TypeFunction
*)(t1
);
5823 assert(tf
->ty
== Tfunction
);
5827 arguments
= new Expressions();
5828 functionArguments(loc
, sc
, tf
, arguments
);
5835 target_ptrdiff_t offset
= 0;
5837 if (f
->tintro
->next
->isBaseOf(t
, &offset
) && offset
)
5839 type
= f
->tintro
->next
;
5840 return castTo(sc
, t
);
5847 int CallExp::checkSideEffect(int flag
)
5852 Expression
*CallExp::toLvalue(Scope
*sc
, Expression
*e
)
5854 if (type
->toBasetype()->ty
== Tstruct
)
5857 return Expression::toLvalue(sc
, e
);
5860 void CallExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
5863 expToCBuffer(buf
, hgs
, e1
, precedence
[op
]);
5864 buf
->writeByte('(');
5865 argsToCBuffer(buf
, arguments
, hgs
);
5866 buf
->writeByte(')');
5870 /************************************************************/
5872 AddrExp::AddrExp(Loc loc
, Expression
*e
)
5873 : UnaExp(loc
, TOKaddress
, sizeof(AddrExp
), e
)
5877 Expression
*AddrExp::semantic(Scope
*sc
)
5880 printf("AddrExp::semantic('%s')\n", toChars());
5884 UnaExp::semantic(sc
);
5885 e1
= e1
->toLvalue(sc
, NULL
);
5888 error("cannot take address of %s", e1
->toChars());
5889 type
= Type::tint32
;
5892 type
= e1
->type
->pointerTo();
5894 // See if this should really be a delegate
5895 if (e1
->op
== TOKdotvar
)
5897 DotVarExp
*dve
= (DotVarExp
*)e1
;
5898 FuncDeclaration
*f
= dve
->var
->isFuncDeclaration();
5903 e
= new DelegateExp(loc
, dve
->e1
, f
);
5904 e
= e
->semantic(sc
);
5908 else if (e1
->op
== TOKvar
)
5910 VarExp
*dve
= (VarExp
*)e1
;
5911 FuncDeclaration
*f
= dve
->var
->isFuncDeclaration();
5913 if (f
&& f
->isNested())
5916 e
= new DelegateExp(loc
, e1
, f
);
5917 e
= e
->semantic(sc
);
5921 else if (e1
->op
== TOKarray
)
5923 if (e1
->type
->toBasetype()->ty
== Tbit
)
5924 error("cannot take address of bit in array");
5926 return optimize(WANTvalue
);
5931 /************************************************************/
5933 PtrExp::PtrExp(Loc loc
, Expression
*e
)
5934 : UnaExp(loc
, TOKstar
, sizeof(PtrExp
), e
)
5937 type
= e
->type
->next
;
5940 PtrExp::PtrExp(Loc loc
, Expression
*e
, Type
*t
)
5941 : UnaExp(loc
, TOKstar
, sizeof(PtrExp
), e
)
5946 Expression
*PtrExp::semantic(Scope
*sc
)
5950 printf("PtrExp::semantic('%s')\n", toChars());
5952 UnaExp::semantic(sc
);
5953 e1
= resolveProperties(sc
, e1
);
5957 printf("PtrExp::semantic('%s')\n", toChars());
5958 tb
= e1
->type
->toBasetype();
5966 // Rewrite *p as p[0]
5967 e
= new IndexExp(loc
, e1
, new IntegerExp(0));
5968 return e
->semantic(sc
);
5975 e1
= e1
->castTo(sc
, type
->pointerTo());
5979 error("can only * a pointer, not a '%s'", e1
->type
->toChars());
5980 type
= Type::tint32
;
5987 Expression
*PtrExp::toLvalue(Scope
*sc
, Expression
*e
)
5990 tym
= tybasic(e1
->ET
->Tty
);
5991 if (!(tyscalar(tym
) ||
5993 tym
== TYarray
&& e
->Eoper
== TOKaddr
))
5994 synerr(EM_lvalue
); // lvalue expected
5999 void PtrExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
6001 buf
->writeByte('*');
6002 expToCBuffer(buf
, hgs
, e1
, precedence
[op
]);
6005 /************************************************************/
6007 NegExp::NegExp(Loc loc
, Expression
*e
)
6008 : UnaExp(loc
, TOKneg
, sizeof(NegExp
), e
)
6012 Expression
*NegExp::semantic(Scope
*sc
)
6016 printf("NegExp::semantic('%s')\n", toChars());
6020 UnaExp::semantic(sc
);
6021 e1
= resolveProperties(sc
, e1
);
6022 e
= op_overload(sc
);
6027 e1
->checkArithmetic();
6033 /************************************************************/
6035 UAddExp::UAddExp(Loc loc
, Expression
*e
)
6036 : UnaExp(loc
, TOKuadd
, sizeof(UAddExp
), e
)
6040 Expression
*UAddExp::semantic(Scope
*sc
)
6044 printf("UAddExp::semantic('%s')\n", toChars());
6047 UnaExp::semantic(sc
);
6048 e1
= resolveProperties(sc
, e1
);
6049 e
= op_overload(sc
);
6053 e1
->checkArithmetic();
6057 /************************************************************/
6059 ComExp::ComExp(Loc loc
, Expression
*e
)
6060 : UnaExp(loc
, TOKtilde
, sizeof(ComExp
), e
)
6064 Expression
*ComExp::semantic(Scope
*sc
)
6069 UnaExp::semantic(sc
);
6070 e1
= resolveProperties(sc
, e1
);
6071 e
= op_overload(sc
);
6076 e1
= e1
->checkIntegral();
6082 /************************************************************/
6084 NotExp::NotExp(Loc loc
, Expression
*e
)
6085 : UnaExp(loc
, TOKnot
, sizeof(NotExp
), e
)
6089 Expression
*NotExp::semantic(Scope
*sc
)
6091 UnaExp::semantic(sc
);
6092 e1
= resolveProperties(sc
, e1
);
6093 e1
= e1
->checkToBoolean();
6094 type
= Type::tboolean
;
6105 /************************************************************/
6107 BoolExp::BoolExp(Loc loc
, Expression
*e
, Type
*t
)
6108 : UnaExp(loc
, TOKtobool
, sizeof(BoolExp
), e
)
6113 Expression
*BoolExp::semantic(Scope
*sc
)
6115 UnaExp::semantic(sc
);
6116 e1
= resolveProperties(sc
, e1
);
6117 e1
= e1
->checkToBoolean();
6118 type
= Type::tboolean
;
6122 int BoolExp::isBit()
6127 /************************************************************/
6129 DeleteExp::DeleteExp(Loc loc
, Expression
*e
)
6130 : UnaExp(loc
, TOKdelete
, sizeof(DeleteExp
), e
)
6134 Expression
*DeleteExp::semantic(Scope
*sc
)
6138 UnaExp::semantic(sc
);
6139 e1
= resolveProperties(sc
, e1
);
6140 e1
= e1
->toLvalue(sc
, NULL
);
6143 tb
= e1
->type
->toBasetype();
6146 { TypeClass
*tc
= (TypeClass
*)tb
;
6147 ClassDeclaration
*cd
= tc
->sym
;
6149 if (cd
->isCOMinterface())
6150 { /* Because COM classes are deleted by IUnknown.Release()
6152 error("cannot delete instance of COM interface %s", cd
->toChars());
6157 tb
= tb
->next
->toBasetype();
6158 if (tb
->ty
== Tstruct
)
6160 TypeStruct
*ts
= (TypeStruct
*)tb
;
6161 StructDeclaration
*sd
= ts
->sym
;
6162 FuncDeclaration
*f
= sd
->aggDelete
;
6166 Type
*tpv
= Type::tvoid
->pointerTo();
6168 Expression
*e
= e1
->castTo(sc
, tpv
);
6169 Expression
*ec
= new VarExp(loc
, f
);
6170 e
= new CallExp(loc
, ec
, e
);
6171 return e
->semantic(sc
);
6180 if (e1
->op
== TOKindex
)
6182 IndexExp
*ae
= (IndexExp
*)(e1
);
6183 Type
*tb1
= ae
->e1
->type
->toBasetype();
6184 if (tb1
->ty
== Taarray
)
6187 error("cannot delete type %s", e1
->type
->toChars());
6191 if (e1
->op
== TOKindex
)
6193 IndexExp
*ae
= (IndexExp
*)(e1
);
6194 Type
*tb1
= ae
->e1
->type
->toBasetype();
6195 if (tb1
->ty
== Taarray
)
6196 { if (!global
.params
.useDeprecated
)
6197 error("delete aa[key] deprecated, use aa.remove(key)");
6204 int DeleteExp::checkSideEffect(int flag
)
6209 Expression
*DeleteExp::checkToBoolean()
6211 error("delete does not give a boolean result");
6215 void DeleteExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
6217 buf
->writestring("delete ");
6218 expToCBuffer(buf
, hgs
, e1
, precedence
[op
]);
6221 /************************************************************/
6223 CastExp::CastExp(Loc loc
, Expression
*e
, Type
*t
)
6224 : UnaExp(loc
, TOKcast
, sizeof(CastExp
), e
)
6229 Expression
*CastExp::syntaxCopy()
6231 return new CastExp(loc
, e1
->syntaxCopy(), to
->syntaxCopy());
6235 Expression
*CastExp::semantic(Scope
*sc
)
6241 printf("CastExp::semantic('%s')\n", toChars());
6244 //static int x; assert(++x < 10);
6248 UnaExp::semantic(sc
);
6249 if (e1
->type
) // if not a tuple
6251 e1
= resolveProperties(sc
, e1
);
6252 to
= to
->semantic(loc
, sc
);
6254 e
= op_overload(sc
);
6257 return e
->implicitCastTo(sc
, to
);
6260 Type
*tob
= to
->toBasetype();
6261 if (tob
->ty
== Tstruct
&&
6262 !tob
->equals(e1
->type
->toBasetype()) &&
6263 ((TypeStruct
*)to
)->sym
->search(0, Id::call
, 0)
6272 // Rewrite as to.call(e1)
6273 e
= new TypeExp(loc
, to
);
6274 e
= new DotIdExp(loc
, e
, Id::call
);
6275 e
= new CallExp(loc
, e
, e1
);
6276 e
= e
->semantic(sc
);
6280 e
= e1
->castTo(sc
, to
->maybe());
6284 int CastExp::checkSideEffect(int flag
)
6288 * cast(classtype)func()
6290 if (!to
->equals(Type::tvoid
) &&
6291 !(to
->ty
== Tclass
&& e1
->op
== TOKcall
&& e1
->type
->ty
== Tclass
))
6292 return Expression::checkSideEffect(flag
);
6296 void CastExp::checkEscape()
6297 { Type
*tb
= type
->toBasetype();
6298 if (tb
->ty
== Tarray
&& e1
->op
== TOKvar
&&
6299 e1
->type
->toBasetype()->ty
== Tsarray
)
6300 { VarExp
*ve
= (VarExp
*)e1
;
6301 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
6304 if (!v
->isDataseg() && !v
->isParameter())
6305 error("escaping reference to local %s", v
->toChars());
6310 void CastExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
6312 buf
->writestring("cast(");
6313 to
->toCBuffer(buf
, NULL
, hgs
);
6314 buf
->writeByte(')');
6315 expToCBuffer(buf
, hgs
, e1
, precedence
[op
]);
6319 /************************************************************/
6321 SliceExp::SliceExp(Loc loc
, Expression
*e1
, Expression
*lwr
, Expression
*upr
)
6322 : UnaExp(loc
, TOKslice
, sizeof(SliceExp
), e1
)
6329 Expression
*SliceExp::syntaxCopy()
6331 Expression
*lwr
= NULL
;
6333 lwr
= this->lwr
->syntaxCopy();
6335 Expression
*upr
= NULL
;
6337 upr
= this->upr
->syntaxCopy();
6339 return new SliceExp(loc
, e1
->syntaxCopy(), lwr
, upr
);
6342 Expression
*SliceExp::semantic(Scope
*sc
)
6344 AggregateDeclaration
*ad
;
6345 //FuncDeclaration *fd;
6349 printf("SliceExp::semantic('%s')\n", toChars());
6354 UnaExp::semantic(sc
);
6355 e1
= resolveProperties(sc
, e1
);
6359 Type
*t
= e1
->type
->toBasetype();
6360 if (t
->ty
== Tpointer
)
6363 error("need upper and lower bound to slice pointer");
6365 else if (t
->ty
== Tarray
)
6368 else if (t
->ty
== Tsarray
)
6371 else if (t
->ty
== Tclass
)
6373 ad
= ((TypeClass
*)t
)->sym
;
6376 else if (t
->ty
== Tstruct
)
6378 ad
= ((TypeStruct
*)t
)->sym
;
6381 if (search_function(ad
, Id::slice
))
6383 // Rewrite as e1.slice(lwr, upr)
6384 e
= new DotIdExp(loc
, e1
, Id::slice
);
6389 e
= new CallExp(loc
, e
, lwr
, upr
);
6393 e
= new CallExp(loc
, e
);
6395 e
= e
->semantic(sc
);
6400 else if (t
->ty
== Ttuple
)
6405 { error("need upper and lower bound to slice tuple");
6412 if (t
->ty
== Tsarray
|| t
->ty
== Tarray
|| t
->ty
== Ttuple
)
6414 sym
= new ArrayScopeSymbol(this);
6416 sym
->parent
= sc
->scopesym
;
6421 { lwr
= lwr
->semantic(sc
);
6422 lwr
= resolveProperties(sc
, lwr
);
6423 lwr
= lwr
->implicitCastTo(sc
, Type::tsize_t
);
6426 { upr
= upr
->semantic(sc
);
6427 upr
= resolveProperties(sc
, upr
);
6428 upr
= upr
->implicitCastTo(sc
, Type::tsize_t
);
6431 if (t
->ty
== Tsarray
|| t
->ty
== Tarray
|| t
->ty
== Ttuple
)
6434 if (t
->ty
== Ttuple
)
6436 lwr
= lwr
->optimize(WANTvalue
);
6437 upr
= upr
->optimize(WANTvalue
);
6438 uinteger_t i1
= lwr
->toUInteger();
6439 uinteger_t i2
= upr
->toUInteger();
6445 if (e1
->op
== TOKtuple
) // slicing an expression tuple
6446 { te
= (TupleExp
*)e1
;
6447 length
= te
->exps
->dim
;
6449 else if (e1
->op
== TOKtype
) // slicing a type tuple
6450 { tup
= (TypeTuple
*)t
;
6451 length
= Argument::dim(tup
->arguments
);
6456 if (i1
<= i2
&& i2
<= length
)
6457 { size_t j1
= (size_t) i1
;
6458 size_t j2
= (size_t) i2
;
6460 if (e1
->op
== TOKtuple
)
6461 { Expressions
*exps
= new Expressions
;
6462 exps
->setDim(j2
- j1
);
6463 for (size_t i
= 0; i
< j2
- j1
; i
++)
6464 { Expression
*e
= (Expression
*)te
->exps
->data
[j1
+ i
];
6465 exps
->data
[i
] = (void *)e
;
6467 e
= new TupleExp(loc
, exps
);
6470 { Arguments
*args
= new Arguments
;
6471 args
->reserve(j2
- j1
);
6472 for (size_t i
= j1
; i
< j2
; i
++)
6473 { Argument
*arg
= Argument::getNth(tup
->arguments
, i
);
6476 e
= new TypeExp(e1
->loc
, new TypeTuple(args
));
6478 e
= e
->semantic(sc
);
6482 error("string slice [%"PRIuMAX
" .. %"PRIuMAX
"] is out of bounds", i1
, i2
);
6488 type
= t
->next
->arrayOf();
6497 error("%s cannot be sliced with []", s
);
6498 type
= Type::terror
;
6502 void SliceExp::checkEscape()
6507 Expression
*SliceExp::toLvalue(Scope
*sc
, Expression
*e
)
6512 Expression
*SliceExp::modifiableLvalue(Scope
*sc
, Expression
*e
)
6514 error("slice expression %s is not a modifiable lvalue", toChars());
6518 void SliceExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
6520 expToCBuffer(buf
, hgs
, e1
, precedence
[op
]);
6521 buf
->writeByte('[');
6525 expToCBuffer(buf
, hgs
, lwr
, PREC_assign
);
6527 buf
->writeByte('0');
6528 buf
->writestring("..");
6530 expToCBuffer(buf
, hgs
, upr
, PREC_assign
);
6532 buf
->writestring("length"); // BUG: should be array.length
6534 buf
->writeByte(']');
6537 /********************** ArrayLength **************************************/
6539 ArrayLengthExp::ArrayLengthExp(Loc loc
, Expression
*e1
)
6540 : UnaExp(loc
, TOKarraylength
, sizeof(ArrayLengthExp
), e1
)
6544 Expression
*ArrayLengthExp::semantic(Scope
*sc
)
6548 printf("ArrayLengthExp::semantic('%s')\n", toChars());
6552 UnaExp::semantic(sc
);
6553 e1
= resolveProperties(sc
, e1
);
6555 type
= Type::tsize_t
;
6560 void ArrayLengthExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
6562 expToCBuffer(buf
, hgs
, e1
, PREC_primary
);
6563 buf
->writestring(".length");
6566 /*********************** ArrayExp *************************************/
6568 // e1 [ i1, i2, i3, ... ]
6570 ArrayExp::ArrayExp(Loc loc
, Expression
*e1
, Expressions
*args
)
6571 : UnaExp(loc
, TOKarray
, sizeof(ArrayExp
), e1
)
6576 Expression
*ArrayExp::syntaxCopy()
6578 return new ArrayExp(loc
, e1
->syntaxCopy(), arraySyntaxCopy(arguments
));
6581 Expression
*ArrayExp::semantic(Scope
*sc
)
6586 printf("ArrayExp::semantic('%s')\n", toChars());
6588 UnaExp::semantic(sc
);
6589 e1
= resolveProperties(sc
, e1
);
6591 t1
= e1
->type
->toBasetype();
6592 if (t1
->ty
!= Tclass
&& t1
->ty
!= Tstruct
)
6593 { // Convert to IndexExp
6594 if (arguments
->dim
!= 1)
6595 error("only one index allowed to index %s", t1
->toChars());
6596 e
= new IndexExp(loc
, e1
, (Expression
*)arguments
->data
[0]);
6597 return e
->semantic(sc
);
6600 // Run semantic() on each argument
6601 for (size_t i
= 0; i
< arguments
->dim
; i
++)
6602 { e
= (Expression
*)arguments
->data
[i
];
6604 e
= e
->semantic(sc
);
6606 error("%s has no value", e
->toChars());
6607 arguments
->data
[i
] = (void *)e
;
6610 expandTuples(arguments
);
6611 assert(arguments
&& arguments
->dim
);
6613 e
= op_overload(sc
);
6615 { error("no [] operator overload for type %s", e1
->type
->toChars());
6622 Expression
*ArrayExp::toLvalue(Scope
*sc
, Expression
*e
)
6624 if (type
&& type
->toBasetype()->ty
== Tvoid
)
6625 error("voids have no value");
6630 void ArrayExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
6633 expToCBuffer(buf
, hgs
, e1
, PREC_primary
);
6634 buf
->writeByte('[');
6635 argsToCBuffer(buf
, arguments
, hgs
);
6636 buf
->writeByte(']');
6639 /************************* DotExp ***********************************/
6641 DotExp::DotExp(Loc loc
, Expression
*e1
, Expression
*e2
)
6642 : BinExp(loc
, TOKdotexp
, sizeof(DotExp
), e1
, e2
)
6646 Expression
*DotExp::semantic(Scope
*sc
)
6649 printf("DotExp::semantic('%s')\n", toChars());
6650 if (type
) printf("\ttype = %s\n", type
->toChars());
6652 e1
= e1
->semantic(sc
);
6653 e2
= e2
->semantic(sc
);
6654 if (e2
->op
== TOKimport
)
6656 ScopeExp
*se
= (ScopeExp
*)e2
;
6657 TemplateDeclaration
*td
= se
->sds
->isTemplateDeclaration();
6659 { Expression
*e
= new DotTemplateExp(loc
, e1
, td
);
6660 e
= e
->semantic(sc
);
6670 /************************* CommaExp ***********************************/
6672 CommaExp::CommaExp(Loc loc
, Expression
*e1
, Expression
*e2
)
6673 : BinExp(loc
, TOKcomma
, sizeof(CommaExp
), e1
, e2
)
6677 Expression
*CommaExp::semantic(Scope
*sc
)
6680 { BinExp::semanticp(sc
);
6686 void CommaExp::checkEscape()
6691 Expression
*CommaExp::toLvalue(Scope
*sc
, Expression
*e
)
6693 e2
= e2
->toLvalue(sc
, NULL
);
6697 Expression
*CommaExp::modifiableLvalue(Scope
*sc
, Expression
*e
)
6699 e2
= e2
->modifiableLvalue(sc
, e
);
6703 int CommaExp::isBool(int result
)
6705 return e2
->isBool(result
);
6708 int CommaExp::checkSideEffect(int flag
)
6711 return e1
->checkSideEffect(2) || e2
->checkSideEffect(2);
6714 // Don't check e1 until we cast(void) the a,b code generation
6715 return e2
->checkSideEffect(flag
);
6719 /************************** IndexExp **********************************/
6723 IndexExp::IndexExp(Loc loc
, Expression
*e1
, Expression
*e2
)
6724 : BinExp(loc
, TOKindex
, sizeof(IndexExp
), e1
, e2
)
6726 //printf("IndexExp::IndexExp('%s')\n", toChars());
6728 modifiable
= 0; // assume it is an rvalue
6731 Expression
*IndexExp::semantic(Scope
*sc
)
6739 printf("IndexExp::semantic('%s')\n", toChars());
6744 e1
= e1
->semantic(sc
);
6745 assert(e1
->type
); // semantic() should already be run on it
6748 // Note that unlike C we do not implement the int[ptr]
6750 t1
= e1
->type
->toBasetype();
6752 if (t1
->ty
== Tsarray
|| t1
->ty
== Tarray
|| t1
->ty
== Ttuple
)
6753 { // Create scope for 'length' variable
6754 sym
= new ArrayScopeSymbol(this);
6756 sym
->parent
= sc
->scopesym
;
6760 e2
= e2
->semantic(sc
);
6763 error("%s has no value", e2
->toChars());
6764 e2
->type
= Type::terror
;
6766 e2
= resolveProperties(sc
, e2
);
6768 if (t1
->ty
== Tsarray
|| t1
->ty
== Tarray
|| t1
->ty
== Ttuple
)
6775 e2
= e2
->implicitCastTo(sc
, Type::tsize_t
);
6781 e2
= e2
->implicitCastTo(sc
, Type::tsize_t
);
6783 TypeSArray
*tsa
= (TypeSArray
*)t1
;
6785 #if 0 // Don't do now, because it might be short-circuit evaluated
6786 // Do compile time array bounds checking if possible
6787 e2
= e2
->optimize(WANTvalue
);
6788 if (e2
->op
== TOKint64
)
6790 integer_t index
= e2
->toInteger();
6791 integer_t length
= tsa
->dim
->toInteger();
6792 if (index
< 0 || index
>= length
)
6793 error("array index [%lld] is outside array bounds [0 .. %lld]",
6802 { TypeAArray
*taa
= (TypeAArray
*)t1
;
6804 e2
= e2
->implicitCastTo(sc
, taa
->index
); // type checking
6805 e2
= e2
->implicitCastTo(sc
, taa
->key
); // actual argument type
6812 e2
= e2
->implicitCastTo(sc
, Type::tsize_t
);
6813 e2
= e2
->optimize(WANTvalue
);
6814 uinteger_t index
= e2
->toUInteger();
6819 if (e1
->op
== TOKtuple
)
6820 { te
= (TupleExp
*)e1
;
6821 length
= te
->exps
->dim
;
6823 else if (e1
->op
== TOKtype
)
6825 tup
= (TypeTuple
*)t1
;
6826 length
= Argument::dim(tup
->arguments
);
6834 if (e1
->op
== TOKtuple
)
6835 e
= (Expression
*)te
->exps
->data
[(size_t)index
];
6837 e
= new TypeExp(e1
->loc
, Argument::getNth(tup
->arguments
, (size_t)index
)->type
);
6841 error("array index [%"PRIuMAX
"] is outside array bounds [0 .. %"PRIuSIZE
"]",
6849 error("%s must be an array or pointer type, not %s",
6850 e1
->toChars(), e1
->type
->toChars());
6851 type
= Type::tint32
;
6857 Expression
*IndexExp::toLvalue(Scope
*sc
, Expression
*e
)
6859 // if (type && type->toBasetype()->ty == Tvoid)
6860 // error("voids have no value");
6864 Expression
*IndexExp::modifiableLvalue(Scope
*sc
, Expression
*e
)
6866 //printf("IndexExp::modifiableLvalue(%s)\n", toChars());
6868 if (e1
->op
== TOKstring
)
6869 error("string literals are immutable");
6870 if (e1
->type
->toBasetype()->ty
== Taarray
)
6871 e1
= e1
->modifiableLvalue(sc
, e1
);
6872 return toLvalue(sc
, e
);
6875 void IndexExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
6877 expToCBuffer(buf
, hgs
, e1
, PREC_primary
);
6878 buf
->writeByte('[');
6879 expToCBuffer(buf
, hgs
, e2
, PREC_assign
);
6880 buf
->writeByte(']');
6884 /************************* PostExp ***********************************/
6886 PostExp::PostExp(enum TOK op
, Loc loc
, Expression
*e
)
6887 : BinExp(loc
, op
, sizeof(PostExp
), e
,
6888 new IntegerExp(loc
, 1, Type::tint32
))
6892 Expression
*PostExp::semantic(Scope
*sc
)
6893 { Expression
*e
= this;
6897 BinExp::semantic(sc
);
6898 e2
= resolveProperties(sc
, e2
);
6900 e
= op_overload(sc
);
6905 e1
= e1
->modifiableLvalue(sc
, e1
);
6908 if (e1
->type
->ty
== Tpointer
)
6909 e
= scaleFactor(sc
);
6911 e2
= e2
->castTo(sc
, e1
->type
);
6917 void PostExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
6919 expToCBuffer(buf
, hgs
, e1
, precedence
[op
]);
6920 buf
->writestring((op
== TOKplusplus
) ? (char *)"++" : (char *)"--");
6923 /************************************************************/
6925 /* Can be TOKconstruct too */
6927 AssignExp::AssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
6928 : BinExp(loc
, TOKassign
, sizeof(AssignExp
), e1
, e2
)
6933 Expression
*AssignExp::semantic(Scope
*sc
)
6935 Expression
*e1old
= e1
;
6938 printf("AssignExp::semantic('%s')\n", toChars());
6940 //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op));
6942 /* Look for operator overloading of a[i]=value.
6943 * Do it before semantic() otherwise the a[i] will have been
6944 * converted to a.opIndex() already.
6946 if (e1
->op
== TOKarray
)
6948 ArrayExp
*ae
= (ArrayExp
*)e1
;
6949 AggregateDeclaration
*ad
;
6950 Identifier
*id
= Id::index
;
6952 ae
->e1
= ae
->e1
->semantic(sc
);
6953 t1
= ae
->e1
->type
->toBasetype();
6954 if (t1
->ty
== Tstruct
)
6956 ad
= ((TypeStruct
*)t1
)->sym
;
6959 else if (t1
->ty
== Tclass
)
6961 ad
= ((TypeClass
*)t1
)->sym
;
6963 // Rewrite (a[i] = value) to (a.opIndexAssign(value, i))
6964 if (search_function(ad
, Id::indexass
))
6965 { Expression
*e
= new DotIdExp(loc
, ae
->e1
, Id::indexass
);
6966 Expressions
*a
= (Expressions
*)ae
->arguments
->copy();
6969 e
= new CallExp(loc
, e
, a
);
6970 e
= e
->semantic(sc
);
6975 // Rewrite (a[i] = value) to (a.opIndex(i, value))
6976 if (search_function(ad
, id
))
6977 { Expression
*e
= new DotIdExp(loc
, ae
->e1
, id
);
6979 if (1 || !global
.params
.useDeprecated
)
6980 error("operator [] assignment overload with opIndex(i, value) illegal, use opIndexAssign(value, i)");
6982 e
= new CallExp(loc
, e
, (Expression
*)ae
->arguments
->data
[0], e2
);
6983 e
= e
->semantic(sc
);
6989 /* Look for operator overloading of a[i..j]=value.
6990 * Do it before semantic() otherwise the a[i..j] will have been
6991 * converted to a.opSlice() already.
6993 if (e1
->op
== TOKslice
)
6995 SliceExp
*ae
= (SliceExp
*)e1
;
6996 AggregateDeclaration
*ad
;
6997 Identifier
*id
= Id::index
;
6999 ae
->e1
= ae
->e1
->semantic(sc
);
7000 ae
->e1
= resolveProperties(sc
, ae
->e1
);
7001 t1
= ae
->e1
->type
->toBasetype();
7002 if (t1
->ty
== Tstruct
)
7004 ad
= ((TypeStruct
*)t1
)->sym
;
7007 else if (t1
->ty
== Tclass
)
7009 ad
= ((TypeClass
*)t1
)->sym
;
7011 // Rewrite (a[i..j] = value) to (a.opIndexAssign(value, i, j))
7012 if (search_function(ad
, Id::sliceass
))
7013 { Expression
*e
= new DotIdExp(loc
, ae
->e1
, Id::sliceass
);
7014 Expressions
*a
= new Expressions();
7024 e
= new CallExp(loc
, e
, a
);
7025 e
= e
->semantic(sc
);
7031 BinExp::semantic(sc
);
7032 e2
= resolveProperties(sc
, e2
);
7035 /* Rewrite tuple assignment as a tuple of assignments.
7037 if (e1
->op
== TOKtuple
&& e2
->op
== TOKtuple
)
7038 { TupleExp
*tup1
= (TupleExp
*)e1
;
7039 TupleExp
*tup2
= (TupleExp
*)e2
;
7040 size_t dim
= tup1
->exps
->dim
;
7041 if (dim
!= tup2
->exps
->dim
)
7043 error("mismatched tuple lengths, %d and %d", (int)dim
, (int)tup2
->exps
->dim
);
7046 { Expressions
*exps
= new Expressions
;
7049 for (int i
= 0; i
< dim
; i
++)
7050 { Expression
*ex1
= (Expression
*)tup1
->exps
->data
[i
];
7051 Expression
*ex2
= (Expression
*)tup2
->exps
->data
[i
];
7052 exps
->data
[i
] = (void *) new AssignExp(loc
, ex1
, ex2
);
7054 Expression
*e
= new TupleExp(loc
, exps
);
7055 e
= e
->semantic(sc
);
7060 t1
= e1
->type
->toBasetype();
7062 if (t1
->ty
== Tfunction
)
7063 { // Rewrite f=value to f(value)
7066 e
= new CallExp(loc
, e1
, e2
);
7067 e
= e
->semantic(sc
);
7071 /* If it is an assignment from a 'foreign' type,
7072 * check for operator overloading.
7074 if (t1
->ty
== Tclass
|| t1
->ty
== Tstruct
)
7076 if (!e2
->type
->implicitConvTo(e1
->type
))
7078 Expression
*e
= op_overload(sc
);
7086 if (e1
->op
== TOKarraylength
)
7088 // e1 is not an lvalue, but we let code generator handle it
7089 ArrayLengthExp
*ale
= (ArrayLengthExp
*)e1
;
7091 ale
->e1
= ale
->e1
->modifiableLvalue(sc
, e1
);
7093 else if (e1
->op
== TOKslice
)
7096 { // Try to do a decent error message with the expression
7097 // before it got constant folded
7098 e1
= e1
->modifiableLvalue(sc
, e1old
);
7101 if (e1
->op
== TOKslice
&&
7103 e2
->implicitConvTo(t1
->nextOf())
7104 // !(t1->nextOf()->equals(e2->type->nextOf()))
7107 ismemset
= 1; // make it easy for back end to tell what this is
7108 e2
= e2
->implicitCastTo(sc
, t1
->next
);
7110 else if (t1
->ty
== Tsarray
)
7112 error("cannot assign to static array %s", e1
->toChars());
7116 e2
= e2
->implicitCastTo(sc
, e1
->type
);
7123 Expression
*AssignExp::checkToBoolean()
7127 // are usually mistakes.
7129 error("'=' does not give a boolean result");
7133 /************************************************************/
7135 /* Allow pointer arithmetic on e1? */
7136 static bool allowPtrArith(Scope
*sc
, Expression
*e1
)
7138 if (e1
->type
->ty
== Tpointer
)
7140 else if (e1
->type
->ty
== Tmaybe
&& e1
->type
->next
->ty
== Tpointer
)
7142 if (!sc
->inDtemplate
)
7143 e1
->error("Can't do pointer arithmetic on pointer ('%s') that could be null",
7150 AddAssignExp::AddAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7151 : BinExp(loc
, TOKaddass
, sizeof(AddAssignExp
), e1
, e2
)
7155 Expression
*AddAssignExp::semantic(Scope
*sc
)
7161 BinExp::semantic(sc
);
7162 e2
= resolveProperties(sc
, e2
);
7164 e
= op_overload(sc
);
7168 e1
= e1
->modifiableLvalue(sc
, e1
);
7170 Type
*tb1
= e1
->type
->toBasetype();
7171 Type
*tb2
= e2
->type
->toBasetype();
7173 if ((tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
) &&
7174 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
) &&
7175 tb1
->next
->equals(tb2
->next
)
7185 if (allowPtrArith(sc
, e1
) && tb2
->isintegral())
7186 e
= scaleFactor(sc
);
7187 else if (tb1
->ty
== Tbit
|| tb1
->ty
== Tbool
)
7190 // Need to rethink this
7191 if (e1
->op
!= TOKvar
)
7192 { // Rewrite e1+=e2 to (v=&e1),*v=*v+e2
7200 sprintf(name
, "__name%d", ++idn
);
7201 id
= Lexer::idPool(name
);
7203 v
= new VarDeclaration(loc
, tb1
->pointerTo(), id
, NULL
);
7207 v
->parent
= sc
->func
;
7209 ea
= new AddrExp(loc
, e1
);
7210 ea
= new AssignExp(loc
, new VarExp(loc
, v
), ea
);
7212 ex
= new VarExp(loc
, v
);
7213 ex
= new PtrExp(loc
, ex
);
7214 e
= new AddExp(loc
, ex
, e2
);
7215 e
= new CastExp(loc
, e
, e1
->type
);
7216 e
= new AssignExp(loc
, ex
->syntaxCopy(), e
);
7218 e
= new CommaExp(loc
, ea
, e
);
7222 { // Rewrite e1+=e2 to e1=e1+e2
7223 // BUG: doesn't account for side effects in e1
7224 // BUG: other assignment operators for bits aren't handled at all
7225 e
= new AddExp(loc
, e1
, e2
);
7226 e
= new CastExp(loc
, e
, e1
->type
);
7227 e
= new AssignExp(loc
, e1
->syntaxCopy(), e
);
7229 e
= e
->semantic(sc
);
7235 e1
->checkArithmetic();
7236 e2
->checkArithmetic();
7237 if (type
->isreal() || type
->isimaginary())
7239 assert(global
.errors
|| e2
->type
->isfloating());
7240 e2
= e2
->castTo(sc
, e1
->type
);
7248 /************************************************************/
7250 MinAssignExp::MinAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7251 : BinExp(loc
, TOKminass
, sizeof(MinAssignExp
), e1
, e2
)
7255 Expression
*MinAssignExp::semantic(Scope
*sc
)
7261 BinExp::semantic(sc
);
7262 e2
= resolveProperties(sc
, e2
);
7264 e
= op_overload(sc
);
7268 e1
= e1
->modifiableLvalue(sc
, e1
);
7272 if (allowPtrArith(sc
, e1
) && e2
->type
->isintegral())
7273 e
= scaleFactor(sc
);
7276 e1
= e1
->checkArithmetic();
7277 e2
= e2
->checkArithmetic();
7280 if (type
->isreal() || type
->isimaginary())
7282 assert(e2
->type
->isfloating());
7283 e2
= e2
->castTo(sc
, e1
->type
);
7290 /************************************************************/
7292 CatAssignExp::CatAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7293 : BinExp(loc
, TOKcatass
, sizeof(CatAssignExp
), e1
, e2
)
7297 Expression
*CatAssignExp::semantic(Scope
*sc
)
7300 BinExp::semantic(sc
);
7301 e2
= resolveProperties(sc
, e2
);
7303 e
= op_overload(sc
);
7307 if (e1
->op
== TOKslice
)
7308 { SliceExp
*se
= (SliceExp
*)e1
;
7310 if (se
->e1
->type
->toBasetype()->ty
== Tsarray
)
7311 error("cannot append to static array %s", se
->e1
->type
->toChars());
7314 e1
= e1
->modifiableLvalue(sc
, e1
);
7316 Type
*tb1
= e1
->type
->toBasetype();
7317 Type
*tb2
= e2
->type
->toBasetype();
7321 if ((tb1
->ty
== Tarray
) &&
7322 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
) &&
7323 e2
->implicitConvTo(e1
->type
)
7324 //e1->type->next->equals(e2->type->next)
7327 e2
= e2
->castTo(sc
, e1
->type
);
7331 else if ((tb1
->ty
== Tarray
) &&
7332 e2
->implicitConvTo(tb1
->next
)
7335 e2
= e2
->castTo(sc
, tb1
->next
);
7341 error("cannot append type %s to type %s", tb2
->toChars(), tb1
->toChars());
7342 type
= Type::tint32
;
7348 /************************************************************/
7350 MulAssignExp::MulAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7351 : BinExp(loc
, TOKmulass
, sizeof(MulAssignExp
), e1
, e2
)
7355 Expression
*MulAssignExp::semantic(Scope
*sc
)
7358 BinExp::semantic(sc
);
7359 e2
= resolveProperties(sc
, e2
);
7361 e
= op_overload(sc
);
7365 e1
= e1
->modifiableLvalue(sc
, e1
);
7370 e1
->checkArithmetic();
7371 e2
->checkArithmetic();
7372 if (e2
->type
->isfloating())
7380 if (t2
->isimaginary() || t2
->iscomplex())
7382 e2
= e2
->castTo(sc
, t1
);
7385 else if (t1
->isimaginary())
7387 if (t2
->isimaginary() || t2
->iscomplex())
7391 case Timaginary32
: t2
= Type::tfloat32
; break;
7392 case Timaginary64
: t2
= Type::tfloat64
; break;
7393 case Timaginary80
: t2
= Type::tfloat80
; break;
7397 e2
= e2
->castTo(sc
, t2
);
7404 /************************************************************/
7406 DivAssignExp::DivAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7407 : BinExp(loc
, TOKdivass
, sizeof(DivAssignExp
), e1
, e2
)
7411 Expression
*DivAssignExp::semantic(Scope
*sc
)
7414 BinExp::semantic(sc
);
7415 e2
= resolveProperties(sc
, e2
);
7417 e
= op_overload(sc
);
7421 e1
= e1
->modifiableLvalue(sc
, e1
);
7426 e1
->checkArithmetic();
7427 e2
->checkArithmetic();
7428 if (e2
->type
->isimaginary())
7435 // Therefore, the result is 0
7436 e2
= new CommaExp(loc
, e2
, new RealExp(loc
, 0, t1
));
7438 e
= new AssignExp(loc
, e1
, e2
);
7442 else if (t1
->isimaginary())
7447 case Timaginary32
: t2
= Type::tfloat32
; break;
7448 case Timaginary64
: t2
= Type::tfloat64
; break;
7449 case Timaginary80
: t2
= Type::tfloat80
; break;
7453 e2
= e2
->castTo(sc
, t2
);
7454 e
= new AssignExp(loc
, e1
, e2
);
7462 /************************************************************/
7464 ModAssignExp::ModAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7465 : BinExp(loc
, TOKmodass
, sizeof(ModAssignExp
), e1
, e2
)
7469 Expression
*ModAssignExp::semantic(Scope
*sc
)
7471 return commonSemanticAssign(sc
);
7474 /************************************************************/
7476 ShlAssignExp::ShlAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7477 : BinExp(loc
, TOKshlass
, sizeof(ShlAssignExp
), e1
, e2
)
7481 Expression
*ShlAssignExp::semantic(Scope
*sc
)
7484 //printf("ShlAssignExp::semantic()\n");
7485 BinExp::semantic(sc
);
7486 e2
= resolveProperties(sc
, e2
);
7488 e
= op_overload(sc
);
7492 e1
= e1
->modifiableLvalue(sc
, e1
);
7497 e1
->checkIntegral();
7498 e2
= e2
->checkIntegral();
7499 e2
= e2
->castTo(sc
, Type::tshiftcnt
);
7503 /************************************************************/
7505 ShrAssignExp::ShrAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7506 : BinExp(loc
, TOKshrass
, sizeof(ShrAssignExp
), e1
, e2
)
7510 Expression
*ShrAssignExp::semantic(Scope
*sc
)
7513 BinExp::semantic(sc
);
7514 e2
= resolveProperties(sc
, e2
);
7516 e
= op_overload(sc
);
7520 e1
= e1
->modifiableLvalue(sc
, e1
);
7525 e1
->checkIntegral();
7526 e2
= e2
->checkIntegral();
7527 e2
= e2
->castTo(sc
, Type::tshiftcnt
);
7531 /************************************************************/
7533 UshrAssignExp::UshrAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7534 : BinExp(loc
, TOKushrass
, sizeof(UshrAssignExp
), e1
, e2
)
7538 Expression
*UshrAssignExp::semantic(Scope
*sc
)
7541 BinExp::semantic(sc
);
7542 e2
= resolveProperties(sc
, e2
);
7544 e
= op_overload(sc
);
7548 e1
= e1
->modifiableLvalue(sc
, e1
);
7553 e1
->checkIntegral();
7554 e2
= e2
->checkIntegral();
7555 e2
= e2
->castTo(sc
, Type::tshiftcnt
);
7559 /************************************************************/
7561 AndAssignExp::AndAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7562 : BinExp(loc
, TOKandass
, sizeof(AndAssignExp
), e1
, e2
)
7566 Expression
*AndAssignExp::semantic(Scope
*sc
)
7568 return commonSemanticAssignIntegral(sc
);
7571 /************************************************************/
7573 OrAssignExp::OrAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7574 : BinExp(loc
, TOKorass
, sizeof(OrAssignExp
), e1
, e2
)
7578 Expression
*OrAssignExp::semantic(Scope
*sc
)
7580 return commonSemanticAssignIntegral(sc
);
7583 /************************************************************/
7585 XorAssignExp::XorAssignExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7586 : BinExp(loc
, TOKxorass
, sizeof(XorAssignExp
), e1
, e2
)
7590 Expression
*XorAssignExp::semantic(Scope
*sc
)
7592 return commonSemanticAssignIntegral(sc
);
7595 /************************* AddExp *****************************/
7597 AddExp::AddExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7598 : BinExp(loc
, TOKadd
, sizeof(AddExp
), e1
, e2
)
7602 Expression
*AddExp::semantic(Scope
*sc
)
7606 printf("AddExp::semantic('%s')\n", toChars());
7610 BinExp::semanticp(sc
);
7612 e
= op_overload(sc
);
7616 Type
*tb1
= e1
->type
->toBasetype();
7617 Type
*tb2
= e2
->type
->toBasetype();
7619 if ((tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
) &&
7620 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
) &&
7621 tb1
->next
->equals(tb2
->next
)
7627 else if (tb1
->ty
== Tpointer
&& e2
->type
->isintegral() ||
7628 tb2
->ty
== Tpointer
&& e1
->type
->isintegral())
7629 e
= scaleFactor(sc
);
7630 else if (tb1
->ty
== Tpointer
&& tb2
->ty
== Tpointer
)
7632 incompatibleTypes();
7639 if ((e1
->type
->isreal() && e2
->type
->isimaginary()) ||
7640 (e1
->type
->isimaginary() && e2
->type
->isreal()))
7642 switch (type
->toBasetype()->ty
)
7646 type
= Type::tcomplex32
;
7651 type
= Type::tcomplex64
;
7656 type
= Type::tcomplex80
;
7670 /************************************************************/
7672 MinExp::MinExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7673 : BinExp(loc
, TOKmin
, sizeof(MinExp
), e1
, e2
)
7677 Expression
*MinExp::semantic(Scope
*sc
)
7683 printf("MinExp::semantic('%s')\n", toChars());
7688 BinExp::semanticp(sc
);
7690 e
= op_overload(sc
);
7695 t1
= e1
->type
->toBasetype();
7696 t2
= e2
->type
->toBasetype();
7697 if (t1
->ty
== Tpointer
)
7699 if (t2
->ty
== Tpointer
)
7700 { // Need to divide the result by the stride
7701 // Replace (ptr - ptr) with (ptr - ptr) / stride
7705 typeCombine(sc
); // make sure pointer types are compatible
7706 type
= Type::tptrdiff_t
;
7707 stride
= t2
->next
->size();
7708 e
= new DivExp(loc
, this, new IntegerExp(0, stride
, Type::tptrdiff_t
));
7709 e
->type
= Type::tptrdiff_t
;
7712 else if (t2
->isintegral())
7713 e
= scaleFactor(sc
);
7715 { error("incompatible types for -");
7716 return new IntegerExp(0);
7719 else if (t2
->ty
== Tpointer
)
7722 error("can't subtract pointer from %s", e1
->type
->toChars());
7723 return new IntegerExp(0);
7728 t1
= e1
->type
->toBasetype();
7729 t2
= e2
->type
->toBasetype();
7730 if ((t1
->isreal() && t2
->isimaginary()) ||
7731 (t1
->isimaginary() && t2
->isreal()))
7737 type
= Type::tcomplex32
;
7742 type
= Type::tcomplex64
;
7747 type
= Type::tcomplex80
;
7758 /************************* CatExp *****************************/
7760 CatExp::CatExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7761 : BinExp(loc
, TOKcat
, sizeof(CatExp
), e1
, e2
)
7765 Expression
*CatExp::semantic(Scope
*sc
)
7768 //printf("CatExp::semantic() %s\n", toChars());
7771 BinExp::semanticp(sc
);
7772 e
= op_overload(sc
);
7776 Type
*tb1
= e1
->type
->toBasetype();
7777 Type
*tb2
= e2
->type
->toBasetype();
7780 /* BUG: Should handle things like:
7790 if ((tb1
->ty
== Tsarray
|| tb1
->ty
== Tarray
) &&
7791 e2
->type
->equals(tb1
->next
))
7793 type
= tb1
->next
->arrayOf();
7794 if (tb2
->ty
== Tarray
)
7795 { // Make e2 into [e2]
7796 e2
= new ArrayLiteralExp(e2
->loc
, e2
);
7801 else if ((tb2
->ty
== Tsarray
|| tb2
->ty
== Tarray
) &&
7802 e1
->type
->equals(tb2
->next
))
7804 type
= tb2
->next
->arrayOf();
7805 if (tb1
->ty
== Tarray
)
7806 { // Make e1 into [e1]
7807 e1
= new ArrayLiteralExp(e1
->loc
, e1
);
7815 if (type
->ty
== Tmaybe
)
7816 error("Cannot join arrays that may be null (%s)", toChars());
7818 if (type
->toBasetype()->ty
== Tsarray
)
7819 type
= type
->toBasetype()->next
->arrayOf();
7826 if (e1
->op
== TOKstring
&& e2
->op
== TOKstring
)
7827 e
= optimize(WANTvalue
);
7828 else if (e1
->type
->equals(e2
->type
) &&
7829 (e1
->type
->toBasetype()->ty
== Tarray
||
7830 e1
->type
->toBasetype()->ty
== Tsarray
))
7836 error("Can only concatenate arrays, not (%s ~ %s)",
7837 e1
->type
->toChars(), e2
->type
->toChars());
7838 type
= Type::tint32
;
7841 e
->type
= e
->type
->semantic(loc
, sc
);
7847 /************************************************************/
7849 MulExp::MulExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7850 : BinExp(loc
, TOKmul
, sizeof(MulExp
), e1
, e2
)
7854 Expression
*MulExp::semantic(Scope
*sc
)
7858 printf("MulExp::semantic() %s\n", toChars());
7865 BinExp::semanticp(sc
);
7866 e
= op_overload(sc
);
7871 e1
->checkArithmetic();
7872 e2
->checkArithmetic();
7873 if (type
->isfloating())
7874 { Type
*t1
= e1
->type
;
7875 Type
*t2
= e2
->type
;
7881 else if (t2
->isreal())
7885 else if (t1
->isimaginary())
7887 if (t2
->isimaginary())
7892 case Timaginary32
: type
= Type::tfloat32
; break;
7893 case Timaginary64
: type
= Type::tfloat64
; break;
7894 case Timaginary80
: type
= Type::tfloat80
; break;
7901 e
= new NegExp(loc
, this);
7902 e
= e
->semantic(sc
);
7906 type
= t2
; // t2 is complex
7908 else if (t2
->isimaginary())
7910 type
= t1
; // t1 is complex
7916 /************************************************************/
7918 DivExp::DivExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7919 : BinExp(loc
, TOKdiv
, sizeof(DivExp
), e1
, e2
)
7923 Expression
*DivExp::semantic(Scope
*sc
)
7929 BinExp::semanticp(sc
);
7930 e
= op_overload(sc
);
7935 e1
->checkArithmetic();
7936 e2
->checkArithmetic();
7937 if (type
->isfloating())
7938 { Type
*t1
= e1
->type
;
7939 Type
*t2
= e2
->type
;
7944 if (t2
->isimaginary())
7949 e
= new NegExp(loc
, this);
7950 e
= e
->semantic(sc
);
7954 else if (t2
->isreal())
7958 else if (t1
->isimaginary())
7960 if (t2
->isimaginary())
7964 case Timaginary32
: type
= Type::tfloat32
; break;
7965 case Timaginary64
: type
= Type::tfloat64
; break;
7966 case Timaginary80
: type
= Type::tfloat80
; break;
7971 type
= t2
; // t2 is complex
7973 else if (t2
->isimaginary())
7975 type
= t1
; // t1 is complex
7981 /************************************************************/
7983 ModExp::ModExp(Loc loc
, Expression
*e1
, Expression
*e2
)
7984 : BinExp(loc
, TOKmod
, sizeof(ModExp
), e1
, e2
)
7988 Expression
*ModExp::semantic(Scope
*sc
)
7994 BinExp::semanticp(sc
);
7995 e
= op_overload(sc
);
8000 e1
->checkArithmetic();
8001 e2
->checkArithmetic();
8002 if (type
->isfloating())
8004 if (e2
->type
->iscomplex())
8005 { error("cannot perform modulo complex arithmetic");
8006 return new IntegerExp(0);
8012 /************************************************************/
8014 ShlExp::ShlExp(Loc loc
, Expression
*e1
, Expression
*e2
)
8015 : BinExp(loc
, TOKshl
, sizeof(ShlExp
), e1
, e2
)
8019 Expression
*ShlExp::semantic(Scope
*sc
)
8022 //printf("ShlExp::semantic(), type = %p\n", type);
8024 { BinExp::semanticp(sc
);
8025 e
= op_overload(sc
);
8028 e1
= e1
->checkIntegral();
8029 e2
= e2
->checkIntegral();
8030 e1
= e1
->integralPromotions(sc
);
8031 e2
= e2
->castTo(sc
, Type::tshiftcnt
);
8037 /************************************************************/
8039 ShrExp::ShrExp(Loc loc
, Expression
*e1
, Expression
*e2
)
8040 : BinExp(loc
, TOKshr
, sizeof(ShrExp
), e1
, e2
)
8044 Expression
*ShrExp::semantic(Scope
*sc
)
8048 { BinExp::semanticp(sc
);
8049 e
= op_overload(sc
);
8052 e1
= e1
->checkIntegral();
8053 e2
= e2
->checkIntegral();
8054 e1
= e1
->integralPromotions(sc
);
8055 e2
= e2
->castTo(sc
, Type::tshiftcnt
);
8061 /************************************************************/
8063 UshrExp::UshrExp(Loc loc
, Expression
*e1
, Expression
*e2
)
8064 : BinExp(loc
, TOKushr
, sizeof(UshrExp
), e1
, e2
)
8068 Expression
*UshrExp::semantic(Scope
*sc
)
8072 { BinExp::semanticp(sc
);
8073 e
= op_overload(sc
);
8076 e1
= e1
->checkIntegral();
8077 e2
= e2
->checkIntegral();
8078 e1
= e1
->integralPromotions(sc
);
8079 e2
= e2
->castTo(sc
, Type::tshiftcnt
);
8085 /************************************************************/
8087 AndExp::AndExp(Loc loc
, Expression
*e1
, Expression
*e2
)
8088 : BinExp(loc
, TOKand
, sizeof(AndExp
), e1
, e2
)
8092 Expression
*AndExp::semantic(Scope
*sc
)
8096 { BinExp::semanticp(sc
);
8097 e
= op_overload(sc
);
8100 if (e1
->type
->toBasetype()->ty
== Tbool
&&
8101 e2
->type
->toBasetype()->ty
== Tbool
)
8109 e1
->checkIntegral();
8110 e2
->checkIntegral();
8116 /************************************************************/
8118 OrExp::OrExp(Loc loc
, Expression
*e1
, Expression
*e2
)
8119 : BinExp(loc
, TOKor
, sizeof(OrExp
), e1
, e2
)
8123 Expression
*OrExp::semantic(Scope
*sc
)
8127 { BinExp::semanticp(sc
);
8128 e
= op_overload(sc
);
8131 if (e1
->type
->toBasetype()->ty
== Tbool
&&
8132 e2
->type
->toBasetype()->ty
== Tbool
)
8140 e1
->checkIntegral();
8141 e2
->checkIntegral();
8147 /************************************************************/
8149 XorExp::XorExp(Loc loc
, Expression
*e1
, Expression
*e2
)
8150 : BinExp(loc
, TOKxor
, sizeof(XorExp
), e1
, e2
)
8154 Expression
*XorExp::semantic(Scope
*sc
)
8158 { BinExp::semanticp(sc
);
8159 e
= op_overload(sc
);
8162 if (e1
->type
->toBasetype()->ty
== Tbool
&&
8163 e2
->type
->toBasetype()->ty
== Tbool
)
8171 e1
->checkIntegral();
8172 e2
->checkIntegral();
8179 /************************************************************/
8181 OrOrExp::OrOrExp(Loc loc
, Expression
*e1
, Expression
*e2
)
8182 : BinExp(loc
, TOKoror
, sizeof(OrOrExp
), e1
, e2
)
8186 Expression
*OrOrExp::semantic(Scope
*sc
)
8190 // same as for AndAnd
8191 e1
= e1
->semantic(sc
);
8192 e1
= resolveProperties(sc
, e1
);
8193 e1
= e1
->checkToPointer();
8194 e1
= e1
->checkToBoolean();
8195 cs1
= sc
->callSuper
;
8197 if (sc
->flags
& SCOPEstaticif
)
8199 /* If in static if, don't evaluate e2 if we don't have to.
8201 e1
= e1
->optimize(WANTflags
);
8202 if (e1
->isBool(TRUE
))
8204 return new IntegerExp(loc
, 1, Type::tboolean
);
8208 e2
= e2
->semantic(sc
);
8209 sc
->mergeCallSuper(loc
, cs1
);
8210 e2
= resolveProperties(sc
, e2
);
8211 e2
= e2
->checkToPointer();
8213 type
= Type::tboolean
;
8214 if (e1
->type
->ty
== Tvoid
)
8216 if (e2
->op
== TOKtype
|| e2
->op
== TOKimport
)
8217 error("%s is not an expression", e2
->toChars());
8221 Expression
*OrOrExp::checkToBoolean()
8223 e2
= e2
->checkToBoolean();
8227 int OrOrExp::isBit()
8232 int OrOrExp::checkSideEffect(int flag
)
8236 return e1
->checkSideEffect(2) || e2
->checkSideEffect(2);
8239 { e1
->checkSideEffect(1);
8240 return e2
->checkSideEffect(flag
);
8244 /************************************************************/
8246 AndAndExp::AndAndExp(Loc loc
, Expression
*e1
, Expression
*e2
)
8247 : BinExp(loc
, TOKandand
, sizeof(AndAndExp
), e1
, e2
)
8251 Expression
*AndAndExp::semantic(Scope
*sc
)
8256 e1
= e1
->semantic(sc
);
8257 e1
= resolveProperties(sc
, e1
);
8258 e1
= e1
->checkToPointer();
8259 e1
= e1
->checkToBoolean();
8260 cs1
= sc
->callSuper
;
8262 if (sc
->flags
& SCOPEstaticif
)
8264 /* If in static if, don't evaluate e2 if we don't have to.
8266 e1
= e1
->optimize(WANTflags
);
8267 if (e1
->isBool(FALSE
))
8269 return new IntegerExp(loc
, 0, Type::tboolean
);
8273 e2
= e2
->semantic(sc
);
8274 sc
->mergeCallSuper(loc
, cs1
);
8275 e2
= resolveProperties(sc
, e2
);
8276 e2
= e2
->checkToPointer();
8278 type
= Type::tboolean
;
8279 if (e1
->type
->ty
== Tvoid
)
8281 if (e2
->op
== TOKtype
|| e2
->op
== TOKimport
)
8282 error("%s is not an expression", e2
->toChars());
8286 Expression
*AndAndExp::checkToBoolean()
8288 e2
= e2
->checkToBoolean();
8292 int AndAndExp::isBit()
8297 int AndAndExp::checkSideEffect(int flag
)
8301 return e1
->checkSideEffect(2) || e2
->checkSideEffect(2);
8305 e1
->checkSideEffect(1);
8306 return e2
->checkSideEffect(flag
);
8310 /************************************************************/
8312 InExp::InExp(Loc loc
, Expression
*e1
, Expression
*e2
)
8313 : BinExp(loc
, TOKin
, sizeof(InExp
), e1
, e2
)
8317 Expression
*InExp::semantic(Scope
*sc
)
8323 BinExp::semanticp(sc
);
8324 e
= op_overload(sc
);
8328 //type = Type::tboolean;
8329 Type
*t2b
= e2
->type
->toBasetype();
8330 if (t2b
->ty
!= Taarray
)
8332 error("rvalue of in expression must be an associative array, not %s", e2
->type
->toChars());
8333 type
= Type::terror
;
8337 TypeAArray
*ta
= (TypeAArray
*)t2b
;
8339 // Convert key to type of key
8340 e1
= e1
->implicitCastTo(sc
, ta
->index
);
8342 // Return type is pointer to value
8343 type
= ta
->next
->pointerTo();
8354 /************************************************************/
8356 /* This deletes the key e1 from the associative array e2
8359 RemoveExp::RemoveExp(Loc loc
, Expression
*e1
, Expression
*e2
)
8360 : BinExp(loc
, TOKremove
, sizeof(RemoveExp
), e1
, e2
)
8365 /************************************************************/
8367 CmpExp::CmpExp(enum TOK op
, Loc loc
, Expression
*e1
, Expression
*e2
)
8368 : BinExp(loc
, op
, sizeof(CmpExp
), e1
, e2
)
8372 Expression
*CmpExp::semantic(Scope
*sc
)
8378 printf("CmpExp::semantic('%s')\n", toChars());
8383 BinExp::semanticp(sc
);
8385 if (e1
->type
->toBasetype()->ty
== Tclass
&& e2
->op
== TOKnull
||
8386 e2
->type
->toBasetype()->ty
== Tclass
&& e1
->op
== TOKnull
)
8388 error("do not use null when comparing class types");
8391 e
= op_overload(sc
);
8394 e
= new CmpExp(op
, loc
, e
, new IntegerExp(loc
, 0, Type::tint32
));
8395 e
= e
->semantic(sc
);
8400 type
= Type::tboolean
;
8402 // Special handling for array comparisons
8403 t1
= e1
->type
->toBasetype();
8404 t2
= e2
->type
->toBasetype();
8405 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
8406 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
8408 if (!t1
->next
->equals(t2
->next
))
8409 error("array comparison type mismatch, %s vs %s", t1
->next
->toChars(), t2
->next
->toChars());
8412 else if (t1
->ty
== Tstruct
|| t2
->ty
== Tstruct
||
8413 (t1
->ty
== Tclass
&& t2
->ty
== Tclass
))
8415 if (t2
->ty
== Tstruct
)
8416 error("need member function opCmp() for %s %s to compare", t2
->toDsymbol(sc
)->kind(), t2
->toChars());
8418 error("need member function opCmp() for %s %s to compare", t1
->toDsymbol(sc
)->kind(), t1
->toChars());
8422 else if (t1
->iscomplex() || t2
->iscomplex())
8424 error("compare not defined for complex operands");
8425 e
= new IntegerExp(0);
8439 /************************************************************/
8441 EqualExp::EqualExp(enum TOK op
, Loc loc
, Expression
*e1
, Expression
*e2
)
8442 : BinExp(loc
, op
, sizeof(EqualExp
), e1
, e2
)
8444 assert(op
== TOKequal
|| op
== TOKnotequal
);
8447 Expression
*EqualExp::semantic(Scope
*sc
)
8452 //printf("EqualExp::semantic('%s')\n", toChars());
8456 BinExp::semanticp(sc
);
8458 /* Before checking for operator overloading, check to see if we're
8459 * comparing the addresses of two statics. If so, we can just see
8460 * if they are the same symbol.
8462 if (e1
->op
== TOKaddress
&& e2
->op
== TOKaddress
)
8463 { AddrExp
*ae1
= (AddrExp
*)e1
;
8464 AddrExp
*ae2
= (AddrExp
*)e2
;
8466 if (ae1
->e1
->op
== TOKvar
&& ae2
->e1
->op
== TOKvar
)
8467 { VarExp
*ve1
= (VarExp
*)ae1
->e1
;
8468 VarExp
*ve2
= (VarExp
*)ae2
->e1
;
8470 if (ve1
->var
== ve2
->var
/*|| ve1->var->toSymbol() == ve2->var->toSymbol()*/)
8472 // They are the same, result is 'true' for ==, 'false' for !=
8473 e
= new IntegerExp(loc
, (op
== TOKequal
), Type::tboolean
);
8479 if (e1
->type
->toBasetype()->ty
== Tclass
&& e2
->op
== TOKnull
||
8480 e2
->type
->toBasetype()->ty
== Tclass
&& e1
->op
== TOKnull
)
8482 error("use '%s' instead of '%s' when comparing with null",
8483 Token::toChars(op
== TOKequal
? TOKidentity
: TOKnotidentity
),
8484 Token::toChars(op
));
8487 //if (e2->op != TOKnull)
8489 e
= op_overload(sc
);
8492 if (op
== TOKnotequal
)
8494 e
= new NotExp(e
->loc
, e
);
8495 e
= e
->semantic(sc
);
8501 e
= typeCombine(sc
);
8502 type
= Type::tboolean
;
8504 // Special handling for array comparisons
8505 t1
= e1
->type
->toBasetype();
8506 t2
= e2
->type
->toBasetype();
8507 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
8508 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
8510 if (!t1
->next
->equals(t2
->next
))
8511 error("array comparison type mismatch, %s vs %s", t1
->next
->toChars(), t2
->next
->toChars());
8515 if (e1
->type
!= e2
->type
&& e1
->type
->isfloating() && e2
->type
->isfloating())
8517 // Cast both to complex
8518 e1
= e1
->castTo(sc
, Type::tcomplex80
);
8519 e2
= e2
->castTo(sc
, Type::tcomplex80
);
8525 int EqualExp::isBit()
8532 /************************************************************/
8534 IdentityExp::IdentityExp(enum TOK op
, Loc loc
, Expression
*e1
, Expression
*e2
)
8535 : BinExp(loc
, op
, sizeof(IdentityExp
), e1
, e2
)
8539 Expression
*IdentityExp::semantic(Scope
*sc
)
8544 BinExp::semanticp(sc
);
8545 type
= Type::tboolean
;
8547 if (e1
->type
!= e2
->type
&& e1
->type
->isfloating() && e2
->type
->isfloating())
8549 // Cast both to complex
8550 e1
= e1
->castTo(sc
, Type::tcomplex80
);
8551 e2
= e2
->castTo(sc
, Type::tcomplex80
);
8556 int IdentityExp::isBit()
8562 /****************************************************************/
8564 CondExp::CondExp(Loc loc
, Expression
*econd
, Expression
*e1
, Expression
*e2
)
8565 : BinExp(loc
, TOKquestion
, sizeof(CondExp
), e1
, e2
)
8567 this->econd
= econd
;
8570 Expression
*CondExp::syntaxCopy()
8572 return new CondExp(loc
, econd
->syntaxCopy(), e1
->syntaxCopy(), e2
->syntaxCopy());
8576 Expression
*CondExp::semantic(Scope
*sc
)
8583 printf("CondExp::semantic('%s')\n", toChars());
8588 econd
= econd
->semantic(sc
);
8589 econd
= resolveProperties(sc
, econd
);
8590 econd
= econd
->checkToPointer();
8591 econd
= econd
->checkToBoolean();
8593 #if 0 /* this cannot work right because the types of e1 and e2
8594 * both contribute to the type of the result.
8596 if (sc
->flags
& SCOPEstaticif
)
8598 /* If in static if, don't evaluate what we don't have to.
8600 econd
= econd
->optimize(WANTflags
);
8601 if (econd
->isBool(TRUE
))
8603 e1
= e1
->semantic(sc
);
8604 e1
= resolveProperties(sc
, e1
);
8607 else if (econd
->isBool(FALSE
))
8609 e2
= e2
->semantic(sc
);
8610 e2
= resolveProperties(sc
, e2
);
8617 cs0
= sc
->callSuper
;
8618 e1
= e1
->semantic(sc
);
8619 e1
= resolveProperties(sc
, e1
);
8620 cs1
= sc
->callSuper
;
8621 sc
->callSuper
= cs0
;
8622 e2
= e2
->semantic(sc
);
8623 e2
= resolveProperties(sc
, e2
);
8624 sc
->mergeCallSuper(loc
, cs1
);
8627 // If either operand is void, the result is void
8630 if (t1
->ty
== Tvoid
|| t2
->ty
== Tvoid
)
8637 switch (e1
->type
->toBasetype()->ty
)
8642 e2
= e2
->castTo(sc
, e1
->type
);
8645 switch (e2
->type
->toBasetype()->ty
)
8650 e1
= e1
->castTo(sc
, e2
->type
);
8657 Expression
*CondExp::toLvalue(Scope
*sc
, Expression
*ex
)
8661 // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)
8662 e
= new PtrExp(loc
, this, type
);
8664 e1
= e1
->addressOf(sc
);
8665 //e1 = e1->toLvalue(sc, NULL);
8667 e2
= e2
->addressOf(sc
);
8668 //e2 = e2->toLvalue(sc, NULL);
8676 Expression
*CondExp::modifiableLvalue(Scope
*sc
, Expression
*e
)
8678 error("conditional expression %s is not a modifiable lvalue", toChars());
8682 void CondExp::checkEscape()
8689 Expression
*CondExp::checkToBoolean()
8691 e1
= e1
->checkToBoolean();
8692 e2
= e2
->checkToBoolean();
8696 int CondExp::checkSideEffect(int flag
)
8700 return econd
->checkSideEffect(2) ||
8701 e1
->checkSideEffect(2) ||
8702 e2
->checkSideEffect(2);
8706 econd
->checkSideEffect(1);
8707 e1
->checkSideEffect(flag
);
8708 return e2
->checkSideEffect(flag
);
8712 void CondExp::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
8714 expToCBuffer(buf
, hgs
, econd
, PREC_oror
);
8715 buf
->writestring(" ? ");
8716 expToCBuffer(buf
, hgs
, e1
, PREC_expr
);
8717 buf
->writestring(" : ");
8718 expToCBuffer(buf
, hgs
, e2
, PREC_cond
);