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