Mercurial > projects > ddmd
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 |