comparison dmd/FuncDeclaration.d @ 179:cd48cb899aee

Updated to dmd2.040
author korDen
date Sun, 17 Oct 2010 20:56:07 +0400
parents e3afd1303184
children b0d41ff5e0df
comparison
equal deleted inserted replaced
178:e3afd1303184 179:cd48cb899aee
4 import dmd.Declaration; 4 import dmd.Declaration;
5 import dmd.DotIdExp; 5 import dmd.DotIdExp;
6 import dmd.AddrExp; 6 import dmd.AddrExp;
7 import dmd.TryFinallyStatement; 7 import dmd.TryFinallyStatement;
8 import dmd.TryCatchStatement; 8 import dmd.TryCatchStatement;
9 import dmd.SharedStaticDtorDeclaration;
9 import dmd.Catch; 10 import dmd.Catch;
10 import dmd.DeclarationStatement; 11 import dmd.DeclarationStatement;
11 import dmd.StaticDtorDeclaration; 12 import dmd.StaticDtorDeclaration;
12 import dmd.GlobalExpressions; 13 import dmd.GlobalExpressions;
13 import dmd.PeelStatement; 14 import dmd.PeelStatement;
18 import dmd.ExpInitializer; 19 import dmd.ExpInitializer;
19 import dmd.BE; 20 import dmd.BE;
20 import dmd.Id; 21 import dmd.Id;
21 import dmd.StorageClassDeclaration; 22 import dmd.StorageClassDeclaration;
22 import dmd.StringExp; 23 import dmd.StringExp;
24 import dmd.PASS;
23 import dmd.DsymbolExp; 25 import dmd.DsymbolExp;
24 import dmd.HaltExp; 26 import dmd.HaltExp;
25 import dmd.CommaExp; 27 import dmd.CommaExp;
26 import dmd.ReturnStatement; 28 import dmd.ReturnStatement;
27 import dmd.IntegerExp; 29 import dmd.IntegerExp;
28 import dmd.ExpStatement; 30 import dmd.ExpStatement;
29 import dmd.CSX; 31 import dmd.CSX;
32 import dmd.PROT;
30 import dmd.CompoundStatement; 33 import dmd.CompoundStatement;
31 import dmd.LabelStatement; 34 import dmd.LabelStatement;
32 import dmd.ThisExp; 35 import dmd.ThisExp;
33 import dmd.SuperExp; 36 import dmd.SuperExp;
34 import dmd.IdentifierExp; 37 import dmd.IdentifierExp;
148 VarDeclaration v_argptr; // '_argptr' variable 151 VarDeclaration v_argptr; // '_argptr' variable
149 } 152 }
150 Dsymbols parameters; // Array of VarDeclaration's for parameters 153 Dsymbols parameters; // Array of VarDeclaration's for parameters
151 DsymbolTable labtab; // statement label symbol table 154 DsymbolTable labtab; // statement label symbol table
152 Declaration overnext; // next in overload list 155 Declaration overnext; // next in overload list
153 Loc endloc; // location of closing curly bracket 156 Loc endloc; // location of closing curly bracket
154 int vtblIndex; // for member functions, index into vtbl[] 157 int vtblIndex; // for member functions, index into vtbl[]
155 int naked; // !=0 if naked 158 int naked; // !=0 if naked
156 int inlineAsm; // !=0 if has inline assembler 159 int inlineAsm; // !=0 if has inline assembler
157 ILS inlineStatus; 160 ILS inlineStatus;
158 int inlineNest; // !=0 if nested inline 161 int inlineNest; // !=0 if nested inline
159 int cantInterpret; // !=0 if cannot interpret function 162 int cantInterpret; // !=0 if cannot interpret function
160 int semanticRun; // 1 semantic() run 163 PASS semanticRun;
161 // 2 semantic2() run 164 // this function's frame ptr
162 // 3 semantic3() started
163 // 4 semantic3() done
164 // 5 toObjFile() run
165 // this function's frame ptr
166 ForeachStatement fes; // if foreach body, this is the foreach 165 ForeachStatement fes; // if foreach body, this is the foreach
167 int introducing; // !=0 if 'introducing' function 166 int introducing; // !=0 if 'introducing' function
168 Type tintro; // if !=null, then this is the type 167 Type tintro; // if !=null, then this is the type
169 // of the 'introducing' function 168 // of the 'introducing' function
170 // this one is overriding 169 // this one is overriding
229 naked = 0; 228 naked = 0;
230 inlineStatus = ILS.ILSuninitialized; 229 inlineStatus = ILS.ILSuninitialized;
231 inlineNest = 0; 230 inlineNest = 0;
232 inlineAsm = 0; 231 inlineAsm = 0;
233 cantInterpret = 0; 232 cantInterpret = 0;
234 semanticRun = 0; 233 semanticRun = PASSinit;
235 version (DMDV1) { 234 version (DMDV1) {
236 nestedFrameRef = 0; 235 nestedFrameRef = 0;
237 } 236 }
238 fes = null; 237 fes = null;
239 introducing = 0; 238 introducing = 0;
289 printf("\tFuncLiteralDeclaration()\n"); 288 printf("\tFuncLiteralDeclaration()\n");
290 printf("sc.parent = %s, parent = %s\n", sc.parent.toChars(), parent ? parent.toChars() : ""); 289 printf("sc.parent = %s, parent = %s\n", sc.parent.toChars(), parent ? parent.toChars() : "");
291 printf("type: %p, %s\n", type, type.toChars()); 290 printf("type: %p, %s\n", type, type.toChars());
292 } 291 }
293 292
294 if (semanticRun && isFuncLiteralDeclaration()) 293 if (semanticRun != PASSinit && isFuncLiteralDeclaration())
295 { 294 {
296 /* Member functions that have return types that are 295 /* Member functions that have return types that are
297 * forward references can have semantic() run more than 296 * forward references can have semantic() run more than
298 * once on them. 297 * once on them.
299 * See test\interface2.d, test20 298 * See test\interface2.d, test20
300 */ 299 */
301 return; 300 return;
302 } 301 }
303 assert(semanticRun <= 1); 302
304 semanticRun = 1; 303 parent = sc.parent;
304 Dsymbol parent = toParent();
305
306 if (semanticRun == PASSsemanticdone)
307 {
308 if (!parent.isClassDeclaration())
309 return;
310 // need to re-run semantic() in order to set the class's vtbl[]
311 }
312 else
313 {
314 assert(semanticRun <= PASSsemantic);
315 semanticRun = PASSsemantic;
316 }
317
318 uint dprogress_save = global.dprogress;
319
320 foverrides.setDim(0); // reset in case semantic() is being retried for this function
305 321
306 storage_class |= sc.stc & ~STC.STCref; 322 storage_class |= sc.stc & ~STC.STCref;
307 //printf("function storage_class = x%x\n", storage_class); 323 //printf("function storage_class = x%llx, sc->stc = x%llx\n", storage_class, sc->stc);
308 324
309 if (!originalType) 325 if (!originalType)
310 originalType = type; 326 originalType = type;
311 if (!type.deco) 327 if (!type.deco)
312 { 328 {
313 sc = sc.push(); 329 sc = sc.push();
314 sc.stc |= storage_class & STC.STCref; // forward refness to function type 330 sc.stc |= storage_class & STCref; // forward to function type
315 type = type.semantic(loc, sc); 331 type = type.semantic(loc, sc);
316 sc = sc.pop(); 332 sc = sc.pop();
317 333
318 /* Apply const, immutable and shared storage class 334 /* Apply const, immutable and shared storage class
319 * to the function type 335 * to the function type
385 } 401 }
386 f = cast(TypeFunction)type; 402 f = cast(TypeFunction)type;
387 size_t nparams = Parameter.dim(f.parameters); 403 size_t nparams = Parameter.dim(f.parameters);
388 404
389 linkage = sc.linkage; 405 linkage = sc.linkage;
390 // if (!parent)
391 {
392 //parent = sc.scopesym;
393 parent = sc.parent;
394 }
395 protection = sc.protection; 406 protection = sc.protection;
396 Dsymbol parent = toParent();
397 407
398 if (storage_class & STC.STCscope) 408 if (storage_class & STC.STCscope)
399 error("functions cannot be scope"); 409 error("functions cannot be scope");
400 410
401 if (isAbstract() && !isVirtual()) 411 if (isAbstract() && !isVirtual())
432 sd = parent.isStructDeclaration(); 442 sd = parent.isStructDeclaration();
433 if (sd) 443 if (sd)
434 { 444 {
435 if (isCtorDeclaration()) 445 if (isCtorDeclaration())
436 { 446 {
437 return; 447 goto Ldone;
438 } 448 }
439 static if (false) { 449 static if (false) {
440 // Verify no constructors, destructors, etc. 450 // Verify no constructors, destructors, etc.
441 if (isCtorDeclaration() 451 if (isCtorDeclaration()
442 //||isDtorDeclaration() 452 //||isDtorDeclaration()
473 ///} 483 ///}
474 isDtorDeclaration() || 484 isDtorDeclaration() ||
475 isInvariantDeclaration() || 485 isInvariantDeclaration() ||
476 isUnitTestDeclaration() || isNewDeclaration() || isDelete()) 486 isUnitTestDeclaration() || isNewDeclaration() || isDelete())
477 error("special function not allowed in interface %s", id.toChars()); 487 error("special function not allowed in interface %s", id.toChars());
478 if (fbody) 488 if (fbody && isVirtual())
479 error("function body is not abstract in interface %s", id.toChars()); 489 error("function body is not abstract in interface %s", id.toChars());
480 } 490 }
481 491
482 /* Template member functions aren't virtual: 492 /* Template member functions aren't virtual:
483 * interface TestInterface { void tpl(T)(); } 493 * interface TestInterface { void tpl(T)(); }
543 { 553 {
544 //printf("\tnot virtual\n"); 554 //printf("\tnot virtual\n");
545 goto Ldone; 555 goto Ldone;
546 } 556 }
547 557
548 // Find index of existing function in vtbl[] to override 558 /* Find index of existing function in base class's vtbl[] to override
549 vi = findVtblIndex(cd.vtbl, cd.baseClass ? cd.baseClass.vtbl.dim : 0); 559 * (the index will be the same as in cd's current vtbl[])
560 */
561 vi = cd.baseClass ? findVtblIndex(cd.baseClass.vtbl, cd.baseClass.vtbl.dim) : -1;
550 switch (vi) 562 switch (vi)
551 { 563 {
552 case -1: 564 case -1:
553 /* Didn't find one, so 565 /* Didn't find one, so
554 * This is an 'introducing' function which gets a new 566 * This is an 'introducing' function which gets a new
584 vtblIndex = vi; 596 vtblIndex = vi;
585 } 597 }
586 break; 598 break;
587 599
588 case -2: // can't determine because of fwd refs 600 case -2: // can't determine because of fwd refs
589 cd.sizeok = 2; // can't finish due to forward reference 601 cd.sizeok = 2; // can't finish due to forward reference
590 return; 602 global.dprogress = dprogress_save;
603 return;
591 604
592 default: 605 default:
593 { 606 {
594 FuncDeclaration fdv = cast(FuncDeclaration)cd.vtbl.data[vi]; 607 FuncDeclaration fdv = cast(FuncDeclaration)cd.baseClass.vtbl.data[vi];
608
595 // This function is covariant with fdv 609 // This function is covariant with fdv
596 if (fdv.isFinal()) 610 if (fdv.isFinal())
597 error("cannot override final function %s", fdv.toPrettyChars()); 611 error("cannot override final function %s", fdv.toPrettyChars());
598 612
599 version (DMDV2) { 613 version (DMDV2) {
663 case -1: 677 case -1:
664 break; 678 break;
665 679
666 case -2: 680 case -2:
667 cd.sizeok = 2; // can't finish due to forward reference 681 cd.sizeok = 2; // can't finish due to forward reference
682 global.dprogress = dprogress_save;
668 return; 683 return;
669 684
670 default: 685 default:
671 { FuncDeclaration fdv = cast(FuncDeclaration)b.base.vtbl.data[vi]; 686 { FuncDeclaration fdv = cast(FuncDeclaration)b.base.vtbl.data[vi];
672 Type ti = null; 687 Type ti = null;
677 692
678 if (fdv.tintro) 693 if (fdv.tintro)
679 ti = fdv.tintro; 694 ti = fdv.tintro;
680 else if (!type.equals(fdv.type)) 695 else if (!type.equals(fdv.type))
681 { 696 {
682 /* Only need to have a tintro if the vptr 697 /* Only need to have a tintro if the vptr
683 * offsets differ 698 * offsets differ
684 */ 699 */
685 int offset; 700 uint errors = global.errors;
686 if (fdv.type.nextOf().isBaseOf(type.nextOf(), &offset)) 701 global.gag++; // suppress printing of error messages
687 { 702 int offset;
688 ti = fdv.type; 703 int baseOf = fdv.type.nextOf().isBaseOf(type.nextOf(), &offset);
689 static if (false) { 704 global.gag--; // suppress printing of error messages
690 if (offset) 705 if (errors != global.errors)
691 ti = fdv.type;
692 else if (type.nextOf().ty == Tclass)
693 { 706 {
694 ClassDeclaration cdn = (cast(TypeClass)type.nextOf()).sym; 707 // any error in isBaseOf() is a forward reference error, so we bail out
695 if (cdn && cdn.sizeok != 1) 708 global.errors = errors;
696 ti = fdv.type; 709 cd.sizeok = 2; // can't finish due to forward reference
710 global.dprogress = dprogress_save;
711 return;
712 }
713 if (baseOf)
714 {
715 ti = fdv.type;
716 }
717 }
718 if (ti)
719 {
720 if (tintro && !tintro.equals(ti))
721 {
722 error("incompatible covariant types %s and %s", tintro.toChars(), ti.toChars());
723 }
724 tintro = ti;
725 }
726 goto L2;
727 }
728 }
729 }
730
731 if (introducing && isOverride())
732 {
733 error("does not override any function");
734 }
735
736 L2: ;
737 /* Go through all the interface bases.
738 * Disallow overriding any final functions in the interface(s).
739 */
740 for (int i = 0; i < cd.interfaces_dim; i++)
741 {
742 BaseClass b = cd.interfaces[i];
743 if (b.base)
744 {
745 Dsymbol s = search_function(b.base, ident);
746 if (s)
747 {
748 FuncDeclaration f_ = s.isFuncDeclaration();
749 if (f_)
750 {
751 f_ = f_.overloadExactMatch(type);
752 if (f_ && f_.isFinal() && f_.prot() != PROT.PROTprivate)
753 error("cannot override final function %s.%s", b.base.toChars(), f_.toPrettyChars());
697 } 754 }
698 }
699 } 755 }
700 } 756 }
701 if (ti) 757 }
702 {
703 if (tintro && !tintro.equals(ti))
704 {
705 error("incompatible covariant types %s and %s", tintro.toChars(), ti.toChars());
706 }
707 tintro = ti;
708 }
709 goto L2;
710 }
711 }
712 }
713
714 if (introducing && isOverride())
715 {
716 error("does not override any function");
717 }
718
719 L2: ;
720 } 758 }
721 else if (isOverride() && !parent.isTemplateInstance()) 759 else if (isOverride() && !parent.isTemplateInstance())
722 error("override only applies to class member functions"); 760 error("override only applies to class member functions");
723 761
724 /* Do not allow template instances to add virtual functions 762 /* Do not allow template instances to add virtual functions
805 goto Lassignerr; 843 goto Lassignerr;
806 } 844 }
807 } 845 }
808 } 846 }
809 847
810 if (isVirtual()) 848 if (isVirtual() && semanticRun != PASSsemanticdone)
811 { 849 {
812 /* Rewrite contracts as nested functions, then call them. 850 /* Rewrite contracts as nested functions, then call them.
813 * Doing it as nested functions means that overriding functions 851 * Doing it as nested functions means that overriding functions
814 * can call them. 852 * can call them.
815 */ 853 */
861 fdensure = fd; 899 fdensure = fd;
862 } 900 }
863 } 901 }
864 902
865 Ldone: 903 Ldone:
904 global.dprogress++;
905 semanticRun = PASSsemanticdone;
906
866 /* Save scope for possible later use (if we need the 907 /* Save scope for possible later use (if we need the
867 * function internals) 908 * function internals)
868 */ 909 */
869 scope_ = sc.clone(); 910 scope_ = sc.clone();
870 scope_.setNoFree(); 911 scope_.setNoFree();
902 //printf("storage class = x%x %x\n", sc.stc, storage_class); 943 //printf("storage class = x%x %x\n", sc.stc, storage_class);
903 //{ static int x; if (++x == 2) *(char*)0=0; } 944 //{ static int x; if (++x == 2) *(char*)0=0; }
904 //printf("\tlinkage = %d\n", sc.linkage); 945 //printf("\tlinkage = %d\n", sc.linkage);
905 946
906 //printf(" sc.incontract = %d\n", sc.incontract); 947 //printf(" sc.incontract = %d\n", sc.incontract);
907 if (semanticRun >= 3) 948 if (semanticRun >= PASSsemantic3)
908 return; 949 return;
909 semanticRun = 3; 950 semanticRun = PASSsemantic3;
910 951
911 if (!type || type.ty != TY.Tfunction) 952 if (!type || type.ty != TY.Tfunction)
912 return; 953 return;
913 f = cast(TypeFunction)(type); 954 f = cast(TypeFunction)(type);
914 955
1669 } 1710 }
1670 1711
1671 sc2.callSuper = 0; 1712 sc2.callSuper = 0;
1672 sc2.pop(); 1713 sc2.pop();
1673 } 1714 }
1674 semanticRun = 4; 1715
1716 semanticRun = PASSsemantic3done;
1675 } 1717 }
1676 1718
1677 // called from semantic3 1719 // called from semantic3
1678 void varArgs(Scope sc, TypeFunction, ref VarDeclaration, ref VarDeclaration) 1720 void varArgs(Scope sc, TypeFunction, ref VarDeclaration, ref VarDeclaration)
1679 { 1721 {
1761 } 1803 }
1762 1804
1763 /************************************************* 1805 /*************************************************
1764 * Find index of function in vtbl[0..dim] that 1806 * Find index of function in vtbl[0..dim] that
1765 * this function overrides. 1807 * this function overrides.
1808 * Prefer an exact match to a covariant one.
1766 * Returns: 1809 * Returns:
1767 * -1 didn't find one 1810 * -1 didn't find one
1768 * -2 can't determine because of forward references 1811 * -2 can't determine because of forward references
1769 */ 1812 */
1770 int findVtblIndex(Array vtbl, int dim) 1813 int findVtblIndex(Array vtbl, int dim)
1771 { 1814 {
1815 FuncDeclaration mismatch = null;
1816 int bestvi = -1;
1772 for (int vi = 0; vi < dim; vi++) 1817 for (int vi = 0; vi < dim; vi++)
1773 { 1818 {
1774 FuncDeclaration fdv = (cast(Dsymbol)vtbl.data[vi]).isFuncDeclaration(); 1819 FuncDeclaration fdv = (cast(Dsymbol)vtbl.data[vi]).isFuncDeclaration();
1775 if (fdv && fdv.ident is ident) 1820 if (fdv && fdv.ident is ident)
1776 { 1821 {
1822 if (type.equals(fdv.type)) // if exact match
1823 return vi; // no need to look further
1777 int cov = type.covariant(fdv.type); 1824 int cov = type.covariant(fdv.type);
1778 //printf("\tbaseclass cov = %d\n", cov); 1825 //printf("\tbaseclass cov = %d\n", cov);
1779 switch (cov) 1826 switch (cov)
1780 { 1827 {
1781 case 0: // types are distinct 1828 case 0: // types are distinct
1782 break; 1829 break;
1783 1830
1784 case 1: 1831 case 1:
1785 return vi; 1832 bestvi = vi; // covariant, but not identical
1833 break; // keep looking for an exact match
1786 1834
1787 case 2: 1835 case 2:
1788 //type.print(); 1836 mismatch = fdv; // overrides, but is not covariant
1789 //fdv.type.print(); 1837 break; // keep looking for an exact match
1790 //printf("%s %s\n", type.deco, fdv.type.deco);
1791 error("of type %s overrides but is not covariant with %s of type %s",
1792 type.toChars(), fdv.toPrettyChars(), fdv.type.toChars());
1793 break;
1794 1838
1795 case 3: 1839 case 3:
1796 return -2; // forward references 1840 return -2; // forward references
1797 1841
1798 default: 1842 default:
1799 writef("cov = %d\n", cov); 1843 writef("cov = %d\n", cov);
1800 assert(false); 1844 assert(false);
1801 } 1845 }
1802 } 1846 }
1803 } 1847 }
1804 return -1; 1848 if (bestvi == -1 && mismatch)
1849 {
1850 //type.print();
1851 //mismatch.type.print();
1852 //writef("%s %s\n", type.deco, mismatch.type.deco);
1853 error("of type %s overrides but is not covariant with %s of type %s",
1854 type.toChars(), mismatch.toPrettyChars(), mismatch.type.toChars());
1855 }
1856 return bestvi;
1805 } 1857 }
1806 1858
1807 /**************************************************** 1859 /****************************************************
1808 * Overload this FuncDeclaration with the new one f. 1860 * Overload this FuncDeclaration with the new one f.
1809 * Return !=0 if successful; i.e. no conflict. 1861 * Return !=0 if successful; i.e. no conflict.
2326 printf("FuncDeclaration.isVirtual(%s)\n", toChars()); 2378 printf("FuncDeclaration.isVirtual(%s)\n", toChars());
2327 printf("isMember:%p isStatic:%d private:%d ctor:%d !Dlinkage:%d\n", isMember(), isStatic(), protection == PROT.PROTprivate, isCtorDeclaration(), linkage != LINK.LINKd); 2379 printf("isMember:%p isStatic:%d private:%d ctor:%d !Dlinkage:%d\n", isMember(), isStatic(), protection == PROT.PROTprivate, isCtorDeclaration(), linkage != LINK.LINKd);
2328 printf("result is %d\n", 2380 printf("result is %d\n",
2329 isMember() && !(isStatic() || protection == PROT.PROTprivate || protection == PROT.PROTpackage) && toParent().isClassDeclaration()); 2381 isMember() && !(isStatic() || protection == PROT.PROTprivate || protection == PROT.PROTpackage) && toParent().isClassDeclaration());
2330 } 2382 }
2331 return isMember() && !(isStatic() || protection == PROT.PROTprivate || protection == PROT.PROTpackage) && toParent().isClassDeclaration(); 2383 Dsymbol p = toParent();
2384 return isMember() &&
2385 !(isStatic() || protection == PROT.PROTprivate || protection == PROT.PROTpackage) &&
2386 p.isClassDeclaration() &&
2387 !(p.isInterfaceDeclaration() && isFinal());
2332 } 2388 }
2333 2389
2334 override bool isFinal() 2390 override bool isFinal()
2335 { 2391 {
2336 ClassDeclaration cd; 2392 ClassDeclaration cd;
2402 else if (ident == Id.values) 2458 else if (ident == Id.values)
2403 return interpret_values(istate, thisarg, this); 2459 return interpret_values(istate, thisarg, this);
2404 } 2460 }
2405 } 2461 }
2406 2462
2407 if (cantInterpret || semanticRun == 3) 2463 if (cantInterpret || semanticRun == PASSsemantic3)
2408 return null; 2464 return null;
2409 2465
2410 if (!fbody) 2466 if (!fbody)
2411 { 2467 {
2412 cantInterpret = 1; 2468 cantInterpret = 1;
2413 return null; 2469 return null;
2414 } 2470 }
2415 2471
2416 if (semanticRun < 3 && scope_) 2472 if (semanticRun < PASSsemantic3 && scope_)
2417 { 2473 {
2418 semantic3(scope_); 2474 semantic3(scope_);
2419 if (global.errors) // if errors compiling this function 2475 if (global.errors) // if errors compiling this function
2420 return null; 2476 return null;
2421 } 2477 }
2422 if (semanticRun < 4) 2478 if (semanticRun < PASSsemantic3done)
2423 return null; 2479 return null;
2424 2480
2425 Type tb = type.toBasetype(); 2481 Type tb = type.toBasetype();
2426 assert(tb.ty == Tfunction); 2482 assert(tb.ty == Tfunction);
2427 TypeFunction tf = cast(TypeFunction)tb; 2483 TypeFunction tf = cast(TypeFunction)tb;
2431 cantInterpret = 1; 2487 cantInterpret = 1;
2432 error("C-style variadic functions are not yet implemented in CTFE"); 2488 error("C-style variadic functions are not yet implemented in CTFE");
2433 return null; 2489 return null;
2434 } 2490 }
2435 2491
2436 // Ensure there are no lazy parameters
2437 if (tf.parameters)
2438 {
2439 size_t dim = Parameter.dim(tf.parameters);
2440 for (size_t i = 0; i < dim; i++)
2441 {
2442 auto arg = Parameter.getNth(tf.parameters, i);
2443 if (arg.storageClass & STClazy)
2444 {
2445 cantInterpret = 1;
2446 return null;
2447 }
2448 }
2449 }
2450
2451 scope InterState istatex = new InterState(); 2492 scope InterState istatex = new InterState();
2452 istatex.caller = istate; 2493 istatex.caller = istate;
2453 istatex.fd = this; 2494 istatex.fd = this;
2454 istatex.localThis = thisarg; 2495 istatex.localThis = thisarg;
2455 2496
2477 for (size_t i = 0; i < dim; i++) 2518 for (size_t i = 0; i < dim; i++)
2478 { 2519 {
2479 Expression earg = arguments[i]; 2520 Expression earg = arguments[i];
2480 auto arg = Parameter.getNth(tf.parameters, i); 2521 auto arg = Parameter.getNth(tf.parameters, i);
2481 2522
2482 if (arg.storageClass & (STCout | STCref)) 2523 if (arg.storageClass & (STCout | STCref | STClazy))
2483 { 2524 {
2484 } 2525 }
2485 else 2526 else
2486 { /* Value parameters 2527 { /* Value parameters
2487 */ 2528 */
2684 } 2725 }
2685 2726
2686 if (needThis() && !hasthis) 2727 if (needThis() && !hasthis)
2687 return 0; 2728 return 0;
2688 2729
2689 if (inlineNest || (semanticRun < 3 && !hdrscan)) 2730 if (inlineNest || (semanticRun < PASSsemantic3 && !hdrscan))
2690 { 2731 {
2691 version (CANINLINE_LOG) { 2732 version (CANINLINE_LOG) {
2692 printf("\t1: no, inlineNest = %d, semanticRun = %d\n", inlineNest, semanticRun); 2733 printf("\t1: no, inlineNest = %d, semanticRun = %d\n", inlineNest, semanticRun);
2693 } 2734 }
2694 return 0; 2735 return 0;
3290 { 3331 {
3291 obj_append(this); 3332 obj_append(this);
3292 return; 3333 return;
3293 } 3334 }
3294 3335
3295 if (semanticRun >= 5) // if toObjFile() already run 3336 if (semanticRun >= PASSobj) // if toObjFile() already run
3296 return; 3337 return;
3297 3338 semanticRun = PASSobj;
3298 semanticRun = 5;
3299 3339
3300 if (!func.fbody) 3340 if (!func.fbody)
3301 { 3341 {
3302 return; 3342 return;
3303 } 3343 }
3347 { 3387 {
3348 const(char)* libname = (global.params.symdebug) ? global.params.debuglibname : global.params.defaultlibname; 3388 const(char)* libname = (global.params.symdebug) ? global.params.debuglibname : global.params.defaultlibname;
3349 3389
3350 // Pull in RTL startup code 3390 // Pull in RTL startup code
3351 if (func.isMain()) 3391 if (func.isMain())
3352 { objextdef("_main"); 3392 {
3393 objextdef("_main");
3353 version (POSIX) { ///TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 3394 version (POSIX) { ///TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
3354 obj_ehsections(); // initialize exception handling sections 3395 obj_ehsections(); // initialize exception handling sections
3355 } else { 3396 }
3397 version (TARGET_WINDOS) {
3356 objextdef("__acrtused_con"); 3398 objextdef("__acrtused_con");
3357 } 3399 }
3358 obj_includelib(libname); 3400 obj_includelib(libname);
3359 s.Sclass = SC.SCglobal; 3401 s.Sclass = SC.SCglobal;
3360 } 3402 }
3361 else if (strcmp(s.Sident.ptr, "main".ptr) == 0 && linkage == LINK.LINKc) 3403 else if (strcmp(s.Sident.ptr, "main".ptr) == 0 && linkage == LINK.LINKc)
3362 s.Sclass = SC.SCglobal; 3404 {
3363 3405 version (TARGET_WINDOS) {
3406 objextdef("__acrtused_con"); // bring in C startup code
3407 obj_includelib("snn.lib"); // bring in C runtime library
3408 }
3409 s.Sclass = SCglobal;
3410 }
3364 else if (func.isWinMain()) 3411 else if (func.isWinMain())
3365 { 3412 {
3366 objextdef("__acrtused"); 3413 objextdef("__acrtused");
3367 obj_includelib(libname); 3414 obj_includelib(libname);
3368 s.Sclass = SC.SCglobal; 3415 s.Sclass = SC.SCglobal;
3638 } 3685 }
3639 } 3686 }
3640 } 3687 }
3641 3688
3642 // If static constructor 3689 // If static constructor
3643 if (isStaticConstructor()) 3690 if (isSharedStaticCtorDeclaration()) // must come first because it derives from StaticCtorDeclaration
3644 { 3691 {
3645 elem* e = el_una(OPER.OPucall, TYM.TYvoid, el_var(s)); 3692 elem* e = el_una(OPucall, TYvoid, el_var(s));
3693 global.esharedctor = el_combine(global.esharedctor, e);
3694 }
3695 else if (isStaticCtorDeclaration())
3696 {
3697 elem* e = el_una(OPucall, TYvoid, el_var(s));
3646 global.ector = el_combine(global.ector, e); 3698 global.ector = el_combine(global.ector, e);
3647 } 3699 }
3648 3700
3649 // If static destructor 3701 // If static destructor
3650 if (isStaticDestructor()) 3702 if (auto f_ = isSharedStaticDtorDeclaration()) // must come first because it derives from StaticDtorDeclaration
3651 { 3703 {
3652 elem* e; 3704 elem* e;
3653 3705
3654 version (STATICCTOR) { 3706 version (STATICCTOR) {
3655 e = el_bin(OPER.OPcall, TYM.TYvoid, el_var(rtlsym[RTLSYM.RTLSYM_FATEXIT]), el_ptr(s)); 3707 e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_FATEXIT]), el_ptr(s));
3656 ector = el_combine(ector, e); 3708 esharedctor = el_combine(esharedctor, e);
3709 shareddtorcount++;
3710 } else {
3711 if (f_.vgate)
3712 {
3713 /* Increment destructor's vgate at construction time
3714 */
3715 global.esharedctorgates.push(cast(void*)f_);
3716 }
3717
3718 e = el_una(OPucall, TYvoid, el_var(s));
3719 global.eshareddtor = el_combine(e, global.eshareddtor);
3720 }
3721 }
3722 else if (auto f_ = isStaticDtorDeclaration())
3723 {
3724 elem* e;
3725
3726 version (STATICCTOR) {
3727 e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_FATEXIT]), el_ptr(s));
3728 global.ector = el_combine(ector, e);
3657 dtorcount++; 3729 dtorcount++;
3658 } else { 3730 } else {
3659 StaticDtorDeclaration f2 = isStaticDtorDeclaration(); 3731 if (f_.vgate)
3660 assert(f2); 3732 { /* Increment destructor's vgate at construction time
3661 if (f2.vgate)
3662 {
3663 /* Increment destructor's vgate at construction time
3664 */ 3733 */
3665 global.ectorgates.push(cast(void*)f2); 3734 global.ectorgates.push(cast(void*)f_);
3666 } 3735 }
3667 3736
3668 e = el_una(OPER.OPucall, TYM.TYvoid, el_var(s)); 3737 e = el_una(OPucall, TYvoid, el_var(s));
3669 global.edtor = el_combine(e, global.edtor); 3738 global.edtor = el_combine(e, global.edtor);
3670 } 3739 }
3671 } 3740 }
3672 3741
3673 // If unit test 3742 // If unit test