root/branches/dmdfe-2.0/expression.c

Revision 914, 206.3 kB (checked in by Gregor, 3 months ago)

MERGE: DMD 2.019

Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2008 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <ctype.h>
13 #include <assert.h>
14 #include <complex>
15 #include <math.h>
16
17 #if _WIN32 && __DMC__
18 extern "C" char * __cdecl __locale_decpoint;
19 #endif
20
21 #if __WIN32 && __GNUC__
22 #define isnan _isnan
23 #elif __APPLE__
24 using std::isnan;
25 #endif
26
27 #if IN_GCC
28 // Issues with using -include total.h (defines integer_t) and then complex.h fails...
29 #undef integer_t
30 #endif
31
32 #ifdef __APPLE__
33 #define integer_t dmd_integer_t
34 #endif
35
36 #if IN_GCC || IN_DMDFE
37 #include "mem.h"
38 #elif _WIN32
39 #include "..\root\mem.h"
40 #elif linux
41 #include "../root/mem.h"
42 #endif
43
44 //#include "port.h"
45 #include "mtype.h"
46 #include "init.h"
47 #include "expression.h"
48 #include "template.h"
49 #include "utf.h"
50 #include "enum.h"
51 #include "scope.h"
52 #include "statement.h"
53 #include "declaration.h"
54 #include "aggregate.h"
55 #include "import.h"
56 #include "id.h"
57 #include "dsymbol.h"
58 #include "module.h"
59 #include "attrib.h"
60 #include "hdrgen.h"
61 #include "parse.h"
62
63 Expression *expandVar(int result, VarDeclaration *v);
64
65 #define LOGSEMANTIC 0
66
67 /**********************************
68  * Set operator precedence for each operator.
69  */
70
71 // Operator precedence - greater values are higher precedence
72
73 enum PREC
74 {
75     PREC_zero,
76     PREC_expr,
77     PREC_assign,
78     PREC_cond,
79     PREC_oror,
80     PREC_andand,
81     PREC_or,
82     PREC_xor,
83     PREC_and,
84     PREC_equal,
85     PREC_rel,
86     PREC_shift,
87     PREC_add,
88     PREC_mul,
89     PREC_unary,
90     PREC_primary,
91 };
92
93 enum PREC precedence[TOKMAX];
94
95 void initPrecedence()
96 {
97     precedence[TOKdotvar] = PREC_primary;
98     precedence[TOKimport] = PREC_primary;
99     precedence[TOKidentifier] = PREC_primary;
100     precedence[TOKthis] = PREC_primary;
101     precedence[TOKsuper] = PREC_primary;
102     precedence[TOKint64] = PREC_primary;
103     precedence[TOKfloat64] = PREC_primary;
104     precedence[TOKnull] = PREC_primary;
105     precedence[TOKstring] = PREC_primary;
106     precedence[TOKarrayliteral] = PREC_primary;
107     precedence[TOKtypedot] = PREC_primary;
108     precedence[TOKtypeid] = PREC_primary;
109     precedence[TOKis] = PREC_primary;
110     precedence[TOKassert] = PREC_primary;
111     precedence[TOKfunction] = PREC_primary;
112     precedence[TOKvar] = PREC_primary;
113 #if V2
114     precedence[TOKdefault] = PREC_primary;
115 #endif
116
117     // post
118     precedence[TOKdotti] = PREC_primary;
119     precedence[TOKdot] = PREC_primary;
120 //  precedence[TOKarrow] = PREC_primary;
121     precedence[TOKplusplus] = PREC_primary;
122     precedence[TOKminusminus] = PREC_primary;
123     precedence[TOKcall] = PREC_primary;
124     precedence[TOKslice] = PREC_primary;
125     precedence[TOKarray] = PREC_primary;
126
127     precedence[TOKaddress] = PREC_unary;
128     precedence[TOKstar] = PREC_unary;
129     precedence[TOKneg] = PREC_unary;
130     precedence[TOKuadd] = PREC_unary;
131     precedence[TOKnot] = PREC_unary;
132     precedence[TOKtobool] = PREC_add;
133     precedence[TOKtilde] = PREC_unary;
134     precedence[TOKdelete] = PREC_unary;
135     precedence[TOKnew] = PREC_unary;
136     precedence[TOKcast] = PREC_unary;
137
138     precedence[TOKmul] = PREC_mul;
139     precedence[TOKdiv] = PREC_mul;
140     precedence[TOKmod] = PREC_mul;
141
142     precedence[TOKadd] = PREC_add;
143     precedence[TOKmin] = PREC_add;
144     precedence[TOKcat] = PREC_add;
145
146     precedence[TOKshl] = PREC_shift;
147     precedence[TOKshr] = PREC_shift;
148     precedence[TOKushr] = PREC_shift;
149
150     precedence[TOKlt] = PREC_rel;
151     precedence[TOKle] = PREC_rel;
152     precedence[TOKgt] = PREC_rel;
153     precedence[TOKge] = PREC_rel;
154     precedence[TOKunord] = PREC_rel;
155     precedence[TOKlg] = PREC_rel;
156     precedence[TOKleg] = PREC_rel;
157     precedence[TOKule] = PREC_rel;
158     precedence[TOKul] = PREC_rel;
159     precedence[TOKuge] = PREC_rel;
160     precedence[TOKug] = PREC_rel;
161     precedence[TOKue] = PREC_rel;
162     precedence[TOKin] = PREC_rel;
163
164     precedence[TOKequal] = PREC_equal;
165     precedence[TOKnotequal] = PREC_equal;
166     precedence[TOKidentity] = PREC_equal;
167     precedence[TOKnotidentity] = PREC_equal;
168
169     precedence[TOKand] = PREC_and;
170
171     precedence[TOKxor] = PREC_xor;
172
173     precedence[TOKor] = PREC_or;
174
175     precedence[TOKandand] = PREC_andand;
176
177     precedence[TOKoror] = PREC_oror;
178
179     precedence[TOKquestion] = PREC_cond;
180
181     precedence[TOKassign] = PREC_assign;
182     precedence[TOKconstruct] = PREC_assign;
183     precedence[TOKblit] = PREC_assign;
184     precedence[TOKaddass] = PREC_assign;
185     precedence[TOKminass] = PREC_assign;
186     precedence[TOKcatass] = PREC_assign;
187     precedence[TOKmulass] = PREC_assign;
188     precedence[TOKdivass] = PREC_assign;
189     precedence[TOKmodass] = PREC_assign;
190     precedence[TOKshlass] = PREC_assign;
191     precedence[TOKshrass] = PREC_assign;
192     precedence[TOKushrass] = PREC_assign;
193     precedence[TOKandass] = PREC_assign;
194     precedence[TOKorass] = PREC_assign;
195     precedence[TOKxorass] = PREC_assign;
196
197     precedence[TOKcomma] = PREC_expr;
198 }
199
200 /*************************************************************
201  * Given var, we need to get the
202  * right 'this' pointer if var is in an outer class, but our
203  * existing 'this' pointer is in an inner class.
204  * Input:
205  *  e1  existing 'this'
206  *  ad  struct or class we need the correct 'this' for
207  *  var the specific member of ad we're accessing
208  */
209
210 Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
211     Expression *e1, Declaration *var)
212 {
213     //printf("\ngetRightThis(e1 = %s, ad = %s, var = %s)\n", e1->toChars(), ad->toChars(), var->toChars());
214  L1:
215     Type *t = e1->type->toBasetype();
216     //printf("e1->type = %s, var->type = %s\n", e1->type->toChars(), var->type->toChars());
217
218     /* If e1 is not the 'this' pointer for ad
219      */
220     if (ad &&
221     !(t->ty == Tpointer && t->nextOf()->ty == Tstruct &&
222       ((TypeStruct *)t->nextOf())->sym == ad)
223     &&
224     !(t->ty == Tstruct &&
225       ((TypeStruct *)t)->sym == ad)
226        )
227     {
228     ClassDeclaration *cd = ad->isClassDeclaration();
229     ClassDeclaration *tcd = t->isClassHandle();
230
231     /* e1 is the right this if ad is a base class of e1
232      */
233     if (!cd || !tcd ||
234         !(tcd == cd || cd->isBaseOf(tcd, NULL))
235        )
236     {
237         /* Only classes can be inner classes with an 'outer'
238          * member pointing to the enclosing class instance
239          */
240         if (tcd && tcd->isNested())
241         {   /* e1 is the 'this' pointer for an inner class: tcd.
242          * Rewrite it as the 'this' pointer for the outer class.
243          */
244
245         e1 = new DotVarExp(loc, e1, tcd->vthis);
246         e1->type = tcd->vthis->type;
247         // Do not call checkNestedRef()
248         //e1 = e1->semantic(sc);
249
250         // Skip up over nested functions, and get the enclosing
251         // class type.
252         int n = 0;
253         Dsymbol *s;
254         for (s = tcd->toParent();
255              s && s->isFuncDeclaration();
256              s = s->toParent())
257         {   FuncDeclaration *f = s->isFuncDeclaration();
258             if (f->vthis)
259             {
260             //printf("rewriting e1 to %s's this\n", f->toChars());
261             n++;
262             e1 = new VarExp(loc, f->vthis);
263             }
264         }
265         if (s && s->isClassDeclaration())
266         {   e1->type = s->isClassDeclaration()->type;
267             if (n > 1)
268             e1 = e1->semantic(sc);
269         }
270         else
271             e1 = e1->semantic(sc);
272         goto L1;
273         }
274         /* Can't find a path from e1 to ad
275          */
276         e1->error("this for %s needs to be type %s not type %s",
277         var->toChars(), ad->toChars(), t->toChars());
278     }
279     }
280     return e1;
281 }
282
283 /*****************************************
284  * Determine if 'this' is available.
285  * If it is, return the FuncDeclaration that has it.
286  */
287
288 FuncDeclaration *hasThis(Scope *sc)
289 {   FuncDeclaration *fd;
290     FuncDeclaration *fdthis;
291
292     //printf("hasThis()\n");
293     fdthis = sc->parent->isFuncDeclaration();
294     //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : "");
295
296     // Go upwards until we find the enclosing member function
297     fd = fdthis;
298     while (1)
299     {
300     if (!fd)
301     {
302         goto Lno;
303     }
304     if (!fd->isNested())
305         break;
306
307     Dsymbol *parent = fd->parent;
308     while (parent)
309     {
310         TemplateInstance *ti = parent->isTemplateInstance();
311         if (ti)
312         parent = ti->parent;
313         else
314         break;
315     }
316
317     fd = fd->parent->isFuncDeclaration();
318     }
319
320     if (!fd->isThis())
321     {   //printf("test '%s'\n", fd->toChars());
322     goto Lno;
323     }
324
325     assert(fd->vthis);
326     return fd;
327
328 Lno:
329     return NULL;        // don't have 'this' available
330 }
331
332
333 /***************************************
334  * Pull out any properties.
335  */
336
337 Expression *resolveProperties(Scope *sc, Expression *e)
338 {
339     //printf("resolveProperties(%s)\n", e->toChars());
340     if (e->type)
341     {
342     Type *t = e->type->toBasetype();
343
344     if (t->ty == Tfunction || e->op == TOKoverloadset)
345     {
346         e = new CallExp(e->loc, e);
347         e = e->semantic(sc);
348     }
349
350     /* Look for e being a lazy parameter; rewrite as delegate call
351      */
352     else if (e->op == TOKvar)
353     {   VarExp *ve = (VarExp *)e;
354
355         if (ve->var->storage_class & STClazy)
356         {
357         e = new CallExp(e->loc, e);
358         e = e->semantic(sc);
359         }
360     }
361
362     else if (e->op == TOKdotexp)
363     {
364         e->error("expression has no value");
365     }
366
367     }
368     return e;
369 }
370
371 /******************************
372  * Perform semantic() on an array of Expressions.
373  */
374
375 void arrayExpressionSemantic(Expressions *exps, Scope *sc)
376 {
377     if (exps)
378     {
379     for (size_t i = 0; i < exps->dim; i++)
380     {   Expression *e = (Expression *)exps->data[i];
381
382         e = e->semantic(sc);
383         exps->data[i] = (void *)e;
384     }
385     }
386 }
387
388
389 /******************************
390  * Perform canThrow() on an array of Expressions.
391  */
392
393 #if V2
394 int arrayExpressionCanThrow(Expressions *exps)
395 {
396     if (exps)
397     {
398     for (size_t i = 0; i < exps->dim; i++)
399     {   Expression *e = (Expression *)exps->data[i];
400         if (e && e->canThrow())
401         return 1;
402     }
403     }
404     return 0;
405 }
406 #endif
407
408 /****************************************
409  * Expand tuples.
410  */
411
412 void expandTuples(Expressions *exps)
413 {
414     //printf("expandTuples()\n");
415     if (exps)
416     {
417     for (size_t i = 0; i < exps->dim; i++)
418     {   Expression *arg = (Expression *)exps->data[i];
419         if (!arg)
420         continue;
421
422         // Look for tuple with 0 members
423         if (arg->op == TOKtype)
424         {   TypeExp *e = (TypeExp *)arg;
425         if (e->type->toBasetype()->ty == Ttuple)
426         {   TypeTuple *tt = (TypeTuple *)e->type->toBasetype();
427
428             if (!tt->arguments || tt->arguments->dim == 0)
429             {
430             exps->remove(i);
431             if (i == exps->dim)
432                 return;
433             i--;
434             continue;
435             }
436         }
437         }
438
439         // Inline expand all the tuples
440         while (arg->op == TOKtuple)
441         {   TupleExp *te = (TupleExp *)arg;
442
443         exps->remove(i);        // remove arg
444         exps->insert(i, te->exps);  // replace with tuple contents
445         if (i == exps->dim)
446             return;     // empty tuple, no more arguments
447         arg = (Expression *)exps->data[i];
448         }
449     }
450     }
451 }
452
453 /****************************************
454  * Preprocess arguments to function.
455  */
456
457 void preFunctionArguments(Loc loc, Scope *sc, Expressions *exps)
458 {
459     if (exps)
460     {
461     expandTuples(exps);
462
463     for (size_t i = 0; i < exps->dim; i++)
464     {   Expression *arg = (Expression *)exps->data[i];
465
466         if (!arg->type)
467         {
468 #ifdef DEBUG
469         if (!global.gag)
470             printf("1: \n");
471 #endif
472         arg->error("%s is not an expression", arg->toChars());
473         arg = new IntegerExp(arg->loc, 0, Type::tint32);
474         }
475
476         arg = resolveProperties(sc, arg);
477         exps->data[i] = (void *) arg;
478
479         //arg->rvalue();
480 #if 0
481         if (arg->type->ty == Tfunction)
482         {
483         arg = new AddrExp(arg->loc, arg);
484         arg = arg->semantic(sc);
485         exps->data[i] = (void *) arg;
486         }
487 #endif
488     }
489     }
490 }
491
492 /*********************************************
493  * Call copy constructor for struct value argument.
494  */
495 #if V2
496 Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
497 {
498     Type *tb = e->type->toBasetype();
499     assert(tb->ty == Tstruct);
500     StructDeclaration *sd = ((TypeStruct *)tb)->sym;
501     if (sd->cpctor)
502     {
503     /* Create a variable tmp, and replace the argument e with:
504      *  (tmp = e),tmp
505      * and let AssignExp() handle the construction.
506      * This is not the most efficent, ideally tmp would be constructed
507      * directly onto the stack.
508      */
509     Identifier *idtmp = Lexer::uniqueId("__tmp");
510     VarDeclaration *tmp = new VarDeclaration(loc, tb, idtmp, new ExpInitializer(0, e));
511     Expression *ae = new DeclarationExp(loc, tmp);
512     e = new CommaExp(loc, ae, new VarExp(loc, tmp));
513     e = e->semantic(sc);
514     }
515     return e;
516 }
517 #endif
518
519 /****************************************
520  * Now that we know the exact type of the function we're calling,
521  * the arguments[] need to be adjusted:
522  *  1. implicitly convert argument to the corresponding parameter type
523  *  2. add default arguments for any missing arguments
524  *  3. do default promotions on arguments corresponding to ...
525  *  4. add hidden _arguments[] argument
526  *  5. call copy constructor for struct value arguments
527  */
528
529 void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *arguments)
530 {
531     unsigned n;
532
533     //printf("functionArguments()\n");
534     assert(arguments);
535     size_t nargs = arguments ? arguments->dim : 0;
536     size_t nparams = Argument::dim(tf->parameters);
537
538     if (nargs > nparams && tf->varargs == 0)
539     error(loc, "expected " ZU " arguments, not " ZU, nparams, nargs);
540
541     n = (nargs > nparams) ? nargs : nparams;    // n = max(nargs, nparams)
542
543     int done = 0;
544     for (size_t i = 0; i < n; i++)
545     {
546     Expression *arg;
547
548     if (i < nargs)
549         arg = (Expression *)arguments->data[i];
550     else
551         arg = NULL;
552     Type *tb;
553
554     if (i < nparams)
555     {
556         Argument *p = Argument::getNth(tf->parameters, i);
557
558         if (!arg)
559         {
560         if (!p->defaultArg)
561         {
562             if (tf->varargs == 2 && i + 1 == nparams)
563             goto L2;
564             error(loc, "expected " ZU " arguments, not " ZU, nparams, nargs);
565             break;
566         }
567         arg = p->defaultArg;
568 #if V2
569         if (arg->op == TOKdefault)
570         {   DefaultInitExp *de = (DefaultInitExp *)arg;
571             arg = de->resolve(loc, sc);
572         }
573         else
574 #endif
575             arg = arg->copy();
576         arguments->push(arg);
577         nargs++;
578         }
579
580         if (tf->varargs == 2 && i + 1 == nparams)
581         {
582         //printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars());
583         if (arg->implicitConvTo(p->type))
584         {
585             if (nargs != nparams)
586                 error(loc, "expected " ZU " arguments, not " ZU, nparams, nargs);
587             goto L1;
588         }
589          L2:
590         Type *tb = p->type->toBasetype();
591         Type *tret = p->isLazyArray();
592         switch (tb->ty)
593         {
594             case Tsarray:
595             case Tarray:
596             {   // Create a static array variable v of type arg->type
597 #ifdef IN_GCC
598             /* GCC 4.0 does not like zero length arrays used like
599                this; pass a null array value instead. Could also
600                just make a one-element array. */
601             if (nargs - i == 0)
602             {
603                 arg = new NullExp(loc);
604                 break;
605             }
606 #endif
607             Identifier *id = Lexer::uniqueId("__arrayArg");
608             Type *t = new TypeSArray(((TypeArray *)tb)->next, new IntegerExp(nargs - i));
609             t = t->semantic(loc, sc);
610             VarDeclaration *v = new VarDeclaration(loc, t, id, new VoidInitializer(loc));
611             v->semantic(sc);
612             v->parent = sc->parent;
613             //sc->insert(v);
614
615             Expression *c = new DeclarationExp(0, v);
616             c->type = v->type;
617
618             for (size_t u = i; u < nargs; u++)
619             {   Expression *a = (Expression *)arguments->data[u];
620                 if (tret && !((TypeArray *)tb)->next->equals(a->type))
621                 a = a->toDelegate(sc, tret);
622
623                 Expression *e = new VarExp(loc, v);
624                 e = new IndexExp(loc, e, new IntegerExp(u + 1 - nparams));
625                 AssignExp *ae = new AssignExp(loc, e, a);
626                 ae->op = TOKconstruct;
627                 if (c)
628                 c = new CommaExp(loc, c, ae);
629                 else
630                 c = ae;
631             }
632             arg = new VarExp(loc, v);
633             if (c)
634                 arg = new CommaExp(loc, c, arg);
635             break;
636             }
637             case Tclass:
638             {   /* Set arg to be:
639              *  new Tclass(arg0, arg1, ..., argn)
640              */
641             Expressions *args = new Expressions();
642             args->setDim(nargs - i);
643             for (size_t u = i; u < nargs; u++)
644                 args->data[u - i] = arguments->data[u];
645             arg = new NewExp(loc,