Mercurial > projects > ldc
comparison dmd2/template.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | 5fa3e0ea06e9 |
children | 54b3c1394d62 |
comparison
equal
deleted
inserted
replaced
1423:42bd767ec5a4 | 1452:638d16625da2 |
---|---|
1 | 1 |
2 // Compiler implementation of the D programming language | 2 // Compiler implementation of the D programming language |
3 // Copyright (c) 1999-2008 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. |
11 // Handle template implementation | 11 // Handle template implementation |
12 | 12 |
13 #include <stdio.h> | 13 #include <stdio.h> |
14 #include <assert.h> | 14 #include <assert.h> |
15 | 15 |
16 #if !IN_LLVM | |
17 #endif | |
18 #include "root.h" | 16 #include "root.h" |
19 #include "mem.h" | 17 #include "rmem.h" |
20 #include "stringtable.h" | 18 #include "stringtable.h" |
21 #include "mars.h" | 19 #include "mars.h" |
22 #include "identifier.h" | 20 #include "identifier.h" |
23 #include "mtype.h" | 21 #include "mtype.h" |
24 #include "template.h" | 22 #include "template.h" |
35 #include <windows.h> | 33 #include <windows.h> |
36 long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep); | 34 long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep); |
37 #endif | 35 #endif |
38 | 36 |
39 #define LOG 0 | 37 #define LOG 0 |
40 | |
41 | 38 |
42 /******************************************** | 39 /******************************************** |
43 * These functions substitute for dynamic_cast. dynamic_cast does not work | 40 * These functions substitute for dynamic_cast. dynamic_cast does not work |
44 * on earlier versions of gcc. | 41 * on earlier versions of gcc. |
45 */ | 42 */ |
158 } | 155 } |
159 } | 156 } |
160 } | 157 } |
161 } | 158 } |
162 | 159 |
160 //printf("t1 = %s\n", t1->toChars()); | |
161 //printf("t2 = %s\n", t2->toChars()); | |
163 if (!t2 || !t1->equals(t2)) | 162 if (!t2 || !t1->equals(t2)) |
164 goto Lnomatch; | 163 goto Lnomatch; |
165 } | 164 } |
166 else if (e1) | 165 else if (e1) |
167 { | 166 { |
185 //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars()); | 184 //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars()); |
186 if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) | 185 if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) |
187 { | 186 { |
188 goto Lnomatch; | 187 goto Lnomatch; |
189 } | 188 } |
189 #if DMDV2 | |
190 VarDeclaration *v1 = s1->isVarDeclaration(); | 190 VarDeclaration *v1 = s1->isVarDeclaration(); |
191 VarDeclaration *v2 = s2->isVarDeclaration(); | 191 VarDeclaration *v2 = s2->isVarDeclaration(); |
192 if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) | 192 if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) |
193 { ExpInitializer *ei1 = v1->init->isExpInitializer(); | 193 { ExpInitializer *ei1 = v1->init->isExpInitializer(); |
194 ExpInitializer *ei2 = v2->init->isExpInitializer(); | 194 ExpInitializer *ei2 = v2->init->isExpInitializer(); |
195 if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) | 195 if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) |
196 goto Lnomatch; | 196 goto Lnomatch; |
197 } | 197 } |
198 #endif | |
198 } | 199 } |
199 else if (v1) | 200 else if (v1) |
200 { | 201 { |
201 if (!v2) | 202 if (!v2) |
202 goto Lnomatch; | 203 goto Lnomatch; |
260 #endif | 261 #endif |
261 assert(0); | 262 assert(0); |
262 } | 263 } |
263 } | 264 } |
264 | 265 |
266 #if DMDV2 | |
265 Object *objectSyntaxCopy(Object *o) | 267 Object *objectSyntaxCopy(Object *o) |
266 { | 268 { |
267 if (!o) | 269 if (!o) |
268 return NULL; | 270 return NULL; |
269 Type *t = isType(o); | 271 Type *t = isType(o); |
272 Expression *e = isExpression(o); | 274 Expression *e = isExpression(o); |
273 if (e) | 275 if (e) |
274 return e->syntaxCopy(); | 276 return e->syntaxCopy(); |
275 return o; | 277 return o; |
276 } | 278 } |
279 #endif | |
277 | 280 |
278 | 281 |
279 /* ======================== TemplateDeclaration ============================= */ | 282 /* ======================== TemplateDeclaration ============================= */ |
280 | 283 |
281 TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, | 284 TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, |
305 this->members = decldefs; | 308 this->members = decldefs; |
306 this->overnext = NULL; | 309 this->overnext = NULL; |
307 this->overroot = NULL; | 310 this->overroot = NULL; |
308 this->scope = NULL; | 311 this->scope = NULL; |
309 this->onemember = NULL; | 312 this->onemember = NULL; |
313 this->literal = 0; | |
310 } | 314 } |
311 | 315 |
312 Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) | 316 Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) |
313 { | 317 { |
314 //printf("TemplateDeclaration::syntaxCopy()\n"); | 318 //printf("TemplateDeclaration::syntaxCopy()\n"); |
329 Expression *e = NULL; | 333 Expression *e = NULL; |
330 if (constraint) | 334 if (constraint) |
331 e = constraint->syntaxCopy(); | 335 e = constraint->syntaxCopy(); |
332 d = Dsymbol::arraySyntaxCopy(members); | 336 d = Dsymbol::arraySyntaxCopy(members); |
333 td = new TemplateDeclaration(loc, ident, p, e, d); | 337 td = new TemplateDeclaration(loc, ident, p, e, d); |
334 | 338 |
339 #if IN_LLVM | |
335 // LDC | 340 // LDC |
336 td->intrinsicName = intrinsicName; | 341 td->intrinsicName = intrinsicName; |
337 | 342 #endif |
343 | |
338 return td; | 344 return td; |
339 } | 345 } |
340 | 346 |
341 void TemplateDeclaration::semantic(Scope *sc) | 347 void TemplateDeclaration::semantic(Scope *sc) |
342 { | 348 { |
346 if (scope) | 352 if (scope) |
347 return; // semantic() already run | 353 return; // semantic() already run |
348 | 354 |
349 if (sc->func) | 355 if (sc->func) |
350 { | 356 { |
351 // error("cannot declare template at function scope %s", sc->func->toChars()); | 357 #if DMDV1 |
358 error("cannot declare template at function scope %s", sc->func->toChars()); | |
359 #endif | |
352 } | 360 } |
353 | 361 |
354 if (/*global.params.useArrayBounds &&*/ sc->module) | 362 if (/*global.params.useArrayBounds &&*/ sc->module) |
355 { | 363 { |
356 // Generate this function as it may be used | 364 // Generate this function as it may be used |
357 // when template is instantiated in other modules | 365 // when template is instantiated in other modules |
358 sc->module->toModuleArray(); | 366 |
367 // FIXME: LDC | |
368 //sc->module->toModuleArray(); | |
359 } | 369 } |
360 | 370 |
361 if (/*global.params.useAssert &&*/ sc->module) | 371 if (/*global.params.useAssert &&*/ sc->module) |
362 { | 372 { |
363 // Generate this function as it may be used | 373 // Generate this function as it may be used |
364 // when template is instantiated in other modules | 374 // when template is instantiated in other modules |
365 sc->module->toModuleAssert(); | 375 |
376 // FIXME: LDC | |
377 //sc->module->toModuleAssert(); | |
366 } | 378 } |
367 | 379 |
368 /* Remember Scope for later instantiations, but make | 380 /* Remember Scope for later instantiations, but make |
369 * a copy since attributes can change. | 381 * a copy since attributes can change. |
370 */ | 382 */ |
374 // Set up scope for parameters | 386 // Set up scope for parameters |
375 ScopeDsymbol *paramsym = new ScopeDsymbol(); | 387 ScopeDsymbol *paramsym = new ScopeDsymbol(); |
376 paramsym->parent = sc->parent; | 388 paramsym->parent = sc->parent; |
377 Scope *paramscope = sc->push(paramsym); | 389 Scope *paramscope = sc->push(paramsym); |
378 paramscope->parameterSpecialization = 1; | 390 paramscope->parameterSpecialization = 1; |
391 paramscope->stc = 0; | |
392 | |
393 if (!parent) | |
394 parent = sc->parent; | |
379 | 395 |
380 if (global.params.doDocComments) | 396 if (global.params.doDocComments) |
381 { | 397 { |
382 origParameters = new TemplateParameters(); | 398 origParameters = new TemplateParameters(); |
383 origParameters->setDim(parameters->dim); | 399 origParameters->setDim(parameters->dim); |
534 // Set up scope for parameters | 550 // Set up scope for parameters |
535 assert((size_t)scope > 0x10000); | 551 assert((size_t)scope > 0x10000); |
536 ScopeDsymbol *paramsym = new ScopeDsymbol(); | 552 ScopeDsymbol *paramsym = new ScopeDsymbol(); |
537 paramsym->parent = scope->parent; | 553 paramsym->parent = scope->parent; |
538 Scope *paramscope = scope->push(paramsym); | 554 Scope *paramscope = scope->push(paramsym); |
555 paramscope->stc = 0; | |
539 | 556 |
540 // Attempt type deduction | 557 // Attempt type deduction |
541 m = MATCHexact; | 558 m = MATCHexact; |
542 for (int i = 0; i < dedtypes_dim; i++) | 559 for (int i = 0; i < dedtypes_dim; i++) |
543 { MATCH m2; | 560 { MATCH m2; |
589 dedtypes->data[i] = ti->tiargs->data[i]; | 606 dedtypes->data[i] = ti->tiargs->data[i]; |
590 } | 607 } |
591 } | 608 } |
592 } | 609 } |
593 | 610 |
611 #if DMDV2 | |
594 if (m && constraint && !(flag & 1)) | 612 if (m && constraint && !(flag & 1)) |
595 { /* Check to see if constraint is satisfied. | 613 { /* Check to see if constraint is satisfied. |
596 */ | 614 */ |
597 Expression *e = constraint->syntaxCopy(); | 615 Expression *e = constraint->syntaxCopy(); |
598 paramscope->flags |= SCOPEstaticif; | 616 paramscope->flags |= SCOPEstaticif; |
605 else | 623 else |
606 { | 624 { |
607 e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); | 625 e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); |
608 } | 626 } |
609 } | 627 } |
628 #endif | |
610 | 629 |
611 #if LOGM | 630 #if LOGM |
612 // Print out the results | 631 // Print out the results |
613 printf("--------------------------\n"); | 632 printf("--------------------------\n"); |
614 printf("template %s\n", toChars()); | 633 printf("template %s\n", toChars()); |
742 size_t nargsi; // array size of targsi | 761 size_t nargsi; // array size of targsi |
743 int fptupindex = -1; | 762 int fptupindex = -1; |
744 int tuple_dim = 0; | 763 int tuple_dim = 0; |
745 MATCH match = MATCHexact; | 764 MATCH match = MATCHexact; |
746 FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration(); | 765 FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration(); |
747 TypeFunction *fdtype; // type of fd | 766 Arguments *fparameters; // function parameter list |
748 TemplateTupleParameter *tp; | 767 int fvarargs; // function varargs |
749 Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T | 768 Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T |
750 | 769 |
751 #if 0 | 770 #if 0 |
752 printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars()); | 771 printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars()); |
753 for (i = 0; i < fargs->dim; i++) | 772 for (i = 0; i < fargs->dim; i++) |
754 { Expression *e = (Expression *)fargs->data[i]; | 773 { Expression *e = (Expression *)fargs->data[i]; |
755 printf("\tfarg[%d] is %s, type is %s\n", i, e->toChars(), e->type->toChars()); | 774 printf("\tfarg[%d] is %s, type is %s\n", i, e->toChars(), e->type->toChars()); |
756 } | 775 } |
776 printf("fd = %s\n", fd->toChars()); | |
777 printf("fd->type = %p\n", fd->type); | |
757 #endif | 778 #endif |
758 | 779 |
759 assert((size_t)scope > 0x10000); | 780 assert((size_t)scope > 0x10000); |
760 | 781 |
761 dedargs->setDim(parameters->dim); | 782 dedargs->setDim(parameters->dim); |
767 // Set up scope for parameters | 788 // Set up scope for parameters |
768 ScopeDsymbol *paramsym = new ScopeDsymbol(); | 789 ScopeDsymbol *paramsym = new ScopeDsymbol(); |
769 paramsym->parent = scope->parent; | 790 paramsym->parent = scope->parent; |
770 Scope *paramscope = scope->push(paramsym); | 791 Scope *paramscope = scope->push(paramsym); |
771 | 792 |
772 tp = isVariadic(); | 793 TemplateTupleParameter *tp = isVariadic(); |
794 | |
795 #if 0 | |
796 for (i = 0; i < dedargs->dim; i++) | |
797 { | |
798 printf("\tdedarg[%d] = ", i); | |
799 Object *oarg = (Object *)dedargs->data[i]; | |
800 if (oarg) printf("%s", oarg->toChars()); | |
801 printf("\n"); | |
802 } | |
803 #endif | |
804 | |
773 | 805 |
774 nargsi = 0; | 806 nargsi = 0; |
775 if (targsi) | 807 if (targsi) |
776 { // Set initial template arguments | 808 { // Set initial template arguments |
809 size_t n; | |
777 | 810 |
778 nargsi = targsi->dim; | 811 nargsi = targsi->dim; |
779 if (nargsi > parameters->dim) | 812 n = parameters->dim; |
813 if (tp) | |
814 n--; | |
815 if (nargsi > n) | |
780 { if (!tp) | 816 { if (!tp) |
781 goto Lnomatch; | 817 goto Lnomatch; |
782 dedargs->setDim(nargsi); | 818 |
783 dedargs->zero(); | 819 /* The extra initial template arguments |
784 } | 820 * now form the tuple argument. |
785 | 821 */ |
786 memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data)); | 822 Tuple *t = new Tuple(); |
787 | 823 assert(parameters->dim); |
788 for (i = 0; i < nargsi; i++) | 824 dedargs->data[parameters->dim - 1] = (void *)t; |
825 | |
826 tuple_dim = nargsi - n; | |
827 t->objects.setDim(tuple_dim); | |
828 for (size_t i = 0; i < tuple_dim; i++) | |
829 { | |
830 t->objects.data[i] = (void *)targsi->data[n + i]; | |
831 } | |
832 declareParameter(paramscope, tp, t); | |
833 } | |
834 else | |
835 n = nargsi; | |
836 | |
837 memcpy(dedargs->data, targsi->data, n * sizeof(*dedargs->data)); | |
838 | |
839 for (size_t i = 0; i < n; i++) | |
789 { assert(i < parameters->dim); | 840 { assert(i < parameters->dim); |
790 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; | 841 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; |
791 MATCH m; | 842 MATCH m; |
792 Declaration *sparam; | 843 Declaration *sparam = NULL; |
793 | 844 |
794 m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam); | 845 m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam); |
795 //printf("\tdeduceType m = %d\n", m); | 846 //printf("\tdeduceType m = %d\n", m); |
796 if (m == MATCHnomatch) | 847 if (m == MATCHnomatch) |
797 goto Lnomatch; | 848 goto Lnomatch; |
801 sparam->semantic(paramscope); | 852 sparam->semantic(paramscope); |
802 if (!paramscope->insert(sparam)) | 853 if (!paramscope->insert(sparam)) |
803 goto Lnomatch; | 854 goto Lnomatch; |
804 } | 855 } |
805 } | 856 } |
806 | 857 #if 0 |
807 assert(fd->type->ty == Tfunction); | 858 for (i = 0; i < dedargs->dim; i++) |
808 fdtype = (TypeFunction *)fd->type; | 859 { |
809 | 860 printf("\tdedarg[%d] = ", i); |
810 nfparams = Argument::dim(fdtype->parameters); // number of function parameters | 861 Object *oarg = (Object *)dedargs->data[i]; |
862 if (oarg) printf("%s", oarg->toChars()); | |
863 printf("\n"); | |
864 } | |
865 #endif | |
866 | |
867 if (fd->type) | |
868 { | |
869 assert(fd->type->ty == Tfunction); | |
870 TypeFunction *fdtype = (TypeFunction *)fd->type; | |
871 fparameters = fdtype->parameters; | |
872 fvarargs = fdtype->varargs; | |
873 } | |
874 else | |
875 { CtorDeclaration *fctor = fd->isCtorDeclaration(); | |
876 assert(fctor); | |
877 fparameters = fctor->arguments; | |
878 fvarargs = fctor->varargs; | |
879 } | |
880 | |
881 nfparams = Argument::dim(fparameters); // number of function parameters | |
811 nfargs = fargs->dim; // number of function arguments | 882 nfargs = fargs->dim; // number of function arguments |
812 | 883 |
813 /* Check for match of function arguments with variadic template | 884 /* Check for match of function arguments with variadic template |
814 * parameter, such as: | 885 * parameter, such as: |
815 * | 886 * |
821 if (nfparams == 0) // if no function parameters | 892 if (nfparams == 0) // if no function parameters |
822 { | 893 { |
823 Tuple *t = new Tuple(); | 894 Tuple *t = new Tuple(); |
824 //printf("t = %p\n", t); | 895 //printf("t = %p\n", t); |
825 dedargs->data[parameters->dim - 1] = (void *)t; | 896 dedargs->data[parameters->dim - 1] = (void *)t; |
897 declareParameter(paramscope, tp, t); | |
826 goto L2; | 898 goto L2; |
827 } | 899 } |
828 else if (nfargs < nfparams - 1) | 900 else if (nfargs < nfparams - 1) |
829 goto L1; | 901 goto L1; |
830 else | 902 else |
834 * type identifiers. | 906 * type identifiers. |
835 * Set the index of this function parameter to fptupindex. | 907 * Set the index of this function parameter to fptupindex. |
836 */ | 908 */ |
837 for (fptupindex = 0; fptupindex < nfparams; fptupindex++) | 909 for (fptupindex = 0; fptupindex < nfparams; fptupindex++) |
838 { | 910 { |
839 Argument *fparam = (Argument *)fdtype->parameters->data[fptupindex]; | 911 Argument *fparam = (Argument *)fparameters->data[fptupindex]; |
840 if (fparam->type->ty != Tident) | 912 if (fparam->type->ty != Tident) |
841 continue; | 913 continue; |
842 TypeIdentifier *tid = (TypeIdentifier *)fparam->type; | 914 TypeIdentifier *tid = (TypeIdentifier *)fparam->type; |
843 if (!tp->ident->equals(tid->ident) || tid->idents.dim) | 915 if (!tp->ident->equals(tid->ident) || tid->idents.dim) |
844 continue; | 916 continue; |
845 | 917 |
846 if (fdtype->varargs) // variadic function doesn't | 918 if (fvarargs) // variadic function doesn't |
847 goto Lnomatch; // go with variadic template | 919 goto Lnomatch; // go with variadic template |
848 | 920 |
849 /* The types of the function arguments | 921 /* The types of the function arguments |
850 * now form the tuple argument. | 922 * now form the tuple argument. |
851 */ | 923 */ |
856 t->objects.setDim(tuple_dim); | 928 t->objects.setDim(tuple_dim); |
857 for (i = 0; i < tuple_dim; i++) | 929 for (i = 0; i < tuple_dim; i++) |
858 { Expression *farg = (Expression *)fargs->data[fptupindex + i]; | 930 { Expression *farg = (Expression *)fargs->data[fptupindex + i]; |
859 t->objects.data[i] = (void *)farg->type; | 931 t->objects.data[i] = (void *)farg->type; |
860 } | 932 } |
933 declareParameter(paramscope, tp, t); | |
861 goto L2; | 934 goto L2; |
862 } | 935 } |
863 fptupindex = -1; | 936 fptupindex = -1; |
864 } | 937 } |
865 } | 938 } |
867 L1: | 940 L1: |
868 if (nfparams == nfargs) | 941 if (nfparams == nfargs) |
869 ; | 942 ; |
870 else if (nfargs > nfparams) | 943 else if (nfargs > nfparams) |
871 { | 944 { |
872 if (fdtype->varargs == 0) | 945 if (fvarargs == 0) |
873 goto Lnomatch; // too many args, no match | 946 goto Lnomatch; // too many args, no match |
874 match = MATCHconvert; // match ... with a conversion | 947 match = MATCHconvert; // match ... with a conversion |
875 } | 948 } |
876 | 949 |
877 L2: | 950 L2: |
951 #if DMDV2 | |
878 // Match 'ethis' to any TemplateThisParameter's | 952 // Match 'ethis' to any TemplateThisParameter's |
879 if (ethis) | 953 if (ethis) |
880 { | 954 { |
881 for (size_t i = 0; i < parameters->dim; i++) | 955 for (size_t i = 0; i < parameters->dim; i++) |
882 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; | 956 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; |
883 TemplateThisParameter *ttp = tp->isTemplateThisParameter(); | 957 TemplateThisParameter *ttp = tp->isTemplateThisParameter(); |
884 if (ttp) | 958 if (ttp) |
885 { MATCH m; | 959 { MATCH m; |
886 | 960 |
887 Type *t = new TypeIdentifier(0, ttp->ident); | 961 Type *t = new TypeIdentifier(0, ttp->ident); |
888 m = ethis->type->deduceType(scope, t, parameters, &dedtypes); | 962 m = ethis->type->deduceType(paramscope, t, parameters, &dedtypes); |
889 if (!m) | 963 if (!m) |
890 goto Lnomatch; | 964 goto Lnomatch; |
891 if (m < match) | 965 if (m < match) |
892 match = m; // pick worst match | 966 match = m; // pick worst match |
893 } | 967 } |
894 } | 968 } |
895 } | 969 } |
970 #endif | |
896 | 971 |
897 // Loop through the function parameters | 972 // Loop through the function parameters |
898 for (i = 0; i < nfparams; i++) | 973 for (i = 0; i < nfparams; i++) |
899 { | 974 { |
900 /* Skip over function parameters which wound up | 975 /* Skip over function parameters which wound up |
905 break; | 980 break; |
906 i += tuple_dim - 1; | 981 i += tuple_dim - 1; |
907 continue; | 982 continue; |
908 } | 983 } |
909 | 984 |
910 Argument *fparam = Argument::getNth(fdtype->parameters, i); | 985 Argument *fparam = Argument::getNth(fparameters, i); |
911 | 986 |
912 if (i >= nfargs) // if not enough arguments | 987 if (i >= nfargs) // if not enough arguments |
913 { | 988 { |
914 if (fparam->defaultArg) | 989 if (fparam->defaultArg) |
915 { /* Default arguments do not participate in template argument | 990 { /* Default arguments do not participate in template argument |
922 { Expression *farg = (Expression *)fargs->data[i]; | 997 { Expression *farg = (Expression *)fargs->data[i]; |
923 #if 0 | 998 #if 0 |
924 printf("\tfarg->type = %s\n", farg->type->toChars()); | 999 printf("\tfarg->type = %s\n", farg->type->toChars()); |
925 printf("\tfparam->type = %s\n", fparam->type->toChars()); | 1000 printf("\tfparam->type = %s\n", fparam->type->toChars()); |
926 #endif | 1001 #endif |
1002 Type *argtype = farg->type; | |
1003 | |
1004 #if DMDV2 | |
1005 /* Allow string literals which are type [] to match with [dim] | |
1006 */ | |
1007 if (farg->op == TOKstring) | |
1008 { StringExp *se = (StringExp *)farg; | |
1009 if (!se->committed && argtype->ty == Tarray && | |
1010 fparam->type->toBasetype()->ty == Tsarray) | |
1011 { | |
1012 argtype = new TypeSArray(argtype->nextOf(), new IntegerExp(se->loc, se->len, Type::tindex)); | |
1013 argtype = argtype->semantic(se->loc, NULL); | |
1014 argtype = argtype->invariantOf(); | |
1015 } | |
1016 } | |
1017 #endif | |
1018 | |
927 MATCH m; | 1019 MATCH m; |
928 //m = farg->type->toHeadMutable()->deduceType(scope, fparam->type, parameters, &dedtypes); | 1020 m = argtype->deduceType(paramscope, fparam->type, parameters, &dedtypes); |
929 m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes); | |
930 //printf("\tdeduceType m = %d\n", m); | 1021 //printf("\tdeduceType m = %d\n", m); |
931 | 1022 |
932 /* If no match, see if there's a conversion to a delegate | 1023 /* If no match, see if there's a conversion to a delegate |
933 */ | 1024 */ |
934 if (!m && fparam->type->toBasetype()->ty == Tdelegate) | 1025 if (!m && fparam->type->toBasetype()->ty == Tdelegate) |
936 TypeDelegate *td = (TypeDelegate *)fparam->type->toBasetype(); | 1027 TypeDelegate *td = (TypeDelegate *)fparam->type->toBasetype(); |
937 TypeFunction *tf = (TypeFunction *)td->next; | 1028 TypeFunction *tf = (TypeFunction *)td->next; |
938 | 1029 |
939 if (!tf->varargs && Argument::dim(tf->parameters) == 0) | 1030 if (!tf->varargs && Argument::dim(tf->parameters) == 0) |
940 { | 1031 { |
941 m = farg->type->deduceType(scope, tf->next, parameters, &dedtypes); | 1032 m = farg->type->deduceType(paramscope, tf->next, parameters, &dedtypes); |
942 if (!m && tf->next->toBasetype()->ty == Tvoid) | 1033 if (!m && tf->next->toBasetype()->ty == Tvoid) |
943 m = MATCHconvert; | 1034 m = MATCHconvert; |
944 } | 1035 } |
945 //printf("\tm2 = %d\n", m); | 1036 //printf("\tm2 = %d\n", m); |
946 } | 1037 } |
953 } | 1044 } |
954 | 1045 |
955 /* The following code for variadic arguments closely | 1046 /* The following code for variadic arguments closely |
956 * matches TypeFunction::callMatch() | 1047 * matches TypeFunction::callMatch() |
957 */ | 1048 */ |
958 if (!(fdtype->varargs == 2 && i + 1 == nfparams)) | 1049 if (!(fvarargs == 2 && i + 1 == nfparams)) |
959 goto Lnomatch; | 1050 goto Lnomatch; |
960 | 1051 |
961 /* Check for match with function parameter T... | 1052 /* Check for match with function parameter T... |
962 */ | 1053 */ |
963 Type *tb = fparam->type->toBasetype(); | 1054 Type *tb = fparam->type->toBasetype(); |
964 switch (tb->ty) | 1055 switch (tb->ty) |
965 { | 1056 { |
966 // Perhaps we can do better with this, see TypeFunction::callMatch() | 1057 // Perhaps we can do better with this, see TypeFunction::callMatch() |
967 case Tsarray: | 1058 case Tsarray: |
968 { TypeSArray *tsa = (TypeSArray *)tb; | 1059 { TypeSArray *tsa = (TypeSArray *)tb; |
969 integer_t sz = tsa->dim->toInteger(); | 1060 dinteger_t sz = tsa->dim->toInteger(); |
970 if (sz != nfargs - i) | 1061 if (sz != nfargs - i) |
971 goto Lnomatch; | 1062 goto Lnomatch; |
972 } | 1063 } |
973 case Tarray: | 1064 case Tarray: |
974 { TypeArray *ta = (TypeArray *)tb; | 1065 { TypeArray *ta = (TypeArray *)tb; |
996 } | 1087 } |
997 } | 1088 } |
998 } | 1089 } |
999 else | 1090 else |
1000 { | 1091 { |
1001 m = arg->type->deduceType(scope, ta->next, parameters, &dedtypes); | 1092 m = arg->type->deduceType(paramscope, ta->next, parameters, &dedtypes); |
1002 //m = arg->implicitConvTo(ta->next); | 1093 //m = arg->implicitConvTo(ta->next); |
1003 } | 1094 } |
1004 if (m == MATCHnomatch) | 1095 if (m == MATCHnomatch) |
1005 goto Lnomatch; | 1096 goto Lnomatch; |
1006 if (m < match) | 1097 if (m < match) |
1029 * But for function templates, we really need them to match | 1120 * But for function templates, we really need them to match |
1030 */ | 1121 */ |
1031 Object *oarg = (Object *)dedargs->data[i]; | 1122 Object *oarg = (Object *)dedargs->data[i]; |
1032 Object *oded = (Object *)dedtypes.data[i]; | 1123 Object *oded = (Object *)dedtypes.data[i]; |
1033 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded); | 1124 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded); |
1125 //if (oarg) printf("oarg: %s\n", oarg->toChars()); | |
1126 //if (oded) printf("oded: %s\n", oded->toChars()); | |
1034 if (!oarg) | 1127 if (!oarg) |
1035 { | 1128 { |
1036 if (oded) | 1129 if (oded) |
1037 { | 1130 { |
1038 if (tp->specialization()) | 1131 if (tp->specialization()) |
1059 declareParameter(paramscope, tp, oded); | 1152 declareParameter(paramscope, tp, oded); |
1060 dedargs->data[i] = (void *)oded; | 1153 dedargs->data[i] = (void *)oded; |
1061 } | 1154 } |
1062 } | 1155 } |
1063 | 1156 |
1157 #if DMDV2 | |
1064 if (constraint) | 1158 if (constraint) |
1065 { /* Check to see if constraint is satisfied. | 1159 { /* Check to see if constraint is satisfied. |
1066 */ | 1160 */ |
1067 Expression *e = constraint->syntaxCopy(); | 1161 Expression *e = constraint->syntaxCopy(); |
1068 paramscope->flags |= SCOPEstaticif; | 1162 paramscope->flags |= SCOPEstaticif; |
1075 else | 1169 else |
1076 { | 1170 { |
1077 e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); | 1171 e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); |
1078 } | 1172 } |
1079 } | 1173 } |
1080 | 1174 #endif |
1081 | 1175 |
1082 #if 0 | 1176 #if 0 |
1083 for (i = 0; i < dedargs->dim; i++) | 1177 for (i = 0; i < dedargs->dim; i++) |
1084 { Type *t = (Type *)dedargs->data[i]; | 1178 { Type *t = (Type *)dedargs->data[i]; |
1085 printf("\tdedargs[%d] = %d, %s\n", i, t->dyncast(), t->toChars()); | 1179 printf("\tdedargs[%d] = %d, %s\n", i, t->dyncast(), t->toChars()); |
1108 Expression *ea = isExpression(o); | 1202 Expression *ea = isExpression(o); |
1109 Dsymbol *sa = isDsymbol(o); | 1203 Dsymbol *sa = isDsymbol(o); |
1110 Tuple *va = isTuple(o); | 1204 Tuple *va = isTuple(o); |
1111 | 1205 |
1112 Dsymbol *s; | 1206 Dsymbol *s; |
1207 | |
1208 // See if tp->ident already exists with a matching definition | |
1209 Dsymbol *scopesym; | |
1210 s = sc->search(loc, tp->ident, &scopesym); | |
1211 if (s && scopesym == sc->scopesym) | |
1212 { | |
1213 TupleDeclaration *td = s->isTupleDeclaration(); | |
1214 if (va && td) | |
1215 { Tuple tup; | |
1216 tup.objects = *td->objects; | |
1217 if (match(va, &tup, this, sc)) | |
1218 { | |
1219 return; | |
1220 } | |
1221 } | |
1222 } | |
1113 | 1223 |
1114 if (targ) | 1224 if (targ) |
1115 { | 1225 { |
1116 //printf("type %s\n", targ->toChars()); | 1226 //printf("type %s\n", targ->toChars()); |
1117 s = new AliasDeclaration(0, tp->ident, targ); | 1227 s = new AliasDeclaration(0, tp->ident, targ); |
1296 if (!fd) | 1406 if (!fd) |
1297 goto Lerror; | 1407 goto Lerror; |
1298 return fd; | 1408 return fd; |
1299 | 1409 |
1300 Lerror: | 1410 Lerror: |
1411 #if DMDV2 | |
1301 if (!(flags & 1)) | 1412 if (!(flags & 1)) |
1413 #endif | |
1302 { | 1414 { |
1303 HdrGenState hgs; | 1415 HdrGenState hgs; |
1304 | 1416 |
1305 OutBuffer bufa; | 1417 OutBuffer bufa; |
1306 Objects *args = targsi; | 1418 Objects *args = targsi; |
1314 } | 1426 } |
1315 } | 1427 } |
1316 | 1428 |
1317 OutBuffer buf; | 1429 OutBuffer buf; |
1318 argExpTypesToCBuffer(&buf, fargs, &hgs); | 1430 argExpTypesToCBuffer(&buf, fargs, &hgs); |
1319 | |
1320 error(loc, "cannot deduce template function from argument types !(%s)(%s)", | 1431 error(loc, "cannot deduce template function from argument types !(%s)(%s)", |
1321 bufa.toChars(), buf.toChars()); | 1432 bufa.toChars(), buf.toChars()); |
1322 } | 1433 } |
1323 return NULL; | 1434 return NULL; |
1324 } | 1435 } |
1341 if (i) | 1452 if (i) |
1342 buf->writeByte(','); | 1453 buf->writeByte(','); |
1343 tp->toCBuffer(buf, hgs); | 1454 tp->toCBuffer(buf, hgs); |
1344 } | 1455 } |
1345 buf->writeByte(')'); | 1456 buf->writeByte(')'); |
1346 | 1457 #if DMDV2 |
1347 if (constraint) | 1458 if (constraint) |
1348 { buf->writestring(" if ("); | 1459 { buf->writestring(" if ("); |
1349 constraint->toCBuffer(buf, hgs); | 1460 constraint->toCBuffer(buf, hgs); |
1350 buf->writeByte(')'); | 1461 buf->writeByte(')'); |
1351 } | 1462 } |
1463 #endif | |
1352 | 1464 |
1353 if (hgs->hdrgen) | 1465 if (hgs->hdrgen) |
1354 { | 1466 { |
1355 hgs->tpltMember++; | 1467 hgs->tpltMember++; |
1356 buf->writenl(); | 1468 buf->writenl(); |
1381 if (i) | 1493 if (i) |
1382 buf.writeByte(','); | 1494 buf.writeByte(','); |
1383 tp->toCBuffer(&buf, &hgs); | 1495 tp->toCBuffer(&buf, &hgs); |
1384 } | 1496 } |
1385 buf.writeByte(')'); | 1497 buf.writeByte(')'); |
1386 | 1498 #if DMDV2 |
1387 if (constraint) | 1499 if (constraint) |
1388 { buf.writestring(" if ("); | 1500 { buf.writestring(" if ("); |
1389 constraint->toCBuffer(&buf, &hgs); | 1501 constraint->toCBuffer(&buf, &hgs); |
1390 buf.writeByte(')'); | 1502 buf.writeByte(')'); |
1391 } | 1503 } |
1392 | 1504 #endif |
1393 buf.writeByte(0); | 1505 buf.writeByte(0); |
1394 return (char *)buf.extractData(); | 1506 return (char *)buf.extractData(); |
1395 } | 1507 } |
1396 | 1508 |
1397 /* ======================== Type ============================================ */ | 1509 /* ======================== Type ============================================ */ |
1548 return MATCHexact; | 1660 return MATCHexact; |
1549 | 1661 |
1550 Lnomatch: | 1662 Lnomatch: |
1551 return MATCHnomatch; | 1663 return MATCHnomatch; |
1552 | 1664 |
1665 #if DMDV2 | |
1553 Lconst: | 1666 Lconst: |
1554 return MATCHconst; | 1667 return MATCHconst; |
1555 } | 1668 #endif |
1669 } | |
1670 | |
1671 #if DMDV2 | |
1672 MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, | |
1673 Objects *dedtypes) | |
1674 { | |
1675 #if 0 | |
1676 printf("TypeDArray::deduceType()\n"); | |
1677 printf("\tthis = %d, ", ty); print(); | |
1678 printf("\ttparam = %d, ", tparam->ty); tparam->print(); | |
1679 #endif | |
1680 return Type::deduceType(sc, tparam, parameters, dedtypes); | |
1681 | |
1682 Lnomatch: | |
1683 return MATCHnomatch; | |
1684 } | |
1685 #endif | |
1556 | 1686 |
1557 MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, | 1687 MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, |
1558 Objects *dedtypes) | 1688 Objects *dedtypes) |
1559 { | 1689 { |
1560 #if 0 | 1690 #if 0 |
1687 if (nfparams > 0 && nfargs >= nfparams - 1) | 1817 if (nfparams > 0 && nfargs >= nfparams - 1) |
1688 { | 1818 { |
1689 /* See if 'A' of the template parameter matches 'A' | 1819 /* See if 'A' of the template parameter matches 'A' |
1690 * of the type of the last function parameter. | 1820 * of the type of the last function parameter. |
1691 */ | 1821 */ |
1692 Argument *fparam = (Argument *)tp->parameters->data[nfparams - 1]; | 1822 Argument *fparam = Argument::getNth(tp->parameters, nfparams - 1); |
1823 assert(fparam); | |
1824 assert(fparam->type); | |
1693 if (fparam->type->ty != Tident) | 1825 if (fparam->type->ty != Tident) |
1694 goto L1; | 1826 goto L1; |
1695 TypeIdentifier *tid = (TypeIdentifier *)fparam->type; | 1827 TypeIdentifier *tid = (TypeIdentifier *)fparam->type; |
1696 if (tid->idents.dim) | 1828 if (tid->idents.dim) |
1697 goto L1; | 1829 goto L1; |
1778 | 1910 |
1779 MATCH TypeInstance::deduceType(Scope *sc, | 1911 MATCH TypeInstance::deduceType(Scope *sc, |
1780 Type *tparam, TemplateParameters *parameters, | 1912 Type *tparam, TemplateParameters *parameters, |
1781 Objects *dedtypes) | 1913 Objects *dedtypes) |
1782 { | 1914 { |
1783 //printf("TypeInstance::deduceType(tparam = %s) %s\n", tparam->toChars(), toChars()); | 1915 #if 0 |
1784 //printf("\ttparam = %d, ", tparam->ty); tparam->print(); | 1916 printf("TypeInstance::deduceType()\n"); |
1917 printf("\tthis = %d, ", ty); print(); | |
1918 printf("\ttparam = %d, ", tparam->ty); tparam->print(); | |
1919 #endif | |
1785 | 1920 |
1786 // Extra check | 1921 // Extra check |
1787 if (tparam && tparam->ty == Tinstance) | 1922 if (tparam && tparam->ty == Tinstance) |
1788 { | 1923 { |
1789 TypeInstance *tp = (TypeInstance *)tparam; | 1924 TypeInstance *tp = (TypeInstance *)tparam; |
1834 } | 1969 } |
1835 else if (tempinst->tempdecl != tp->tempinst->tempdecl) | 1970 else if (tempinst->tempdecl != tp->tempinst->tempdecl) |
1836 goto Lnomatch; | 1971 goto Lnomatch; |
1837 | 1972 |
1838 L2: | 1973 L2: |
1839 if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim) | |
1840 goto Lnomatch; | |
1841 | 1974 |
1842 for (int i = 0; i < tempinst->tiargs->dim; i++) | 1975 for (int i = 0; i < tempinst->tiargs->dim; i++) |
1843 { | 1976 { |
1844 //printf("\ttest: tempinst->tiargs[%d]\n", i); | 1977 //printf("\ttest: tempinst->tiargs[%d]\n", i); |
1978 if (i >= tp->tempinst->tiargs->dim) | |
1979 goto Lnomatch; | |
1980 | |
1845 int j; | 1981 int j; |
1846 Object *o1 = (Object *)tempinst->tiargs->data[i]; | 1982 Object *o1 = (Object *)tempinst->tiargs->data[i]; |
1847 Object *o2 = (Object *)tp->tempinst->tiargs->data[i]; | 1983 Object *o2 = (Object *)tp->tempinst->tiargs->data[i]; |
1848 | 1984 |
1849 Type *t1 = isType(o1); | 1985 Type *t1 = isType(o1); |
1850 Type *t2 = isType(o2); | 1986 Type *t2 = isType(o2); |
1851 | 1987 |
1852 Expression *e1 = isExpression(o1); | 1988 Expression *e1 = isExpression(o1); |
1853 Expression *e2 = isExpression(o2); | 1989 Expression *e2 = isExpression(o2); |
1854 | 1990 |
1991 Dsymbol *s1 = isDsymbol(o1); | |
1992 Dsymbol *s2 = isDsymbol(o2); | |
1993 | |
1994 Tuple *v1 = isTuple(o1); | |
1995 Tuple *v2 = isTuple(o2); | |
1855 #if 0 | 1996 #if 0 |
1856 if (t1) printf("t1 = %s\n", t1->toChars()); | 1997 if (t1) printf("t1 = %s\n", t1->toChars()); |
1857 if (t2) printf("t2 = %s\n", t2->toChars()); | 1998 if (t2) printf("t2 = %s\n", t2->toChars()); |
1858 if (e1) printf("e1 = %s\n", e1->toChars()); | 1999 if (e1) printf("e1 = %s\n", e1->toChars()); |
1859 if (e2) printf("e2 = %s\n", e2->toChars()); | 2000 if (e2) printf("e2 = %s\n", e2->toChars()); |
1860 #endif | 2001 if (s1) printf("s1 = %s\n", s1->toChars()); |
2002 if (s2) printf("s2 = %s\n", s2->toChars()); | |
2003 if (v1) printf("v1 = %s\n", v1->toChars()); | |
2004 if (v2) printf("v2 = %s\n", v2->toChars()); | |
2005 #endif | |
2006 | |
2007 TemplateTupleParameter *ttp; | |
2008 if (t2 && | |
2009 t2->ty == Tident && | |
2010 i == tp->tempinst->tiargs->dim - 1 && | |
2011 i == tempinst->tempdecl->parameters->dim - 1 && | |
2012 (ttp = tempinst->tempdecl->isVariadic()) != NULL) | |
2013 { | |
2014 /* Given: | |
2015 * struct A(B...) {} | |
2016 * alias A!(int, float) X; | |
2017 * static if (!is(X Y == A!(Z), Z)) | |
2018 * deduce that Z is a tuple(int, float) | |
2019 */ | |
2020 | |
2021 j = templateParameterLookup(t2, parameters); | |
2022 if (j == -1) | |
2023 goto Lnomatch; | |
2024 | |
2025 /* Create tuple from remaining args | |
2026 */ | |
2027 Tuple *vt = new Tuple(); | |
2028 int vtdim = tempinst->tiargs->dim - i; | |
2029 vt->objects.setDim(vtdim); | |
2030 for (size_t k = 0; k < vtdim; k++) | |
2031 vt->objects.data[k] = (void *)tempinst->tiargs->data[i + k]; | |
2032 | |
2033 Tuple *v = (Tuple *)dedtypes->data[j]; | |
2034 if (v) | |
2035 { | |
2036 if (!match(v, vt, tempinst->tempdecl, sc)) | |
2037 goto Lnomatch; | |
2038 } | |
2039 else | |
2040 dedtypes->data[j] = vt; | |
2041 break; //return MATCHexact; | |
2042 } | |
1861 | 2043 |
1862 if (t1 && t2) | 2044 if (t1 && t2) |
1863 { | 2045 { |
1864 if (!t1->deduceType(sc, t2, parameters, dedtypes)) | 2046 if (!t1->deduceType(sc, t2, parameters, dedtypes)) |
1865 goto Lnomatch; | 2047 goto Lnomatch; |
1901 if (!m) | 2083 if (!m) |
1902 goto Lnomatch; | 2084 goto Lnomatch; |
1903 dedtypes->data[j] = e1; | 2085 dedtypes->data[j] = e1; |
1904 } | 2086 } |
1905 } | 2087 } |
1906 // BUG: Need to handle alias and tuple parameters | 2088 else if (s1 && t2 && t2->ty == Tident) |
2089 { | |
2090 j = templateParameterLookup(t2, parameters); | |
2091 if (j == -1) | |
2092 goto Lnomatch; | |
2093 TemplateParameter *tp = (TemplateParameter *)parameters->data[j]; | |
2094 // BUG: use tp->matchArg() instead of the following | |
2095 TemplateAliasParameter *ta = tp->isTemplateAliasParameter(); | |
2096 if (!ta) | |
2097 goto Lnomatch; | |
2098 Dsymbol *s = (Dsymbol *)dedtypes->data[j]; | |
2099 if (s) | |
2100 { | |
2101 if (!s1->equals(s)) | |
2102 goto Lnomatch; | |
2103 } | |
2104 else | |
2105 { | |
2106 dedtypes->data[j] = s1; | |
2107 } | |
2108 } | |
2109 else if (s1 && s2) | |
2110 { | |
2111 if (!s1->equals(s2)) | |
2112 goto Lnomatch; | |
2113 } | |
2114 // BUG: Need to handle tuple parameters | |
1907 else | 2115 else |
1908 goto Lnomatch; | 2116 goto Lnomatch; |
1909 } | 2117 } |
1910 } | 2118 } |
1911 return Type::deduceType(sc, tparam, parameters, dedtypes); | 2119 return Type::deduceType(sc, tparam, parameters, dedtypes); |
2535 } | 2743 } |
2536 return MATCHexact; | 2744 return MATCHexact; |
2537 | 2745 |
2538 Lnomatch: | 2746 Lnomatch: |
2539 *psparam = NULL; | 2747 *psparam = NULL; |
2748 //printf("\tm = %d\n", MATCHnomatch); | |
2540 return MATCHnomatch; | 2749 return MATCHnomatch; |
2541 } | 2750 } |
2542 | 2751 |
2543 | 2752 |
2544 void TemplateAliasParameter::print(Object *oarg, Object *oded) | 2753 void TemplateAliasParameter::print(Object *oarg, Object *oded) |
2768 vt = valType->semantic(0, sc); | 2977 vt = valType->semantic(0, sc); |
2769 //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars()); | 2978 //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars()); |
2770 //printf("vt = %s\n", vt->toChars()); | 2979 //printf("vt = %s\n", vt->toChars()); |
2771 if (ei->type) | 2980 if (ei->type) |
2772 { | 2981 { |
2773 //ei->type = ei->type->toHeadMutable(); | |
2774 m = (MATCH)ei->implicitConvTo(vt); | 2982 m = (MATCH)ei->implicitConvTo(vt); |
2775 //printf("m: %d\n", m); | 2983 //printf("m: %d\n", m); |
2776 if (!m) | 2984 if (!m) |
2777 goto Lnomatch; | 2985 goto Lnomatch; |
2778 } | 2986 } |
3002 this->loc = loc; | 3210 this->loc = loc; |
3003 this->name = ident; | 3211 this->name = ident; |
3004 this->tiargs = NULL; | 3212 this->tiargs = NULL; |
3005 this->tempdecl = NULL; | 3213 this->tempdecl = NULL; |
3006 this->inst = NULL; | 3214 this->inst = NULL; |
3215 this->tinst = NULL; | |
3007 this->argsym = NULL; | 3216 this->argsym = NULL; |
3008 this->aliasdecl = NULL; | 3217 this->aliasdecl = NULL; |
3009 this->semanticdone = 0; | 3218 this->semanticdone = 0; |
3010 this->semantictiargsdone = 0; | 3219 this->semantictiargsdone = 0; |
3011 this->withsym = NULL; | 3220 this->withsym = NULL; |
3012 this->nest = 0; | 3221 this->nest = 0; |
3013 this->havetempdecl = 0; | 3222 this->havetempdecl = 0; |
3014 this->isnested = NULL; | 3223 this->isnested = NULL; |
3015 this->errors = 0; | 3224 this->errors = 0; |
3016 | 3225 |
3226 #if IN_LLVM | |
3017 // LDC | 3227 // LDC |
3018 this->tinst = NULL; | 3228 this->emittedInModule = NULL; |
3019 this->tmodule = NULL; | 3229 this->tmodule = NULL; |
3230 #endif | |
3020 } | 3231 } |
3021 | 3232 |
3022 /***************** | 3233 /***************** |
3023 * This constructor is only called when we figured out which function | 3234 * This constructor is only called when we figured out which function |
3024 * template to instantiate. | 3235 * template to instantiate. |
3033 this->loc = loc; | 3244 this->loc = loc; |
3034 this->name = td->ident; | 3245 this->name = td->ident; |
3035 this->tiargs = tiargs; | 3246 this->tiargs = tiargs; |
3036 this->tempdecl = td; | 3247 this->tempdecl = td; |
3037 this->inst = NULL; | 3248 this->inst = NULL; |
3249 this->tinst = NULL; | |
3038 this->argsym = NULL; | 3250 this->argsym = NULL; |
3039 this->aliasdecl = NULL; | 3251 this->aliasdecl = NULL; |
3040 this->semanticdone = 0; | 3252 this->semanticdone = 0; |
3041 this->semantictiargsdone = 1; | 3253 this->semantictiargsdone = 1; |
3042 this->withsym = NULL; | 3254 this->withsym = NULL; |
3043 this->nest = 0; | 3255 this->nest = 0; |
3044 this->havetempdecl = 1; | 3256 this->havetempdecl = 1; |
3045 this->isnested = NULL; | 3257 this->isnested = NULL; |
3046 this->errors = 0; | 3258 this->errors = 0; |
3047 | 3259 |
3260 #if IN_LLVM | |
3048 // LDC | 3261 // LDC |
3049 this->tinst = NULL; | 3262 this->tinst = NULL; |
3050 this->tmodule = NULL; | 3263 this->tmodule = NULL; |
3264 #endif | |
3051 | 3265 |
3052 assert((size_t)tempdecl->scope > 0x10000); | 3266 assert((size_t)tempdecl->scope > 0x10000); |
3053 } | 3267 } |
3054 | 3268 |
3055 | 3269 |
3105 printf("-TemplateInstance::semantic('%s', this=%p) already run\n", inst->toChars(), inst); | 3319 printf("-TemplateInstance::semantic('%s', this=%p) already run\n", inst->toChars(), inst); |
3106 #endif | 3320 #endif |
3107 return; | 3321 return; |
3108 } | 3322 } |
3109 | 3323 |
3324 // get the enclosing template instance from the scope tinst | |
3325 tinst = sc->tinst; | |
3326 | |
3110 if (semanticdone != 0) | 3327 if (semanticdone != 0) |
3111 { | 3328 { |
3112 error(loc, "recursive template expansion"); | 3329 error(loc, "recursive template expansion"); |
3113 // inst = this; | 3330 // inst = this; |
3114 return; | 3331 return; |
3115 } | 3332 } |
3116 semanticdone = 1; | 3333 semanticdone = 1; |
3117 | 3334 #if IN_LLVM |
3118 // get the enclosing template instance from the scope tinst | 3335 // get the enclosing template instance from the scope tinst |
3119 tinst = sc->tinst; | 3336 tinst = sc->tinst; |
3120 | 3337 |
3121 // get the module of the outermost enclosing instantiation | 3338 // get the module of the outermost enclosing instantiation |
3122 if (tinst) | 3339 if (tinst) |
3123 tmodule = tinst->tmodule; | 3340 tmodule = tinst->tmodule; |
3124 else | 3341 else |
3125 tmodule = sc->module; | 3342 tmodule = sc->module; |
3126 //printf("%s in %s\n", toChars(), tmodule->toChars()); | 3343 //printf("%s in %s\n", toChars(), tmodule->toChars()); |
3344 #endif | |
3127 | 3345 |
3128 #if LOG | 3346 #if LOG |
3129 printf("\tdo semantic\n"); | 3347 printf("\tdo semantic\n"); |
3130 #endif | 3348 #endif |
3131 if (havetempdecl) | 3349 if (havetempdecl) |
3155 //printf("error return %p, %d\n", tempdecl, global.errors); | 3373 //printf("error return %p, %d\n", tempdecl, global.errors); |
3156 return; // error recovery | 3374 return; // error recovery |
3157 } | 3375 } |
3158 } | 3376 } |
3159 | 3377 |
3160 isNested(tiargs); | 3378 hasNestedArgs(tiargs); |
3161 | 3379 |
3162 /* See if there is an existing TemplateInstantiation that already | 3380 /* See if there is an existing TemplateInstantiation that already |
3163 * implements the typeargs. If so, just refer to that one instead. | 3381 * implements the typeargs. If so, just refer to that one instead. |
3164 */ | 3382 */ |
3165 | 3383 |
3171 #endif | 3389 #endif |
3172 assert(tdtypes.dim == ti->tdtypes.dim); | 3390 assert(tdtypes.dim == ti->tdtypes.dim); |
3173 | 3391 |
3174 // Nesting must match | 3392 // Nesting must match |
3175 if (isnested != ti->isnested) | 3393 if (isnested != ti->isnested) |
3394 { | |
3395 //printf("test2 isnested %s ti->isnested %s\n", isnested ? isnested->toChars() : "", ti->isnested ? ti->isnested->toChars() : ""); | |
3176 continue; | 3396 continue; |
3397 } | |
3177 #if 0 | 3398 #if 0 |
3178 if (isnested && sc->parent != ti->parent) | 3399 if (isnested && sc->parent != ti->parent) |
3179 continue; | 3400 continue; |
3180 #endif | 3401 #endif |
3181 for (size_t j = 0; j < tdtypes.dim; j++) | 3402 for (size_t j = 0; j < tdtypes.dim; j++) |
3182 { Object *o1 = (Object *)tdtypes.data[j]; | 3403 { Object *o1 = (Object *)tdtypes.data[j]; |
3183 Object *o2 = (Object *)ti->tdtypes.data[j]; | 3404 Object *o2 = (Object *)ti->tdtypes.data[j]; |
3184 if (!match(o1, o2, tempdecl, sc)) | 3405 if (!match(o1, o2, tempdecl, sc)) |
3406 { | |
3185 goto L1; | 3407 goto L1; |
3408 } | |
3186 } | 3409 } |
3187 | 3410 |
3188 // It's a match | 3411 // It's a match |
3189 inst = ti; | 3412 inst = ti; |
3190 parent = ti->parent; | 3413 parent = ti->parent; |
3229 if (scx->scopesym) | 3452 if (scx->scopesym) |
3230 break; | 3453 break; |
3231 #endif | 3454 #endif |
3232 | 3455 |
3233 //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); | 3456 //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); |
3234 if (scx && scx->scopesym && scx->scopesym->members && !scx->scopesym->isTemplateMixin()) | 3457 if (scx && scx->scopesym && |
3458 scx->scopesym->members && !scx->scopesym->isTemplateMixin() | |
3459 #if 0 // removed because it bloated compile times | |
3460 /* The problem is if A imports B, and B imports A, and both A | |
3461 * and B instantiate the same template, does the compilation of A | |
3462 * or the compilation of B do the actual instantiation? | |
3463 * | |
3464 * see bugzilla 2500. | |
3465 */ | |
3466 && !scx->module->selfImports() | |
3467 #endif | |
3468 ) | |
3235 { | 3469 { |
3236 //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); | 3470 //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); |
3237 a = scx->scopesym->members; | 3471 a = scx->scopesym->members; |
3238 } | 3472 } |
3239 else | 3473 else |
3271 printf("\tcreate scope for template parameters '%s'\n", toChars()); | 3505 printf("\tcreate scope for template parameters '%s'\n", toChars()); |
3272 #endif | 3506 #endif |
3273 argsym = new ScopeDsymbol(); | 3507 argsym = new ScopeDsymbol(); |
3274 argsym->parent = scope->parent; | 3508 argsym->parent = scope->parent; |
3275 scope = scope->push(argsym); | 3509 scope = scope->push(argsym); |
3510 // scope->stc = 0; | |
3276 | 3511 |
3277 // Declare each template parameter as an alias for the argument type | 3512 // Declare each template parameter as an alias for the argument type |
3278 declareParameters(scope); | 3513 Scope *paramscope = scope->push(); |
3514 paramscope->stc = 0; | |
3515 declareParameters(paramscope); | |
3516 paramscope->pop(); | |
3279 | 3517 |
3280 // Add members of template instance to template instance symbol table | 3518 // Add members of template instance to template instance symbol table |
3281 // parent = scope->scopesym; | 3519 // parent = scope->scopesym; |
3282 symtab = new DsymbolTable(); | 3520 symtab = new DsymbolTable(); |
3283 int memnum = 0; | 3521 int memnum = 0; |
3308 //printf("'%s', '%s'\n", s->ident->toChars(), tempdecl->ident->toChars()); | 3546 //printf("'%s', '%s'\n", s->ident->toChars(), tempdecl->ident->toChars()); |
3309 if (s->ident && s->ident->equals(tempdecl->ident)) | 3547 if (s->ident && s->ident->equals(tempdecl->ident)) |
3310 { | 3548 { |
3311 //printf("setting aliasdecl\n"); | 3549 //printf("setting aliasdecl\n"); |
3312 aliasdecl = new AliasDeclaration(loc, s->ident, s); | 3550 aliasdecl = new AliasDeclaration(loc, s->ident, s); |
3551 | |
3552 #if IN_LLVM | |
3553 // LDC propagate internal information | |
3554 if (tempdecl->llvmInternal) { | |
3555 s->llvmInternal = tempdecl->llvmInternal; | |
3556 if (FuncDeclaration* fd = s->isFuncDeclaration()) { | |
3557 fd->intrinsicName = tempdecl->intrinsicName; | |
3558 } | |
3559 } | |
3560 #endif | |
3313 } | 3561 } |
3314 } | 3562 } |
3315 } | 3563 } |
3316 | 3564 |
3317 // Do semantic() analysis on template instance members | 3565 // Do semantic() analysis on template instance members |
3322 sc2 = scope->push(this); | 3570 sc2 = scope->push(this); |
3323 //printf("isnested = %d, sc->parent = %s\n", isnested, sc->parent->toChars()); | 3571 //printf("isnested = %d, sc->parent = %s\n", isnested, sc->parent->toChars()); |
3324 sc2->parent = /*isnested ? sc->parent :*/ this; | 3572 sc2->parent = /*isnested ? sc->parent :*/ this; |
3325 sc2->tinst = this; | 3573 sc2->tinst = this; |
3326 | 3574 |
3327 #if !IN_LLVM | |
3328 #if WINDOWS_SEH | 3575 #if WINDOWS_SEH |
3329 __try | 3576 __try |
3330 { | 3577 { |
3331 #endif | 3578 #endif |
3332 #endif | 3579 static int nest; |
3580 //printf("%d\n", nest); | |
3581 if (++nest > 500) | |
3582 { | |
3583 global.gag = 0; // ensure error message gets printed | |
3584 error("recursive expansion"); | |
3585 fatal(); | |
3586 } | |
3333 for (int i = 0; i < members->dim; i++) | 3587 for (int i = 0; i < members->dim; i++) |
3334 { | 3588 { |
3335 Dsymbol *s = (Dsymbol *)members->data[i]; | 3589 Dsymbol *s = (Dsymbol *)members->data[i]; |
3336 //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars()); | 3590 //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars()); |
3337 //printf("test: isnested = %d, sc2->parent = %s\n", isnested, sc2->parent->toChars()); | 3591 //printf("test: isnested = %d, sc2->parent = %s\n", isnested, sc2->parent->toChars()); |
3340 //printf("test3: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars()); | 3594 //printf("test3: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars()); |
3341 s->semantic(sc2); | 3595 s->semantic(sc2); |
3342 //printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars()); | 3596 //printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars()); |
3343 sc2->module->runDeferredSemantic(); | 3597 sc2->module->runDeferredSemantic(); |
3344 } | 3598 } |
3345 #if !IN_LLVM | 3599 --nest; |
3346 #if WINDOWS_SEH | 3600 #if WINDOWS_SEH |
3347 } | 3601 } |
3348 __except (__ehfilter(GetExceptionInformation())) | 3602 __except (__ehfilter(GetExceptionInformation())) |
3349 { | 3603 { |
3350 global.gag = 0; // ensure error message gets printed | 3604 global.gag = 0; // ensure error message gets printed |
3351 error("recursive expansion"); | 3605 error("recursive expansion"); |
3352 fatal(); | 3606 fatal(); |
3353 } | 3607 } |
3354 #endif | 3608 #endif |
3355 #endif | |
3356 | 3609 |
3357 /* If any of the instantiation members didn't get semantic() run | 3610 /* If any of the instantiation members didn't get semantic() run |
3358 * on them due to forward references, we cannot run semantic2() | 3611 * on them due to forward references, we cannot run semantic2() |
3359 * or semantic3() yet. | 3612 * or semantic3() yet. |
3360 */ | 3613 */ |
3389 | 3642 |
3390 // Give additional context info if error occurred during instantiation | 3643 // Give additional context info if error occurred during instantiation |
3391 if (global.errors != errorsave) | 3644 if (global.errors != errorsave) |
3392 { | 3645 { |
3393 error("error instantiating"); | 3646 error("error instantiating"); |
3394 if(tinst) | 3647 if (tinst && !global.gag) |
3395 tinst->printInstantiationTrace(); | 3648 { tinst->printInstantiationTrace(); |
3649 fatal(); | |
3650 } | |
3396 errors = 1; | 3651 errors = 1; |
3397 if (global.gag) | 3652 if (global.gag) |
3398 tempdecl->instances.remove(tempdecl_instance_idx); | 3653 tempdecl->instances.remove(tempdecl_instance_idx); |
3399 } | 3654 } |
3400 | 3655 |
3419 */ | 3674 */ |
3420 | 3675 |
3421 void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags) | 3676 void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags) |
3422 { | 3677 { |
3423 // Run semantic on each argument, place results in tiargs[] | 3678 // Run semantic on each argument, place results in tiargs[] |
3424 //printf("+TemplateInstance::semanticTiargs()\n"); | 3679 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); |
3425 if (!tiargs) | 3680 if (!tiargs) |
3426 return; | 3681 return; |
3427 for (size_t j = 0; j < tiargs->dim; j++) | 3682 for (size_t j = 0; j < tiargs->dim; j++) |
3428 { | 3683 { |
3429 Object *o = (Object *)tiargs->data[j]; | 3684 Object *o = (Object *)tiargs->data[j]; |
3499 if (ea->op == TOKtype) | 3754 if (ea->op == TOKtype) |
3500 tiargs->data[j] = ea->type; | 3755 tiargs->data[j] = ea->type; |
3501 } | 3756 } |
3502 else if (sa) | 3757 else if (sa) |
3503 { | 3758 { |
3759 TemplateDeclaration *td = sa->isTemplateDeclaration(); | |
3760 if (td && !td->scope && td->literal) | |
3761 td->semantic(sc); | |
3504 } | 3762 } |
3505 else | 3763 else |
3506 { | 3764 { |
3507 assert(0); | 3765 assert(0); |
3508 } | 3766 } |
3750 /***************************************** | 4008 /***************************************** |
3751 * Determines if a TemplateInstance will need a nested | 4009 * Determines if a TemplateInstance will need a nested |
3752 * generation of the TemplateDeclaration. | 4010 * generation of the TemplateDeclaration. |
3753 */ | 4011 */ |
3754 | 4012 |
3755 int TemplateInstance::isNested(Objects *args) | 4013 int TemplateInstance::hasNestedArgs(Objects *args) |
3756 { int nested = 0; | 4014 { int nested = 0; |
3757 //printf("TemplateInstance::isNested('%s')\n", tempdecl->ident->toChars()); | 4015 //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars()); |
3758 | 4016 |
3759 /* A nested instance happens when an argument references a local | 4017 /* A nested instance happens when an argument references a local |
3760 * symbol that is on the stack. | 4018 * symbol that is on the stack. |
3761 */ | 4019 */ |
3762 for (size_t i = 0; i < args->dim; i++) | 4020 for (size_t i = 0; i < args->dim; i++) |
3778 } | 4036 } |
3779 } | 4037 } |
3780 else if (sa) | 4038 else if (sa) |
3781 { | 4039 { |
3782 Lsa: | 4040 Lsa: |
3783 Declaration *d = sa->isDeclaration(); | 4041 Declaration *d = NULL; |
4042 TemplateDeclaration *td = sa->isTemplateDeclaration(); | |
4043 if (td && td->literal) | |
4044 { | |
4045 goto L2; | |
4046 } | |
4047 d = sa->isDeclaration(); | |
3784 if (d && !d->isDataseg() && | 4048 if (d && !d->isDataseg() && |
3785 #if DMDV2 | 4049 #if DMDV2 |
3786 !(d->storage_class & STCmanifest) && | 4050 !(d->storage_class & STCmanifest) && |
3787 #endif | 4051 #endif |
3788 (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) && | 4052 (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) && |
3789 !isTemplateMixin()) | 4053 !isTemplateMixin()) |
3790 { | 4054 { |
4055 L2: | |
3791 // if module level template | 4056 // if module level template |
3792 if (tempdecl->toParent()->isModule()) | 4057 if (tempdecl->toParent()->isModule()) |
3793 { Dsymbol *dparent = d->toParent(); | 4058 { Dsymbol *dparent = sa->toParent(); |
3794 if (!isnested) | 4059 if (!isnested) |
3795 isnested = dparent; | 4060 isnested = dparent; |
3796 else if (isnested != dparent) | 4061 else if (isnested != dparent) |
3797 { | 4062 { |
3798 /* Select the more deeply nested of the two. | 4063 /* Select the more deeply nested of the two. |
3801 for (Dsymbol *p = isnested; p; p = p->parent) | 4066 for (Dsymbol *p = isnested; p; p = p->parent) |
3802 { | 4067 { |
3803 if (p == dparent) | 4068 if (p == dparent) |
3804 goto L1; // isnested is most nested | 4069 goto L1; // isnested is most nested |
3805 } | 4070 } |
3806 for (Dsymbol *p = dparent; 1; p = p->parent) | 4071 for (Dsymbol *p = dparent; p; p = p->parent) |
3807 { | 4072 { |
3808 if (p == isnested) | 4073 if (p == isnested) |
3809 { isnested = dparent; | 4074 { isnested = dparent; |
3810 goto L1; // dparent is most nested | 4075 goto L1; // dparent is most nested |
3811 } | 4076 } |
3812 } | 4077 } |
3813 error("is nested in both %s and %s", isnested->toChars(), dparent->toChars()); | 4078 error("%s is nested in both %s and %s", |
4079 toChars(), isnested->toChars(), dparent->toChars()); | |
3814 } | 4080 } |
3815 L1: | 4081 L1: |
3816 //printf("\tnested inside %s\n", isnested->toChars()); | 4082 //printf("\tnested inside %s\n", isnested->toChars()); |
3817 nested |= 1; | 4083 nested |= 1; |
3818 } | 4084 } |
3820 error("cannot use local '%s' as parameter to non-global template %s", d->toChars(), tempdecl->toChars()); | 4086 error("cannot use local '%s' as parameter to non-global template %s", d->toChars(), tempdecl->toChars()); |
3821 } | 4087 } |
3822 } | 4088 } |
3823 else if (va) | 4089 else if (va) |
3824 { | 4090 { |
3825 nested |= isNested(&va->objects); | 4091 nested |= hasNestedArgs(&va->objects); |
3826 } | 4092 } |
3827 } | 4093 } |
3828 return nested; | 4094 return nested; |
3829 } | 4095 } |
3830 | 4096 |
3839 char *id; | 4105 char *id; |
3840 Objects *args; | 4106 Objects *args; |
3841 | 4107 |
3842 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); | 4108 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); |
3843 id = tempdecl->ident->toChars(); | 4109 id = tempdecl->ident->toChars(); |
3844 buf.printf("__T%"PRIuSIZE"%s", strlen(id), id); | 4110 buf.printf("__T%zu%s", strlen(id), id); |
3845 args = tiargs; | 4111 args = tiargs; |
3846 for (int i = 0; i < args->dim; i++) | 4112 for (int i = 0; i < args->dim; i++) |
3847 { Object *o = (Object *)args->data[i]; | 4113 { Object *o = (Object *)args->data[i]; |
3848 Type *ta = isType(o); | 4114 Type *ta = isType(o); |
3849 Expression *ea = isExpression(o); | 4115 Expression *ea = isExpression(o); |
3888 continue; | 4154 continue; |
3889 } | 4155 } |
3890 #if 1 | 4156 #if 1 |
3891 /* Use deco that matches what it would be for a function parameter | 4157 /* Use deco that matches what it would be for a function parameter |
3892 */ | 4158 */ |
3893 //buf.writestring(ea->type->toHeadMutable()->deco); | |
3894 buf.writestring(ea->type->deco); | 4159 buf.writestring(ea->type->deco); |
3895 #else | 4160 #else |
3896 // Use type of parameter, not type of argument | 4161 // Use type of parameter, not type of argument |
3897 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; | 4162 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; |
3898 assert(tp); | 4163 assert(tp); |
3905 else if (sa) | 4170 else if (sa) |
3906 { | 4171 { |
3907 Lsa: | 4172 Lsa: |
3908 buf.writeByte('S'); | 4173 buf.writeByte('S'); |
3909 Declaration *d = sa->isDeclaration(); | 4174 Declaration *d = sa->isDeclaration(); |
3910 if (d && !d->type->deco) | 4175 if (d && (!d->type || !d->type->deco)) |
3911 { error("forward reference of %s", d->toChars()); | 4176 { error("forward reference of %s", d->toChars()); |
3912 continue; | 4177 continue; |
3913 } | 4178 } |
3914 #if 0 | 4179 #if 0 |
3915 VarDeclaration *v = sa->isVarDeclaration(); | 4180 VarDeclaration *v = sa->isVarDeclaration(); |
4017 sc = sc->pop(); | 4282 sc = sc->pop(); |
4018 sc->pop(); | 4283 sc->pop(); |
4019 } | 4284 } |
4020 } | 4285 } |
4021 | 4286 |
4287 #if IN_DMD | |
4288 | |
4289 void TemplateInstance::printInstantiationTrace() | |
4290 { | |
4291 if (global.gag) | |
4292 return; | |
4293 } | |
4294 | |
4022 void TemplateInstance::toObjFile(int multiobj) | 4295 void TemplateInstance::toObjFile(int multiobj) |
4023 { | 4296 { |
4024 #if LOG | 4297 #if LOG |
4025 printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this); | 4298 printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this); |
4026 #endif | 4299 #endif |
4027 if (!errors && members) | 4300 if (!errors && members) |
4028 { | 4301 { |
4029 if (multiobj) | 4302 if (multiobj) |
4030 // Append to list of object files to be written later | 4303 // Append to list of object files to be written later |
4031 //obj_append(this); | 4304 obj_append(this); |
4032 assert(0 && "multiobj"); | |
4033 else | 4305 else |
4034 { | 4306 { |
4035 for (int i = 0; i < members->dim; i++) | 4307 for (int i = 0; i < members->dim; i++) |
4036 { | 4308 { |
4037 Dsymbol *s = (Dsymbol *)members->data[i]; | 4309 Dsymbol *s = (Dsymbol *)members->data[i]; |
4038 s->toObjFile(multiobj); | 4310 s->toObjFile(multiobj); |
4039 } | 4311 } |
4040 } | 4312 } |
4041 } | 4313 } |
4042 } | 4314 } |
4315 | |
4316 #endif | |
4043 | 4317 |
4044 void TemplateInstance::inlineScan() | 4318 void TemplateInstance::inlineScan() |
4045 { | 4319 { |
4046 #if LOG | 4320 #if LOG |
4047 printf("TemplateInstance::inlineScan('%s')\n", toChars()); | 4321 printf("TemplateInstance::inlineScan('%s')\n", toChars()); |
4094 | 4368 |
4095 if (inst != this) | 4369 if (inst != this) |
4096 return inst->toAlias(); | 4370 return inst->toAlias(); |
4097 | 4371 |
4098 if (aliasdecl) | 4372 if (aliasdecl) |
4373 { | |
4099 return aliasdecl->toAlias(); | 4374 return aliasdecl->toAlias(); |
4375 } | |
4100 | 4376 |
4101 return inst; | 4377 return inst; |
4102 } | 4378 } |
4103 | 4379 |
4104 AliasDeclaration *TemplateInstance::isAliasDeclaration() | 4380 AliasDeclaration *TemplateInstance::isAliasDeclaration() |
4126 toCBuffer(&buf, &hgs); | 4402 toCBuffer(&buf, &hgs); |
4127 s = buf.toChars(); | 4403 s = buf.toChars(); |
4128 buf.data = NULL; | 4404 buf.data = NULL; |
4129 return s; | 4405 return s; |
4130 } | 4406 } |
4407 | |
4408 #if IN_LLVM | |
4131 | 4409 |
4132 void TemplateInstance::printInstantiationTrace() | 4410 void TemplateInstance::printInstantiationTrace() |
4133 { | 4411 { |
4134 if(global.gag) | 4412 if(global.gag) |
4135 return; | 4413 return; |
4163 {} | 4441 {} |
4164 for(; i < n_instantiations; ++i, cur = cur->tinst) | 4442 for(; i < n_instantiations; ++i, cur = cur->tinst) |
4165 fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars()); | 4443 fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars()); |
4166 } | 4444 } |
4167 } | 4445 } |
4446 | |
4447 #endif | |
4168 | 4448 |
4169 /* ======================== TemplateMixin ================================ */ | 4449 /* ======================== TemplateMixin ================================ */ |
4170 | 4450 |
4171 TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual, | 4451 TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual, |
4172 Array *idents, Objects *tiargs) | 4452 Array *idents, Objects *tiargs) |
4434 printf("\tdo semantic() on template instance members '%s'\n", toChars()); | 4714 printf("\tdo semantic() on template instance members '%s'\n", toChars()); |
4435 #endif | 4715 #endif |
4436 Scope *sc2; | 4716 Scope *sc2; |
4437 sc2 = scope->push(this); | 4717 sc2 = scope->push(this); |
4438 sc2->offset = sc->offset; | 4718 sc2->offset = sc->offset; |
4719 | |
4720 static int nest; | |
4721 //printf("%d\n", nest); | |
4722 if (++nest > 500) | |
4723 { | |
4724 global.gag = 0; // ensure error message gets printed | |
4725 error("recursive expansion"); | |
4726 fatal(); | |
4727 } | |
4728 | |
4439 for (int i = 0; i < members->dim; i++) | 4729 for (int i = 0; i < members->dim; i++) |
4440 { | 4730 { |
4441 Dsymbol *s = (Dsymbol *)members->data[i]; | 4731 Dsymbol *s = (Dsymbol *)members->data[i]; |
4442 s->semantic(sc2); | 4732 s->semantic(sc2); |
4443 } | 4733 } |
4734 | |
4735 nest--; | |
4736 | |
4444 sc->offset = sc2->offset; | 4737 sc->offset = sc2->offset; |
4445 | 4738 |
4446 /* The problem is when to parse the initializer for a variable. | 4739 /* The problem is when to parse the initializer for a variable. |
4447 * Perhaps VarDeclaration::semantic() should do it like it does | 4740 * Perhaps VarDeclaration::semantic() should do it like it does |
4448 * for initializers inside a function. | 4741 * for initializers inside a function. |
4619 buf->writebyte(';'); | 4912 buf->writebyte(';'); |
4620 buf->writenl(); | 4913 buf->writenl(); |
4621 } | 4914 } |
4622 | 4915 |
4623 | 4916 |
4917 #if IN_DMD | |
4624 void TemplateMixin::toObjFile(int multiobj) | 4918 void TemplateMixin::toObjFile(int multiobj) |
4625 { | 4919 { |
4626 //printf("TemplateMixin::toObjFile('%s')\n", toChars()); | 4920 //printf("TemplateMixin::toObjFile('%s')\n", toChars()); |
4627 TemplateInstance::toObjFile(multiobj); | 4921 TemplateInstance::toObjFile(multiobj); |
4628 } | 4922 } |
4629 | 4923 #endif |
4924 |