Mercurial > projects > ddmd
comparison dmd/CallExp.d @ 130:60bb0fe4563e
dmdfe 2.037 first main iteration
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Thu, 09 Sep 2010 22:51:44 +0100 |
parents | e28b18c23469 |
children | af1bebfd96a4 |
comparison
equal
deleted
inserted
replaced
129:010eb8f0e18d | 130:60bb0fe4563e |
---|---|
47 import dmd.DelegateExp; | 47 import dmd.DelegateExp; |
48 import dmd.IdentifierExp; | 48 import dmd.IdentifierExp; |
49 import dmd.DotVarExp; | 49 import dmd.DotVarExp; |
50 import dmd.DotIdExp; | 50 import dmd.DotIdExp; |
51 import dmd.TY; | 51 import dmd.TY; |
52 import dmd.TRUST; | |
52 import dmd.Id; | 53 import dmd.Id; |
53 import dmd.TypeAArray; | 54 import dmd.TypeAArray; |
54 import dmd.RemoveExp; | 55 import dmd.RemoveExp; |
55 import dmd.backend.elem; | 56 import dmd.backend.elem; |
56 import dmd.UnaExp; | 57 import dmd.UnaExp; |
212 { | 213 { |
213 /* Attempt to instantiate ti. If that works, go with it. | 214 /* Attempt to instantiate ti. If that works, go with it. |
214 * If not, go with partial explicit specialization. | 215 * If not, go with partial explicit specialization. |
215 */ | 216 */ |
216 ti.semanticTiargs(sc); | 217 ti.semanticTiargs(sc); |
217 uint errors = global.errors; | 218 if (ti.needsTypeInference(sc)) |
218 global.gag++; | 219 { |
219 ti.semantic(sc); | 220 /* Go with partial explicit specialization |
220 global.gag--; | |
221 if (errors != global.errors) | |
222 { | |
223 /* Didn't work, go with partial explicit specialization | |
224 */ | 221 */ |
225 global.errors = errors; | |
226 targsi = ti.tiargs; | 222 targsi = ti.tiargs; |
227 tierror = ti; // for error reporting | 223 tierror = ti; // for error reporting |
228 e1 = new IdentifierExp(loc, ti.name); | 224 e1 = new IdentifierExp(loc, ti.name); |
229 } | 225 } |
226 else | |
227 { | |
228 ti.semantic(sc); | |
229 } | |
230 } | 230 } |
231 } | 231 } |
232 | 232 |
233 /* This recognizes: | 233 /* This recognizes: |
234 * expr.foo!(tiargs)(funcargs) | 234 * expr.foo!(tiargs)(funcargs) |
235 */ | 235 */ |
236 Ldotti: | |
236 if (e1.op == TOK.TOKdotti && !e1.type) | 237 if (e1.op == TOK.TOKdotti && !e1.type) |
237 { | 238 { |
238 DotTemplateInstanceExp se = cast(DotTemplateInstanceExp)e1; | 239 DotTemplateInstanceExp se = cast(DotTemplateInstanceExp)e1; |
239 TemplateInstance ti = se.ti; | 240 TemplateInstance ti = se.ti; |
240 if (!ti.semanticRun) | 241 if (!ti.semanticRun) |
241 { | 242 { |
242 /* Attempt to instantiate ti. If that works, go with it. | 243 /* Attempt to instantiate ti. If that works, go with it. |
243 * If not, go with partial explicit specialization. | 244 * If not, go with partial explicit specialization. |
244 */ | 245 */ |
245 ti.semanticTiargs(sc); | 246 ti.semanticTiargs(sc); |
247 static if (false) { | |
246 Expression etmp = e1.trySemantic(sc); | 248 Expression etmp = e1.trySemantic(sc); |
247 if (etmp) | 249 if (etmp) |
248 e1 = etmp; // it worked | 250 e1 = etmp; // it worked |
249 else // didn't work | 251 else // didn't work |
250 { | 252 { |
251 targsi = ti.tiargs; | 253 targsi = ti.tiargs; |
252 tierror = ti; // for error reporting | 254 tierror = ti; // for error reporting |
253 e1 = new DotIdExp(loc, se.e1, ti.name); | 255 e1 = new DotIdExp(loc, se.e1, ti.name); |
254 } | 256 } |
257 } else { | |
258 if (!ti.tempdecl) | |
259 { | |
260 se.getTempdecl(sc); | |
261 } | |
262 if (ti.tempdecl && ti.needsTypeInference(sc)) | |
263 { | |
264 /* Go with partial explicit specialization | |
265 */ | |
266 targsi = ti.tiargs; | |
267 tierror = ti; // for error reporting | |
268 e1 = new DotIdExp(loc, se.e1, ti.name); | |
269 } | |
270 else | |
271 { | |
272 e1 = e1.semantic(sc); | |
273 } | |
274 } | |
255 } | 275 } |
256 } | 276 } |
257 } | 277 } |
258 | 278 |
259 istemp = 0; | 279 istemp = 0; |
260 Lagain: | 280 Lagain: |
261 //printf("Lagain: %s\n", toChars()); | 281 //printf("Lagain: %s\n", toChars()); |
282 //printf("test1 %s\n", toChars()); | |
262 f = null; | 283 f = null; |
263 if (e1.op == TOK.TOKthis || e1.op == TOK.TOKsuper) | 284 if (e1.op == TOK.TOKthis || e1.op == TOK.TOKsuper) |
264 { | 285 { |
265 // semantic() run later for these | 286 // semantic() run later for these |
266 } | 287 } |
267 else | 288 else |
268 { | 289 { |
269 UnaExp.semantic(sc); | 290 if (e1.op == TOK.TOKdot) |
291 { | |
292 auto die = cast(DotIdExp)e1; | |
293 e1 = die.semantic(sc, 1); | |
294 /* Look for e1 having been rewritten to expr.opDispatch!(string) | |
295 * We handle such earlier, so go back. | |
296 * Note that in the rewrite, we carefully did not run semantic() on e1 | |
297 */ | |
298 if (e1.op == TOK.TOKdotti && !e1.type) | |
299 { | |
300 goto Ldotti; | |
301 } | |
302 } | |
303 else | |
304 UnaExp.semantic(sc); | |
270 | 305 |
271 /* Look for e1 being a lazy parameter | 306 /* Look for e1 being a lazy parameter |
272 */ | 307 */ |
273 if (e1.op == TOK.TOKvar) | 308 if (e1.op == TOK.TOKvar) |
274 { | 309 { |
391 return e; | 426 return e; |
392 } | 427 } |
393 } | 428 } |
394 | 429 |
395 arrayExpressionSemantic(arguments, sc); | 430 arrayExpressionSemantic(arguments, sc); |
396 preFunctionArguments(loc, sc, arguments); | 431 preFunctionParameters(loc, sc, arguments); |
397 | 432 |
398 if (e1.op == TOK.TOKdotvar && t1.ty == TY.Tfunction || | 433 if (e1.op == TOK.TOKdotvar && t1.ty == TY.Tfunction || |
399 e1.op == TOK.TOKdottd) | 434 e1.op == TOK.TOKdottd) |
400 { | 435 { |
401 DotVarExp dve; | 436 DotVarExp dve; |
448 } | 483 } |
449 | 484 |
450 checkDeprecated(sc, f); | 485 checkDeprecated(sc, f); |
451 version (DMDV2) { | 486 version (DMDV2) { |
452 checkPurity(sc, f); | 487 checkPurity(sc, f); |
488 checkSafety(sc, f); | |
453 } | 489 } |
454 accessCheck(loc, sc, ue.e1, f); | 490 accessCheck(loc, sc, ue.e1, f); |
455 if (!f.needThis()) | 491 if (!f.needThis()) |
456 { | 492 { |
457 VarExp ve = new VarExp(loc, f); | 493 VarExp ve = new VarExp(loc, f); |
561 | 597 |
562 f = resolveFuncCall(sc, loc, cd.baseClass.ctor, null, null, arguments, 0); | 598 f = resolveFuncCall(sc, loc, cd.baseClass.ctor, null, null, arguments, 0); |
563 checkDeprecated(sc, f); | 599 checkDeprecated(sc, f); |
564 version (DMDV2) { | 600 version (DMDV2) { |
565 checkPurity(sc, f); | 601 checkPurity(sc, f); |
602 checkSafety(sc, f); | |
566 } | 603 } |
567 e1 = new DotVarExp(e1.loc, e1, f); | 604 e1 = new DotVarExp(e1.loc, e1, f); |
568 e1 = e1.semantic(sc); | 605 e1 = e1.semantic(sc); |
569 t1 = e1.type; | 606 t1 = e1.type; |
570 } | 607 } |
600 | 637 |
601 f = resolveFuncCall(sc, loc, cd.ctor, null, null, arguments, 0); | 638 f = resolveFuncCall(sc, loc, cd.ctor, null, null, arguments, 0); |
602 checkDeprecated(sc, f); | 639 checkDeprecated(sc, f); |
603 version (DMDV2) { | 640 version (DMDV2) { |
604 checkPurity(sc, f); | 641 checkPurity(sc, f); |
642 checkSafety(sc, f); | |
605 } | 643 } |
606 e1 = new DotVarExp(e1.loc, e1, f); | 644 e1 = new DotVarExp(e1.loc, e1, f); |
607 e1 = e1.semantic(sc); | 645 e1 = e1.semantic(sc); |
608 t1 = e1.type; | 646 t1 = e1.type; |
609 | 647 |
667 tf = cast(TypeFunction)(td.next); | 705 tf = cast(TypeFunction)(td.next); |
668 if (sc.func && sc.func.isPure() && !tf.ispure) | 706 if (sc.func && sc.func.isPure() && !tf.ispure) |
669 { | 707 { |
670 error("pure function '%s' cannot call impure delegate '%s'", sc.func.toChars(), e1.toChars()); | 708 error("pure function '%s' cannot call impure delegate '%s'", sc.func.toChars(), e1.toChars()); |
671 } | 709 } |
710 if (sc.func && sc.func.isSafe() && tf.trust <= TRUST.TRUSTsystem) | |
711 { | |
712 error("safe function '%s' cannot call system delegate '%s'", sc.func.toChars(), e1.toChars()); | |
713 } | |
672 goto Lcheckargs; | 714 goto Lcheckargs; |
673 } | 715 } |
674 else if (t1.ty == TY.Tpointer && (cast(TypePointer)t1).next.ty == TY.Tfunction) | 716 else if (t1.ty == TY.Tpointer && (cast(TypePointer)t1).next.ty == TY.Tfunction) |
675 { | 717 { |
676 Expression e = new PtrExp(loc, e1); | 718 Expression e = new PtrExp(loc, e1); |
677 t1 = (cast(TypePointer)t1).next; | 719 t1 = (cast(TypePointer)t1).next; |
678 if (sc.func && sc.func.isPure() && !(cast(TypeFunction)t1).ispure) | 720 if (sc.func && sc.func.isPure() && !(cast(TypeFunction)t1).ispure) |
679 { | 721 { |
680 error("pure function '%s' cannot call impure function pointer '%s'", sc.func.toChars(), e1.toChars()); | 722 error("pure function '%s' cannot call impure function pointer '%s'", sc.func.toChars(), e1.toChars()); |
723 } | |
724 if (sc.func && sc.func.isSafe() && !(cast(TypeFunction)t1).trust <= TRUST.TRUSTsystem) | |
725 { | |
726 error("safe function '%s' cannot call system function pointer '%s'", sc.func.toChars(), e1.toChars()); | |
681 } | 727 } |
682 e.type = t1; | 728 e.type = t1; |
683 e1 = e; | 729 e1 = e; |
684 } | 730 } |
685 else if (e1.op == TOK.TOKtemplate) | 731 else if (e1.op == TOK.TOKtemplate) |
706 goto Lagain; | 752 goto Lagain; |
707 } | 753 } |
708 else | 754 else |
709 { | 755 { |
710 error("function expected before (), not %s of type %s", e1.toChars(), e1.type.toChars()); | 756 error("function expected before (), not %s of type %s", e1.toChars(), e1.type.toChars()); |
711 type = Type.terror; | 757 return new ErrorExp(); |
712 return this; | |
713 } | 758 } |
714 } | 759 } |
715 else if (e1.op == TOK.TOKvar) | 760 else if (e1.op == TOK.TOKvar) |
716 { | 761 { |
717 // Do overload resolution | 762 // Do overload resolution |
724 f = f.overloadResolve(loc, null, arguments); | 769 f = f.overloadResolve(loc, null, arguments); |
725 | 770 |
726 checkDeprecated(sc, f); | 771 checkDeprecated(sc, f); |
727 version (DMDV2) { | 772 version (DMDV2) { |
728 checkPurity(sc, f); | 773 checkPurity(sc, f); |
774 checkSafety(sc, f); | |
729 } | 775 } |
730 | 776 |
731 if (f.needThis() && hasThis(sc)) | 777 if (f.needThis() && hasThis(sc)) |
732 { | 778 { |
733 // Supply an implicit 'this', as in | 779 // Supply an implicit 'this', as in |
752 type = tf.next; | 798 type = tf.next; |
753 | 799 |
754 if (!arguments) | 800 if (!arguments) |
755 arguments = new Expressions(); | 801 arguments = new Expressions(); |
756 | 802 |
757 functionArguments(loc, sc, tf, arguments); | 803 functionParameters(loc, sc, tf, arguments); |
758 | 804 |
759 if (!type) | 805 if (!type) |
760 { | 806 { |
761 error("forward reference to inferred return type of function call %s", toChars()); | 807 error("forward reference to inferred return type of function call %s", toChars()); |
762 type = Type.terror; | 808 type = Type.terror; |