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);