comparison dmd/template.c @ 159:5acec6b2eef8 trunk

[svn r175] merged dmd 1.029
author ChristianK
date Thu, 01 May 2008 15:15:28 +0200
parents 0ab29b838084
children 297690b5d4a5
comparison
equal deleted inserted replaced
158:287540c5f05e 159:5acec6b2eef8
128 Expression *e2 = isExpression(o2); 128 Expression *e2 = isExpression(o2);
129 Dsymbol *s1 = isDsymbol(o1); 129 Dsymbol *s1 = isDsymbol(o1);
130 Dsymbol *s2 = isDsymbol(o2); 130 Dsymbol *s2 = isDsymbol(o2);
131 Tuple *v1 = isTuple(o1); 131 Tuple *v1 = isTuple(o1);
132 Tuple *v2 = isTuple(o2); 132 Tuple *v2 = isTuple(o2);
133 //printf("\t match t1 %p t2 %p, e1 %p e2 %p, s1 %p s2 %p, v1 %p v2 %p\n", t1,t2,e1,e2,s1,s2,v1,v2);
133 134
134 /* A proper implementation of the various equals() overrides 135 /* A proper implementation of the various equals() overrides
135 * should make it possible to just do o1->equals(o2), but 136 * should make it possible to just do o1->equals(o2), but
136 * we'll do that another day. 137 * we'll do that another day.
137 */ 138 */
156 } 157 }
157 } 158 }
158 } 159 }
159 160
160 if (!t2 || !t1->equals(t2)) 161 if (!t2 || !t1->equals(t2))
161 goto L1; 162 goto Lnomatch;
162 } 163 }
163 else if (e1) 164 else if (e1)
164 { 165 {
165 #if 0 166 #if 0
166 if (e1 && e2) 167 if (e1 && e2)
167 { 168 {
168 printf("match %d\n", e1->equals(e2)); 169 printf("match %d\n", e1->equals(e2));
169 e1->print(); 170 e1->print();
170 e2->print(); 171 e2->print();
171 } 172 e1->type->print();
172 #endif 173 e2->type->print();
173 if (!e2 || !e1->equals(e2)) 174 }
174 goto L1; 175 #endif
176 if (!e2)
177 goto Lnomatch;
178 if (!e1->equals(e2))
179 goto Lnomatch;
175 } 180 }
176 else if (s1) 181 else if (s1)
177 { 182 {
178 //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars()); 183 //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars());
179 if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) 184 if (!s2 || !s1->equals(s2) || s1->parent != s2->parent)
180 goto L1; 185 {
186 goto Lnomatch;
187 }
181 } 188 }
182 else if (v1) 189 else if (v1)
183 { 190 {
184 if (!v2) 191 if (!v2)
185 goto L1; 192 goto Lnomatch;
186 if (v1->objects.dim != v2->objects.dim) 193 if (v1->objects.dim != v2->objects.dim)
187 goto L1; 194 goto Lnomatch;
188 for (size_t i = 0; i < v1->objects.dim; i++) 195 for (size_t i = 0; i < v1->objects.dim; i++)
189 { 196 {
190 if (!match((Object *)v1->objects.data[i], 197 if (!match((Object *)v1->objects.data[i],
191 (Object *)v2->objects.data[i], 198 (Object *)v2->objects.data[i],
192 tempdecl, sc)) 199 tempdecl, sc))
193 goto L1; 200 goto Lnomatch;
194 } 201 }
195 } 202 }
196 return 1; // match 203 return 1; // match
197 L1: 204 Lnomatch:
198 return 0; // nomatch; 205 return 0; // nomatch;
199 } 206 }
200 207
201 /**************************************** 208 /****************************************
202 */ 209 */
266 } 273 }
267 } 274 }
268 #endif 275 #endif
269 this->loc = loc; 276 this->loc = loc;
270 this->parameters = parameters; 277 this->parameters = parameters;
278 this->origParameters = parameters;
271 this->members = decldefs; 279 this->members = decldefs;
272 this->overnext = NULL; 280 this->overnext = NULL;
273 this->overroot = NULL; 281 this->overroot = NULL;
274 this->scope = NULL; 282 this->scope = NULL;
275 this->onemember = NULL; 283 this->onemember = NULL;
334 ScopeDsymbol *paramsym = new ScopeDsymbol(); 342 ScopeDsymbol *paramsym = new ScopeDsymbol();
335 paramsym->parent = sc->parent; 343 paramsym->parent = sc->parent;
336 Scope *paramscope = sc->push(paramsym); 344 Scope *paramscope = sc->push(paramsym);
337 paramscope->parameterSpecialization = 1; 345 paramscope->parameterSpecialization = 1;
338 346
347 if (global.params.doDocComments)
348 {
349 origParameters = new TemplateParameters();
350 origParameters->setDim(parameters->dim);
351 for (int i = 0; i < parameters->dim; i++)
352 {
353 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
354 origParameters->data[i] = (void *)tp->syntaxCopy();
355 }
356 }
357
339 for (int i = 0; i < parameters->dim; i++) 358 for (int i = 0; i < parameters->dim; i++)
340 { 359 {
341 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 360 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
342 361
343 tp->declareParameter(paramscope); 362 tp->declareParameter(paramscope);
346 for (int i = 0; i < parameters->dim; i++) 365 for (int i = 0; i < parameters->dim; i++)
347 { 366 {
348 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 367 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
349 368
350 tp->semantic(paramscope); 369 tp->semantic(paramscope);
370 if (i + 1 != parameters->dim && tp->isTemplateTupleParameter())
371 error("template tuple parameter must be last one");
351 } 372 }
352 373
353 paramscope->pop(); 374 paramscope->pop();
354 375
355 if (members) 376 if (members)
435 * Given that ti is an instance of this TemplateDeclaration, 456 * Given that ti is an instance of this TemplateDeclaration,
436 * deduce the types of the parameters to this, and store 457 * deduce the types of the parameters to this, and store
437 * those deduced types in dedtypes[]. 458 * those deduced types in dedtypes[].
438 * Input: 459 * Input:
439 * flag 1: don't do semantic() because of dummy types 460 * flag 1: don't do semantic() because of dummy types
461 * 2: don't change types in matchArg()
440 * Output: 462 * Output:
441 * dedtypes deduced arguments 463 * dedtypes deduced arguments
442 * Return match level. 464 * Return match level.
443 */ 465 */
444 466
445 MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti, 467 MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
446 Objects *dedtypes, int flag) 468 Objects *dedtypes, int flag)
447 { MATCH m; 469 { MATCH m;
448 int dedtypes_dim = dedtypes->dim; 470 int dedtypes_dim = dedtypes->dim;
449 471
450 #if LOG 472 #define LOGM 0
451 printf("+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag); 473 #if LOGM
474 printf("\n+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
452 #endif 475 #endif
453 476
454 #if 0 477 #if 0
455 printf("dedtypes->dim = %d, parameters->dim = %d\n", dedtypes_dim, parameters->dim); 478 printf("dedtypes->dim = %d, parameters->dim = %d\n", dedtypes_dim, parameters->dim);
456 if (ti->tiargs->dim) 479 if (ti->tiargs->dim)
464 int variadic = isVariadic() != NULL; 487 int variadic = isVariadic() != NULL;
465 488
466 // If more arguments than parameters, no match 489 // If more arguments than parameters, no match
467 if (ti->tiargs->dim > parameters_dim && !variadic) 490 if (ti->tiargs->dim > parameters_dim && !variadic)
468 { 491 {
469 #if LOG 492 #if LOGM
470 printf(" no match: more arguments than parameters\n"); 493 printf(" no match: more arguments than parameters\n");
471 #endif 494 #endif
472 return MATCHnomatch; 495 return MATCHnomatch;
473 } 496 }
474 497
487 { MATCH m2; 510 { MATCH m2;
488 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 511 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
489 Declaration *sparam; 512 Declaration *sparam;
490 513
491 //printf("\targument [%d]\n", i); 514 //printf("\targument [%d]\n", i);
492 #if 0 515 #if LOGM
493 //printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null"); 516 //printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
494 TemplateTypeParameter *ttp = tp->isTemplateTypeParameter(); 517 TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
495 if (ttp) 518 if (ttp)
496 printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : ""); 519 printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : "");
497 #endif 520 #endif
526 dedtypes->data[i] = ti->tiargs->data[i]; 549 dedtypes->data[i] = ti->tiargs->data[i];
527 } 550 }
528 } 551 }
529 } 552 }
530 553
531 #if 0 554 #if LOGM
532 // Print out the results 555 // Print out the results
533 printf("--------------------------\n"); 556 printf("--------------------------\n");
534 printf("template %s\n", toChars()); 557 printf("template %s\n", toChars());
535 printf("instance %s\n", ti->toChars()); 558 printf("instance %s\n", ti->toChars());
536 if (m) 559 if (m)
551 } 574 }
552 else 575 else
553 goto Lnomatch; 576 goto Lnomatch;
554 #endif 577 #endif
555 578
556 #if LOG 579 #if LOGM
557 printf(" match = %d\n", m); 580 printf(" match = %d\n", m);
558 #endif 581 #endif
559 goto Lret; 582 goto Lret;
560 583
561 Lnomatch: 584 Lnomatch:
562 #if LOG 585 #if LOGM
563 printf(" no match\n"); 586 printf(" no match\n");
564 #endif 587 #endif
565 m = MATCHnomatch; 588 m = MATCHnomatch;
566 589
567 Lret: 590 Lret:
568 paramscope->pop(); 591 paramscope->pop();
569 #if LOG 592 #if LOGM
570 printf("-TemplateDeclaration::matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m); 593 printf("-TemplateDeclaration::matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m);
571 #endif 594 #endif
572 return m; 595 return m;
573 } 596 }
574 597
643 * Input: 666 * Input:
644 * targsi Expression/Type initial list of template arguments 667 * targsi Expression/Type initial list of template arguments
645 * fargs arguments to function 668 * fargs arguments to function
646 * Output: 669 * Output:
647 * dedargs Expression/Type deduced template arguments 670 * dedargs Expression/Type deduced template arguments
671 * Returns:
672 * match level
648 */ 673 */
649 674
650 MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, 675 MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs,
651 Objects *dedargs) 676 Objects *dedargs)
652 { 677 {
653 size_t i; 678 size_t i;
654 size_t nfparams; 679 size_t nfparams;
655 size_t nfparams2;
656 size_t nfargs; 680 size_t nfargs;
657 size_t nargsi; 681 size_t nargsi; // array size of targsi
682 int fptupindex = -1;
683 int tuple_dim = 0;
658 MATCH match = MATCHexact; 684 MATCH match = MATCHexact;
659 FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration(); 685 FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration();
660 TypeFunction *fdtype; 686 TypeFunction *fdtype; // type of fd
661 TemplateTupleParameter *tp; 687 TemplateTupleParameter *tp;
662 Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T 688 Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
663 689
664 #if 0 690 #if 0
665 printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars()); 691 printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars());
680 // Set up scope for parameters 706 // Set up scope for parameters
681 ScopeDsymbol *paramsym = new ScopeDsymbol(); 707 ScopeDsymbol *paramsym = new ScopeDsymbol();
682 paramsym->parent = scope->parent; 708 paramsym->parent = scope->parent;
683 Scope *paramscope = scope->push(paramsym); 709 Scope *paramscope = scope->push(paramsym);
684 710
711 tp = isVariadic();
712
685 nargsi = 0; 713 nargsi = 0;
686 if (targsi) 714 if (targsi)
687 { // Set initial template arguments 715 { // Set initial template arguments
688 716
689 nargsi = targsi->dim; 717 nargsi = targsi->dim;
690 if (nargsi > parameters->dim) 718 if (nargsi > parameters->dim)
691 goto Lnomatch; 719 { if (!tp)
720 goto Lnomatch;
721 dedargs->setDim(nargsi);
722 dedargs->zero();
723 }
692 724
693 memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data)); 725 memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
694 726
695 for (i = 0; i < nargsi; i++) 727 for (i = 0; i < nargsi; i++)
696 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 728 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
697 MATCH m; 729 MATCH m;
698 Declaration *sparam; 730 Declaration *sparam;
699 731
700 m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam); 732 m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
733 //printf("\tdeduceType m = %d\n", m);
701 if (m == MATCHnomatch) 734 if (m == MATCHnomatch)
702 goto Lnomatch; 735 goto Lnomatch;
703 if (m < match) 736 if (m < match)
704 match = m; 737 match = m;
705 738
711 744
712 assert(fd->type->ty == Tfunction); 745 assert(fd->type->ty == Tfunction);
713 fdtype = (TypeFunction *)fd->type; 746 fdtype = (TypeFunction *)fd->type;
714 747
715 nfparams = Argument::dim(fdtype->parameters); // number of function parameters 748 nfparams = Argument::dim(fdtype->parameters); // number of function parameters
716 nfparams2 = nfparams;
717 nfargs = fargs->dim; // number of function arguments 749 nfargs = fargs->dim; // number of function arguments
718 750
719 /* Check for match of function arguments with variadic template 751 /* Check for match of function arguments with variadic template
720 * parameter, such as: 752 * parameter, such as:
721 * 753 *
722 * template Foo(T, A...) { void Foo(T t, A a); } 754 * template Foo(T, A...) { void Foo(T t, A a); }
723 * void main() { Foo(1,2,3); } 755 * void main() { Foo(1,2,3); }
724 */ 756 */
725 tp = isVariadic(); 757 tp = isVariadic();
726 if (tp) 758 if (tp) // if variadic
727 { 759 {
728 if (nfparams == 0) // if no function parameters 760 if (nfparams == 0) // if no function parameters
729 { 761 {
730 Tuple *t = new Tuple(); 762 Tuple *t = new Tuple();
731 //printf("t = %p\n", t); 763 //printf("t = %p\n", t);
734 } 766 }
735 else if (nfargs < nfparams - 1) 767 else if (nfargs < nfparams - 1)
736 goto L1; 768 goto L1;
737 else 769 else
738 { 770 {
739 /* See if 'A' of the template parameter matches 'A' 771 /* Figure out which of the function parameters matches
740 * of the type of the last function parameter. 772 * the tuple template parameter. Do this by matching
773 * type identifiers.
774 * Set the index of this function parameter to fptupindex.
741 */ 775 */
742 Argument *fparam = (Argument *)fdtype->parameters->data[nfparams - 1]; 776 for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
743 if (fparam->type->ty != Tident) 777 {
744 goto L1; 778 Argument *fparam = (Argument *)fdtype->parameters->data[fptupindex];
745 TypeIdentifier *tid = (TypeIdentifier *)fparam->type; 779 if (fparam->type->ty != Tident)
746 if (!tp->ident->equals(tid->ident) || tid->idents.dim) 780 continue;
747 goto L1; 781 TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
748 782 if (!tp->ident->equals(tid->ident) || tid->idents.dim)
749 if (fdtype->varargs) // variadic function doesn't 783 continue;
750 goto Lnomatch; // go with variadic template 784
751 785 if (fdtype->varargs) // variadic function doesn't
752 /* The types of the function arguments [nfparams - 1 .. nfargs] 786 goto Lnomatch; // go with variadic template
753 * now form the tuple argument. 787
754 */ 788 /* The types of the function arguments
755 Tuple *t = new Tuple(); 789 * now form the tuple argument.
756 dedargs->data[parameters->dim - 1] = (void *)t; 790 */
757 791 Tuple *t = new Tuple();
758 int tuple_dim = nfargs - (nfparams - 1); 792 dedargs->data[parameters->dim - 1] = (void *)t;
759 t->objects.setDim(tuple_dim); 793
760 for (i = 0; i < tuple_dim; i++) 794 tuple_dim = nfargs - (nfparams - 1);
761 { Expression *farg = (Expression *)fargs->data[nfparams - 1 + i]; 795 t->objects.setDim(tuple_dim);
762 t->objects.data[i] = (void *)farg->type; 796 for (i = 0; i < tuple_dim; i++)
763 } 797 { Expression *farg = (Expression *)fargs->data[fptupindex + i];
764 nfparams2--; // don't consider the last parameter for type deduction 798 t->objects.data[i] = (void *)farg->type;
765 goto L2; 799 }
800 goto L2;
801 }
802 fptupindex = -1;
766 } 803 }
767 } 804 }
768 805
769 L1: 806 L1:
770 if (nfparams == nfargs) 807 if (nfparams == nfargs)
776 match = MATCHconvert; // match ... with a conversion 813 match = MATCHconvert; // match ... with a conversion
777 } 814 }
778 815
779 L2: 816 L2:
780 // Loop through the function parameters 817 // Loop through the function parameters
781 for (i = 0; i < nfparams2; i++) 818 for (i = 0; i < nfparams; i++)
782 { 819 {
820 /* Skip over function parameters which wound up
821 * as part of a template tuple parameter.
822 */
823 if (i == fptupindex)
824 { if (fptupindex == nfparams - 1)
825 break;
826 i += tuple_dim - 1;
827 continue;
828 }
829
783 Argument *fparam = Argument::getNth(fdtype->parameters, i); 830 Argument *fparam = Argument::getNth(fdtype->parameters, i);
784 Expression *farg;
785 MATCH m;
786 831
787 if (i >= nfargs) // if not enough arguments 832 if (i >= nfargs) // if not enough arguments
788 { 833 {
789 if (fparam->defaultArg) 834 if (fparam->defaultArg)
790 { /* Default arguments do not participate in template argument 835 { /* Default arguments do not participate in template argument
792 */ 837 */
793 goto Lmatch; 838 goto Lmatch;
794 } 839 }
795 } 840 }
796 else 841 else
797 { farg = (Expression *)fargs->data[i]; 842 { Expression *farg = (Expression *)fargs->data[i];
798 #if 0 843 #if 0
799 printf("\tfarg->type = %s\n", farg->type->toChars()); 844 printf("\tfarg->type = %s\n", farg->type->toChars());
800 printf("\tfparam->type = %s\n", fparam->type->toChars()); 845 printf("\tfparam->type = %s\n", fparam->type->toChars());
801 #endif 846 #endif
802 847
848 MATCH m;
803 m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes); 849 m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes);
804 //printf("\tdeduceType m = %d\n", m); 850 //printf("\tdeduceType m = %d\n", m);
805 851
806 /* If no match, see if there's a conversion to a delegate 852 /* If no match, see if there's a conversion to a delegate
807 */ 853 */
850 /* Fill in any missing arguments with their defaults. 896 /* Fill in any missing arguments with their defaults.
851 */ 897 */
852 for (i = nargsi; i < dedargs->dim; i++) 898 for (i = nargsi; i < dedargs->dim; i++)
853 { 899 {
854 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 900 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
901 //printf("tp[%d] = %s\n", i, tp->ident->toChars());
902 /* For T:T*, the dedargs is the T*, dedtypes is the T
903 * But for function templates, we really need them to match
904 */
855 Object *oarg = (Object *)dedargs->data[i]; 905 Object *oarg = (Object *)dedargs->data[i];
856 Object *o = (Object *)dedtypes.data[i]; 906 Object *oded = (Object *)dedtypes.data[i];
857 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, o); 907 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
858 if (!oarg) 908 if (!oarg)
859 { 909 {
860 if (o) 910 if (oded)
861 { 911 {
862 if (tp->specialization()) 912 if (tp->specialization())
863 error("specialization not allowed for deduced parameter %s", tp->ident->toChars()); 913 { /* The specialization can work as long as afterwards
914 * the oded == oarg
915 */
916 Declaration *sparam;
917 dedargs->data[i] = (void *)oded;
918 MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
919 //printf("m2 = %d\n", m2);
920 if (!m2)
921 goto Lnomatch;
922 if (m2 < match)
923 match = m2; // pick worst match
924 if (dedtypes.data[i] != oded)
925 error("specialization not allowed for deduced parameter %s", tp->ident->toChars());
926 }
864 } 927 }
865 else 928 else
866 { o = tp->defaultArg(paramscope); 929 { oded = tp->defaultArg(paramscope);
867 if (!o) 930 if (!oded)
868 goto Lnomatch; 931 goto Lnomatch;
869 #if 0 932 }
870 Match m; 933 declareParameter(paramscope, tp, oded);
871 Declaration *sparam; 934 dedargs->data[i] = (void *)oded;
872 m = tp->matchArg(paramscope, dedargs, i, parameters, &sparam);
873 if (!m)
874 goto Lnomatch;
875 #endif
876 }
877 declareParameter(paramscope, tp, o);
878 dedargs->data[i] = (void *)o;
879 } 935 }
880 } 936 }
881 937
882 #if 0 938 #if 0
883 for (i = 0; i < dedargs->dim; i++) 939 for (i = 0; i < dedargs->dim; i++)
885 printf("\tdedargs[%d] = %d, %s\n", i, t->dyncast(), t->toChars()); 941 printf("\tdedargs[%d] = %d, %s\n", i, t->dyncast(), t->toChars());
886 } 942 }
887 #endif 943 #endif
888 944
889 paramscope->pop(); 945 paramscope->pop();
890 //printf("\tmatch\n"); 946 //printf("\tmatch %d\n", match);
891 return match; 947 return match;
892 948
893 Lnomatch: 949 Lnomatch:
894 paramscope->pop(); 950 paramscope->pop();
895 //printf("\tnomatch\n"); 951 //printf("\tnomatch\n");
1042 // Disambiguate by picking the most specialized TemplateDeclaration 1098 // Disambiguate by picking the most specialized TemplateDeclaration
1043 int c1 = td->leastAsSpecialized(td_best); 1099 int c1 = td->leastAsSpecialized(td_best);
1044 int c2 = td_best->leastAsSpecialized(td); 1100 int c2 = td_best->leastAsSpecialized(td);
1045 //printf("c1 = %d, c2 = %d\n", c1, c2); 1101 //printf("c1 = %d, c2 = %d\n", c1, c2);
1046 1102
1047 if (c1 && !c2) 1103 if (c1 > c2)
1048 goto Ltd; 1104 goto Ltd;
1049 else if (!c1 && c2) 1105 else if (c1 < c2)
1050 goto Ltd_best; 1106 goto Ltd_best;
1051 else 1107 else
1052 goto Lambig; 1108 goto Lambig;
1053 } 1109 }
1054 1110
1114 buf->writestring(ident->toChars()); 1170 buf->writestring(ident->toChars());
1115 buf->writeByte('('); 1171 buf->writeByte('(');
1116 for (int i = 0; i < parameters->dim; i++) 1172 for (int i = 0; i < parameters->dim; i++)
1117 { 1173 {
1118 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 1174 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
1175 if (hgs->ddoc)
1176 tp = (TemplateParameter *)origParameters->data[i];
1119 if (i) 1177 if (i)
1120 buf->writeByte(','); 1178 buf->writeByte(',');
1121 tp->toCBuffer(buf, hgs); 1179 tp->toCBuffer(buf, hgs);
1122 } 1180 }
1123 buf->writeByte(')'); 1181 buf->writeByte(')');
1514 /* Handle case of: 1572 /* Handle case of:
1515 * template Foo(T : sa!(T), alias sa) 1573 * template Foo(T : sa!(T), alias sa)
1516 */ 1574 */
1517 int i = templateIdentifierLookup(tp->tempinst->name, parameters); 1575 int i = templateIdentifierLookup(tp->tempinst->name, parameters);
1518 if (i == -1) 1576 if (i == -1)
1577 { /* Didn't find it as a parameter identifier. Try looking
1578 * it up and seeing if is an alias. See Bugzilla 1454
1579 */
1580 Dsymbol *s = tempinst->tempdecl->scope->search(0, tp->tempinst->name, NULL);
1581 if (s)
1582 {
1583 s = s->toAlias();
1584 TemplateDeclaration *td = s->isTemplateDeclaration();
1585 if (td && td == tempinst->tempdecl)
1586 goto L2;
1587 }
1519 goto Lnomatch; 1588 goto Lnomatch;
1589 }
1520 TemplateParameter *tpx = (TemplateParameter *)parameters->data[i]; 1590 TemplateParameter *tpx = (TemplateParameter *)parameters->data[i];
1521 // This logic duplicates tpx->matchArg() 1591 // This logic duplicates tpx->matchArg()
1522 TemplateAliasParameter *ta = tpx->isTemplateAliasParameter(); 1592 TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
1523 if (!ta) 1593 if (!ta)
1524 goto Lnomatch; 1594 goto Lnomatch;
1538 } 1608 }
1539 } 1609 }
1540 else if (tempinst->tempdecl != tp->tempinst->tempdecl) 1610 else if (tempinst->tempdecl != tp->tempinst->tempdecl)
1541 goto Lnomatch; 1611 goto Lnomatch;
1542 1612
1613 L2:
1543 if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim) 1614 if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim)
1544 goto Lnomatch; 1615 goto Lnomatch;
1545 1616
1546 for (int i = 0; i < tempinst->tiargs->dim; i++) 1617 for (int i = 0; i < tempinst->tiargs->dim; i++)
1547 { 1618 {
1548 //printf("test: [%d]\n", i); 1619 //printf("\ttest: tempinst->tiargs[%d]\n", i);
1620 int j;
1549 Object *o1 = (Object *)tempinst->tiargs->data[i]; 1621 Object *o1 = (Object *)tempinst->tiargs->data[i];
1550 Object *o2 = (Object *)tp->tempinst->tiargs->data[i]; 1622 Object *o2 = (Object *)tp->tempinst->tiargs->data[i];
1551 1623
1552 Type *t1 = isType(o1); 1624 Type *t1 = isType(o1);
1553 Type *t2 = isType(o2); 1625 Type *t2 = isType(o2);
1568 goto Lnomatch; 1640 goto Lnomatch;
1569 } 1641 }
1570 else if (e1 && e2) 1642 else if (e1 && e2)
1571 { 1643 {
1572 if (!e1->equals(e2)) 1644 if (!e1->equals(e2))
1645 { if (e2->op == TOKvar)
1646 {
1647 /*
1648 * (T:Number!(e2), int e2)
1649 */
1650 j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters);
1651 goto L1;
1652 }
1573 goto Lnomatch; 1653 goto Lnomatch;
1654 }
1574 } 1655 }
1575 else if (e1 && t2 && t2->ty == Tident) 1656 else if (e1 && t2 && t2->ty == Tident)
1576 { int i = templateParameterLookup(t2, parameters); 1657 {
1577 if (i == -1) 1658 j = templateParameterLookup(t2, parameters);
1659 L1:
1660 if (j == -1)
1578 goto Lnomatch; 1661 goto Lnomatch;
1579 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 1662 TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
1580 // BUG: use tp->matchArg() instead of the following 1663 // BUG: use tp->matchArg() instead of the following
1581 TemplateValueParameter *tv = tp->isTemplateValueParameter(); 1664 TemplateValueParameter *tv = tp->isTemplateValueParameter();
1582 if (!tv) 1665 if (!tv)
1583 goto Lnomatch; 1666 goto Lnomatch;
1584 Expression *e = (Expression *)dedtypes->data[i]; 1667 Expression *e = (Expression *)dedtypes->data[j];
1585 if (e) 1668 if (e)
1586 { 1669 {
1587 if (!e1->equals(e)) 1670 if (!e1->equals(e))
1588 goto Lnomatch; 1671 goto Lnomatch;
1589 } 1672 }
1590 else 1673 else
1591 { Type *vt = tv->valType->semantic(0, sc); 1674 { Type *vt = tv->valType->semantic(0, sc);
1592 MATCH m = (MATCH)e1->implicitConvTo(vt); 1675 MATCH m = (MATCH)e1->implicitConvTo(vt);
1593 if (!m) 1676 if (!m)
1594 goto Lnomatch; 1677 goto Lnomatch;
1595 dedtypes->data[i] = e1; 1678 dedtypes->data[j] = e1;
1596 } 1679 }
1597 } 1680 }
1598 // BUG: Need to handle alias and tuple parameters 1681 // BUG: Need to handle alias and tuple parameters
1599 else 1682 else
1600 goto Lnomatch; 1683 goto Lnomatch;
2349 sparam->storage_class = STCconst; 2432 sparam->storage_class = STCconst;
2350 *psparam = sparam; 2433 *psparam = sparam;
2351 return m; 2434 return m;
2352 2435
2353 Lnomatch: 2436 Lnomatch:
2437 //printf("\tno match\n");
2354 *psparam = NULL; 2438 *psparam = NULL;
2355 return MATCHnomatch; 2439 return MATCHnomatch;
2356 } 2440 }
2357 2441
2358 2442
2778 //printf("\t2: adding to module %s\n", m->toChars()); 2862 //printf("\t2: adding to module %s\n", m->toChars());
2779 a = m->members; 2863 a = m->members;
2780 if (m->semanticdone >= 3) 2864 if (m->semanticdone >= 3)
2781 dosemantic3 = 1; 2865 dosemantic3 = 1;
2782 } 2866 }
2783 for (i = 0; 1; i++) 2867 for (int i = 0; 1; i++)
2784 { 2868 {
2785 if (i == a->dim) 2869 if (i == a->dim)
2786 { 2870 {
2787 a->push(this); 2871 a->push(this);
2788 break; 2872 break;
2951 Object *o = (Object *)tiargs->data[j]; 3035 Object *o = (Object *)tiargs->data[j];
2952 Type *ta = isType(o); 3036 Type *ta = isType(o);
2953 Expression *ea = isExpression(o); 3037 Expression *ea = isExpression(o);
2954 Dsymbol *sa = isDsymbol(o); 3038 Dsymbol *sa = isDsymbol(o);
2955 3039
2956 //printf("1: tiargs->data[%d] = %p, %p, %p\n", j, o, isDsymbol(o), isTuple(o)); 3040 //printf("1: tiargs->data[%d] = %p, %p, %p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
2957 if (ta) 3041 if (ta)
2958 { 3042 {
2959 //printf("type %s\n", ta->toChars()); 3043 //printf("type %s\n", ta->toChars());
2960 // It might really be an Expression or an Alias 3044 // It might really be an Expression or an Alias
2961 ta->resolve(loc, sc, &ea, &ta, &sa); 3045 ta->resolve(loc, sc, &ea, &ta, &sa);
3194 // Disambiguate by picking the most specialized TemplateDeclaration 3278 // Disambiguate by picking the most specialized TemplateDeclaration
3195 int c1 = td->leastAsSpecialized(td_best); 3279 int c1 = td->leastAsSpecialized(td_best);
3196 int c2 = td_best->leastAsSpecialized(td); 3280 int c2 = td_best->leastAsSpecialized(td);
3197 //printf("c1 = %d, c2 = %d\n", c1, c2); 3281 //printf("c1 = %d, c2 = %d\n", c1, c2);
3198 3282
3199 if (c1 && !c2) 3283 if (c1 > c2)
3200 goto Ltd; 3284 goto Ltd;
3201 else if (!c1 && c2) 3285 else if (c1 < c2)
3202 goto Ltd_best; 3286 goto Ltd_best;
3203 else 3287 else
3204 goto Lambig; 3288 goto Lambig;
3205 } 3289 }
3206 3290
3303 (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) && 3387 (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) &&
3304 !isTemplateMixin()) 3388 !isTemplateMixin())
3305 { 3389 {
3306 // if module level template 3390 // if module level template
3307 if (tempdecl->toParent()->isModule()) 3391 if (tempdecl->toParent()->isModule())
3308 { 3392 { Dsymbol *dparent = d->toParent();
3309 if (isnested && isnested != d->toParent()) 3393 if (!isnested)
3310 error("inconsistent nesting levels %s and %s", isnested->toChars(), d->toParent()->toChars()); 3394 isnested = dparent;
3311 isnested = d->toParent(); 3395 else if (isnested != dparent)
3396 {
3397 /* Select the more deeply nested of the two.
3398 * Error if one is not nested inside the other.
3399 */
3400 for (Dsymbol *p = isnested; p; p = p->parent)
3401 {
3402 if (p == dparent)
3403 goto L1; // isnested is most nested
3404 }
3405 for (Dsymbol *p = dparent; 1; p = p->parent)
3406 {
3407 if (p == isnested)
3408 { isnested = dparent;
3409 goto L1; // dparent is most nested
3410 }
3411 }
3412 error("is nested in both %s and %s", isnested->toChars(), dparent->toChars());
3413 }
3414 L1:
3415 //printf("\tnested inside %s\n", isnested->toChars());
3312 nested |= 1; 3416 nested |= 1;
3313 } 3417 }
3314 else 3418 else
3315 error("cannot use local '%s' as template parameter", d->toChars()); 3419 error("cannot use local '%s' as template parameter", d->toChars());
3316 } 3420 }