Mercurial > projects > ldc
comparison dmd/opover.c @ 1587:def7a1d494fd
Merge DMD 1.051
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Fri, 06 Nov 2009 23:58:01 +0100 |
parents | 78038e540342 |
children | 207a8a438dea |
comparison
equal
deleted
inserted
replaced
1586:7f728c52e63c | 1587:def7a1d494fd |
---|---|
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. |
31 #include "scope.h" | 31 #include "scope.h" |
32 | 32 |
33 static Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Identifier *id); | 33 static Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Identifier *id); |
34 static void inferApplyArgTypesX(Module* from, FuncDeclaration *fstart, Arguments *arguments); | 34 static void inferApplyArgTypesX(Module* from, FuncDeclaration *fstart, Arguments *arguments); |
35 static int inferApplyArgTypesY(TypeFunction *tf, Arguments *arguments); | 35 static int inferApplyArgTypesY(TypeFunction *tf, Arguments *arguments); |
36 static void templateResolve(Match *m, TemplateDeclaration *td, Scope *sc, Loc loc, Objects *targsi, Expressions *arguments); | 36 static void templateResolve(Match *m, TemplateDeclaration *td, Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *arguments); |
37 | 37 |
38 /******************************** Expression **************************/ | 38 /******************************** Expression **************************/ |
39 | 39 |
40 | 40 |
41 /*********************************** | 41 /*********************************** |
156 * Return NULL if not an operator overload. | 156 * Return NULL if not an operator overload. |
157 */ | 157 */ |
158 | 158 |
159 Expression *UnaExp::op_overload(Scope *sc) | 159 Expression *UnaExp::op_overload(Scope *sc) |
160 { | 160 { |
161 //printf("UnaExp::op_overload() (%s)\n", toChars()); | |
161 AggregateDeclaration *ad; | 162 AggregateDeclaration *ad; |
162 Dsymbol *fd; | 163 Dsymbol *fd; |
163 Type *t1 = e1->type->toBasetype(); | 164 Type *t1 = e1->type->toBasetype(); |
164 | 165 |
165 if (t1->ty == Tclass) | 166 if (t1->ty == Tclass) |
175 fd = search_function(ad, opId()); | 176 fd = search_function(ad, opId()); |
176 if (fd) | 177 if (fd) |
177 { | 178 { |
178 if (op == TOKarray) | 179 if (op == TOKarray) |
179 { | 180 { |
180 Expression *e; | 181 /* Rewrite op e1[arguments] as: |
182 * e1.fd(arguments) | |
183 */ | |
184 Expression *e = new DotIdExp(loc, e1, fd->ident); | |
181 ArrayExp *ae = (ArrayExp *)this; | 185 ArrayExp *ae = (ArrayExp *)this; |
182 | |
183 e = new DotIdExp(loc, e1, fd->ident); | |
184 e = new CallExp(loc, e, ae->arguments); | 186 e = new CallExp(loc, e, ae->arguments); |
185 e = e->semantic(sc); | 187 e = e->semantic(sc); |
186 return e; | 188 return e; |
187 } | 189 } |
188 else | 190 else |
189 { | 191 { |
190 // Rewrite +e1 as e1.add() | 192 // Rewrite +e1 as e1.add() |
191 return build_overload(loc, sc, e1, NULL, fd->ident); | 193 return build_overload(loc, sc, e1, NULL, fd->ident); |
192 } | 194 } |
193 } | 195 } |
196 | |
197 #if DMDV2 | |
198 // Didn't find it. Forward to aliasthis | |
199 if (ad->aliasthis) | |
200 { | |
201 /* Rewrite op(e1) as: | |
202 * op(e1.aliasthis) | |
203 */ | |
204 Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident); | |
205 Expression *e = copy(); | |
206 ((UnaExp *)e)->e1 = e1; | |
207 e = e->semantic(sc); | |
208 return e; | |
209 } | |
210 #endif | |
194 } | 211 } |
195 return NULL; | 212 return NULL; |
196 } | 213 } |
197 | 214 |
198 | 215 |
262 if (s) | 279 if (s) |
263 { | 280 { |
264 fd = s->isFuncDeclaration(); | 281 fd = s->isFuncDeclaration(); |
265 if (fd) | 282 if (fd) |
266 { | 283 { |
267 overloadResolveX(&m, fd, &args2, sc->module); | 284 overloadResolveX(&m, fd, NULL, &args2, sc->module); |
268 } | 285 } |
269 else | 286 else |
270 { td = s->isTemplateDeclaration(); | 287 { td = s->isTemplateDeclaration(); |
271 templateResolve(&m, td, sc, loc, NULL, &args2); | 288 templateResolve(&m, td, sc, loc, NULL, NULL, &args2); |
272 } | 289 } |
273 } | 290 } |
274 | 291 |
275 lastf = m.lastf; | 292 lastf = m.lastf; |
276 | 293 |
277 if (s_r) | 294 if (s_r) |
278 { | 295 { |
279 fd = s_r->isFuncDeclaration(); | 296 fd = s_r->isFuncDeclaration(); |
280 if (fd) | 297 if (fd) |
281 { | 298 { |
282 overloadResolveX(&m, fd, &args1, sc->module); | 299 overloadResolveX(&m, fd, NULL, &args1, sc->module); |
283 } | 300 } |
284 else | 301 else |
285 { td = s_r->isTemplateDeclaration(); | 302 { td = s_r->isTemplateDeclaration(); |
286 templateResolve(&m, td, sc, loc, NULL, &args1); | 303 templateResolve(&m, td, sc, loc, NULL, NULL, &args1); |
287 } | 304 } |
288 } | 305 } |
289 | 306 |
290 if (m.count > 1) | 307 if (m.count > 1) |
291 { | 308 { |
333 /* Try: | 350 /* Try: |
334 * a.opfunc_r(b) | 351 * a.opfunc_r(b) |
335 * b.opfunc(a) | 352 * b.opfunc(a) |
336 * and see which is better. | 353 * and see which is better. |
337 */ | 354 */ |
338 Expression *e; | |
339 FuncDeclaration *lastf; | 355 FuncDeclaration *lastf; |
340 | 356 |
341 if (!argsset) | 357 if (!argsset) |
342 { args1.setDim(1); | 358 { args1.setDim(1); |
343 args1.data[0] = (void*) e1; | 359 args1.data[0] = (void*) e1; |
351 if (s_r) | 367 if (s_r) |
352 { | 368 { |
353 fd = s_r->isFuncDeclaration(); | 369 fd = s_r->isFuncDeclaration(); |
354 if (fd) | 370 if (fd) |
355 { | 371 { |
356 overloadResolveX(&m, fd, &args2, sc->module); | 372 overloadResolveX(&m, fd, NULL, &args2, sc->module); |
357 } | 373 } |
358 else | 374 else |
359 { td = s_r->isTemplateDeclaration(); | 375 { td = s_r->isTemplateDeclaration(); |
360 templateResolve(&m, td, sc, loc, NULL, &args2); | 376 templateResolve(&m, td, sc, loc, NULL, NULL, &args2); |
361 } | 377 } |
362 } | 378 } |
363 lastf = m.lastf; | 379 lastf = m.lastf; |
364 | 380 |
365 if (s) | 381 if (s) |
366 { | 382 { |
367 fd = s->isFuncDeclaration(); | 383 fd = s->isFuncDeclaration(); |
368 if (fd) | 384 if (fd) |
369 { | 385 { |
370 overloadResolveX(&m, fd, &args1, sc->module); | 386 overloadResolveX(&m, fd, NULL, &args1, sc->module); |
371 } | 387 } |
372 else | 388 else |
373 { td = s->isTemplateDeclaration(); | 389 { td = s->isTemplateDeclaration(); |
374 templateResolve(&m, td, sc, loc, NULL, &args1); | 390 templateResolve(&m, td, sc, loc, NULL, NULL, &args1); |
375 } | 391 } |
376 } | 392 } |
377 | 393 |
378 if (m.count > 1) | 394 if (m.count > 1) |
379 { | 395 { |
386 else if (m.last == MATCHnomatch) | 402 else if (m.last == MATCHnomatch) |
387 { | 403 { |
388 m.lastf = m.anyf; | 404 m.lastf = m.anyf; |
389 } | 405 } |
390 | 406 |
407 Expression *e; | |
391 if (lastf && m.lastf == lastf || | 408 if (lastf && m.lastf == lastf || |
392 id_r && m.last == MATCHnomatch) | 409 id_r && m.last == MATCHnomatch) |
393 // Rewrite (e1 op e2) as e1.opfunc_r(e2) | 410 // Rewrite (e1 op e2) as e1.opfunc_r(e2) |
394 e = build_overload(loc, sc, e1, e2, id_r); | 411 e = build_overload(loc, sc, e1, e2, id_r); |
395 else | 412 else |
421 | 438 |
422 return e; | 439 return e; |
423 } | 440 } |
424 } | 441 } |
425 | 442 |
443 #if DMDV2 | |
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 #endif | |
426 return NULL; | 470 return NULL; |
427 } | 471 } |
428 | 472 |
429 /*********************************** | 473 /*********************************** |
430 * 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. |
431 */ | 475 */ |
432 | 476 |
433 static Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Identifier *id) | 477 Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Identifier *id) |
434 { | 478 { |
435 Expression *e; | 479 Expression *e; |
436 | 480 |
437 //printf("build_overload(id = '%s')\n", id->toChars()); | 481 //printf("build_overload(id = '%s')\n", id->toChars()); |
438 //earg->print(); | 482 //earg->print(); |
497 if (!arg->type) | 541 if (!arg->type) |
498 break; | 542 break; |
499 } | 543 } |
500 | 544 |
501 AggregateDeclaration *ad; | 545 AggregateDeclaration *ad; |
502 FuncDeclaration *fd; | |
503 | 546 |
504 Argument *arg = (Argument *)arguments->data[0]; | 547 Argument *arg = (Argument *)arguments->data[0]; |
505 Type *taggr = aggr->type; | 548 Type *taggr = aggr->type; |
506 if (!taggr) | 549 if (!taggr) |
507 return; | 550 return; |
568 Dsymbol *s = search_function(ad, | 611 Dsymbol *s = search_function(ad, |
569 (op == TOKforeach_reverse) ? Id::applyReverse | 612 (op == TOKforeach_reverse) ? Id::applyReverse |
570 : Id::apply); | 613 : Id::apply); |
571 if (s) | 614 if (s) |
572 { | 615 { |
573 fd = s->isFuncDeclaration(); | 616 FuncDeclaration *fd = s->isFuncDeclaration(); |
574 if (fd) | 617 if (fd) |
575 inferApplyArgTypesX(from, fd, arguments); | 618 inferApplyArgTypesX(from, fd, arguments); |
576 } | 619 } |
577 break; | 620 break; |
578 } | 621 } |
580 case Tdelegate: | 623 case Tdelegate: |
581 { | 624 { |
582 if (0 && aggr->op == TOKdelegate) | 625 if (0 && aggr->op == TOKdelegate) |
583 { DelegateExp *de = (DelegateExp *)aggr; | 626 { DelegateExp *de = (DelegateExp *)aggr; |
584 | 627 |
585 fd = de->func->isFuncDeclaration(); | 628 FuncDeclaration *fd = de->func->isFuncDeclaration(); |
586 if (fd) | 629 if (fd) |
587 inferApplyArgTypesX(from, fd, arguments); | 630 inferApplyArgTypesX(from, fd, arguments); |
588 } | 631 } |
589 else | 632 else |
590 { | 633 { |
717 } | 760 } |
718 | 761 |
719 /************************************** | 762 /************************************** |
720 */ | 763 */ |
721 | 764 |
722 static void templateResolve(Match *m, TemplateDeclaration *td, Scope *sc, Loc loc, Objects *targsi, Expressions *arguments) | 765 static void templateResolve(Match *m, TemplateDeclaration *td, Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *arguments) |
723 { | 766 { |
724 FuncDeclaration *fd; | 767 FuncDeclaration *fd; |
725 | 768 |
726 assert(td); | 769 assert(td); |
727 fd = td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments); | 770 fd = td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments); |