Mercurial > projects > ldc
comparison dmd2/opover.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | 356e65836fb5 |
children | 54b3c1394d62 |
comparison
equal
deleted
inserted
replaced
1423:42bd767ec5a4 | 1452:638d16625da2 |
---|---|
1 | 1 |
2 // Compiler implementation of the D programming language | 2 // Compiler implementation of the D programming language |
3 // Copyright (c) 1999-2007 by Digital Mars | 3 // Copyright (c) 1999-2009 by Digital Mars |
4 // All Rights Reserved | 4 // All Rights Reserved |
5 // written by Walter Bright | 5 // written by Walter Bright |
6 // http://www.digitalmars.com | 6 // http://www.digitalmars.com |
7 // License for redistribution is by either the Artistic License | 7 // License for redistribution is by either the Artistic License |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | 8 // in artistic.txt, or the GNU General Public License in gnu.txt. |
13 #include <ctype.h> | 13 #include <ctype.h> |
14 #include <assert.h> | 14 #include <assert.h> |
15 #if _MSC_VER | 15 #if _MSC_VER |
16 #include <complex> | 16 #include <complex> |
17 #else | 17 #else |
18 #include <complex> | |
18 #endif | 19 #endif |
19 | 20 |
20 #ifdef __APPLE__ | 21 #ifdef __APPLE__ |
21 #define integer_t dmd_integer_t | 22 #define integer_t dmd_integer_t |
22 #endif | 23 #endif |
23 | 24 |
24 #if IN_GCC || IN_LLVM | 25 #include "rmem.h" |
25 #include "mem.h" | |
26 #elif POSIX | |
27 #include "../root/mem.h" | |
28 #elif _WIN32 | |
29 #include "..\root\mem.h" | |
30 #endif | |
31 | 26 |
32 //#include "port.h" | 27 //#include "port.h" |
33 #include "mtype.h" | 28 #include "mtype.h" |
34 #include "init.h" | 29 #include "init.h" |
35 #include "expression.h" | 30 #include "expression.h" |
36 #include "id.h" | 31 #include "id.h" |
37 #include "declaration.h" | 32 #include "declaration.h" |
38 #include "aggregate.h" | 33 #include "aggregate.h" |
39 #include "template.h" | 34 #include "template.h" |
40 | 35 #include "scope.h" |
41 static void inferApplyArgTypesX(FuncDeclaration *fstart, Arguments *arguments); | 36 |
37 static void inferApplyArgTypesX(Module* from, FuncDeclaration *fstart, Arguments *arguments); | |
42 static void inferApplyArgTypesZ(TemplateDeclaration *tstart, Arguments *arguments); | 38 static void inferApplyArgTypesZ(TemplateDeclaration *tstart, Arguments *arguments); |
43 static int inferApplyArgTypesY(TypeFunction *tf, Arguments *arguments); | 39 static int inferApplyArgTypesY(TypeFunction *tf, Arguments *arguments); |
44 static void templateResolve(Match *m, TemplateDeclaration *td, Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *arguments); | 40 static void templateResolve(Match *m, TemplateDeclaration *td, Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *arguments); |
45 | 41 |
46 /******************************** Expression **************************/ | 42 /******************************** Expression **************************/ |
164 * Return NULL if not an operator overload. | 160 * Return NULL if not an operator overload. |
165 */ | 161 */ |
166 | 162 |
167 Expression *UnaExp::op_overload(Scope *sc) | 163 Expression *UnaExp::op_overload(Scope *sc) |
168 { | 164 { |
165 //printf("UnaExp::op_overload() (%s)\n", toChars()); | |
169 AggregateDeclaration *ad; | 166 AggregateDeclaration *ad; |
170 Dsymbol *fd; | 167 Dsymbol *fd; |
171 Type *t1 = e1->type->toBasetype(); | 168 Type *t1 = e1->type->toBasetype(); |
172 | 169 |
173 if (t1->ty == Tclass) | 170 if (t1->ty == Tclass) |
183 fd = search_function(ad, opId()); | 180 fd = search_function(ad, opId()); |
184 if (fd) | 181 if (fd) |
185 { | 182 { |
186 if (op == TOKarray) | 183 if (op == TOKarray) |
187 { | 184 { |
188 Expression *e; | 185 /* Rewrite op e1[arguments] as: |
186 * e1.fd(arguments) | |
187 */ | |
188 Expression *e = new DotIdExp(loc, e1, fd->ident); | |
189 ArrayExp *ae = (ArrayExp *)this; | 189 ArrayExp *ae = (ArrayExp *)this; |
190 | |
191 e = new DotIdExp(loc, e1, fd->ident); | |
192 e = new CallExp(loc, e, ae->arguments); | 190 e = new CallExp(loc, e, ae->arguments); |
193 e = e->semantic(sc); | 191 e = e->semantic(sc); |
194 return e; | 192 return e; |
195 } | 193 } |
196 else | 194 else |
197 { | 195 { |
198 // Rewrite +e1 as e1.add() | 196 // Rewrite +e1 as e1.add() |
199 return build_overload(loc, sc, e1, NULL, fd->ident); | 197 return build_overload(loc, sc, e1, NULL, fd->ident); |
200 } | 198 } |
199 } | |
200 | |
201 // Didn't find it. Forward to aliasthis | |
202 if (ad->aliasthis) | |
203 { | |
204 /* Rewrite op(e1) as: | |
205 * op(e1.aliasthis) | |
206 */ | |
207 Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident); | |
208 Expression *e = copy(); | |
209 ((UnaExp *)e)->e1 = e1; | |
210 e = e->semantic(sc); | |
211 return e; | |
201 } | 212 } |
202 } | 213 } |
203 return NULL; | 214 return NULL; |
204 } | 215 } |
205 | 216 |
270 if (s) | 281 if (s) |
271 { | 282 { |
272 fd = s->isFuncDeclaration(); | 283 fd = s->isFuncDeclaration(); |
273 if (fd) | 284 if (fd) |
274 { | 285 { |
275 overloadResolveX(&m, fd, NULL, &args2); | 286 overloadResolveX(&m, fd, NULL, &args2, sc->module); |
276 } | 287 } |
277 else | 288 else |
278 { td = s->isTemplateDeclaration(); | 289 { td = s->isTemplateDeclaration(); |
279 templateResolve(&m, td, sc, loc, NULL, NULL, &args2); | 290 templateResolve(&m, td, sc, loc, NULL, NULL, &args2); |
280 } | 291 } |
281 } | 292 } |
282 | 293 |
283 lastf = m.lastf; | 294 lastf = m.lastf; |
284 | 295 |
285 if (s_r) | 296 if (s_r) |
286 { | 297 { |
287 fd = s_r->isFuncDeclaration(); | 298 fd = s_r->isFuncDeclaration(); |
288 if (fd) | 299 if (fd) |
289 { | 300 { |
290 overloadResolveX(&m, fd, NULL, &args1); | 301 overloadResolveX(&m, fd, NULL, &args1, sc->module); |
291 } | 302 } |
292 else | 303 else |
293 { td = s_r->isTemplateDeclaration(); | 304 { td = s_r->isTemplateDeclaration(); |
294 templateResolve(&m, td, sc, loc, NULL, NULL, &args1); | 305 templateResolve(&m, td, sc, loc, NULL, NULL, &args1); |
295 } | 306 } |
341 /* Try: | 352 /* Try: |
342 * a.opfunc_r(b) | 353 * a.opfunc_r(b) |
343 * b.opfunc(a) | 354 * b.opfunc(a) |
344 * and see which is better. | 355 * and see which is better. |
345 */ | 356 */ |
346 Expression *e; | |
347 FuncDeclaration *lastf; | |
348 | 357 |
349 if (!argsset) | 358 if (!argsset) |
350 { args1.setDim(1); | 359 { args1.setDim(1); |
351 args1.data[0] = (void*) e1; | 360 args1.data[0] = (void*) e1; |
352 args2.setDim(1); | 361 args2.setDim(1); |
359 if (s_r) | 368 if (s_r) |
360 { | 369 { |
361 fd = s_r->isFuncDeclaration(); | 370 fd = s_r->isFuncDeclaration(); |
362 if (fd) | 371 if (fd) |
363 { | 372 { |
364 overloadResolveX(&m, fd, NULL, &args2); | 373 overloadResolveX(&m, fd, NULL, &args2, sc->module); |
365 } | 374 } |
366 else | 375 else |
367 { td = s_r->isTemplateDeclaration(); | 376 { td = s_r->isTemplateDeclaration(); |
368 templateResolve(&m, td, sc, loc, NULL, NULL, &args2); | 377 templateResolve(&m, td, sc, loc, NULL, NULL, &args2); |
369 } | 378 } |
370 } | 379 } |
371 lastf = m.lastf; | 380 FuncDeclaration *lastf = m.lastf; |
372 | 381 |
373 if (s) | 382 if (s) |
374 { | 383 { |
375 fd = s->isFuncDeclaration(); | 384 fd = s->isFuncDeclaration(); |
376 if (fd) | 385 if (fd) |
377 { | 386 { |
378 overloadResolveX(&m, fd, NULL, &args1); | 387 overloadResolveX(&m, fd, NULL, &args1, sc->module); |
379 } | 388 } |
380 else | 389 else |
381 { td = s->isTemplateDeclaration(); | 390 { td = s->isTemplateDeclaration(); |
382 templateResolve(&m, td, sc, loc, NULL, NULL, &args1); | 391 templateResolve(&m, td, sc, loc, NULL, NULL, &args1); |
383 } | 392 } |
394 else if (m.last == MATCHnomatch) | 403 else if (m.last == MATCHnomatch) |
395 { | 404 { |
396 m.lastf = m.anyf; | 405 m.lastf = m.anyf; |
397 } | 406 } |
398 | 407 |
408 Expression *e; | |
399 if (lastf && m.lastf == lastf || | 409 if (lastf && m.lastf == lastf || |
400 id_r && m.last == MATCHnomatch) | 410 id_r && m.last == MATCHnomatch) |
401 // Rewrite (e1 op e2) as e1.opfunc_r(e2) | 411 // Rewrite (e1 op e2) as e1.opfunc_r(e2) |
402 e = build_overload(loc, sc, e1, e2, id_r); | 412 e = build_overload(loc, sc, e1, e2, id_r); |
403 else | 413 else |
429 | 439 |
430 return e; | 440 return e; |
431 } | 441 } |
432 } | 442 } |
433 | 443 |
444 // Try alias this on first operand | |
445 if (ad1 && ad1->aliasthis) | |
446 { | |
447 /* Rewrite (e1 op e2) as: | |
448 * (e1.aliasthis op e2) | |
449 */ | |
450 Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident); | |
451 Expression *e = copy(); | |
452 ((BinExp *)e)->e1 = e1; | |
453 e = e->semantic(sc); | |
454 return e; | |
455 } | |
456 | |
457 // Try alias this on second operand | |
458 if (ad2 && ad2->aliasthis) | |
459 { | |
460 /* Rewrite (e1 op e2) as: | |
461 * (e1 op e2.aliasthis) | |
462 */ | |
463 Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident); | |
464 Expression *e = copy(); | |
465 ((BinExp *)e)->e2 = e2; | |
466 e = e->semantic(sc); | |
467 return e; | |
468 } | |
469 | |
434 return NULL; | 470 return NULL; |
435 } | 471 } |
436 | 472 |
437 /*********************************** | 473 /*********************************** |
438 * Utility to build a function call out of this reference and argument. | 474 * Utility to build a function call out of this reference and argument. |
489 * Given array of arguments and an aggregate type, | 525 * Given array of arguments and an aggregate type, |
490 * if any of the argument types are missing, attempt to infer | 526 * if any of the argument types are missing, attempt to infer |
491 * them from the aggregate type. | 527 * them from the aggregate type. |
492 */ | 528 */ |
493 | 529 |
494 void inferApplyArgTypes(enum TOK op, Arguments *arguments, Expression *aggr) | 530 void inferApplyArgTypes(enum TOK op, Arguments *arguments, Expression *aggr, Module* from) |
495 { | 531 { |
496 if (!arguments || !arguments->dim) | 532 if (!arguments || !arguments->dim) |
497 return; | 533 return; |
498 | 534 |
499 /* Return if no arguments need types. | 535 /* Return if no arguments need types. |
579 (op == TOKforeach_reverse) ? Id::applyReverse | 615 (op == TOKforeach_reverse) ? Id::applyReverse |
580 : Id::apply); | 616 : Id::apply); |
581 if (s) | 617 if (s) |
582 { | 618 { |
583 FuncDeclaration *fd = s->isFuncDeclaration(); | 619 FuncDeclaration *fd = s->isFuncDeclaration(); |
584 if (fd) | 620 if (fd) |
585 { inferApplyArgTypesX(fd, arguments); | 621 { inferApplyArgTypesX(from, fd, arguments); |
586 break; | 622 break; |
587 } | 623 } |
588 #if 0 | 624 #if 0 |
589 TemplateDeclaration *td = s->isTemplateDeclaration(); | 625 TemplateDeclaration *td = s->isTemplateDeclaration(); |
590 if (td) | 626 if (td) |
601 if (0 && aggr->op == TOKdelegate) | 637 if (0 && aggr->op == TOKdelegate) |
602 { DelegateExp *de = (DelegateExp *)aggr; | 638 { DelegateExp *de = (DelegateExp *)aggr; |
603 | 639 |
604 FuncDeclaration *fd = de->func->isFuncDeclaration(); | 640 FuncDeclaration *fd = de->func->isFuncDeclaration(); |
605 if (fd) | 641 if (fd) |
606 inferApplyArgTypesX(fd, arguments); | 642 inferApplyArgTypesX(from, fd, arguments); |
607 } | 643 } |
608 else | 644 else |
609 { | 645 { |
610 inferApplyArgTypesY((TypeFunction *)tab->nextOf(), arguments); | 646 inferApplyArgTypesY((TypeFunction *)tab->nextOf(), arguments); |
611 } | 647 } |
631 if (arguments->dim == 0) | 667 if (arguments->dim == 0) |
632 return 1; | 668 return 1; |
633 return 0; | 669 return 0; |
634 } | 670 } |
635 | 671 |
636 static void inferApplyArgTypesX(FuncDeclaration *fstart, Arguments *arguments) | 672 static void inferApplyArgTypesX(Module* from, FuncDeclaration *fstart, Arguments *arguments) |
637 { | 673 { |
638 overloadApply(fstart, &fp3, arguments); | 674 overloadApply(from, fstart, &fp3, arguments); |
639 } | 675 } |
640 | 676 |
641 /****************************** | 677 /****************************** |
642 * Infer arguments from type of function. | 678 * Infer arguments from type of function. |
643 * Returns: | 679 * Returns: |