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;