root/trunk/src/template.c

Revision 843, 160.5 kB (checked in by walter, 1 year ago)

more 64

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2010 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 // Handle template implementation
11
12 #include <stdio.h>
13 #include <assert.h>
14
15 #include "root.h"
16 #include "rmem.h"
17 #include "stringtable.h"
18
19 #include "mtype.h"
20 #include "template.h"
21 #include "init.h"
22 #include "expression.h"
23 #include "scope.h"
24 #include "module.h"
25 #include "aggregate.h"
26 #include "declaration.h"
27 #include "dsymbol.h"
28 #include "mars.h"
29 #include "dsymbol.h"
30 #include "identifier.h"
31 #include "hdrgen.h"
32 #include "id.h"
33
34 #if WINDOWS_SEH
35 #include <windows.h>
36 long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep);
37 #endif
38
39 #define LOG     0
40
41 /********************************************
42  * These functions substitute for dynamic_cast. dynamic_cast does not work
43  * on earlier versions of gcc.
44  */
45
46 Expression *isExpression(Object *o)
47 {
48     //return dynamic_cast<Expression *>(o);
49     if (!o || o->dyncast() != DYNCAST_EXPRESSION)
50         return NULL;
51     return (Expression *)o;
52 }
53
54 Dsymbol *isDsymbol(Object *o)
55 {
56     //return dynamic_cast<Dsymbol *>(o);
57     if (!o || o->dyncast() != DYNCAST_DSYMBOL)
58         return NULL;
59     return (Dsymbol *)o;
60 }
61
62 Type *isType(Object *o)
63 {
64     //return dynamic_cast<Type *>(o);
65     if (!o || o->dyncast() != DYNCAST_TYPE)
66         return NULL;
67     return (Type *)o;
68 }
69
70 Tuple *isTuple(Object *o)
71 {
72     //return dynamic_cast<Tuple *>(o);
73     if (!o || o->dyncast() != DYNCAST_TUPLE)
74         return NULL;
75     return (Tuple *)o;
76 }
77
78 /**************************************
79  * Is this Object an error?
80  */
81 int isError(Object *o)
82 {
83     Type *t = isType(o);
84     if (t)
85         return (t->ty == Terror);
86     Expression *e = isExpression(o);
87     if (e)
88         return (e->op == TOKerror);
89     Tuple *v = isTuple(o);
90     if (v)
91         return arrayObjectIsError(&v->objects);
92     return 0;
93 }
94
95 /**************************************
96  * Are any of the Objects an error?
97  */
98 int arrayObjectIsError(Objects *args)
99 {
100     for (size_t i = 0; i < args->dim; i++)
101     {
102         Object *o = (Object *)args->data[i];
103         if (isError(o))
104             return 1;
105     }
106     return 0;
107 }
108
109 /***********************
110  * Try to get arg as a type.
111  */
112
113 Type *getType(Object *o)
114 {
115     Type *t = isType(o);
116     if (!t)
117     {   Expression *e = isExpression(o);
118         if (e)
119             t = e->type;
120     }
121     return t;
122 }
123
124 Dsymbol *getDsymbol(Object *oarg)
125 {
126     Dsymbol *sa;
127     Expression *ea = isExpression(oarg);
128     if (ea)
129     {   // Try to convert Expression to symbol
130         if (ea->op == TOKvar)
131             sa = ((VarExp *)ea)->var;
132         else if (ea->op == TOKfunction)
133             sa = ((FuncExp *)ea)->fd;
134         else
135             sa = NULL;
136     }
137     else
138     {   // Try to convert Type to symbol
139         Type *ta = isType(oarg);
140         if (ta)
141             sa = ta->toDsymbol(NULL);
142         else
143             sa = isDsymbol(oarg);       // if already a symbol
144     }
145     return sa;
146 }
147
148 /******************************
149  * If o1 matches o2, return 1.
150  * Else, return 0.
151  */
152
153 int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
154 {
155     Type *t1 = isType(o1);
156     Type *t2 = isType(o2);
157     Expression *e1 = isExpression(o1);
158     Expression *e2 = isExpression(o2);
159     Dsymbol *s1 = isDsymbol(o1);
160     Dsymbol *s2 = isDsymbol(o2);
161     Tuple *v1 = isTuple(o1);
162     Tuple *v2 = isTuple(o2);
163
164     //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);
165
166     /* A proper implementation of the various equals() overrides
167      * should make it possible to just do o1->equals(o2), but
168      * we'll do that another day.
169      */
170
171     if (t1)
172     {
173         /* if t1 is an instance of ti, then give error
174          * about recursive expansions.
175          */
176         Dsymbol *s = t1->toDsymbol(sc);
177         if (s && s->parent)
178         {   TemplateInstance *ti1 = s->parent->isTemplateInstance();
179             if (ti1 && ti1->tempdecl == tempdecl)
180             {
181                 for (Scope *sc1 = sc; sc1; sc1 = sc1->enclosing)
182                 {
183                     if (sc1->scopesym == ti1)
184                     {
185                         error("recursive template expansion for template argument %s", t1->toChars());
186                         return 1;       // fake a match
187                     }
188                 }
189             }
190         }
191
192         //printf("t1 = %s\n", t1->toChars());
193         //printf("t2 = %s\n", t2->toChars());
194         if (!t2 || !t1->equals(t2))
195             goto Lnomatch;
196     }
197     else if (e1)
198     {
199 #if 0
200         if (e1 && e2)
201         {
202             printf("match %d\n", e1->equals(e2));
203             e1->print();
204             e2->print();
205             e1->type->print();
206             e2->type->print();
207         }
208 #endif
209         if (!e2)
210             goto Lnomatch;
211         if (!e1->equals(e2))
212             goto Lnomatch;
213     }
214     else if (s1)
215     {
216         if (!s2 || !s1->equals(s2) || s1->parent != s2->parent)
217         {
218             if (s2)
219             {
220                 VarDeclaration *v1 = s1->isVarDeclaration();
221                 VarDeclaration *v2 = s2->isVarDeclaration();
222                 if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest)
223                 {   ExpInitializer *ei1 = v1->init->isExpInitializer();
224                     ExpInitializer *ei2 = v2->init->isExpInitializer();
225                     if (ei1 && ei2 && ei1->exp->equals(ei2->exp))
226                         goto Lmatch;
227                 }
228             }
229             goto Lnomatch;
230         }
231 #if DMDV2
232         VarDeclaration *v1 = s1->isVarDeclaration();
233         VarDeclaration *v2 = s2->isVarDeclaration();
234         if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest)
235         {   ExpInitializer *ei1 = v1->init->isExpInitializer();
236             ExpInitializer *ei2 = v2->init->isExpInitializer();
237             if (ei1 && ei2 && !ei1->exp->equals(ei2->exp))
238                 goto Lnomatch;
239         }
240 #endif
241     }
242     else if (v1)
243     {
244         if (!v2)
245             goto Lnomatch;
246         if (v1->objects.dim != v2->objects.dim)
247             goto Lnomatch;
248         for (size_t i = 0; i < v1->objects.dim; i++)
249         {
250             if (!match((Object *)v1->objects.data[i],
251                        (Object *)v2->objects.data[i],
252                        tempdecl, sc))
253                 goto Lnomatch;
254         }
255     }
256 Lmatch:
257     //printf("match\n");
258     return 1;   // match
259 Lnomatch:
260     //printf("nomatch\n");
261     return 0;   // nomatch;
262 }
263
264
265 /************************************
266  * Match an array of them.
267  */
268 int arrayObjectMatch(Objects *oa1, Objects *oa2, TemplateDeclaration *tempdecl, Scope *sc)
269 {
270     if (oa1 == oa2)
271         return 1;
272     if (oa1->dim != oa2->dim)
273         return 0;
274     for (size_t j = 0; j < oa1->dim; j++)
275     {   Object *o1 = (Object *)oa1->data[j];
276         Object *o2 = (Object *)oa2->data[j];
277         if (!match(o1, o2, tempdecl, sc))
278         {
279             return 0;
280         }
281     }
282     return 1;
283 }
284
285 /****************************************
286  */
287
288 void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg)
289 {
290     //printf("ObjectToCBuffer()\n");
291     Type *t = isType(oarg);
292     Expression *e = isExpression(oarg);
293     Dsymbol *s = isDsymbol(oarg);
294     Tuple *v = isTuple(oarg);
295     if (t)
296     {   //printf("\tt: %s ty = %d\n", t->toChars(), t->ty);
297         t->toCBuffer(buf, NULL, hgs);
298     }
299     else if (e)
300         e->toCBuffer(buf, hgs);
301     else if (s)
302     {
303         char *p = s->ident ? s->ident->toChars() : s->toChars();
304         buf->writestring(p);
305     }
306     else if (v)
307     {
308         Objects *args = &v->objects;
309         for (size_t i = 0; i < args->dim; i++)
310         {
311             if (i)
312                 buf->writeByte(',');
313             Object *o = (Object *)args->data[i];
314             ObjectToCBuffer(buf, hgs, o);
315         }
316     }
317     else if (!oarg)
318     {
319         buf->writestring("NULL");
320     }
321     else
322     {
323 #ifdef DEBUG
324         printf("bad Object = %p\n", oarg);
325 #endif
326         assert(0);
327     }
328 }
329
330 #if DMDV2
331 Object *objectSyntaxCopy(Object *o)
332 {
333     if (!o)
334         return NULL;
335     Type *t = isType(o);
336     if (t)
337         return t->syntaxCopy();
338     Expression *e = isExpression(o);
339     if (e)
340         return e->syntaxCopy();
341     return o;
342 }
343 #endif
344
345
346 /* ======================== TemplateDeclaration ============================= */
347
348 TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id,
349         TemplateParameters *parameters, Expression *constraint, Dsymbols *decldefs, int ismixin)
350     : ScopeDsymbol(id)
351 {
352 #if LOG
353     printf("TemplateDeclaration(this = %p, id = '%s')\n", this, id->toChars());
354 #endif
355 #if 0
356     if (parameters)
357         for (int i = 0; i < parameters->dim; i++)
358         {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
359             //printf("\tparameter[%d] = %p\n", i, tp);
360             TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
361
362             if (ttp)
363             {
364                 printf("\tparameter[%d] = %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : "");
365             }
366         }
367 #endif
368     this->loc = loc;
369     this->parameters = parameters;
370     this->origParameters = parameters;
371     this->constraint = constraint;
372     this->members = decldefs;
373     this->overnext = NULL;
374     this->overroot = NULL;
375     this->semanticRun = 0;
376     this->onemember = NULL;
377     this->literal = 0;
378     this->ismixin = ismixin;
379     this->previous = NULL;
380 }
381
382 Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *)
383 {
384     //printf("TemplateDeclaration::syntaxCopy()\n");
385     TemplateDeclaration *td;
386     TemplateParameters *p;
387
388     p = NULL;
389     if (parameters)
390     {
391         p = new TemplateParameters();
392         p->setDim(parameters->dim);
393         for (int i = 0; i < p->dim; i++)
394         {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
395             p->data[i] = (void *)tp->syntaxCopy();
396         }
397     }
398     Expression *e = NULL;
399     if (constraint)
400         e = constraint->syntaxCopy();
401     Dsymbols *d = Dsymbol::arraySyntaxCopy(members);
402     td = new TemplateDeclaration(loc, ident, p, e, d, ismixin);
403     return td;
404 }
405
406 void TemplateDeclaration::semantic(Scope *sc)
407 {
408 #if LOG
409     printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars());
410     printf("sc->stc = %llx\n", sc->stc);
411     printf("sc->module = %s\n", sc->module->toChars());
412 #endif
413     if (semanticRun)
414         return;         // semantic() already run
415     semanticRun = 1;
416
417     if (sc->module && sc->module->ident == Id::object && ident == Id::AssociativeArray)
418     {   Type::associativearray = this;
419     }
420
421     if (sc->func)
422     {
423 #if DMDV1
424         error("cannot declare template at function scope %s", sc->func->toChars());
425 #endif
426     }
427
428     if (/*global.params.useArrayBounds &&*/ sc->module)
429     {
430         // Generate this function as it may be used
431         // when template is instantiated in other modules
432         sc->module->toModuleArray();
433     }
434
435     if (/*global.params.useAssert &&*/ sc->module)
436     {
437         // Generate this function as it may be used
438         // when template is instantiated in other modules
439         sc->module->toModuleAssert();
440     }
441
442     /* Remember Scope for later instantiations, but make
443      * a copy since attributes can change.
444      */
445     this->scope = new Scope(*sc);
446     this->scope->setNoFree();
447
448     // Set up scope for parameters
449     ScopeDsymbol *paramsym = new ScopeDsymbol();
450     paramsym->parent = sc->parent;
451     Scope *paramscope = sc->push(paramsym);
452     paramscope->parameterSpecialization = 1;
453     paramscope->stc = 0;
454
455     if (!parent)
456         parent = sc->parent;
457
458     if (global.params.doDocComments)
459     {
460         origParameters = new TemplateParameters();
461         origParameters->setDim(parameters->dim);
462         for (int i = 0; i < parameters->dim; i++)
463         {
464             TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
465             origParameters->data[i] = (void *)tp->syntaxCopy();
466         }
467     }
468
469     for (int i = 0; i < parameters->dim; i++)
470     {
471         TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
472
473         tp->declareParameter(paramscope);
474     }
475
476     for (int i = 0; i < parameters->dim; i++)
477     {
478         TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
479
480         tp->semantic(paramscope);
481         if (i + 1 != parameters->dim && tp->isTemplateTupleParameter())
482             error("template tuple parameter must be last one");
483     }
484
485     paramscope->pop();
486
487     if (members)
488     {
489         Dsymbol *s;
490         if (Dsymbol::oneMembers(members, &s))
491         {
492             if (s && s->ident && s->ident->equals(ident))
493             {
494                 onemember = s;
495                 s->parent = this;
496             }
497         }
498     }
499
500     /* BUG: should check:
501      *  o no virtual functions or non-static data members of classes
502      */
503 }
504
505 const char *TemplateDeclaration::kind()
506 {
507     return (onemember && onemember->isAggregateDeclaration())
508                 ? onemember->kind()
509                 : (char *)"template";
510 }
511
512 /**********************************
513  * Overload existing TemplateDeclaration 'this' with the new one 's'.
514  * Return !=0 if successful; i.e. no conflict.
515  */
516
517 int TemplateDeclaration::overloadInsert(Dsymbol *s)
518 {
519     TemplateDeclaration **pf;
520     TemplateDeclaration *f;
521
522 #if LOG
523     printf("TemplateDeclaration::overloadInsert('%s')\n", s->toChars());
524 #endif
525     f = s->isTemplateDeclaration();
526     if (!f)
527         return FALSE;
528     TemplateDeclaration *pthis = this;
529     for (pf = &pthis; *pf; pf = &(*pf)->overnext)
530     {
531 #if 0
532         // Conflict if TemplateParameter's match
533         // Will get caught anyway later with TemplateInstance, but
534         // should check it now.
535         TemplateDeclaration *f2 = *pf;
536
537         if (f->parameters->dim != f2->parameters->dim)
538             goto Lcontinue;
539
540         for (int i = 0; i < f->parameters->dim; i++)
541         {   TemplateParameter *p1 = (TemplateParameter *)f->parameters->data[i];
542             TemplateParameter *p2 = (TemplateParameter *)f2->parameters->data[i];
543
544             if (!p1->overloadMatch(p2))
545                 goto Lcontinue;
546         }
547
548 #if LOG
549         printf("\tfalse: conflict\n");
550 #endif
551         return FALSE;
552
553      Lcontinue:
554         ;
555 #endif
556     }
557
558     f->overroot = this;
559     *pf = f;
560 #if LOG
561     printf("\ttrue: no conflict\n");
562 #endif
563     return TRUE;
564 }
565
566 /****************************
567  * Declare all the function parameters as variables
568  * and add them to the scope
569  */
570 void TemplateDeclaration::makeParamNamesVisibleInConstraint(Scope *paramscope)
571 {
572     /* We do this ONLY if there is only one function in the template.
573      */
574     FuncDeclaration *fd = onemember && onemember->toAlias() ?
575         onemember->toAlias()->isFuncDeclaration() : NULL;
576     if (fd)
577     {
578         paramscope->parent = fd;
579         int fvarargs;                           // function varargs
580         Parameters *fparameters = fd->getParameters(&fvarargs);
581         size_t nfparams = Parameter::dim(fparameters); // Num function parameters
582         for (int i = 0; i < nfparams; i++)
583         {
584             Parameter *fparam = Parameter::getNth(fparameters, i)->syntaxCopy();
585             if (!fparam->ident)
586                 continue;                       // don't add it, if it has no name
587             Type *vtype = fparam->type->syntaxCopy();
588             // isPure will segfault if called on a ctor, because fd->type is null.
589             if (fd->type && fd->isPure())
590                 vtype = vtype->addMod(MODconst);
591             VarDeclaration *v = new VarDeclaration(loc, vtype, fparam->ident, NULL);
592             v->storage_class |= STCparameter;
593             // Not sure if this condition is correct/necessary.
594             //   It's from func.c
595             if (//fd->type && fd->type->ty == Tfunction &&
596              fvarargs == 2 && i + 1 == nfparams)
597                 v->storage_class |= STCvariadic;
598
599             v->storage_class |= fparam->storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
600             v->semantic(paramscope);
601             if (!paramscope->insert(v))
602                 error("parameter %s.%s is already defined", toChars(), v->toChars());
603             else
604                 v->parent = this;
605         }
606     }
607 }
608
609 /***************************************
610  * Given that ti is an instance of this TemplateDeclaration,
611  * deduce the types of the parameters to this, and store
612  * those deduced types in dedtypes[].
613  * Input:
614  *      flag    1: don't do semantic() because of dummy types
615  *              2: don't change types in matchArg()
616  * Output:
617  *      dedtypes        deduced arguments
618  * Return match level.
619  */
620
621 MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
622         Objects *dedtypes, int flag)
623 {   MATCH m;
624     int dedtypes_dim = dedtypes->dim;
625
626 #define LOGM 0
627 #if LOGM
628     printf("\n+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
629 #endif
630
631 #if 0
632     printf("dedtypes->dim = %d, parameters->dim = %d\n", dedtypes_dim, parameters->dim);
633     if (ti->tiargs->dim)
634         printf("ti->tiargs->dim = %d, [0] = %p\n",
635             ti->tiargs->dim,
636             ti->tiargs->data[0]);
637 #endif
638     dedtypes->zero();
639
640     int parameters_dim = parameters->dim;
641     int variadic = isVariadic() != NULL;
642
643     // If more arguments than parameters, no match
644     if (ti->tiargs->dim > parameters_dim && !variadic)
645     {
646 #if LOGM
647         printf(" no match: more arguments than parameters\n");
648 #endif
649         return MATCHnomatch;
650     }
651
652     assert(dedtypes_dim == parameters_dim);
653     assert(dedtypes_dim >= ti->tiargs->dim || variadic);
654
655     // Set up scope for parameters
656     assert((size_t)scope > 0x10000);
657     ScopeDsymbol *paramsym = new ScopeDsymbol();
658     paramsym->parent = scope->parent;
659     Scope *paramscope = scope->push(paramsym);
660     paramscope->stc = 0;
661
662     // Attempt type deduction
663     m = MATCHexact;
664     for (int i = 0; i < dedtypes_dim; i++)
665     {   MATCH m2;
666         TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
667         Declaration *sparam;
668
669         //printf("\targument [%d]\n", i);
670 #if LOGM
671         //printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
672         TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
673         if (ttp)
674             printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : "");
675 #endif
676
677 #if DMDV1
678         m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam);
679 #else
680         m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam, (flag & 2) ? 1 : 0);
681
682 #endif
683         //printf("\tm2 = %d\n", m2);
684
685         if (m2 == MATCHnomatch)
686         {
687 #if 0
688             printf("\tmatchArg() for parameter %i failed\n", i);
689 #endif
690             goto Lnomatch;
691         }
692
693         if (m2 < m)
694             m = m2;
695
696         if (!flag)
697             sparam->semantic(paramscope);
698         if (!paramscope->insert(sparam))
699             goto Lnomatch;
700     }
701
702     if (!flag)
703     {
704         /* Any parameter left without a type gets the type of
705          * its corresponding arg
706          */
707         for (int i = 0; i < dedtypes_dim; i++)
708         {
709             if (!dedtypes->data[i])
710             {   assert(i < ti->tiargs->dim);
711                 dedtypes->data[i] = ti->tiargs->data[i];
712             }
713         }
714     }
715
716 #if DMDV2
717     if (m && constraint && !(flag & 1))
718     {   /* Check to see if constraint is satisfied.
719          */
720         makeParamNamesVisibleInConstraint(paramscope);
721         Expression *e = constraint->syntaxCopy();
722         Scope *sc = paramscope->push();
723         sc->flags |= SCOPEstaticif;
724         e = e->semantic(sc);
725         sc->pop();
726         e = e->optimize(WANTvalue | WANTinterpret);
727         if (e->isBool(TRUE))
728             ;
729         else if (e->isBool(FALSE))
730             goto Lnomatch;
731         else
732         {
733             e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars());
734         }
735     }
736 #endif
737
738 #if LOGM
739     // Print out the results
740     printf("--------------------------\n");
741     printf("template %s\n", toChars());
742     printf("instance %s\n", ti->toChars());
743     if (m)
744     {
745         for (int i = 0; i < dedtypes_dim; i++)
746         {
747             TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
748             Object *oarg;
749
750             printf(" [%d]", i);
751
752             if (i < ti->tiargs->dim)
753                 oarg = (Object *)ti->tiargs->data[i];
754             else
755                 oarg = NULL;
756             tp->print(oarg, (Object *)dedtypes->data[i]);
757         }
758     }
759     else
760         goto Lnomatch;
761 #endif
762
763 #if LOGM
764     printf(" match = %d\n", m);
765 #endif
766     goto Lret;
767
768 Lnomatch:
769 #if LOGM
770     printf(" no match\n");
771 #endif
772     m = MATCHnomatch;
773
774 Lret:
775     paramscope->pop();
776 #if LOGM
777     printf("-TemplateDeclaration::matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m);
778 #endif
779     return m;
780 }
781
782 /********************************************
783  * Determine partial specialization order of 'this' vs td2.
784  * Returns:
785  *      match   this is at least as specialized as td2
786  *      0       td2 is more specialized than this
787  */
788
789 MATCH TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
790 {
791     /* This works by taking the template parameters to this template
792      * declaration and feeding them to td2 as if it were a template
793      * instance.
794      * If it works, then this template is at least as specialized
795      * as td2.
796      */
797
798     TemplateInstance ti(0, ident);      // create dummy template instance
799     Objects dedtypes;
800
801 #define LOG_LEASTAS     0
802
803 #if LOG_LEASTAS
804     printf("%s.leastAsSpecialized(%s)\n", toChars(), td2->toChars());
805 #endif
806
807     // Set type arguments to dummy template instance to be types
808     // generated from the parameters to this template declaration
809     ti.tiargs = new Objects();
810     ti.tiargs->setDim(parameters->dim);
811     for (int i = 0; i < ti.tiargs->dim; i++)
812     {
813         TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
814
815         void *p = tp->dummyArg();
816         if (p)
817             ti.tiargs->data[i] = p;
818         else
819             ti.tiargs->setDim(i);
820     }
821
822     // Temporary Array to hold deduced types
823     //dedtypes.setDim(parameters->dim);
824     dedtypes.setDim(td2->parameters->dim);
825
826     // Attempt a type deduction
827     MATCH m = td2->matchWithInstance(&ti, &dedtypes, 1);
828     if (m)
829     {
830         /* A non-variadic template is more specialized than a
831          * variadic one.
832          */
833         if (isVariadic() && !td2->isVariadic())
834             goto L1;
835
836 #if LOG_LEASTAS
837         printf("  matches %d, so is least as specialized\n", m);
838 #endif
839         return m;
840     }
841   L1:
842 #if LOG_LEASTAS
843     printf("  doesn't match, so is not as specialized\n");
844 #endif
845     return MATCHnomatch;
846 }
847
848
849 /*************************************************
850  * Match function arguments against a specific template function.
851  * Input:
852  *      loc             instantiation location
853  *      targsi          Expression/Type initial list of template arguments
854  *      ethis           'this' argument if !NULL
855  *      fargs           arguments to function
856  * Output:
857  *      dedargs         Expression/Type deduced template arguments
858  * Returns:
859  *      match level
860  */
861
862 MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objects *targsi,
863         Expression *ethis, Expressions *fargs,
864         Objects *dedargs)
865 {
866     size_t i;
867     size_t nfparams;
868     size_t nfargs;
869     size_t nargsi;              // array size of targsi
870     int fptupindex = -1;
871     int tuple_dim = 0;
872     MATCH match = MATCHexact;
873     FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration();
874     Parameters *fparameters;            // function parameter list
875     int fvarargs;                       // function varargs
876     Objects dedtypes;   // for T:T*, the dedargs is the T*, dedtypes is the T
877
878 #if 0
879     printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars());
880     for (i = 0; i < fargs->dim; i++)
881     {   Expression *e = (Expression *)fargs->data[i];
882         printf("\tfarg[%d] is %s, type is %s\n", i, e->toChars(), e->type->toChars());
883     }
884     printf("fd = %s\n", fd->toChars());
885     printf("fd->type = %s\n", fd->type->toChars());
886     if (ethis)
887         printf("ethis->type = %s\n", ethis->type->toChars());
888 #endif
889
890     assert((size_t)scope > 0x10000);
891
892     dedargs->setDim(parameters->dim);
893     dedargs->zero();
894
895     dedtypes.setDim(parameters->dim);
896     dedtypes.zero();
897
898     // Set up scope for parameters
899     ScopeDsymbol *paramsym = new ScopeDsymbol();
900     paramsym->parent = scope->parent;
901     Scope *paramscope = scope->push(paramsym);
902     paramscope->stc = 0;
903
904     TemplateTupleParameter *tp = isVariadic();
905     int tp_is_declared = 0;
906
907 #if 0
908     for (i = 0; i < dedargs->dim; i++)
909     {
910         printf("\tdedarg[%d] = ", i);
911         Object *oarg = (Object *)dedargs->data[i];
912         if (oarg) printf("%s", oarg->toChars());
913         printf("\n");
914     }
915 #endif
916
917
918     nargsi = 0;
919     if (targsi)
920     {   // Set initial template arguments
921
922         nargsi = targsi->dim;
923         size_t n = parameters->dim;
924         if (tp)
925             n--;
926         if (nargsi > n)
927         {   if (!tp)
928                 goto Lnomatch;
929
930             /* The extra initial template arguments
931              * now form the tuple argument.
932              */
933             Tuple *t = new Tuple();
934             assert(parameters->dim);
935             dedargs->data[parameters->dim - 1] = (void *)t;
936
937             tuple_dim = nargsi - n;
938             t->objects.setDim(tuple_dim);
939             for (size_t i = 0; i < tuple_dim; i++)
940             {
941                 t->objects.data[i] = (void *)targsi->data[n + i];
942             }
943             declareParameter(paramscope, tp, t);
944             tp_is_declared = 1;
945         }
946         else
947             n = nargsi;
948
949         memcpy(dedargs->data, targsi->data, n * sizeof(*dedargs->data));
950
951         for (size_t i = 0; i < n; i++)
952         {   assert(i < parameters->dim);
953             TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
954             MATCH m;
955             Declaration *sparam = NULL;
956
957             m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
958             //printf("\tdeduceType m = %d\n", m);
959             if (m == MATCHnomatch)
960                 goto Lnomatch;
961             if (m < match)
962                 match = m;
963
964             sparam->semantic(paramscope);
965             if (!paramscope->insert(sparam))
966                 goto Lnomatch;
967         }
968     }
969 #if 0
970     for (i = 0; i < dedargs->dim; i++)
971     {
972         printf("\tdedarg[%d] = ", i);
973         Object *oarg = (Object *)dedargs->data[i];
974         if (oarg) printf("%s", oarg->toChars());
975         printf("\n");
976     }
977 #endif
978
979     fparameters = fd->getParameters(&fvarargs);
980     nfparams = Parameter::dim(fparameters);     // number of function parameters
981     nfargs = fargs ? fargs->dim : 0;            // number of function arguments
982
983     /* Check for match of function arguments with variadic template
984      * parameter, such as:
985      *
986      * template Foo(T, A...) { void Foo(T t, A a); }
987      * void main() { Foo(1,2,3); }
988      */
989     if (tp)                             // if variadic
990     {
991         if (nfparams == 0 && nfargs != 0)               // if no function parameters
992         {
993             if (tp_is_declared)
994                 goto L2;
995             Tuple *t = new Tuple();
996             //printf("t = %p\n", t);
997             dedargs->data[parameters->dim - 1] = (void *)t;
998             declareParameter(paramscope, tp, t);
999             goto L2;
1000         }
1001         else if (nfargs < nfparams - 1)
1002             goto L1;
1003         else
1004         {
1005             /* Figure out which of the function parameters matches
1006              * the tuple template parameter. Do this by matching
1007              * type identifiers.
1008              * Set the index of this function parameter to fptupindex.
1009              */
1010             for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
1011             {
1012                 Parameter *fparam = (Parameter *)fparameters->data[fptupindex];
1013                 if (fparam->type->ty != Tident)
1014                     continue;
1015                 TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
1016                 if (!tp->ident->equals(tid->ident) || tid->idents.dim)
1017                     continue;
1018
1019                 if (fvarargs)           // variadic function doesn't
1020                     goto Lnomatch;      // go with variadic template
1021
1022                 if (tp_is_declared)
1023                     goto L2;
1024
1025                 /* The types of the function arguments
1026                  * now form the tuple argument.
1027                  */
1028                 Tuple *t = new Tuple();
1029                 dedargs->data[parameters->dim - 1] = (void *)t;
1030
1031                 tuple_dim = nfargs - (nfparams - 1);
1032                 t->objects.setDim(tuple_dim);
1033                 for (i = 0; i < tuple_dim; i++)
1034                 {   Expression *farg = (Expression *)fargs->data[fptupindex + i];
1035                     t->objects.data[i] = (void *)farg->type;
1036                 }
1037                 declareParameter(paramscope, tp, t);
1038                 goto L2;
1039             }
1040             fptupindex = -1;
1041         }
1042     }
1043
1044 L1:
1045     if (nfparams == nfargs)
1046         ;
1047     else if (nfargs > nfparams)
1048     {
1049         if (fvarargs == 0)
1050             goto Lnomatch;              // too many args, no match
1051         match = MATCHconvert;           // match ... with a conversion
1052     }
1053
1054 L2:
1055 #if DMDV2
1056     if (ethis)
1057     {
1058         // Match 'ethis' to any TemplateThisParameter's
1059         for (size_t i = 0; i < parameters->dim; i++)
1060         {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
1061             TemplateThisParameter *ttp = tp->isTemplateThisParameter();
1062             if (ttp)
1063             {   MATCH m;
1064
1065                 Type *t = new TypeIdentifier(0, ttp->ident);
1066                 m = ethis->type->deduceType(paramscope, t, parameters, &dedtypes);
1067                 if (!m)
1068                     goto Lnomatch;
1069                 if (m < match)
1070                     match = m;          // pick worst match
1071             }
1072         }
1073
1074         // Match attributes of ethis against attributes of fd
1075         if (fd->type)
1076         {
1077             Type *tthis = ethis->type;
1078             unsigned mod = fd->type->mod;
1079             StorageClass stc = scope->stc;
1080             if (stc & (STCshared | STCsynchronized))
1081                 mod |= MODshared;
1082             if (stc & STCimmutable)
1083                 mod |= MODimmutable;
1084             if (stc & STCconst)
1085                 mod |= MODconst;
1086             if (stc & STCwild)
1087                 mod |= MODwild;
1088             // Fix mod
1089             if (mod & MODimmutable)
1090                 mod = MODimmutable;
1091             if (mod & MODconst)
1092                 mod &= ~STCwild;
1093             if (tthis->mod != mod)
1094             {
1095                 if (!MODimplicitConv(tthis->mod, mod))
1096                     goto Lnomatch;
1097                 if (MATCHconst < match)
1098                     match = MATCHconst;
1099             }
1100         }
1101     }
1102 #endif
1103
1104     // Loop through the function parameters
1105     for (size_t parami = 0; parami < nfparams; parami++)
1106     {
1107         /* Skip over function parameters which wound up
1108          * as part of a template tuple parameter.
1109          */
1110         if (parami == fptupindex)
1111             continue;
1112         /* Set i = index into function arguments
1113          * Function parameters correspond to function arguments as follows.
1114          * Note that tuple_dim may be zero, and there may be default or
1115          * variadic arguments at the end.
1116          *  arg [0..fptupindex] == param[0..fptupindex]
1117          *  arg [fptupindex..fptupindex+tuple_dim] == param[fptupindex]
1118          *  arg[fputupindex+dim.. ] == param[fptupindex+1.. ]
1119          */
1120         i = parami;
1121         if (fptupindex >= 0 && parami > fptupindex)
1122             i += tuple_dim - 1;
1123
1124         Parameter *fparam = Parameter::getNth(fparameters, parami);
1125
1126         if (i >= nfargs)                // if not enough arguments
1127         {
1128             if (fparam->defaultArg)
1129             {   /* Default arguments do not participate in template argument
1130                  * deduction.
1131                  */
1132                 goto Lmatch;
1133             }
1134         }
1135         else
1136         {   Expression *farg = (Expression *)fargs->data[i];
1137 #if 0
1138             printf("\tfarg->type   = %s\n", farg->type->toChars());
1139             printf("\tfparam->type = %s\n", fparam->type->toChars());
1140 #endif
1141             Type *argtype = farg->type;
1142
1143 #if DMDV2
1144             /* Allow string literals which are type [] to match with [dim]
1145              */
1146             if (farg->op == TOKstring)
1147             {   StringExp *se = (StringExp *)farg;
1148                 if (!se->committed && argtype->ty == Tarray &&
1149                     fparam->type->toBasetype()->ty == Tsarray)
1150                 {
1151                     argtype = new TypeSArray(argtype->nextOf(), new IntegerExp(se->loc, se->len, Type::tindex));
1152                     argtype = argtype->semantic(se->loc, NULL);
1153                     argtype = argtype->invariantOf();
1154                 }
1155             }
1156 #endif
1157
1158             MATCH m;
1159             m = argtype->deduceType(paramscope, fparam->type, parameters, &dedtypes);
1160             //printf("\tdeduceType m = %d\n", m);
1161
1162             /* If no match, see if there's a conversion to a delegate
1163              */
1164             if (!m && fparam->type->toBasetype()->ty == Tdelegate)
1165             {
1166                 TypeDelegate *td = (TypeDelegate *)fparam->type->toBasetype();
1167                 TypeFunction *tf = (TypeFunction *)td->next;
1168
1169                 if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
1170                 {
1171                     m = farg->type->deduceType(paramscope, tf->next, parameters, &dedtypes);
1172                     if (!m && tf->next->toBasetype()->ty == Tvoid)
1173                         m = MATCHconvert;
1174                 }
1175                 //printf("\tm2 = %d\n", m);
1176             }
1177
1178             if (m)
1179             {   if (m < match)
1180                     match = m;          // pick worst match
1181                 continue;
1182             }
1183         }
1184
1185         /* The following code for variadic arguments closely
1186          * matches TypeFunction::callMatch()
1187          */
1188         if (!(fvarargs == 2 && i + 1 == nfparams))
1189             goto Lnomatch;
1190
1191         /* Check for match with function parameter T...
1192          */
1193         Type *tb = fparam->type->toBasetype();
1194         switch (tb->ty)
1195         {
1196             // Perhaps we can do better with this, see TypeFunction::callMatch()
1197             case Tsarray:
1198             {   TypeSArray *tsa = (TypeSArray *)tb;
1199                 dinteger_t sz = tsa->dim->toInteger();
1200                 if (sz != nfargs - i)
1201                     goto Lnomatch;
1202             }
1203             case Tarray:
1204             {   TypeArray *ta = (TypeArray *)tb;
1205                 for (; i < nfargs; i++)
1206                 {
1207                     Expression *arg = (Expression *)fargs->data[i];
1208                     assert(arg);
1209                     MATCH m;
1210                     /* If lazy array of delegates,
1211                      * convert arg(s) to delegate(s)
1212                      */
1213                     Type *tret = fparam->isLazyArray();
1214                     if (tret)
1215                     {
1216                         if (ta->next->equals(arg->type))
1217                         {   m = MATCHexact;
1218                         }
1219                         else
1220                         {
1221                             m = arg->implicitConvTo(tret);
1222                             if (m == MATCHnomatch)
1223                             {
1224                                 if (tret->toBasetype()->ty == Tvoid)
1225                                     m = MATCHconvert;
1226                             }
1227                         }
1228                     }
1229                     else
1230                     {
1231                         m = arg->type->deduceType(paramscope, ta->next, parameters, &dedtypes);
1232                         //m = arg->implicitConvTo(ta->next);
1233                     }
1234                     if (m == MATCHnomatch)
1235                         goto Lnomatch;
1236                     if (m < match)
1237                         match = m;
1238                 }
1239                 goto Lmatch;
1240             }
1241             case Tclass:
1242             case Tident:
1243                 goto Lmatch;
1244
1245             default:
1246                 goto Lnomatch;
1247         }
1248     }
1249
1250 Lmatch:
1251
1252     for (i = nargsi; i < dedargs->dim; i++)
1253     {
1254         TemplateParameter *tparam = (TemplateParameter *)parameters->data[i];
1255         //printf("tparam[%d] = %s\n", i, tparam->ident->toChars());
1256         /* For T:T*, the dedargs is the T*, dedtypes is the T
1257          * But for function templates, we really need them to match
1258          */
1259         Object *oarg = (Object *)dedargs->data[i];
1260         Object *oded = (Object *)dedtypes.data[i];
1261         //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
1262         //if (oarg) printf("oarg: %s\n", oarg->toChars());
1263         //if (oded) printf("oded: %s\n", oded->toChars());
1264         if (!oarg)
1265         {
1266             if (oded)
1267             {
1268                 if (tparam->specialization())
1269                 {   /* The specialization can work as long as afterwards
1270                      * the oded == oarg
1271                      */
1272                     Declaration *sparam;
1273                     dedargs->data[i] = (void *)oded;
1274                     MATCH m2 = tparam->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam, 0);
1275                     //printf("m2 = %d\n", m2);
1276                     if (!m2)
1277                         goto Lnomatch;
1278                     if (m2 < match)
1279                         match = m2;             // pick worst match
1280                     if (dedtypes.data[i] != oded)
1281                         error("specialization not allowed for deduced parameter %s", tparam->ident->toChars());
1282                 }
1283             }
1284             else
1285             {   oded = tparam->defaultArg(loc, paramscope);
1286                 if (!oded)
1287                 {
1288                     if (tp &&                           // if tuple parameter and
1289                         fptupindex < 0 &&               // tuple parameter was not in function parameter list and
1290                         nargsi == dedargs->dim - 1)     // we're one argument short (i.e. no tuple argument)
1291                     {   // make tuple argument an empty tuple
1292                         oded = (Object *)new Tuple();
1293                     }
1294                     else
1295                         goto Lnomatch;
1296                 }
1297             }
1298             declareParameter(paramscope, tparam, oded);
1299             dedargs->data[i] = (void *)oded;
1300         }
1301     }
1302
1303 #if DMDV2
1304     if (constraint)
1305     {   /* Check to see if constraint is satisfied.
1306          */
1307         makeParamNamesVisibleInConstraint(paramscope);
1308         Expression *e = constraint->syntaxCopy();
1309         paramscope->flags |= SCOPEstaticif;
1310
1311         /* Detect recursive attempts to instantiate this template declaration,
1312          * Bugzilla 4072
1313          *  void foo(T)(T x) if (is(typeof(foo(x)))) { }
1314          *  static assert(!is(typeof(foo(7))));
1315          * Recursive attempts are regarded as a constraint failure.
1316          */
1317         int nmatches = 0;
1318         for (Previous *p = previous; p; p = p->prev)
1319         {
1320             if (arrayObjectMatch(p->dedargs, dedargs, this, sc))
1321             {
1322                 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
1323                 /* It must be a subscope of p->sc, other scope chains are not recursive
1324                  * instantiations.
1325                  */
1326                 for (Scope *scx = sc; scx; scx = scx->enclosing)
1327                 {
1328                     if (scx == p->sc)
1329                         goto Lnomatch;
1330                 }
1331             }
1332             /* BUG: should also check for ref param differences
1333              */
1334         }
1335
1336         Previous pr;
1337         pr.prev = previous;
1338         pr.sc = paramscope;
1339         pr.dedargs = dedargs;
1340         previous = &pr;                 // add this to threaded list
1341
1342         int nerrors = global.errors;
1343
1344         e = e->semantic(paramscope);
1345
1346         previous = pr.prev;             // unlink from threaded list
1347
1348         if (nerrors != global.errors)   // if any errors from evaluating the constraint, no match
1349             goto Lnomatch;
1350
1351         e = e->optimize(WANTvalue | WANTinterpret);
1352         if (e->isBool(TRUE))
1353             ;
1354         else if (e->isBool(FALSE))
1355             goto Lnomatch;
1356         else
1357         {
1358             e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars());
1359         }
1360     }
1361 #endif
1362
1363 #if 0
1364     for (i = 0; i < dedargs->dim; i++)
1365     {   Type *t = (Type *)dedargs->data[i];
1366         printf("\tdedargs[%d] = %d, %s\n", i, t->dyncast(), t->toChars());
1367     }
1368 #endif
1369
1370     paramscope->pop();
1371     //printf("\tmatch %d\n", match);
1372     return match;
1373
1374 Lnomatch:
1375     paramscope->pop();
1376     //printf("\tnomatch\n");
1377     return MATCHnomatch;
1378 }
1379
1380 /**************************************************
1381  * Declare template parameter tp with value o, and install it in the scope sc.
1382  */
1383
1384 void TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, Object *o)
1385 {
1386     //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o);
1387
1388     Type *targ = isType(o);
1389     Expression *ea = isExpression(o);
1390     Dsymbol *sa = isDsymbol(o);
1391     Tuple *va = isTuple(o);
1392
1393     Dsymbol *s;
1394
1395     // See if tp->ident already exists with a matching definition
1396     Dsymbol *scopesym;
1397     s = sc->search(loc, tp->ident, &scopesym);
1398     if (s && scopesym == sc->scopesym)
1399     {
1400         TupleDeclaration *td = s->isTupleDeclaration();
1401         if (va && td)
1402         {   Tuple tup;
1403             tup.objects = *td->objects;
1404             if (match(va, &tup, this, sc))
1405             {
1406                 return;
1407             }
1408         }
1409     }
1410
1411     if (targ)
1412     {
1413         //printf("type %s\n", targ->toChars());
1414         s = new AliasDeclaration(0, tp->ident, targ);
1415     }
1416     else if (sa)
1417     {
1418         //printf("Alias %s %s;\n", sa->ident->toChars(), tp->ident->toChars());
1419         s = new AliasDeclaration(0, tp->ident, sa);
1420     }
1421     else if (ea)
1422     {
1423         // tdtypes.data[i] always matches ea here
1424         Initializer *init = new ExpInitializer(loc, ea);
1425         TemplateValueParameter *tvp = tp->isTemplateValueParameter();
1426
1427         Type *t = tvp ? tvp->valType : NULL;
1428
1429         VarDeclaration *v = new VarDeclaration(loc, t, tp->ident, init);
1430         v->storage_class = STCmanifest;
1431         s = v;
1432     }
1433     else if (va)
1434     {
1435         //printf("\ttuple\n");
1436         s = new TupleDeclaration(loc, tp->ident, &va->objects);
1437     }
1438     else
1439     {
1440 #ifdef DEBUG
1441         o->print();
1442 #endif
1443         assert(0);
1444     }
1445     if (!sc->insert(s))
1446         error("declaration %s is already defined", tp->ident->toChars());
1447     s->semantic(sc);
1448 }
1449
1450 /**************************************
1451  * Determine if TemplateDeclaration is variadic.
1452  */
1453
1454 TemplateTupleParameter *isVariadic(TemplateParameters *parameters)
1455 {   size_t dim = parameters->dim;
1456     TemplateTupleParameter *tp = NULL;
1457
1458     if (dim)
1459         tp = ((TemplateParameter *)parameters->data[dim - 1])->isTemplateTupleParameter();
1460     return tp;
1461 }
1462
1463 TemplateTupleParameter *TemplateDeclaration::isVariadic()
1464 {
1465     return ::isVariadic(parameters);
1466 }
1467
1468 /***********************************
1469  * We can overload templates.
1470  */
1471
1472 int TemplateDeclaration::isOverloadable()
1473 {
1474     return 1;
1475 }
1476
1477 /*************************************************
1478  * Given function arguments, figure out which template function
1479  * to expand, and return that function.
1480  * If no match, give error message and return NULL.
1481  * Input:
1482  *      sc              instantiation scope
1483  *      loc             instantiation location
1484  *      targsi          initial list of template arguments
1485  *      ethis           if !NULL, the 'this' pointer argument
1486  *      fargs           arguments to function
1487  *      flags           1: do not issue error message on no match, just return NULL
1488  */
1489
1490 FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
1491         Objects *targsi, Expression *ethis, Expressions *fargs, int flags)
1492 {
1493     MATCH m_best = MATCHnomatch;
1494     TemplateDeclaration *td_ambig = NULL;
1495     TemplateDeclaration *td_best = NULL;
1496     Objects *tdargs = new Objects();
1497     TemplateInstance *ti;
1498     FuncDeclaration *fd;
1499
1500 #if 0
1501     printf("TemplateDeclaration::deduceFunctionTemplate() %s\n", toChars());
1502     printf("    targsi:\n");
1503     if (targsi)
1504     {   for (int i = 0; i < targsi->dim; i++)
1505         {   Object *arg = (Object *)targsi->data[i];
1506             printf("\t%s\n", arg->toChars());
1507         }
1508     }
1509     printf("    fargs:\n");
1510     for (int i = 0; i < fargs->dim; i++)
1511     {   Expression *arg = (Expression *)fargs->data[i];
1512         printf("\t%s %s\n", arg->type->toChars(), arg->toChars());
1513         //printf("\tty = %d\n", arg->type->ty);
1514     }
1515     printf("stc = %llx\n", scope->stc);
1516 #endif
1517
1518     for (TemplateDeclaration *td = this; td; td = td->overnext)
1519     {
1520         if (!td->semanticRun)
1521         {
1522             error("forward reference to template %s", td->toChars());
1523             goto Lerror;
1524         }
1525         if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration())
1526         {
1527             error("is not a function template");
1528             goto Lerror;
1529         }
1530
1531         MATCH m;
1532         Objects dedargs;
1533
1534         m = td->deduceFunctionTemplateMatch(sc, loc, targsi, ethis, fargs, &dedargs);
1535         //printf("deduceFunctionTemplateMatch = %d\n", m);
1536         if (!m)                 // if no match
1537             continue;
1538
1539         if (m < m_best)
1540             goto Ltd_best;
1541         if (m > m_best)
1542             goto Ltd;
1543
1544         {
1545         // Disambiguate by picking the most specialized TemplateDeclaration
1546         MATCH c1 = td->leastAsSpecialized(td_best);
1547         MATCH c2 = td_best->leastAsSpecialized(td);
1548         //printf("c1 = %d, c2 = %d\n", c1, c2);
1549
1550         if (c1 > c2)
1551             goto Ltd;
1552         else if (c1 < c2)
1553             goto Ltd_best;
1554         else
1555             goto Lambig;
1556         }
1557
1558       Lambig:           // td_best and td are ambiguous
1559         td_ambig = td;
1560         continue;
1561
1562       Ltd_best:         // td_best is the best match so far
1563         td_ambig = NULL;
1564         continue;
1565
1566       Ltd:              // td is the new best match
1567         td_ambig = NULL;
1568         assert((size_t)td->scope > 0x10000);
1569         td_best = td;
1570         m_best = m;
1571         tdargs->setDim(dedargs.dim);
1572         memcpy(tdargs->data, dedargs.data, tdargs->dim * sizeof(void *));
1573         continue;
1574     }
1575     if (!td_best)
1576     {
1577         if (!(flags & 1))
1578             error(loc, "does not match any function template declaration");
1579         goto Lerror;
1580     }
1581     if (td_ambig)
1582     {
1583         error(loc, "%s matches more than one template declaration, %s(%d):%s and %s(%d):%s",
1584                 toChars(),
1585                 td_best->loc.filename,  td_best->loc.linnum,  td_best->toChars(),
1586                 td_ambig->loc.filename, td_ambig->loc.linnum, td_ambig->toChars());
1587     }
1588
1589     /* The best match is td_best with arguments tdargs.
1590      * Now instantiate the template.
1591      */
1592     assert((size_t)td_best->scope > 0x10000);
1593     ti = new TemplateInstance(loc, td_best, tdargs);
1594     ti->semantic(sc, fargs);
1595     fd = ti->toAlias()->isFuncDeclaration();
1596     if (!fd)
1597         goto Lerror;
1598     return fd;
1599
1600   Lerror:
1601 #if DMDV2
1602     if (!(flags & 1))
1603 #endif
1604     {
1605         HdrGenState hgs;
1606
1607         OutBuffer bufa;
1608         Objects *args = targsi;
1609         if (args)
1610         {   for (int i = 0; i < args->dim; i++)
1611             {
1612                 if (i)
1613                     bufa.writeByte(',');
1614                 Object *oarg = (Object *)args->data[i];
1615                 ObjectToCBuffer(&bufa, &hgs, oarg);
1616             }
1617         }
1618
1619         OutBuffer buf;
1620         argExpTypesToCBuffer(&buf, fargs, &hgs);
1621         error(loc, "cannot deduce template function from argument types !(%s)(%s)",
1622                 bufa.toChars(), buf.toChars());
1623     }
1624     return NULL;
1625 }
1626
1627 void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1628 {
1629 #if 0 // Should handle template functions
1630     if (onemember && onemember->isFuncDeclaration())
1631         buf->writestring("foo ");
1632 #endif
1633     buf->writestring(kind());
1634     buf->writeByte(' ');
1635     buf->writestring(ident->toChars());
1636     buf->writeByte('(');
1637     for (int i = 0; i < parameters->dim; i++)
1638     {
1639         TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
1640         if (hgs->ddoc)
1641             tp = (TemplateParameter *)origParameters->data[i];
1642         if (i)
1643             buf->writeByte(',');
1644         tp->toCBuffer(buf, hgs);
1645     }
1646     buf->writeByte(')');
1647 #if DMDV2
1648     if (constraint)
1649     {   buf->writestring(" if (");
1650         constraint->toCBuffer(buf, hgs);
1651         buf->writeByte(')');
1652     }
1653 #endif
1654
1655     if (hgs->hdrgen)
1656     {
1657         hgs->tpltMember++;
1658         buf->writenl();
1659         buf->writebyte('{');
1660         buf->writenl();
1661         for (int i = 0; i < members->dim; i++)
1662         {
1663             Dsymbol *s = (Dsymbol *)members->data[i];
1664             s->toCBuffer(buf, hgs);
1665         }
1666         buf->writebyte('}');
1667         buf->writenl();
1668         hgs->tpltMember--;
1669     }
1670 }
1671
1672
1673 char *TemplateDeclaration::toChars()
1674 {   OutBuffer buf;
1675     HdrGenState hgs;
1676
1677     memset(&hgs, 0, sizeof(hgs));
1678     buf.writestring(ident->toChars());
1679     buf.writeByte('(');
1680     for (int i = 0; i < parameters->dim; i++)
1681     {
1682         TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
1683         if (i)
1684             buf.writeByte(',');
1685         tp->toCBuffer(&buf, &hgs);
1686     }
1687     buf.writeByte(')');
1688 #if DMDV2
1689     if (constraint)
1690     {   buf.writestring(" if (");
1691         constraint->toCBuffer(&buf, &hgs);
1692         buf.writeByte(')');
1693     }
1694 #endif
1695     buf.writeByte(0);
1696     return (char *)buf.extractData();
1697 }
1698
1699 /* ======================== Type ============================================ */
1700
1701 /****
1702  * Given an identifier, figure out which TemplateParameter it is.
1703  * Return -1 if not found.
1704  */
1705
1706 int templateIdentifierLookup(Identifier *id, TemplateParameters *parameters)
1707 {
1708     for (size_t i = 0; i < parameters->dim; i++)
1709     {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
1710
1711         if (tp->ident->equals(id))
1712             return i;
1713     }
1714     return -1;
1715 }
1716
1717 int templateParameterLookup(Type *tparam, TemplateParameters *parameters)
1718 {
1719     assert(tparam->ty == Tident);
1720     TypeIdentifier *tident = (TypeIdentifier *)tparam;
1721     //printf("\ttident = '%s'\n", tident->toChars());
1722     if (tident->idents.dim == 0)
1723     {
1724         return templateIdentifierLookup(tident->ident, parameters);
1725     }
1726     return -1;
1727 }
1728
1729 /* These form the heart of template argument deduction.
1730  * Given 'this' being the type argument to the template instance,
1731  * it is matched against the template declaration parameter specialization
1732  * 'tparam' to determine the type to be used for the parameter.
1733  * Example:
1734  *      template Foo(T:T*)      // template declaration
1735  *      Foo!(int*)              // template instantiation
1736  * Input:
1737  *      this = int*
1738  *      tparam = T
1739  *      parameters = [ T:T* ]   // Array of TemplateParameter's
1740  * Output:
1741  *      dedtypes = [ int ]      // Array of Expression/Type's
1742  */
1743
1744 MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
1745         Objects *dedtypes)
1746 {
1747 #if 0
1748     printf("Type::deduceType()\n");
1749     printf("\tthis   = %d, ", ty); print();
1750     printf("\ttparam = %d, ", tparam->ty); tparam->print();
1751 #endif
1752     if (!tparam)
1753         goto Lnomatch;
1754
1755     if (this == tparam)
1756         goto Lexact;
1757
1758     if (tparam->ty == Tident)
1759     {
1760         // Determine which parameter tparam is
1761         int i = templateParameterLookup(tparam, parameters);
1762         if (i == -1)
1763         {
1764             if (!sc)
1765                 goto Lnomatch;
1766
1767             /* Need a loc to go with the semantic routine.
1768              */
1769             Loc loc;
1770             if (parameters->dim)
1771             {
1772                 TemplateParameter *tp = (TemplateParameter *)parameters->data[0];
1773                 loc = tp->loc;
1774             }
1775
1776             /* BUG: what if tparam is a template instance, that
1777              * has as an argument another Tident?
1778              */
1779             tparam = tparam->semantic(loc, sc);
1780             assert(tparam->ty != Tident);
1781             return deduceType(sc, tparam, parameters, dedtypes);
1782         }
1783
1784         TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
1785
1786         // Found the corresponding parameter tp
1787         if (!tp->isTemplateTypeParameter())
1788             goto Lnomatch;
1789         Type *tt = this;
1790         Type *at = (Type *)dedtypes->data[i];
1791
1792         // 7*7 == 49 cases
1793
1794         #define X(U,T)  ((U) << 4) | (T)
1795         switch (X(tparam->mod, mod))
1796         {
1797             case X(0, 0):
1798             case X(0, MODconst):
1799             case X(0, MODimmutable):
1800             case X(0, MODshared):
1801             case X(0, MODconst | MODshared):
1802             case X(0, MODwild):
1803             case X(0, MODwild | MODshared):
1804                 // foo(U:U) T                              => T
1805                 // foo(U:U) const(T)                       => const(T)
1806                 // foo(U:U) immutable(T)                   => immutable(T)
1807                 // foo(U:U) shared(T)                      => shared(T)
1808                 // foo(U:U) const(shared(T))               => const(shared(T))
1809                 // foo(U:U) wild(T)                        => wild(T)
1810                 // foo(U:U) wild(shared(T))                => wild(shared(T))
1811                 if (!at)
1812                 {   dedtypes->data[i] = (void *)tt;
1813                     goto Lexact;
1814                 }
1815                 break;
1816
1817             case X(MODconst, MODconst):
1818             case X(MODimmutable, MODimmutable):
1819             case X(MODshared, MODshared):
1820             case X(MODconst | MODshared, MODconst | MODshared):
1821             case X(MODwild, MODwild):
1822             case X(MODwild | MODshared, MODwild | MODshared):
1823                 // foo(U:const(U))        const(T)         => T
1824                 // foo(U:immutable(U))    immutable(T)     => T
1825                 // foo(U:shared(U))       shared(T)        => T
1826                 // foo(U:const(shared(U)) const(shared(T)) => T
1827                 // foo(U:wild(U))         wild(T)          => T
1828                 // foo(U:wild(shared(U))  wild(shared(T)) => T
1829                 tt = mutableOf()->unSharedOf();
1830                 if (!at)
1831                 {   dedtypes->data[i] = (void *)tt;
1832                     goto Lexact;
1833                 }
1834                 break;
1835
1836             case X(MODconst, 0):
1837             case X(MODconst, MODimmutable):
1838             case X(MODconst, MODconst | MODshared):
1839             case X(MODconst | MODshared, MODimmutable):
1840             case X(MODconst, MODwild):
1841             case X(MODconst, MODwild | MODshared):
1842                 // foo(U:const(U)) T                       => T
1843                 // foo(U:const(U)) immutable(T)            => T
1844                 // foo(U:const(U)) const(shared(T))        => shared(T)
1845                 // foo(U:const(shared(U)) immutable(T)     => T
1846                 // foo(U:const(U)) wild(shared(T))         => shared(T)
1847                 tt = mutableOf();
1848                 if (!at)
1849                 {   dedtypes->data[i] = (void *)tt;
1850                     goto Lconst;
1851                 }
1852                 break;
1853
1854             case X(MODshared, MODconst | MODshared):
1855             case X(MODconst | MODshared, MODshared):
1856             case X(MODshared, MODwild | MODshared):
1857                 // foo(U:shared(U)) const(shared(T))       => const(T)
1858                 // foo(U:const(shared(U)) shared(T)        => T
1859                 // foo(U:shared(U)) wild(shared(T))        => wild(T)
1860                 tt = unSharedOf();
1861                 if (!at)
1862                 {   dedtypes->data[i] = (void *)tt;
1863                     goto Lconst;
1864                 }
1865                 break;
1866
1867             case X(MODimmutable,         0):
1868             case X(MODimmutable,         MODconst):
1869             case X(MODimmutable,         MODshared):
1870             case X(MODimmutable,         MODconst | MODshared):
1871             case X(MODconst,             MODshared):
1872             case X(MODshared,            0):
1873             case X(MODshared,            MODconst):
1874             case X(MODshared,            MODimmutable):
1875             case X(MODconst | MODshared, 0):
1876             case X(MODconst | MODshared, MODconst):
1877             case X(MODimmutable,         MODwild):
1878             case X(MODshared,            MODwild):
1879             case X(MODconst | MODshared, MODwild):
1880             case X(MODwild,              0):
1881             case X(MODwild,              MODconst):
1882             case X(MODwild,              MODimmutable):
1883             case X(MODwild,              MODshared):
1884             case X(MODwild,              MODconst | MODshared):
1885             case X(MODwild | MODshared,  0):
1886             case X(MODwild | MODshared,  MODconst):
1887             case X(MODwild | MODshared,  MODimmutable):
1888             case X(MODwild | MODshared,  MODshared):
1889             case X(MODwild | MODshared,  MODconst | MODshared):
1890             case X(MODwild | MODshared,  MODwild):
1891             case X(MODimmutable,         MODwild | MODshared):
1892             case X(MODconst | MODshared, MODwild | MODshared):
1893             case X(MODwild,              MODwild | MODshared):
1894
1895                 // foo(U:immutable(U)) T                   => nomatch
1896                 // foo(U:immutable(U)) const(T)            => nomatch
1897                 // foo(U:immutable(U)) shared(T)           => nomatch
1898                 // foo(U:immutable(U)) const(shared(T))    => nomatch
1899                 // foo(U:const(U)) shared(T)               => nomatch
1900                 // foo(U:shared(U)) T                      => nomatch
1901                 // foo(U:shared(U)) const(T)               => nomatch
1902                 // foo(U:shared(U)) immutable(T)           => nomatch
1903                 // foo(U:const(shared(U)) T                => nomatch
1904                 // foo(U:const(shared(U)) const(T)         => nomatch
1905                 // foo(U:immutable(U)) wild(T)             => nomatch
1906                 // foo(U:shared(U)) wild(T)                => nomatch
1907                 // foo(U:const(shared(U)) wild(T)          => nomatch
1908                 // foo(U:wild(U)) T                        => nomatch
1909                 // foo(U:wild(U)) const(T)                 => nomatch
1910                 // foo(U:wild(U)) immutable(T)             => nomatch
1911                 // foo(U:wild(U)) shared(T)                => nomatch
1912                 // foo(U:wild(U)) const(shared(T))         => nomatch
1913                 // foo(U:wild(shared(U)) T                 => nomatch
1914                 // foo(U:wild(shared(U)) const(T)          => nomatch
1915                 // foo(U:wild(shared(U)) immutable(T)      => nomatch
1916                 // foo(U:wild(shared(U)) shared(T)         => nomatch
1917                 // foo(U:wild(shared(U)) const(shared(T))  => nomatch
1918                 // foo(U:wild(shared(U)) wild(T)           => nomatch
1919                 // foo(U:immutable(U)) wild(shared(T))     => nomatch
1920                 // foo(U:const(shared(U))) wild(shared(T)) => nomatch
1921                 // foo(U:wild(U)) wild(shared(T))          => nomatch
1922                 //if (!at)
1923                     goto Lnomatch;
1924                 break;
1925
1926             default:
1927                 assert(0);
1928         }
1929         #undef X
1930
1931         if (tt->equals(at))
1932             goto Lexact;
1933         else if (tt->ty == Tclass && at->ty == Tclass)
1934         {
1935             return tt->implicitConvTo(at);
1936         }
1937         else if (tt->ty == Tsarray && at->ty == Tarray &&
1938             tt->nextOf()->implicitConvTo(at->nextOf()) >= MATCHconst)
1939         {
1940             goto Lexact;
1941         }
1942         else
1943             goto Lnomatch;
1944     }
1945
1946     if (ty != tparam->ty)
1947     {
1948 #if DMDV2
1949         // Can't instantiate AssociativeArray!() without a scope
1950         if (tparam->ty == Taarray && !((TypeAArray*)tparam)->sc)
1951             ((TypeAArray*)tparam)->sc = sc;
1952 #endif
1953        return implicitConvTo(tparam);
1954     }
1955
1956     if (nextOf())
1957         return nextOf()->deduceType(sc, tparam->nextOf(), parameters, dedtypes);
1958
1959 Lexact:
1960     return MATCHexact;
1961
1962 Lnomatch:
1963     return MATCHnomatch;
1964
1965 #if DMDV2
1966 Lconst:
1967     return MATCHconst;
1968 #endif
1969 }
1970
1971 #if DMDV2
1972 MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
1973         Objects *dedtypes)
1974 {
1975 #if 0
1976     printf("TypeDArray::deduceType()\n");
1977     printf("\tthis   = %d, ", ty); print();
1978     printf("\ttparam = %d, ", tparam->ty); tparam->print();
1979 #endif
1980     return Type::deduceType(sc, tparam, parameters, dedtypes);
1981
1982   Lnomatch:
1983     return MATCHnomatch;
1984 }
1985 #endif
1986
1987 MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
1988         Objects *dedtypes)
1989 {
1990 #if 0
1991     printf("TypeSArray::deduceType()\n");
1992     printf("\tthis   = %d, ", ty); print();
1993     printf("\ttparam = %d, ", tparam->ty); tparam->print();
1994 #endif
1995
1996     // Extra check that array dimensions must match
1997     if (tparam)
1998     {
1999         if (tparam->ty == Tsarray)
2000         {
2001             TypeSArray *tp = (TypeSArray *)tparam;
2002
2003             if (tp->dim->op == TOKvar &&
2004                 ((VarExp *)tp->dim)->var->storage_class & STCtemplateparameter)
2005             {   int i = templateIdentifierLookup(((VarExp *)tp->dim)->var->ident, parameters);
2006                 // This code matches code in TypeInstance::deduceType()
2007                 if (i == -1)
2008                     goto Lnomatch;
2009                 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
2010                 TemplateValueParameter *tvp = tp->isTemplateValueParameter();
2011                 if (!tvp)
2012                     goto Lnomatch;
2013                 Expression *e = (Expression *)dedtypes->data[i];
2014                 if (e)
2015                 {
2016                     if (!dim->equals(e))
2017                         goto Lnomatch;
2018                 }
2019                 else
2020                 {   Type *vt = tvp->valType->semantic(0, sc);
2021                     MATCH m = (MATCH)dim->implicitConvTo(vt);
2022                     if (!m)
2023                         goto Lnomatch;
2024                     dedtypes->data[i] = dim;
2025                 }
2026             }
2027             else if (dim->toInteger() != tp->dim->toInteger())
2028                 return MATCHnomatch;
2029         }
2030         else if (tparam->ty == Taarray)
2031         {
2032             TypeAArray *tp = (TypeAArray *)tparam;
2033             if (tp->index->ty == Tident)
2034             {   TypeIdentifier *tident = (TypeIdentifier *)tp->index;
2035
2036                 if (tident->idents.dim == 0)
2037                 {   Identifier *id = tident->ident;
2038
2039                     for (size_t i = 0; i < parameters->dim; i++)
2040                     {
2041                         TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
2042
2043                         if (tp->ident->equals(id))
2044                         {   // Found the corresponding template parameter
2045                             TemplateValueParameter *tvp = tp->isTemplateValueParameter();
2046                             if (!tvp || !tvp->valType->isintegral())
2047                                 goto Lnomatch;
2048
2049                             if (dedtypes->data[i])
2050                             {
2051                                 if (!dim->equals((Object *)dedtypes->data[i]))
2052                                     goto Lnomatch;
2053                             }
2054                             else
2055                             {   dedtypes->data[i] = (void *)dim;
2056                             }
2057                             return next->deduceType(sc, tparam->nextOf(), parameters, dedtypes);
2058                         }
2059                     }
2060                 }
2061             }
2062         }
2063         else if (tparam->ty == Tarray)
2064         {   MATCH m;
2065
2066             m = next->deduceType(sc, tparam->nextOf(), parameters, dedtypes);
2067             if (m == MATCHexact)
2068                 m = MATCHconvert;
2069             return m;
2070         }
2071     }
2072     return Type::deduceType(sc, tparam, parameters, dedtypes);
2073
2074   Lnomatch:
2075     return MATCHnomatch;
2076 }
2077
2078 MATCH TypeAArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
2079 {
2080 #if 0
2081     printf("TypeAArray::deduceType()\n");
2082     printf("\tthis   = %d, ", ty); print();
2083     printf("\ttparam = %d, ", tparam->ty); tparam->print();
2084 #endif
2085
2086     // Extra check that index type must match
2087     if (tparam && tparam->ty == Taarray)
2088     {
2089         TypeAArray *tp = (TypeAArray *)tparam;
2090         if (!index->deduceType(sc, tp->index, parameters, dedtypes))
2091         {
2092             return MATCHnomatch;
2093         }
2094     }
2095     return Type::deduceType(sc, tparam, parameters, dedtypes);
2096 }
2097
2098 MATCH TypeFunction::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
2099 {
2100     //printf("TypeFunction::deduceType()\n");
2101     //printf("\tthis   = %d, ", ty); print();
2102     //printf("\ttparam = %d, ", tparam->ty); tparam->print();
2103
2104     // Extra check that function characteristics must match
2105     if (tparam && tparam->ty == Tfunction)
2106     {
2107         TypeFunction *tp = (TypeFunction *)tparam;
2108         if (varargs != tp->varargs ||
2109             linkage != tp->linkage)
2110             return MATCHnomatch;
2111
2112         size_t nfargs = Parameter::dim(this->parameters);
2113         size_t nfparams = Parameter::dim(tp->parameters);
2114
2115         /* See if tuple match
2116          */
2117         if (nfparams > 0 && nfargs >= nfparams - 1)
2118         {
2119             /* See if 'A' of the template parameter matches 'A'
2120              * of the type of the last function parameter.
2121              */
2122             Parameter *fparam = Parameter::getNth(tp->parameters, nfparams - 1);
2123             assert(fparam);
2124             assert(fparam->type);
2125             if (fparam->type->ty != Tident)
2126                 goto L1;
2127             TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
2128             if (tid->idents.dim)
2129                 goto L1;
2130
2131             /* Look through parameters to find tuple matching tid->ident
2132              */
2133             size_t tupi = 0;
2134             for (; 1; tupi++)
2135             {   if (tupi == parameters->dim)
2136                     goto L1;
2137                 TemplateParameter *t = (TemplateParameter *)parameters->data[tupi];
2138                 TemplateTupleParameter *tup = t->isTemplateTupleParameter();
2139                 if (tup && tup->ident->equals(tid->ident))
2140                     break;
2141             }
2142
2143             /* The types of the function arguments [nfparams - 1 .. nfargs]
2144              * now form the tuple argument.
2145              */
2146             int tuple_dim = nfargs - (nfparams - 1);
2147
2148             /* See if existing tuple, and whether it matches or not
2149              */
2150             Object *o = (Object *)dedtypes->data[tupi];
2151             if (o)
2152             {   // Existing deduced argument must be a tuple, and must match
2153                 Tuple *t = isTuple(o);
2154                 if (!t || t->objects.dim != tuple_dim)
2155                     return MATCHnomatch;
2156                 for (size_t i = 0; i < tuple_dim; i++)
2157                 {   Parameter *arg = Parameter::getNth(this->parameters, nfparams - 1 + i);
2158                     if (!arg->type->equals((Object *)t->objects.data[i]))
2159                         return MATCHnomatch;
2160                 }
2161             }
2162             else
2163             {   // Create new tuple
2164                 Tuple *t = new Tuple();
2165                 t->objects.setDim(tuple_dim);
2166                 for (size_t i = 0; i < tuple_dim; i++)
2167                 {   Parameter *arg = Parameter::getNth(this->parameters, nfparams - 1 + i);
2168                     t->objects.data[i] = (void *)arg->type;
2169                 }
2170                 dedtypes->data[tupi] = (void *)t;
2171             }
2172             nfparams--; // don't consider the last parameter for type deduction
2173             goto L2;
2174         }
2175
2176     L1:
2177         if (nfargs != nfparams)
2178             return MATCHnomatch;
2179     L2:
2180         for (size_t i = 0; i < nfparams; i++)
2181         {
2182             Parameter *a = Parameter::getNth(this->parameters, i);
2183             Parameter *ap = Parameter::getNth(tp->parameters, i);
2184             if (a->storageClass != ap->storageClass ||
2185                 !a->type->deduceType(sc, ap->type, parameters, dedtypes))
2186                 return MATCHnomatch;
2187         }
2188     }
2189     return Type::deduceType(sc, tparam, parameters, dedtypes);
2190 }
2191
2192 MATCH TypeIdentifier::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
2193 {
2194     // Extra check
2195     if (tparam && tparam->ty == Tident)
2196     {
2197         TypeIdentifier *tp = (TypeIdentifier *)tparam;
2198
2199         for (int i = 0; i < idents.dim; i++)
2200         {
2201             Identifier *id1 = (Identifier *)idents.data[i];
2202             Identifier *id2 = (Identifier *)tp->idents.data[i];
2203
2204             if (!id1->equals(id2))
2205                 return MATCHnomatch;
2206         }
2207     }
2208     return Type::deduceType(sc, tparam, parameters, dedtypes);
2209 }
2210
2211 MATCH TypeInstance::deduceType(Scope *sc,
2212         Type *tparam, TemplateParameters *parameters,
2213         Objects *dedtypes)
2214 {
2215 #if 0
2216     printf("TypeInstance::deduceType()\n");
2217     printf("\tthis   = %d, ", ty); print();
2218     printf("\ttparam = %d, ", tparam->ty); tparam->print();
2219 #endif
2220
2221     // Extra check
2222     if (tparam && tparam->ty == Tinstance)
2223     {
2224         TypeInstance *tp = (TypeInstance *)tparam;
2225
2226         //printf("tempinst->tempdecl = %p\n", tempinst->tempdecl);
2227         //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl);
2228         if (!tp->tempinst->tempdecl)
2229         {   //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars());
2230             if (!tp->tempinst->name->equals(tempinst->name))
2231             {
2232                 /* Handle case of:
2233                  *  template Foo(T : sa!(T), alias sa)
2234                  */
2235                 int i = templateIdentifierLookup(tp->tempinst->name, parameters);
2236                 if (i == -1)
2237                 {   /* Didn't find it as a parameter identifier. Try looking
2238                      * it up and seeing if is an alias. See Bugzilla 1454
2239                      */
2240                     Dsymbol *s = tempinst->tempdecl->scope->search(0, tp->tempinst->name, NULL);
2241                     if (s)
2242                     {
2243                         s = s->toAlias();
2244                         TemplateDeclaration *td = s->isTemplateDeclaration();
2245                         if (td && td == tempinst->tempdecl)
2246                             goto L2;
2247                     }
2248                     goto Lnomatch;
2249                 }
2250                 TemplateParameter *tpx = (TemplateParameter *)parameters->data[i];
2251                 // This logic duplicates tpx->matchArg()
2252                 TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
2253                 if (!ta)
2254                     goto Lnomatch;
2255                 Object *sa = tempinst->tempdecl;
2256                 if (!sa)
2257                     goto Lnomatch;
2258                 if (ta->specAlias && sa != ta->specAlias)
2259                     goto Lnomatch;
2260                 if (dedtypes->data[i])
2261                 {   // Must match already deduced symbol
2262                     Object *s = (Object *)dedtypes->data[i];
2263
2264                     if (s != sa)
2265                         goto Lnomatch;
2266                 }
2267                 dedtypes->data[i] = sa;
2268             }
2269         }
2270         else if (tempinst->tempdecl != tp->tempinst->tempdecl)
2271             goto Lnomatch;
2272
2273       L2:
2274
2275         for (int i = 0; 1; i++)
2276         {
2277             //printf("\ttest: tempinst->tiargs[%d]\n", i);
2278             Object *o1;
2279             if (i < tempinst->tiargs->dim)
2280                 o1 = (Object *)tempinst->tiargs->data[i];
2281             else if (i < tempinst->tdtypes.dim && i < tp->tempinst->tiargs->dim)
2282                 // Pick up default arg
2283                 o1 = (Object *)tempinst->tdtypes.data[i];
2284             else
2285                 break;
2286
2287             if (i >= tp->tempinst->tiargs->dim)
2288                 goto Lnomatch;
2289
2290             Object *o2 = (Object *)tp->tempinst->tiargs->data[i];
2291
2292             Type *t1 = isType(o1);
2293             Type *t2 = isType(o2);
2294
2295             Expression *e1 = isExpression(o1);
2296             Expression *e2 = isExpression(o2);
2297
2298             Dsymbol *s1 = isDsymbol(o1);
2299             Dsymbol *s2 = isDsymbol(o2);
2300
2301             Tuple *v1 = isTuple(o1);
2302             Tuple *v2 = isTuple(o2);
2303 #if 0
2304             if (t1)     printf("t1 = %s\n", t1->toChars());
2305             if (t2)     printf("t2 = %s\n", t2->toChars());
2306             if (e1)     printf("e1 = %s\n", e1->toChars());
2307             if (e2)     printf("e2 = %s\n", e2->toChars());
2308             if (s1)     printf("s1 = %s\n", s1->toChars());
2309             if (s2)     printf("s2 = %s\n", s2->toChars());
2310             if (v1)     printf("v1 = %s\n", v1->toChars());
2311             if (v2)     printf("v2 = %s\n", v2->toChars());
2312 #endif
2313
2314             TemplateTupleParameter *ttp;
2315             int j;
2316             if (t2 &&
2317                 t2->ty == Tident &&
2318                 i == tp->tempinst->tiargs->dim - 1 &&
2319                 i == tempinst->tempdecl->parameters->dim - 1 &&
2320                 (ttp = tempinst->tempdecl->isVariadic()) != NULL)
2321             {
2322                 /* Given:
2323                  *  struct A(B...) {}
2324                  *  alias A!(int, float) X;
2325                  *  static if (!is(X Y == A!(Z), Z))
2326                  * deduce that Z is a tuple(int, float)
2327                  */
2328
2329                 j = templateParameterLookup(t2, parameters);
2330                 if (j == -1)
2331                     goto Lnomatch;
2332
2333                 /* Create tuple from remaining args
2334                  */
2335                 Tuple *vt = new Tuple();
2336                 int vtdim = tempinst->tiargs->dim - i;
2337                 vt->objects.setDim(vtdim);
2338                 for (size_t k = 0; k < vtdim; k++)
2339                     vt->objects.data[k] = (void *)tempinst->tiargs->data[i + k];
2340
2341                 Tuple *v = (Tuple *)dedtypes->data[j];
2342                 if (v)
2343                 {
2344                     if (!match(v, vt, tempinst->tempdecl, sc))
2345                         goto Lnomatch;
2346                 }
2347                 else
2348                     dedtypes->data[j] = vt;
2349                 break; //return MATCHexact;
2350             }
2351
2352             if (t1 && t2)
2353             {
2354                 if (!t1->deduceType(sc, t2, parameters, dedtypes))
2355                     goto Lnomatch;
2356             }
2357             else if (e1 && e2)
2358             {
2359                 if (!e1->equals(e2))
2360                 {   if (e2->op == TOKvar)
2361                     {
2362                         /*
2363                          * (T:Number!(e2), int e2)
2364                          */
2365                         j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters);
2366                         goto L1;
2367                     }
2368                     goto Lnomatch;
2369                 }
2370             }
2371             else if (e1 && t2 && t2->ty == Tident)
2372             {
2373                 j = templateParameterLookup(t2, parameters);
2374             L1:
2375                 if (j == -1)
2376                     goto Lnomatch;
2377                 TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
2378                 // BUG: use tp->matchArg() instead of the following
2379                 TemplateValueParameter *tv = tp->isTemplateValueParameter();
2380                 if (!tv)
2381                     goto Lnomatch;
2382                 Expression *e = (Expression *)dedtypes->data[j];
2383                 if (e)
2384                 {
2385                     if (!e1->equals(e))
2386                         goto Lnomatch;
2387                 }
2388                 else
2389                 {   Type *vt = tv->valType->semantic(0, sc);
2390                     MATCH m = (MATCH)e1->implicitConvTo(vt);
2391                     if (!m)
2392                         goto Lnomatch;
2393                     dedtypes->data[j] = e1;
2394                 }
2395             }
2396             else if (s1 && t2 && t2->ty == Tident)
2397             {
2398                 j = templateParameterLookup(t2, parameters);
2399                 if (j == -1)
2400                     goto Lnomatch;
2401                 TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
2402                 // BUG: use tp->matchArg() instead of the following
2403                 TemplateAliasParameter *ta = tp->isTemplateAliasParameter();
2404                 if (!ta)
2405                     goto Lnomatch;
2406                 Dsymbol *s = (Dsymbol *)dedtypes->data[j];
2407                 if (s)
2408                 {
2409                     if (!s1->equals(s))
2410                         goto Lnomatch;
2411                 }
2412                 else
2413                 {
2414                     dedtypes->data[j] = s1;
2415                 }
2416             }
2417             else if (s1 && s2)
2418             {
2419                 if (!s1->equals(s2))
2420                     goto Lnomatch;
2421             }
2422             // BUG: Need to handle tuple parameters
2423             else
2424                 goto Lnomatch;
2425         }
2426     }
2427     return Type::deduceType(sc, tparam, parameters, dedtypes);
2428
2429 Lnomatch:
2430     //printf("no match\n");
2431     return MATCHnomatch;
2432 }
2433
2434 MATCH TypeStruct::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
2435 {
2436     //printf("TypeStruct::deduceType()\n");
2437     //printf("\tthis->parent   = %s, ", sym->parent->toChars()); print();
2438     //printf("\ttparam = %d, ", tparam->ty); tparam->print();
2439
2440     /* If this struct is a template struct, and we're matching
2441      * it against a template instance, convert the struct type
2442      * to a template instance, too, and try again.
2443      */
2444     TemplateInstance *ti = sym->parent->isTemplateInstance();
2445
2446     if (tparam && tparam->ty == Tinstance)
2447     {
2448         if (ti && ti->toAlias() == sym)
2449         {
2450             TypeInstance *t = new TypeInstance(0, ti);
2451             return t->deduceType(sc, tparam, parameters, dedtypes);
2452         }
2453
2454         /* Match things like:
2455          *  S!(T).foo
2456          */
2457         TypeInstance *tpi = (TypeInstance *)tparam;
2458         if (tpi->idents.dim)
2459         {   Identifier *id = (Identifier *)tpi->idents.data[tpi->idents.dim - 1];
2460             if (id->dyncast() == DYNCAST_IDENTIFIER && sym->ident->equals(id))
2461             {
2462                 Type *tparent = sym->parent->getType();
2463                 if (tparent)
2464                 {
2465                     /* Slice off the .foo in S!(T).foo
2466                      */
2467                     tpi->idents.dim--;
2468                     MATCH m = tparent->deduceType(sc, tpi, parameters, dedtypes);
2469                     tpi->idents.dim++;
2470                     return m;
2471                 }
2472             }
2473         }
2474     }
2475
2476     // Extra check
2477     if (tparam && tparam->ty == Tstruct)
2478     {
2479         TypeStruct *tp = (TypeStruct *)tparam;
2480
2481         if (sym != tp->sym)
2482             return MATCHnomatch;
2483     }
2484     return Type::deduceType(sc, tparam, parameters, dedtypes);
2485 }
2486
2487 MATCH TypeEnum::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
2488 {
2489     // Extra check
2490     if (tparam && tparam->ty == Tenum)
2491     {
2492         TypeEnum *tp = (TypeEnum *)tparam;
2493
2494         if (sym != tp->sym)
2495             return MATCHnomatch;
2496     }
2497     return Type::deduceType(sc, tparam, parameters, dedtypes);
2498 }
2499
2500 MATCH TypeTypedef::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
2501 {
2502     // Extra check
2503     if (tparam && tparam->ty == Ttypedef)
2504     {
2505         TypeTypedef *tp = (TypeTypedef *)tparam;
2506
2507         if (sym != tp->sym)
2508             return MATCHnomatch;
2509     }
2510     return Type::deduceType(sc, tparam, parameters, dedtypes);
2511 }
2512
2513 /* Helper for TypeClass::deduceType().
2514  * Classes can match with implicit conversion to a base class or interface.
2515  * This is complicated, because there may be more than one base class which
2516  * matches. In such cases, one or more parameters remain ambiguous.
2517  * For example,
2518  *
2519  *   interface I(X, Y) {}
2520  *   class C : I(uint, double), I(char, double) {}
2521  *   C x;
2522  *   foo(T, U)( I!(T, U) x)
2523  *
2524  *   deduces that U is double, but T remains ambiguous (could be char or uint).
2525  *
2526  * Given a baseclass b, and initial deduced types 'dedtypes', this function
2527  * tries to match tparam with b, and also tries all base interfaces of b.
2528  * If a match occurs, numBaseClassMatches is incremented, and the new deduced
2529  * types are ANDed with the current 'best' estimate for dedtypes.
2530  */
2531 void deduceBaseClassParameters(BaseClass *b,
2532     Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes,
2533     Objects *best, int &numBaseClassMatches)
2534 {
2535     TemplateInstance *parti = b->base ? b->base->parent->isTemplateInstance() : NULL;
2536     if (parti)
2537     {
2538         // Make a temporary copy of dedtypes so we don't destroy it
2539         Objects *tmpdedtypes = new Objects();
2540         tmpdedtypes->setDim(dedtypes->dim);
2541         memcpy(tmpdedtypes->data, dedtypes->data, dedtypes->dim * sizeof(void *));
2542
2543         TypeInstance *t = new TypeInstance(0, parti);
2544         MATCH m = t->deduceType(sc, tparam, parameters, tmpdedtypes);
2545         if (m != MATCHnomatch)
2546         {
2547             // If this is the first ever match, it becomes our best estimate
2548             if (numBaseClassMatches==0)
2549                 memcpy(best->data, tmpdedtypes->data, tmpdedtypes->dim * sizeof(void *));
2550             else for (size_t k = 0; k < tmpdedtypes->dim; ++k)
2551             {
2552                 // If we've found more than one possible type for a parameter,
2553                 // mark it as unknown.
2554                 if (tmpdedtypes->data[k] != best->data[k])
2555                     best->data[k] = dedtypes->data[k];
2556             }
2557             ++numBaseClassMatches;
2558         }
2559     }
2560     // Now recursively test the inherited interfaces
2561     for (size_t j = 0; j < b->baseInterfaces_dim; ++j)
2562     {
2563         deduceBaseClassParameters( &(b->baseInterfaces)[j],
2564             sc, tparam, parameters, dedtypes,
2565             best, numBaseClassMatches);
2566     }
2567
2568 }
2569
2570 MATCH TypeClass::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
2571 {
2572     //printf("TypeClass::deduceType(this = %s)\n", toChars());
2573
2574     /* If this class is a template class, and we're matching
2575      * it against a template instance, convert the class type
2576      * to a template instance, too, and try again.
2577      */
2578     TemplateInstance *ti = sym->parent->isTemplateInstance();
2579
2580     if (tparam && tparam->ty == Tinstance)
2581     {
2582         if (ti && ti->toAlias() == sym)
2583         {
2584             TypeInstance *t = new TypeInstance(0, ti);
2585             MATCH m = t->deduceType(sc, tparam, parameters, dedtypes);
2586             // Even if the match fails, there is still a chance it could match
2587             // a base class.
2588             if (m != MATCHnomatch)
2589                 return m;
2590         }
2591
2592         /* Match things like:
2593          *  S!(T).foo
2594          */
2595         TypeInstance *tpi = (TypeInstance *)tparam;
2596         if (tpi->idents.dim)
2597         {   Identifier *id = (Identifier *)tpi->idents.data[tpi->idents.dim - 1];
2598             if (id->dyncast() == DYNCAST_IDENTIFIER && sym->ident->equals(id))
2599             {
2600                 Type *tparent = sym->parent->getType();
2601                 if (tparent)
2602                 {
2603                     /* Slice off the .foo in S!(T).foo
2604                      */
2605                     tpi->idents.dim--;
2606                     MATCH m = tparent->deduceType(sc, tpi, parameters, dedtypes);
2607                     tpi->idents.dim++;
2608                     return m;
2609                 }
2610             }
2611         }
2612
2613         // If it matches exactly or via implicit conversion, we're done
2614         MATCH m = Type::deduceType(sc, tparam, parameters, dedtypes);
2615         if (m != MATCHnomatch)
2616             return m;
2617
2618         /* There is still a chance to match via implicit conversion to
2619          * a base class or interface. Because there could be more than one such
2620          * match, we need to check them all.
2621          */
2622
2623         int numBaseClassMatches = 0; // Have we found an interface match?
2624
2625         // Our best guess at dedtypes
2626         Objects *best = new Objects();
2627         best->setDim(dedtypes->dim);
2628
2629         ClassDeclaration *s = sym;
2630         while(s && s->baseclasses->dim > 0)
2631         {
2632             // Test the base class
2633             deduceBaseClassParameters((BaseClass *)(s->baseclasses->data[0]),
2634                 sc, tparam, parameters, dedtypes,
2635                 best, numBaseClassMatches);
2636
2637             // Test the interfaces inherited by the base class
2638             for (size_t i = 0; i < s->interfaces_dim; ++i)
2639             {
2640                 BaseClass *b = s->interfaces[i];
2641                 deduceBaseClassParameters(b, sc, tparam, parameters, dedtypes,
2642                     best, numBaseClassMatches);
2643             }
2644             s = ((BaseClass *)(s->baseclasses->data[0]))->base;
2645         }
2646
2647         if (numBaseClassMatches == 0)
2648             return MATCHnomatch;
2649
2650         // If we got at least one match, copy the known types into dedtypes
2651         memcpy(dedtypes->data, best->data, best->dim * sizeof(void *));
2652         return MATCHconvert;
2653     }
2654
2655     // Extra check
2656     if (tparam && tparam->ty == Tclass)
2657     {
2658         TypeClass *tp = (TypeClass *)tparam;
2659
2660         //printf("\t%d\n", (MATCH) implicitConvTo(tp));
2661         return implicitConvTo(tp);
2662     }
2663     return Type::deduceType(sc, tparam, parameters, dedtypes);
2664 }
2665
2666 /* ======================== TemplateParameter =============================== */
2667
2668 TemplateParameter::TemplateParameter(Loc loc, Identifier *ident)
2669 {
2670     this->loc = loc;
2671     this->ident = ident;
2672     this->sparam = NULL;
2673 }
2674
2675 TemplateTypeParameter  *TemplateParameter::isTemplateTypeParameter()
2676 {
2677     return NULL;
2678 }
2679
2680 TemplateValueParameter *TemplateParameter::isTemplateValueParameter()
2681 {
2682     return NULL;
2683 }
2684
2685 TemplateAliasParameter *TemplateParameter::isTemplateAliasParameter()
2686 {
2687     return NULL;
2688 }
2689
2690 TemplateTupleParameter *TemplateParameter::isTemplateTupleParameter()
2691 {
2692     return NULL;
2693 }
2694
2695 #if DMDV2
2696 TemplateThisParameter  *TemplateParameter::isTemplateThisParameter()
2697 {
2698     return NULL;
2699 }
2700 #endif
2701
2702 /* ======================== TemplateTypeParameter =========================== */
2703
2704 // type-parameter
2705
2706 TemplateTypeParameter::TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType,
2707         Type *defaultType)
2708     : TemplateParameter(loc, ident)
2709 {
2710     this->ident = ident;
2711     this->specType = specType;
2712     this->defaultType = defaultType;
2713 }
2714
2715 TemplateTypeParameter  *TemplateTypeParameter::isTemplateTypeParameter()
2716 {
2717     return this;
2718 }
2719
2720 TemplateParameter *TemplateTypeParameter::syntaxCopy()
2721 {
2722     TemplateTypeParameter *tp = new TemplateTypeParameter(loc, ident, specType, defaultType);
2723     if (tp->specType)
2724         tp->specType = specType->syntaxCopy();
2725     if (defaultType)
2726         tp->defaultType = defaultType->syntaxCopy();
2727     return tp;
2728 }
2729
2730 void TemplateTypeParameter::declareParameter(Scope *sc)
2731 {
2732     //printf("TemplateTypeParameter::declareParameter('%s')\n", ident->toChars());
2733     TypeIdentifier *ti = new TypeIdentifier(loc, ident);
2734     sparam = new AliasDeclaration(loc, ident, ti);
2735     if (!sc->insert(sparam))
2736         error(loc, "parameter '%s' multiply defined", ident->toChars());
2737 }
2738
2739 void TemplateTypeParameter::semantic(Scope *sc)
2740 {
2741     //printf("TemplateTypeParameter::semantic('%s')\n", ident->toChars());
2742     if (specType)
2743     {
2744         specType = specType->semantic(loc, sc);
2745     }
2746 #if 0 // Don't do semantic() until instantiation
2747     if (defaultType)
2748     {
2749         defaultType = defaultType->semantic(loc, sc);
2750     }
2751 #endif
2752 }
2753
2754 /****************************************
2755  * Determine if two TemplateParameters are the same
2756  * as far as TemplateDeclaration overloading goes.
2757  * Returns:
2758  *      1       match
2759  *      0       no match
2760  */
2761
2762 int TemplateTypeParameter::overloadMatch(TemplateParameter *tp)
2763 {
2764     TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
2765
2766     if (ttp)
2767     {
2768         if (specType != ttp->specType)
2769             goto Lnomatch;
2770
2771         if (specType && !specType->equals(ttp->specType))
2772             goto Lnomatch;
2773
2774         return 1;                       // match
2775     }
2776
2777 Lnomatch:
2778     return 0;
2779 }
2780
2781 /*******************************************
2782  * Match to a particular TemplateParameter.
2783  * Input:
2784  *      i               i'th argument
2785  *      tiargs[]        actual arguments to template instance
2786  *      parameters[]    template parameters
2787  *      dedtypes[]      deduced arguments to template instance
2788  *      *psparam        set to symbol declared and initialized to dedtypes[i]
2789  *      flags           1: don't do 'toHeadMutable()'
2790  */
2791
2792 MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs,
2793         int i, TemplateParameters *parameters, Objects *dedtypes,
2794         Declaration **psparam, int flags)
2795 {
2796     //printf("TemplateTypeParameter::matchArg()\n");
2797     Type *t;
2798     Object *oarg;
2799     MATCH m = MATCHexact;
2800     Type *ta;
2801
2802     if (i < tiargs->dim)
2803         oarg = (Object *)tiargs->data[i];
2804     else
2805     {   // Get default argument instead
2806         oarg = defaultArg(loc, sc);
2807         if (!oarg)
2808         {   assert(i < dedtypes->dim);
2809             // It might have already been deduced
2810             oarg = (Object *)dedtypes->data[i];
2811             if (!oarg)
2812             {
2813                 goto Lnomatch;
2814             }
2815             flags |= 1;         // already deduced, so don't to toHeadMutable()
2816         }
2817     }
2818
2819     ta = isType(oarg);
2820     if (!ta)
2821     {
2822         //printf("%s %p %p %p\n", oarg->toChars(), isExpression(oarg), isDsymbol(oarg), isTuple(oarg));
2823         goto Lnomatch;
2824     }
2825     //printf("ta is %s\n", ta->toChars());
2826
2827     t = (Type *)dedtypes->data[i];
2828
2829     if (specType)
2830     {
2831         //printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta->toChars(), specType->toChars());
2832         MATCH m2 = ta->deduceType(sc, specType, parameters, dedtypes);
2833         if (m2 == MATCHnomatch)
2834         {   //printf("\tfailed deduceType\n");
2835             goto Lnomatch;
2836         }
2837
2838         if (m2 < m)
2839             m = m2;
2840         t = (Type *)dedtypes->data[i];
2841     }
2842     else
2843     {
2844         // So that matches with specializations are better
2845         m = MATCHconvert;
2846
2847         /* This is so that:
2848          *   template Foo(T), Foo!(const int), => ta == int
2849          */
2850 //      if (!(flags & 1))
2851 //          ta = ta->toHeadMutable();
2852
2853         if (t)
2854         {   // Must match already deduced type
2855
2856             m = MATCHexact;
2857             if (!t->equals(ta))
2858             {   //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
2859                 goto Lnomatch;
2860             }
2861         }
2862     }
2863
2864     if (!t)
2865     {
2866         dedtypes->data[i] = ta;
2867         t = ta;
2868     }
2869     *psparam = new AliasDeclaration(loc, ident, t);
2870     //printf("\tm = %d\n", m);
2871     return m;
2872
2873 Lnomatch:
2874     *psparam = NULL;
2875     //printf("\tm = %d\n", MATCHnomatch);
2876     return MATCHnomatch;
2877 }
2878
2879
2880 void TemplateTypeParameter::print(Object *oarg, Object *oded)
2881 {
2882     printf(" %s\n", ident->toChars());
2883
2884     Type *t  = isType(oarg);
2885     Type *ta = isType(oded);
2886
2887     assert(ta);
2888
2889     if (specType)
2890         printf("\tSpecialization: %s\n", specType->toChars());
2891     if (defaultType)
2892         printf("\tDefault:        %s\n", defaultType->toChars());
2893     printf("\tParameter:       %s\n", t ? t->toChars() : "NULL");
2894     printf("\tDeduced Type:   %s\n", ta->toChars());
2895 }
2896
2897
2898 void TemplateTypeParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2899 {
2900     buf->writestring(ident->toChars());
2901     if (specType)
2902     {
2903         buf->writestring(" : ");
2904         specType->toCBuffer(buf, NULL, hgs);
2905     }
2906     if (defaultType)
2907     {
2908         buf->writestring(" = ");
2909         defaultType->toCBuffer(buf, NULL, hgs);
2910     }
2911 }
2912
2913
2914 void *TemplateTypeParameter::dummyArg()
2915 {   Type *t;
2916
2917     if (specType)
2918         t = specType;
2919     else
2920     {   // Use this for alias-parameter's too (?)
2921         t = new TypeIdentifier(loc, ident);
2922     }
2923     return (void *)t;
2924 }
2925
2926
2927 Object *TemplateTypeParameter::specialization()
2928 {
2929     return specType;
2930 }
2931
2932
2933 Object *TemplateTypeParameter::defaultArg(Loc loc, Scope *sc)
2934 {
2935     Type *t;
2936
2937     t = defaultType;
2938     if (t)
2939     {
2940         t = t->syntaxCopy();
2941         t = t->semantic(loc, sc);
2942     }
2943     return t;
2944 }
2945
2946 /* ======================== TemplateThisParameter =========================== */
2947
2948 #if DMDV2
2949 // this-parameter
2950
2951 TemplateThisParameter::TemplateThisParameter(Loc loc, Identifier *ident,
2952         Type *specType,
2953         Type *defaultType)
2954     : TemplateTypeParameter(loc, ident, specType, defaultType)
2955 {
2956 }
2957
2958 TemplateThisParameter  *TemplateThisParameter::isTemplateThisParameter()
2959 {
2960     return this;
2961 }
2962
2963 TemplateParameter *TemplateThisParameter::syntaxCopy()
2964 {
2965     TemplateThisParameter *tp = new TemplateThisParameter(loc, ident, specType, defaultType);
2966     if (tp->specType)
2967         tp->specType = specType->syntaxCopy();
2968     if (defaultType)
2969         tp->defaultType = defaultType->syntaxCopy();
2970     return tp;
2971 }
2972
2973 void TemplateThisParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2974 {
2975     buf->writestring("this ");
2976     TemplateTypeParameter::toCBuffer(buf, hgs);
2977 }
2978 #endif
2979
2980 /* ======================== TemplateAliasParameter ========================== */
2981
2982 // alias-parameter
2983
2984 Dsymbol *TemplateAliasParameter::sdummy = NULL;
2985
2986 TemplateAliasParameter::TemplateAliasParameter(Loc loc, Identifier *ident,
2987         Type *specType, Object *specAlias, Object *defaultAlias)
2988     : TemplateParameter(loc, ident)
2989 {
2990     this->ident = ident;
2991     this->specType = specType;
2992     this->specAlias = specAlias;
2993     this->defaultAlias = defaultAlias;
2994 }
2995
2996 TemplateAliasParameter *TemplateAliasParameter::isTemplateAliasParameter()
2997 {
2998     return this;
2999 }
3000
3001 TemplateParameter *TemplateAliasParameter::syntaxCopy()
3002 {
3003     TemplateAliasParameter *tp = new TemplateAliasParameter(loc, ident, specType, specAlias, defaultAlias);
3004     if (tp->specType)
3005         tp->specType = specType->syntaxCopy();
3006     tp->specAlias = objectSyntaxCopy(specAlias);
3007     tp->defaultAlias = objectSyntaxCopy(defaultAlias);
3008     return tp;
3009 }
3010
3011 void TemplateAliasParameter::declareParameter(Scope *sc)
3012 {
3013     TypeIdentifier *ti = new TypeIdentifier(loc, ident);
3014     sparam = new AliasDeclaration(loc, ident, ti);
3015     if (!sc->insert(sparam))
3016         error(loc, "parameter '%s' multiply defined", ident->toChars());
3017 }
3018
3019 Object *aliasParameterSemantic(Loc loc, Scope *sc, Object *o)
3020 {
3021     if (o)
3022     {
3023         Expression *ea = isExpression(o);
3024         Type *ta = isType(o);
3025         if (ta)
3026         {   Dsymbol *s = ta->toDsymbol(sc);
3027             if (s)
3028                 o = s;
3029             else
3030                 o = ta->semantic(loc, sc);
3031         }
3032         else if (ea)
3033         {
3034             ea = ea->semantic(sc);
3035             o = ea->optimize(WANTvalue | WANTinterpret);
3036         }
3037     }
3038     return o;
3039 }
3040
3041 void TemplateAliasParameter::semantic(Scope *sc)
3042 {
3043     if (specType)
3044     {
3045         specType = specType->semantic(loc, sc);
3046     }
3047     specAlias = aliasParameterSemantic(loc, sc, specAlias);
3048 #if 0 // Don't do semantic() until instantiation
3049     if (defaultAlias)
3050         defaultAlias = defaultAlias->semantic(loc, sc);
3051 #endif
3052 }
3053
3054 int TemplateAliasParameter::overloadMatch(TemplateParameter *tp)
3055 {
3056     TemplateAliasParameter *tap = tp->isTemplateAliasParameter();
3057
3058     if (tap)
3059     {
3060         if (specAlias != tap->specAlias)
3061             goto Lnomatch;
3062
3063         return 1;                       // match
3064     }
3065
3066 Lnomatch:
3067     return 0;
3068 }
3069
3070 MATCH TemplateAliasParameter::matchArg(Scope *sc,
3071         Objects *tiargs, int i, TemplateParameters *parameters,
3072         Objects *dedtypes,
3073         Declaration **psparam, int flags)
3074 {
3075     Object *sa;
3076     Object *oarg;
3077     Expression *ea;
3078     Dsymbol *s;
3079
3080     //printf("TemplateAliasParameter::matchArg()\n");
3081
3082     if (i < tiargs->dim)
3083         oarg = (Object *)tiargs->data[i];
3084     else
3085     {   // Get default argument instead
3086         oarg = defaultArg(loc, sc);
3087         if (!oarg)
3088         {   assert(i < dedtypes->dim);
3089             // It might have already been deduced
3090             oarg = (Object *)dedtypes->data[i];
3091             if (!oarg)
3092                 goto Lnomatch;
3093         }
3094     }
3095
3096     sa = getDsymbol(oarg);
3097     if (sa)
3098     {
3099         /* specType means the alias must be a declaration with a type
3100          * that matches specType.
3101          */
3102         if (specType)
3103         {   Declaration *d = ((Dsymbol *)sa)->isDeclaration();
3104             if (!d)
3105                 goto Lnomatch;
3106             if (!d->type->equals(specType))
3107                 goto Lnomatch;
3108         }
3109     }
3110     else
3111     {
3112         sa = oarg;
3113         ea = isExpression(oarg);
3114         if (ea)
3115         {   if (specType)
3116             {
3117                 if (!ea->type->equals(specType))
3118                     goto Lnomatch;
3119             }
3120         }
3121         else
3122             goto Lnomatch;
3123     }
3124
3125     if (specAlias)
3126     {
3127         if (sa == sdummy)
3128             goto Lnomatch;
3129         if (sa != specAlias)
3130             goto Lnomatch;
3131     }
3132     else if (dedtypes->data[i])
3133     {   // Must match already deduced symbol
3134         Object *s = (Object *)dedtypes->data[i];
3135
3136         if (!sa || s != sa)
3137             goto Lnomatch;
3138     }
3139     dedtypes->data[i] = sa;
3140
3141     s = isDsymbol(sa);
3142     if (s)
3143         *psparam = new AliasDeclaration(loc, ident, s);
3144     else
3145     {
3146         assert(ea);
3147
3148         // Declare manifest constant
3149         Initializer *init = new ExpInitializer(loc, ea);
3150         VarDeclaration *v = new VarDeclaration(loc, NULL, ident, init);
3151         v->storage_class = STCmanifest;
3152         v->semantic(sc);
3153         *psparam = v;
3154     }
3155     return MATCHexact;
3156
3157 Lnomatch:
3158     *psparam = NULL;
3159     //printf("\tm = %d\n", MATCHnomatch);
3160     return MATCHnomatch;
3161 }
3162
3163
3164 void TemplateAliasParameter::print(Object *oarg, Object *oded)
3165 {
3166     printf(" %s\n", ident->toChars());
3167
3168     Dsymbol *sa = isDsymbol(oded);
3169     assert(sa);
3170
3171     printf("\tParameter alias: %s\n", sa->toChars());
3172 }
3173
3174 void TemplateAliasParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3175 {
3176     buf->writestring("alias ");
3177     if (specType)
3178     {   HdrGenState hgs;
3179         specType->toCBuffer(buf, ident, &hgs);
3180     }
3181     else
3182         buf->writestring(ident->toChars());
3183     if (specAlias)
3184     {
3185         buf->writestring(" : ");
3186         ObjectToCBuffer(buf, hgs, specAlias);
3187     }
3188     if (defaultAlias)
3189     {
3190         buf->writestring(" = ");
3191         ObjectToCBuffer(buf, hgs, defaultAlias);
3192     }
3193 }
3194
3195
3196 void *TemplateAliasParameter::dummyArg()
3197 {   Object *s;
3198
3199     s = specAlias;
3200     if (!s)
3201     {
3202         if (!sdummy)
3203             sdummy = new Dsymbol();
3204         s = sdummy;
3205     }
3206     return (void*)s;
3207 }
3208
3209
3210 Object *TemplateAliasParameter::specialization()
3211 {
3212     return specAlias;
3213 }
3214
3215
3216 Object *TemplateAliasParameter::defaultArg(Loc loc, Scope *sc)
3217 {
3218     Object *da = defaultAlias;
3219     Type *ta = isType(defaultAlias);
3220     if (ta)
3221     {
3222        if (ta->ty == Tinstance)
3223        {
3224            // If the default arg is a template, instantiate for each type
3225            da = ta->syntaxCopy();
3226        }
3227     }
3228
3229     Object *o = aliasParameterSemantic(loc, sc, da);
3230     return o;
3231 }
3232
3233 /* ======================== TemplateValueParameter ========================== */
3234
3235 // value-parameter
3236
3237 Expression *TemplateValueParameter::edummy = NULL;
3238
3239 TemplateValueParameter::TemplateValueParameter(Loc loc, Identifier *ident, Type *valType,
3240         Expression *specValue, Expression *defaultValue)
3241     : TemplateParameter(loc, ident)
3242 {
3243     this->ident = ident;
3244     this->valType = valType;
3245     this->specValue = specValue;
3246     this->defaultValue = defaultValue;
3247 }
3248
3249 TemplateValueParameter *TemplateValueParameter::isTemplateValueParameter()
3250 {
3251     return this;
3252 }
3253
3254 TemplateParameter *TemplateValueParameter::syntaxCopy()
3255 {
3256     TemplateValueParameter *tp =
3257         new TemplateValueParameter(loc, ident, valType, specValue, defaultValue);
3258     tp->valType = valType->syntaxCopy();
3259     if (specValue)
3260         tp->specValue = specValue->syntaxCopy();
3261     if (defaultValue)
3262         tp->defaultValue = defaultValue->syntaxCopy();
3263     return tp;
3264 }
3265
3266 void TemplateValueParameter::declareParameter(Scope *sc)
3267 {
3268     VarDeclaration *v = new VarDeclaration(loc, valType, ident, NULL);
3269     v->storage_class = STCtemplateparameter;
3270     if (!sc->insert(v))
3271         error(loc, "parameter '%s' multiply defined", ident->toChars());
3272     sparam = v;
3273 }
3274
3275 void TemplateValueParameter::semantic(Scope *sc)
3276 {
3277     sparam->semantic(sc);
3278     valType = valType->semantic(loc, sc);
3279     if (!(valType->isintegral() || valType->isfloating() || valType->isString()) &&
3280         valType->ty != Tident)
3281     {
3282         if (valType != Type::terror)
3283             error(loc, "arithmetic/string type expected for value-parameter, not %s", valType->toChars());
3284     }
3285
3286     if (specValue)
3287     {   Expression *e = specValue;
3288
3289         e = e->semantic(sc);
3290         e = e->implicitCastTo(sc, valType);
3291         e = e->optimize(WANTvalue | WANTinterpret);
3292         if (e->op == TOKint64 || e->op == TOKfloat64 ||
3293             e->op == TOKcomplex80 || e->op == TOKnull || e->op == TOKstring)
3294             specValue = e;
3295         //e->toInteger();
3296     }
3297
3298 #if 0   // defer semantic analysis to arg match
3299     if (defaultValue)
3300     {   Expression *e = defaultValue;
3301
3302         e = e->semantic(sc);
3303         e = e->implicitCastTo(sc, valType);
3304         e = e->optimize(WANTvalue | WANTinterpret);
3305         if (e->op == TOKint64)
3306             defaultValue = e;
3307         //e->toInteger();
3308     }
3309 #endif
3310 }
3311
3312 int TemplateValueParameter::overloadMatch(TemplateParameter *tp)
3313 {
3314     TemplateValueParameter *tvp = tp->isTemplateValueParameter();
3315
3316     if (tvp)
3317     {
3318         if (valType != tvp->valType)
3319             goto Lnomatch;
3320
3321         if (valType && !valType->equals(tvp->valType))
3322             goto Lnomatch;
3323
3324         if (specValue != tvp->specValue)
3325             goto Lnomatch;
3326
3327         return 1;                       // match
3328     }
3329
3330 Lnomatch:
3331     return 0;
3332 }
3333
3334
3335 MATCH TemplateValueParameter::matchArg(Scope *sc,
3336         Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
3337         Declaration **psparam, int flags)
3338 {
3339     //printf("TemplateValueParameter::matchArg()\n");
3340
3341     Initializer *init;
3342     Declaration *sparam;
3343     MATCH m = MATCHexact;
3344     Expression *ei;
3345     Object *oarg;
3346
3347     if (i < tiargs->dim)
3348         oarg = (Object *)tiargs->data[i];
3349     else
3350     {   // Get default argument instead
3351         oarg = defaultArg(loc, sc);
3352         if (!oarg)
3353         {   assert(i < dedtypes->dim);
3354             // It might have already been deduced
3355             oarg = (Object *)dedtypes->data[i];
3356             if (!oarg)
3357                 goto Lnomatch;
3358         }
3359     }
3360
3361     ei = isExpression(oarg);
3362     Type *vt;
3363
3364     if (!ei && oarg)
3365         goto Lnomatch;
3366
3367     if (ei && ei->op == TOKvar)
3368     {   // Resolve const variables that we had skipped earlier
3369         ei = ei->optimize(WANTvalue | WANTinterpret);
3370     }
3371
3372     if (specValue)
3373     {
3374         if (!ei || ei == edummy)
3375             goto Lnomatch;
3376
3377         Expression *e = specValue;
3378
3379         e = e->semantic(sc);
3380         e = e->implicitCastTo(sc, valType);
3381         e = e->optimize(WANTvalue | WANTinterpret);
3382         //e->type = e->type->toHeadMutable();
3383
3384         ei = ei->syntaxCopy();
3385         ei = ei->semantic(sc);
3386         ei = ei->optimize(WANTvalue | WANTinterpret);
3387         //ei->type = ei->type->toHeadMutable();
3388         //printf("\tei: %s, %s\n", ei->toChars(), ei->type->toChars());
3389         //printf("\te : %s, %s\n", e->toChars(), e->type->toChars());
3390         if (!ei->equals(e))
3391             goto Lnomatch;
3392     }
3393     else if (dedtypes->data[i])
3394     {   // Must match already deduced value
3395         Expression *e = (Expression *)dedtypes->data[i];
3396
3397         if (!ei || !ei->equals(e))
3398             goto Lnomatch;
3399     }
3400 Lmatch:
3401     //printf("\tvalType: %s, ty = %d\n", valType->toChars(), valType->ty);
3402     vt = valType->semantic(0, sc);
3403     //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars());
3404     //printf("vt = %s\n", vt->toChars());
3405     if (ei->type)
3406     {
3407         m = (MATCH)ei->implicitConvTo(vt);
3408         //printf("m: %d\n", m);
3409         if (!m)
3410             goto Lnomatch;
3411     }
3412     dedtypes->data[i] = ei;
3413
3414     init = new ExpInitializer(loc, ei);
3415     sparam = new VarDeclaration(loc, vt, ident, init);
3416     sparam->storage_class = STCmanifest;
3417     *psparam = sparam;
3418     return m;
3419
3420 Lnomatch:
3421     //printf("\tno match\n");
3422     *psparam = NULL;
3423     return MATCHnomatch;
3424 }
3425
3426
3427 void TemplateValueParameter::print(Object *oarg, Object *oded)
3428 {
3429     printf(" %s\n", ident->toChars());
3430
3431     Expression *ea = isExpression(oded);
3432
3433     if (specValue)
3434         printf("\tSpecialization: %s\n", specValue->toChars());
3435     printf("\tParameter Value: %s\n", ea ? ea->toChars() : "NULL");
3436 }
3437
3438
3439 void TemplateValueParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3440 {
3441     valType->toCBuffer(buf, ident, hgs);
3442     if (specValue)
3443     {
3444         buf->writestring(" : ");
3445         specValue->toCBuffer(buf, hgs);
3446     }
3447     if (defaultValue)
3448     {
3449         buf->writestring(" = ");
3450         defaultValue->toCBuffer(buf, hgs);
3451     }
3452 }
3453
3454
3455 void *TemplateValueParameter::dummyArg()
3456 {   Expression *e;
3457
3458     e = specValue;
3459     if (!e)
3460     {
3461         // Create a dummy value
3462         if (!edummy)
3463             edummy = valType->defaultInit();
3464         e = edummy;
3465     }
3466     return (void *)e;
3467 }
3468
3469
3470 Object *TemplateValueParameter::specialization()
3471 {
3472     return specValue;
3473 }
3474
3475
3476 Object *TemplateValueParameter::defaultArg(Loc loc, Scope *sc)
3477 {
3478     Expression *e = defaultValue;
3479     if (e)
3480     {
3481         e = e->syntaxCopy();
3482         e = e->semantic(sc);
3483 #if DMDV2
3484         e = e->resolveLoc(loc, sc);
3485 #endif
3486     }
3487     return e;
3488 }
3489
3490 /* ======================== TemplateTupleParameter ========================== */
3491
3492 // variadic-parameter
3493
3494 TemplateTupleParameter::TemplateTupleParameter(Loc loc, Identifier *ident)
3495     : TemplateParameter(loc, ident)
3496 {
3497     this->ident = ident;
3498 }
3499
3500 TemplateTupleParameter *TemplateTupleParameter::isTemplateTupleParameter()
3501 {
3502     return this;
3503 }
3504
3505 TemplateParameter *TemplateTupleParameter::syntaxCopy()
3506 {
3507     TemplateTupleParameter *tp = new TemplateTupleParameter(loc, ident);
3508     return tp;
3509 }
3510
3511 void TemplateTupleParameter::declareParameter(Scope *sc)
3512 {
3513     TypeIdentifier *ti = new TypeIdentifier(loc, ident);
3514     sparam = new AliasDeclaration(loc, ident, ti);
3515     if (!sc->insert(sparam))
3516         error(loc, "parameter '%s' multiply defined", ident->toChars());
3517 }
3518
3519 void TemplateTupleParameter::semantic(Scope *sc)
3520 {
3521 }
3522
3523 int TemplateTupleParameter::overloadMatch(TemplateParameter *tp)
3524 {
3525     TemplateTupleParameter *tvp = tp->isTemplateTupleParameter();
3526
3527     if (tvp)
3528     {
3529         return 1;                       // match
3530     }
3531
3532 Lnomatch:
3533     return 0;
3534 }
3535
3536 MATCH TemplateTupleParameter::matchArg(Scope *sc,
3537         Objects *tiargs, int i, TemplateParameters *parameters,
3538         Objects *dedtypes,
3539         Declaration **psparam, int flags)
3540 {
3541     //printf("TemplateTupleParameter::matchArg()\n");
3542
3543     /* The rest of the actual arguments (tiargs[]) form the match
3544      * for the variadic parameter.
3545      */
3546     assert(i + 1 == dedtypes->dim);     // must be the last one
3547     Tuple *ovar;
3548
3549     if (dedtypes->data[i] && isTuple((Object *)dedtypes->data[i]))
3550         // It was already been deduced
3551         ovar = isTuple((Object *)dedtypes->data[i]);
3552     else if (i + 1 == tiargs->dim && isTuple((Object *)tiargs->data[i]))
3553         ovar = isTuple((Object *)tiargs->data[i]);
3554     else
3555     {
3556         ovar = new Tuple();
3557         //printf("ovar = %p\n", ovar);
3558         if (i < tiargs->dim)
3559         {
3560             //printf("i = %d, tiargs->dim = %d\n", i, tiargs->dim);
3561             ovar->objects.setDim(tiargs->dim - i);
3562             for (size_t j = 0; j < ovar->objects.dim; j++)
3563                 ovar->objects.data[j] = tiargs->data[i + j];
3564         }
3565     }
3566     *psparam = new TupleDeclaration(loc, ident, &ovar->objects);
3567     dedtypes->data[i] = (void *)ovar;
3568     return MATCHexact;
3569 }
3570
3571
3572 void TemplateTupleParameter::print(Object *oarg, Object *oded)
3573 {
3574     printf(" %s... [", ident->toChars());
3575     Tuple *v = isTuple(oded);
3576     assert(v);
3577
3578     //printf("|%d| ", v->objects.dim);
3579     for (int i = 0; i < v->objects.dim; i++)
3580     {
3581         if (i)
3582             printf(", ");
3583
3584         Object *o = (Object *)v->objects.data[i];
3585
3586         Dsymbol *sa = isDsymbol(o);
3587         if (sa)
3588             printf("alias: %s", sa->toChars());
3589
3590         Type *ta = isType(o);
3591         if (ta)
3592             printf("type: %s", ta->toChars());
3593
3594         Expression *ea = isExpression(o);
3595         if (ea)
3596             printf("exp: %s", ea->toChars());
3597
3598         assert(!isTuple(o));            // no nested Tuple arguments
3599     }
3600
3601     printf("]\n");
3602 }
3603
3604 void TemplateTupleParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3605 {
3606     buf->writestring(ident->toChars());
3607     buf->writestring("...");
3608 }
3609
3610
3611 void *TemplateTupleParameter::dummyArg()
3612 {
3613     return NULL;
3614 }
3615
3616
3617 Object *TemplateTupleParameter::specialization()
3618 {
3619     return NULL;
3620 }
3621
3622
3623 Object *TemplateTupleParameter::defaultArg(Loc loc, Scope *sc)
3624 {
3625     return NULL;
3626 }
3627
3628 /* ======================== TemplateInstance ================================ */
3629
3630 TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
3631     : ScopeDsymbol(NULL)
3632 {
3633 #if LOG
3634     printf("TemplateInstance(this = %p, ident = '%s')\n", this, ident ? ident->toChars() : "null");
3635 #endif
3636     this->loc = loc;
3637     this->name = ident;
3638     this->tiargs = NULL;
3639     this->tempdecl = NULL;
3640     this->inst = NULL;
3641     this->tinst = NULL;
3642     this->argsym = NULL;
3643     this->aliasdecl = NULL;
3644     this->semanticRun = 0;
3645     this->semantictiargsdone = 0;
3646     this->withsym = NULL;
3647     this->nest = 0;
3648     this->havetempdecl = 0;
3649     this->isnested = NULL;
3650     this->errors = 0;
3651 }
3652
3653 /*****************
3654  * This constructor is only called when we figured out which function
3655  * template to instantiate.
3656  */
3657
3658 TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs)
3659     : ScopeDsymbol(NULL)
3660 {
3661 #if LOG
3662     printf("TemplateInstance(this = %p, tempdecl = '%s')\n", this, td->toChars());
3663 #endif
3664     this->loc = loc;
3665     this->name = td->ident;
3666     this->tiargs = tiargs;
3667     this->tempdecl = td;
3668     this->inst = NULL;
3669     this->tinst = NULL;
3670     this->argsym = NULL;
3671     this->aliasdecl = NULL;
3672     this->semanticRun = 0;
3673     this->semantictiargsdone = 1;
3674     this->withsym = NULL;
3675     this->nest = 0;
3676     this->havetempdecl = 1;
3677     this->isnested = NULL;
3678     this->errors = 0;
3679
3680     assert((size_t)tempdecl->scope > 0x10000);
3681 }
3682
3683
3684 Objects *TemplateInstance::arraySyntaxCopy(Objects *objs)
3685 {
3686     Objects *a = NULL;
3687     if (objs)
3688     {   a = new Objects();
3689         a->setDim(objs->dim);
3690         for (size_t i = 0; i < objs->dim; i++)
3691         {
3692             a->data[i] = objectSyntaxCopy((Object *)objs->data[i]);
3693         }
3694     }
3695     return a;
3696 }
3697
3698 Dsymbol *TemplateInstance::syntaxCopy(Dsymbol *s)
3699 {
3700     TemplateInstance *ti;
3701
3702     if (s)
3703         ti = (TemplateInstance *)s;
3704     else
3705         ti = new TemplateInstance(loc, name);
3706
3707     ti->tiargs = arraySyntaxCopy(tiargs);
3708
3709     ScopeDsymbol::syntaxCopy(ti);
3710     return ti;
3711 }
3712
3713
3714 void TemplateInstance::semantic(Scope *sc)
3715 {
3716     semantic(sc, NULL);
3717 }
3718
3719 void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
3720 {
3721     //printf("TemplateInstance::semantic('%s', this=%p, gag = %d, sc = %p)\n", toChars(), this, global.gag, sc);
3722     if (global.errors && name != Id::AssociativeArray)
3723     {
3724         //printf("not instantiating %s due to %d errors\n", toChars(), global.errors);
3725         if (!global.gag)
3726         {
3727             /* Trying to soldier on rarely generates useful messages
3728              * at this point.
3729              */
3730             fatal();
3731         }
3732 //        return;
3733     }
3734 #if LOG
3735     printf("\n+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this);
3736 #endif
3737     if (inst)           // if semantic() was already run
3738     {
3739 #if LOG
3740         printf("-TemplateInstance::semantic('%s', this=%p) already run\n", inst->toChars(), inst);
3741 #endif
3742         return;
3743     }
3744
3745     // get the enclosing template instance from the scope tinst
3746     tinst = sc->tinst;
3747
3748     if (semanticRun != 0)
3749     {
3750 #if LOG
3751         printf("Recursive template expansion\n");
3752 #endif
3753         error(loc, "recursive template expansion");
3754 //      inst = this;
3755         return;
3756     }
3757     semanticRun = 1;
3758
3759 #if LOG
3760     printf("\tdo semantic\n");
3761 #endif
3762     if (havetempdecl)
3763     {
3764         assert((size_t)tempdecl->scope > 0x10000);
3765         // Deduce tdtypes
3766         tdtypes.setDim(tempdecl->parameters->dim);
3767         if (!tempdecl->matchWithInstance(this, &tdtypes, 2))
3768         {
3769             error("incompatible arguments for template instantiation");
3770             inst = this;
3771             return;
3772         }
3773     }
3774     else
3775     {
3776         /* Run semantic on each argument, place results in tiargs[]
3777          * (if we havetempdecl, then tiargs is already evaluated)
3778          */
3779         semanticTiargs(sc);
3780         if (arrayObjectIsError(tiargs))
3781         {   inst = this;
3782             //printf("error return %p, %d\n", tempdecl, global.errors);
3783             return;             // error recovery
3784         }
3785
3786         tempdecl = findTemplateDeclaration(sc);
3787         if (tempdecl)
3788             tempdecl = findBestMatch(sc);
3789         if (!tempdecl || global.errors)
3790         {   inst = this;
3791             //printf("error return %p, %d\n", tempdecl, global.errors);
3792             return;             // error recovery
3793         }
3794     }
3795
3796     // If tempdecl is a mixin, disallow it
3797     if (tempdecl->ismixin)
3798         error("mixin templates are not regular templates");
3799
3800     hasNestedArgs(tiargs);
3801
3802     /* See if there is an existing TemplateInstantiation that already
3803      * implements the typeargs. If so, just refer to that one instead.
3804      */
3805
3806     for (size_t i = 0; i < tempdecl->instances.dim; i++)
3807     {
3808         TemplateInstance *ti = (TemplateInstance *)tempdecl->instances.data[i];
3809 #if LOG
3810         printf("\t%s: checking for match with instance %d (%p): '%s'\n", toChars(), i, ti, ti->toChars());
3811 #endif
3812         assert(tdtypes.dim == ti->tdtypes.dim);
3813
3814         // Nesting must match
3815         if (isnested != ti->isnested)
3816         {
3817             //printf("test2 isnested %s ti->isnested %s\n", isnested ? isnested->toChars() : "", ti->isnested ? ti->isnested->toChars() : "");
3818             continue;
3819         }
3820 #if 0
3821         if (isnested && sc->parent != ti->parent)
3822             continue;
3823 #endif
3824         if (!arrayObjectMatch(&tdtypes, &ti->tdtypes, tempdecl, sc))
3825             goto L1;
3826
3827         /* Template functions may have different instantiations based on
3828          * "auto ref" parameters.
3829          */
3830         if (fargs)
3831         {
3832             FuncDeclaration *fd = ti->toAlias()->isFuncDeclaration();
3833             if (fd)
3834             {
3835                 Parameters *fparameters = fd->getParameters(NULL);
3836                 size_t nfparams = Parameter::dim(fparameters); // Num function parameters
3837                 for (int i = 0; i < nfparams && i < fargs->dim; i++)
3838                 {   Parameter *fparam = Parameter::getNth(fparameters, i);
3839                     Expression *farg = (Expression *)fargs->data[i];
3840                     if (fparam->storageClass & STCauto)         // if "auto ref"
3841                     {
3842                         if (farg->isLvalue())
3843                         {   if (!(fparam->storageClass & STCref))
3844                                 goto L1;                        // auto ref's don't match
3845                         }
3846                         else
3847                         {   if (fparam->storageClass & STCref)
3848                                 goto L1;                        // auto ref's don't match
3849                         }
3850                     }
3851                 }
3852             }
3853         }
3854
3855         // It's a match
3856         inst = ti;
3857         parent = ti->parent;
3858 #if LOG
3859         printf("\tit's a match with instance %p\n", inst);
3860 #endif
3861         return;
3862
3863      L1:
3864         ;
3865     }
3866
3867     /* So, we need to implement 'this' instance.
3868      */
3869 #if LOG
3870     printf("\timplement template instance %s '%s'\n", tempdecl->parent->toChars(), toChars());
3871     printf("\ttempdecl %s\n", tempdecl->toChars());
3872 #endif
3873     unsigned errorsave = global.errors;
3874     inst = this;
3875     int tempdecl_instance_idx = tempdecl->instances.dim;
3876     tempdecl->instances.push(this);
3877     parent = tempdecl->parent;
3878     //printf("parent = '%s'\n", parent->kind());
3879
3880     ident = genIdent(tiargs);         // need an identifier for name mangling purposes.
3881
3882 #if 1
3883     if (isnested)
3884         parent = isnested;
3885 #endif
3886     //printf("parent = '%s'\n", parent->kind());
3887
3888     // Add 'this' to the enclosing scope's members[] so the semantic routines
3889     // will get called on the instance members
3890 #if 1
3891     int dosemantic3 = 0;
3892     {   Array *a;
3893
3894         Scope *scx = sc;
3895 #if 0
3896         for (scx = sc; scx; scx = scx->enclosing)
3897             if (scx->scopesym)
3898                 break;
3899 #endif
3900
3901         //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
3902         if (scx && scx->scopesym &&
3903             scx->scopesym->members && !scx->scopesym->isTemplateMixin()
3904 #if 0 // removed because it bloated compile times
3905             /* The problem is if A imports B, and B imports A, and both A
3906              * and B instantiate the same template, does the compilation of A
3907              * or the compilation of B do the actual instantiation?
3908              *
3909              * see bugzilla 2500.
3910              */
3911             && !scx->module->selfImports()
3912 #endif
3913            )
3914         {
3915             //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
3916             a = scx->scopesym->members;
3917         }
3918         else
3919         {   Module *m = sc->module->importedFrom;
3920             //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars());
3921             a = m->members;
3922             if (m->semanticRun >= 3)
3923             {
3924                 dosemantic3 = 1;
3925             }
3926         }
3927         for (int i = 0; 1; i++)
3928         {
3929             if (i == a->dim)
3930             {
3931                 a->push(this);
3932                 break;
3933             }
3934             if (this == (Dsymbol *)a->data[i])  // if already in Array
3935                 break;
3936         }
3937     }
3938 #endif
3939
3940     // Copy the syntax trees from the TemplateDeclaration
3941     members = Dsymbol::arraySyntaxCopy(tempdecl->members);
3942
3943     // Create our own scope for the template parameters
3944     Scope *scope = tempdecl->scope;
3945     if (!tempdecl->semanticRun)
3946     {
3947         error("template instantiation %s forward references template declaration %s\n", toChars(), tempdecl->toChars());
3948         return;
3949     }
3950
3951 #if LOG
3952     printf("\tcreate scope for template parameters '%s'\n", toChars());
3953 #endif
3954     argsym = new ScopeDsymbol();
3955     argsym->parent = scope->parent;
3956     scope = scope->push(argsym);
3957 //    scope->stc = 0;
3958
3959     // Declare each template parameter as an alias for the argument type
3960     Scope *paramscope = scope->push();
3961     paramscope->stc = 0;
3962     declareParameters(paramscope);
3963     paramscope->pop();
3964
3965     // Add members of template instance to template instance symbol table
3966 //    parent = scope->scopesym;
3967     symtab = new DsymbolTable();
3968     int memnum = 0;
3969     for (int i = 0; i < members->dim; i++)
3970     {
3971         Dsymbol *s = (Dsymbol *)members->data[i];
3972 #if LOG
3973         printf("\t[%d] adding member '%s' %p kind %s to '%s', memnum = %d\n", i, s->toChars(), s, s->kind(), this->toChars(), memnum);
3974 #endif
3975         memnum |= s->addMember(scope, this, memnum);
3976     }
3977 #if LOG
3978     printf("adding members done\n");
3979 #endif
3980
3981     /* See if there is only one member of template instance, and that
3982      * member has the same name as the template instance.
3983      * If so, this template instance becomes an alias for that member.
3984      */
3985     //printf("members->dim = %d\n", members->dim);
3986     if (members->dim)
3987     {
3988         Dsymbol *s;
3989         if (Dsymbol::oneMembers(members, &s) && s)
3990         {
3991             //printf("s->kind = '%s'\n", s->kind());
3992             //s->print();
3993             //printf("'%s', '%s'\n", s->ident->toChars(), tempdecl->ident->toChars());
3994             if (s->ident && s->ident->equals(tempdecl->ident))
3995             {
3996                 //printf("setting aliasdecl\n");
3997                 aliasdecl = new AliasDeclaration(loc, s->ident, s);
3998             }
3999         }
4000     }
4001
4002     /* If function template declaration
4003      */
4004     if (fargs && aliasdecl)
4005     {
4006         FuncDeclaration *fd = aliasdecl->toAlias()->isFuncDeclaration();
4007         if (fd)
4008         {
4009             /* Transmit fargs to type so that TypeFunction::semantic() can
4010              * resolve any "auto ref" storage classes.
4011              */
4012             TypeFunction *tf = (TypeFunction *)fd->type;
4013             if (tf && tf->ty == Tfunction)
4014                 tf->fargs = fargs;
4015         }
4016     }
4017
4018     // Do semantic() analysis on template instance members
4019 #if LOG
4020     printf("\tdo semantic() on template instance members '%s'\n", toChars());
4021 #endif
4022     Scope *sc2;
4023     sc2 = scope->push(this);
4024     //printf("isnested = %d, sc->parent = %s\n", isnested, sc->parent->toChars());
4025     sc2->parent = /*isnested ? sc->parent :*/ this;
4026     sc2->tinst = this;
4027
4028 #if WINDOWS_SEH
4029   __try
4030   {
4031 #endif
4032     static int nest;
4033     //printf("%d\n", nest);
4034     if (++nest > 500)
4035     {
4036         global.gag = 0;                 // ensure error message gets printed
4037         error("recursive expansion");
4038         fatal();
4039     }
4040     for (int i = 0; i < members->dim; i++)
4041     {
4042         Dsymbol *s = (Dsymbol *)members->data[i];
4043         //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars());
4044         //printf("test: isnested = %d, sc2->parent = %s\n", isnested, sc2->parent->toChars());
4045 //      if (isnested)
4046 //          s->parent = sc->parent;
4047         //printf("test3: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars());
4048         s->semantic(sc2);
4049         //printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars());
4050         sc2->module->runDeferredSemantic();
4051     }
4052     --nest;
4053 #if WINDOWS_SEH
4054   }
4055   __except (__ehfilter(GetExceptionInformation()))
4056   {
4057     global.gag = 0;                     // ensure error message gets printed
4058     error("recursive expansion");
4059     fatal();
4060   }
4061 #endif
4062
4063     /* If any of the instantiation members didn't get semantic() run
4064      * on them due to forward references, we cannot run semantic2()
4065      * or semantic3() yet.
4066      */
4067     for (size_t i = 0; i < Module::deferred.dim; i++)
4068     {   Dsymbol *sd = (Dsymbol *)Module::deferred.data[i];
4069
4070         if (sd->parent == this)
4071             goto Laftersemantic;
4072     }
4073
4074     /* The problem is when to parse the initializer for a variable.
4075      * Perhaps VarDeclaration::semantic() should do it like it does
4076      * for initializers inside a function.
4077      */
4078 //    if (sc->parent->isFuncDeclaration())
4079
4080         /* BUG 782: this has problems if the classes this depends on
4081          * are forward referenced. Find a way to defer semantic()
4082          * on this template.
4083          */
4084         semantic2(sc2);
4085
4086     if (sc->func || dosemantic3)
4087     {
4088 #if WINDOWS_SEH
4089         __try
4090         {
4091 #endif
4092             static int nest;
4093             if (++nest > 300)
4094             {
4095                 global.gag = 0;            // ensure error message gets printed
4096                 error("recursive expansion");
4097                 fatal();
4098             }
4099             semantic3(sc2);
4100             --nest;
4101 #if WINDOWS_SEH
4102         }
4103         __except (__ehfilter(GetExceptionInformation()))
4104         {
4105             global.gag = 0;            // ensure error message gets printed
4106             error("recursive expansion");
4107             fatal();
4108         }
4109 #endif
4110     }
4111
4112   Laftersemantic:
4113     sc2->pop();
4114
4115     scope->pop();
4116
4117     // Give additional context info if error occurred during instantiation
4118     if (global.errors != errorsave)
4119     {
4120         error(loc, "error instantiating");
4121         if (tinst)
4122         {   tinst->printInstantiationTrace();
4123         }
4124         errors = 1;
4125         if (global.gag)
4126         {   // Try to reset things so we can try again later to instantiate it
4127             //printf("remove %s\n", toChars());
4128             tempdecl->instances.remove(tempdecl_instance_idx);
4129             if (!(sc->flags & SCOPEstaticif))
4130             {   // Bugzilla 4302 for discussion
4131                 semanticRun = 0;
4132                 inst = NULL;
4133             }
4134         }
4135     }
4136
4137 #if LOG
4138     printf("-TemplateInstance::semantic('%s', this=%p)\n", toChars(), this);
4139 #endif
4140 }
4141
4142
4143 void TemplateInstance::semanticTiargs(Scope *sc)
4144 {
4145     //printf("+TemplateInstance::semanticTiargs() %s\n", toChars());
4146     if (semantictiargsdone)
4147         return;
4148     semantictiargsdone = 1;
4149     semanticTiargs(loc, sc, tiargs, 0);
4150 }
4151
4152 /**********************************
4153  * Input:
4154  *      flags   1: replace const variables with their initializers
4155  */
4156
4157 void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags)
4158 {
4159     // Run semantic on each argument, place results in tiargs[]
4160     //printf("+TemplateInstance::semanticTiargs() %s\n", toChars());
4161     if (!tiargs)
4162         return;
4163     for (size_t j = 0; j < tiargs->dim; j++)
4164     {
4165         Object *o = (Object *)tiargs->data[j];
4166         Type *ta = isType(o);
4167         Expression *ea = isExpression(o);
4168         Dsymbol *sa = isDsymbol(o);
4169
4170         //printf("1: tiargs->data[%d] = %p, %p, %p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
4171         if (ta)
4172         {
4173             //printf("type %s\n", ta->toChars());
4174             // It might really be an Expression or an Alias
4175             ta->resolve(loc, sc, &ea, &ta, &sa);
4176             if (ea)
4177             {
4178                 ea = ea->semantic(sc);
4179                 /* This test is to skip substituting a const var with
4180                  * its initializer. The problem is the initializer won't
4181                  * match with an 'alias' parameter. Instead, do the
4182                  * const substitution in TemplateValueParameter::matchArg().
4183                  */
4184                 if (ea->op != TOKvar || flags & 1)
4185                     ea = ea->optimize(WANTvalue | WANTinterpret);
4186                 tiargs->data[j] = ea;
4187             }
4188             else if (sa)
4189             {   tiargs->data[j] = sa;
4190                 TupleDeclaration *d = sa->toAlias()->isTupleDeclaration();
4191                 if (d)
4192                 {
4193                     size_t dim = d->objects->dim;
4194                     tiargs->remove(j);
4195                     tiargs->insert(j, d->objects);
4196                     j--;
4197                 }
4198             }
4199             else if (ta)
4200             {
4201               Ltype:
4202                 if (ta->ty == Ttuple)
4203                 {   // Expand tuple
4204                     TypeTuple *tt = (TypeTuple *)ta;
4205                     size_t dim = tt->arguments->dim;
4206                     tiargs->remove(j);
4207                     if (dim)
4208                     {   tiargs->reserve(dim);
4209                         for (size_t i = 0; i < dim; i++)
4210                         {   Parameter *arg = (Parameter *)tt->arguments->data[i];
4211                             tiargs->insert(j + i, arg->type);
4212                         }
4213                     }
4214                     j--;
4215                 }
4216                 else
4217                     tiargs->data[j] = ta;
4218             }
4219             else
4220             {
4221                 assert(global.errors);
4222                 tiargs->data[j] = Type::terror;
4223             }
4224         }
4225         else if (ea)
4226         {
4227             if (!ea)
4228             {   assert(global.errors);
4229                 ea = new ErrorExp();
4230             }
4231             assert(ea);
4232             ea = ea->semantic(sc);
4233             if (ea->op != TOKvar || flags & 1)
4234                 ea = ea->optimize(WANTvalue | WANTinterpret);
4235             tiargs->data[j] = ea;
4236             if (ea->op == TOKtype)
4237             {   ta = ea->type;
4238                 goto Ltype;
4239             }
4240             if (ea->op == TOKtuple)
4241             {   // Expand tuple
4242                 TupleExp *te = (TupleExp *)ea;
4243                 size_t dim = te->exps->dim;
4244                 tiargs->remove(j);
4245                 if (dim)
4246                 {   tiargs->reserve(dim);
4247                     for (size_t i = 0; i < dim; i++)
4248                         tiargs->insert(j + i, te->exps->data[i]);
4249                 }
4250                 j--;
4251             }
4252         }
4253         else if (sa)
4254         {
4255             TemplateDeclaration *td = sa->isTemplateDeclaration();
4256             if (td && !td->semanticRun && td->literal)
4257                 td->semantic(sc);
4258         }
4259         else
4260         {
4261             assert(0);
4262         }
4263         //printf("1: tiargs->data[%d] = %p\n", j, tiargs->data[j]);
4264     }
4265 #if 0
4266     printf("-TemplateInstance::semanticTiargs('%s', this=%p)\n", toChars(), this);
4267     for (size_t j = 0; j < tiargs->dim; j++)
4268     {
4269         Object *o = (Object *)tiargs->data[j];
4270         Type *ta = isType(o);
4271         Expression *ea = isExpression(o);
4272         Dsymbol *sa = isDsymbol(o);
4273         Tuple *va = isTuple(o);
4274
4275         printf("\ttiargs[%d] = ta %p, ea %p, sa %p, va %p\n", j, ta, ea, sa, va);
4276     }
4277 #endif
4278 }
4279
4280 /**********************************************
4281  * Find template declaration corresponding to template instance.
4282  */
4283
4284 TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc)
4285 {
4286     //printf("TemplateInstance::findTemplateDeclaration() %s\n", toChars());
4287     if (!tempdecl)
4288     {
4289         /* Given:
4290          *    foo!( ... )
4291          * figure out which TemplateDeclaration foo refers to.
4292          */
4293         Dsymbol *s;
4294         Dsymbol *scopesym;
4295         Identifier *id;
4296         int i;
4297
4298         id = name;
4299         s = sc->search(loc, id, &scopesym);
4300         if (!s)
4301         {
4302             s = sc->search_correct(id);
4303             if (s)
4304                 error("template '%s' is not defined, did you mean %s?", id->toChars(), s->toChars());
4305             else
4306                 error("template '%s' is not defined", id->toChars());
4307             return NULL;
4308         }
4309
4310         /* If an OverloadSet, look for a unique member that is a template declaration
4311          */
4312         OverloadSet *os = s->isOverloadSet();
4313         if (os)
4314         {   s = NULL;
4315             for (int i = 0; i < os->a.dim; i++)
4316             {   Dsymbol *s2 = (Dsymbol *)os->a.data[i];
4317                 if (s2->isTemplateDeclaration())
4318                 {
4319                     if (s)
4320                         error("ambiguous template declaration %s and %s", s->toPrettyChars(), s2->toPrettyChars());
4321                     s = s2;
4322                 }
4323             }
4324             if (!s)
4325             {   error("template '%s' is not defined", id->toChars());
4326                 return NULL;
4327             }
4328         }
4329
4330 #if LOG
4331         printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind());
4332         if (s->parent)
4333             printf("s->parent = '%s'\n", s->parent->toChars());
4334 #endif
4335         withsym = scopesym->isWithScopeSymbol();
4336
4337         /* We might have found an alias within a template when
4338          * we really want the template.
4339          */
4340         TemplateInstance *ti;
4341         if (s->parent &&
4342             (ti = s->parent->isTemplateInstance()) != NULL)
4343         {
4344             if (ti->tempdecl && ti->tempdecl->ident == id)
4345             {
4346                 /* This is so that one can refer to the enclosing
4347                  * template, even if it has the same name as a member
4348                  * of the template, if it has a !(arguments)
4349                  */
4350                 tempdecl = ti->tempdecl;
4351                 if (tempdecl->overroot)         // if not start of overloaded list of TemplateDeclaration's
4352                     tempdecl = tempdecl->overroot; // then get the start
4353                 s = tempdecl;
4354             }
4355         }
4356
4357         s = s->toAlias();
4358
4359         /* It should be a TemplateDeclaration, not some other symbol
4360          */
4361         tempdecl = s->isTemplateDeclaration();
4362         if (!tempdecl)
4363         {
4364             if (!s->parent && global.errors)
4365                 return NULL;
4366             if (!s->parent && s->getType())
4367             {   Dsymbol *s2 = s->getType()->toDsymbol(sc);
4368                 if (!s2)
4369                 {
4370                     error("%s is not a template declaration, it is a %s", id->toChars(), s->kind());
4371                     return NULL;
4372                 }
4373                 s = s2;
4374             }
4375 #ifdef DEBUG
4376             //if (!s->parent) printf("s = %s %s\n", s->kind(), s->toChars());
4377 #endif
4378             //assert(s->parent);
4379             TemplateInstance *ti = s->parent ? s->parent->isTemplateInstance() : NULL;
4380             if (ti &&
4381                 (ti->name == id ||
4382                  ti->toAlias()->ident == id)
4383                 &&
4384                 ti->tempdecl)
4385             {
4386                 /* This is so that one can refer to the enclosing
4387                  * template, even if it has the same name as a member
4388                  * of the template, if it has a !(arguments)
4389                  */
4390                 tempdecl = ti->tempdecl;
4391                 if (tempdecl->overroot)         // if not start of overloaded list of TemplateDeclaration's
4392                     tempdecl = tempdecl->overroot; // then get the start
4393             }
4394             else
4395             {
4396                 error("%s is not a template declaration, it is a %s", id->toChars(), s->kind());
4397                 return NULL;
4398             }
4399         }
4400     }
4401     else
4402         assert(tempdecl->isTemplateDeclaration());
4403     return tempdecl;
4404 }
4405
4406 TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
4407 {
4408     /* Since there can be multiple TemplateDeclaration's with the same
4409      * name, look for the best match.
4410      */
4411     TemplateDeclaration *td_ambig = NULL;
4412     TemplateDeclaration *td_best = NULL;
4413     MATCH m_best = MATCHnomatch;
4414     Objects dedtypes;
4415
4416 #if LOG
4417     printf("TemplateInstance::findBestMatch()\n");
4418 #endif
4419     // First look for forward references
4420     for (TemplateDeclaration *td = tempdecl; td; td = td->overnext)
4421     {
4422         if (!td->semanticRun)
4423         {
4424             if (td->scope)
4425             {   // Try to fix forward reference
4426                 td->semantic(td->scope);
4427             }
4428             if (!td->semanticRun)
4429             {
4430                 error("%s forward references template declaration %s\n", toChars(), td->toChars());
4431                 return NULL;
4432             }
4433         }
4434     }
4435
4436     for (TemplateDeclaration *td = tempdecl; td; td = td->overnext)
4437     {
4438         MATCH m;
4439
4440 //if (tiargs->dim) printf("2: tiargs->dim = %d, data[0] = %p\n", tiargs->dim, tiargs->data[0]);
4441
4442         // If more arguments than parameters,
4443         // then this is no match.
4444         if (td->parameters->dim < tiargs->dim)
4445         {
4446             if (!td->isVariadic())
4447                 continue;
4448         }
4449
4450         dedtypes.setDim(td->parameters->dim);
4451         dedtypes.zero();
4452         assert(td->semanticRun);
4453         m = td->matchWithInstance(this, &dedtypes, 0);
4454         //printf("matchWithInstance = %d\n", m);
4455         if (!m)                 // no match at all
4456             continue;
4457
4458         if (m < m_best)
4459             goto Ltd_best;
4460         if (m > m_best)
4461             goto Ltd;
4462
4463         {
4464         // Disambiguate by picking the most specialized TemplateDeclaration
4465         MATCH c1 = td->leastAsSpecialized(td_best);
4466         MATCH c2 = td_best->leastAsSpecialized(td);
4467         //printf("c1 = %d, c2 = %d\n", c1, c2);
4468
4469         if (c1 > c2)
4470             goto Ltd;
4471         else if (c1 < c2)
4472             goto Ltd_best;
4473         else
4474             goto Lambig;
4475         }
4476
4477       Lambig:           // td_best and td are ambiguous
4478         td_ambig = td;
4479         continue;
4480
4481       Ltd_best:         // td_best is the best match so far
4482         td_ambig = NULL;
4483         continue;
4484
4485       Ltd:              // td is the new best match
4486         td_ambig = NULL;
4487         td_best = td;
4488         m_best = m;
4489         tdtypes.setDim(dedtypes.dim);
4490         memcpy(tdtypes.data, dedtypes.data, tdtypes.dim * sizeof(void *));
4491         continue;
4492     }
4493
4494     if (!td_best)
4495     {
4496         if (tempdecl && !tempdecl->overnext)
4497             // Only one template, so we can give better error message
4498             error("%s does not match template declaration %s", toChars(), tempdecl->toChars());
4499         else
4500             error("%s does not match any template declaration", toChars());
4501         return NULL;
4502     }
4503     if (td_ambig)
4504     {
4505         error("%s matches more than one template declaration, %s(%d):%s and %s(%d):%s",
4506                 toChars(),
4507                 td_best->loc.filename,  td_best->loc.linnum,  td_best->toChars(),
4508                 td_ambig->loc.filename, td_ambig->loc.linnum, td_ambig->toChars());
4509     }
4510
4511     /* The best match is td_best
4512      */
4513     tempdecl = td_best;
4514
4515 #if 0
4516     /* Cast any value arguments to be same type as value parameter
4517      */
4518     for (size_t i = 0; i < tiargs->dim; i++)
4519     {   Object *o = (Object *)tiargs->data[i];
4520         Expression *ea = isExpression(o);       // value argument
4521         TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i];
4522         assert(tp);
4523         TemplateValueParameter *tvp = tp->isTemplateValueParameter();
4524         if (tvp)
4525         {
4526             assert(ea);
4527             ea = ea->castTo(tvp->valType);
4528             ea = ea->optimize(WANTvalue | WANTinterpret);
4529             tiargs->data[i] = (Object *)ea;
4530         }
4531     }
4532 #endif
4533
4534 #if LOG
4535     printf("\tIt's a match with template declaration '%s'\n", tempdecl->toChars());
4536 #endif
4537     return tempdecl;
4538 }
4539
4540
4541 /*****************************************
4542  * Determines if a TemplateInstance will need a nested
4543  * generation of the TemplateDeclaration.
4544  */
4545
4546 int TemplateInstance::hasNestedArgs(Objects *args)
4547 {   int nested = 0;
4548     //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());
4549
4550     /* A nested instance happens when an argument references a local
4551      * symbol that is on the stack.
4552      */
4553     for (size_t i = 0; i < args->dim; i++)
4554     {   Object *o = (Object *)args->data[i];
4555         Expression *ea = isExpression(o);
4556         Dsymbol *sa = isDsymbol(o);
4557         Tuple *va = isTuple(o);
4558         if (ea)
4559         {
4560             if (ea->op == TOKvar)
4561             {
4562                 sa = ((VarExp *)ea)->var;
4563                 goto Lsa;
4564             }
4565             if (ea->op == TOKfunction)
4566             {
4567                 sa = ((FuncExp *)ea)->fd;
4568                 goto Lsa;
4569             }
4570         }
4571         else if (sa)
4572         {
4573           Lsa:
4574             TemplateDeclaration *td = sa->isTemplateDeclaration();
4575             Declaration *d = sa->isDeclaration();
4576             if ((td && td->literal) ||
4577                 (d && !d->isDataseg() &&
4578 #if DMDV2
4579                  !(d->storage_class & STCmanifest) &&
4580 #endif
4581                  (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) &&
4582                  !isTemplateMixin()
4583                 ))
4584             {
4585                 // if module level template
4586                 if (tempdecl->toParent()->isModule())
4587                 {   Dsymbol *dparent = sa->toParent();
4588                     if (!isnested)
4589                         isnested = dparent;
4590                     else if (isnested != dparent)
4591                     {
4592                         /* Select the more deeply nested of the two.
4593                          * Error if one is not nested inside the other.
4594                          */
4595                         for (Dsymbol *p = isnested; p; p = p->parent)
4596                         {
4597                             if (p == dparent)
4598                                 goto L1;        // isnested is most nested
4599                         }
4600                         for (Dsymbol *p = dparent; p; p = p->parent)
4601                         {
4602                             if (p == isnested)
4603                             {   isnested = dparent;
4604                                 goto L1;        // dparent is most nested
4605                             }
4606                         }
4607                         error("%s is nested in both %s and %s",
4608                                 toChars(), isnested->toChars(), dparent->toChars());
4609                     }
4610                   L1:
4611                     //printf("\tnested inside %s\n", isnested->toChars());
4612                     nested |= 1;
4613                 }
4614                 else
4615                     error("cannot use local '%s' as parameter to non-global template %s", sa->toChars(), tempdecl->toChars());
4616             }
4617         }
4618         else if (va)
4619         {
4620             nested |= hasNestedArgs(&va->objects);
4621         }
4622     }
4623     return nested;
4624 }
4625
4626 /****************************************
4627  * This instance needs an identifier for name mangling purposes.
4628  * Create one by taking the template declaration name and adding
4629  * the type signature for it.
4630  */
4631
4632 Identifier *TemplateInstance::genIdent(Objects *args)
4633 {   OutBuffer buf;
4634
4635     //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
4636     char *id = tempdecl->ident->toChars();
4637     buf.printf("__T%zu%s", strlen(id), id);
4638     for (int i = 0; i < args->dim; i++)
4639     {   Object *o = (Object *)args->data[i];
4640         Type *ta = isType(o);
4641         Expression *ea = isExpression(o);
4642         Dsymbol *sa = isDsymbol(o);
4643         Tuple *va = isTuple(o);
4644         //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va);
4645         if (ta)
4646         {
4647             buf.writeByte('T');
4648             if (ta->deco)
4649                 buf.writestring(ta->deco);
4650             else
4651             {
4652 #ifdef DEBUG
4653                 printf("ta = %d, %s\n", ta->ty, ta->toChars());
4654 #endif
4655                 assert(global.errors);
4656             }
4657         }
4658         else if (ea)
4659         {
4660           Lea:
4661             sinteger_t v;
4662             real_t r;
4663
4664             ea = ea->optimize(WANTvalue | WANTinterpret);
4665             if (ea->op == TOKvar)
4666             {
4667                 sa = ((VarExp *)ea)->var;
4668                 ea = NULL;
4669                 goto Lsa;
4670             }
4671             if (ea->op == TOKfunction)
4672             {
4673                 sa = ((FuncExp *)ea)->fd;
4674                 ea = NULL;
4675                 goto Lsa;
4676             }
4677             buf.writeByte('V');
4678             if (ea->op == TOKtuple)
4679             {   ea->error("tuple is not a valid template value argument");
4680                 continue;
4681             }
4682 #if 1
4683             /* Use deco that matches what it would be for a function parameter
4684              */
4685             buf.writestring(ea->type->deco);
4686 #else
4687             // Use type of parameter, not type of argument
4688             TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i];
4689             assert(tp);
4690             TemplateValueParameter *tvp = tp->isTemplateValueParameter();
4691             assert(tvp);
4692             buf.writestring(tvp->valType->deco);
4693 #endif
4694             ea->toMangleBuffer(&buf);
4695         }
4696         else if (sa)
4697         {
4698           Lsa:
4699             buf.writeByte('S');
4700             Declaration *d = sa->isDeclaration();
4701             if (d && (!d->type || !d->type->deco))
4702             {   error("forward reference of %s", d->toChars());
4703                 continue;
4704             }
4705 #if 0
4706             VarDeclaration *v = sa->isVarDeclaration();
4707             if (v && v->storage_class & STCmanifest)
4708             {   ExpInitializer *ei = v->init->isExpInitializer();
4709                 if (ei)
4710                 {
4711                     ea = ei->exp;
4712                     goto Lea;
4713                 }
4714             }
4715 #endif
4716             const char *p = sa->mangle();
4717
4718             /* Bugzilla 3043: if the first character of p is a digit this
4719              * causes ambiguity issues because the digits of the two numbers are adjacent.
4720              * Current demanglers resolve this by trying various places to separate the
4721              * numbers until one gets a successful demangle.
4722              * Unfortunately, fixing this ambiguity will break existing binary
4723              * compatibility and the demanglers, so we'll leave it as is.
4724              */
4725             buf.printf("%zu%s", strlen(p), p);
4726         }
4727         else if (va)
4728         {
4729             assert(i + 1 == args->dim);         // must be last one
4730             args = &va->objects;
4731             i = -1;
4732         }
4733         else
4734             assert(0);
4735     }
4736     buf.writeByte('Z');
4737     id = buf.toChars();
4738     //buf.data = NULL;                          // we can free the string after call to idPool()
4739     //printf("\tgenIdent = %s\n", id);
4740     return Lexer::idPool(id);
4741 }
4742
4743
4744 /****************************************************
4745  * Declare parameters of template instance, initialize them with the
4746  * template instance arguments.
4747  */
4748
4749 void TemplateInstance::declareParameters(Scope *sc)
4750 {
4751     //printf("TemplateInstance::declareParameters()\n");
4752     for (int i = 0; i < tdtypes.dim; i++)
4753     {
4754         TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i];
4755         //Object *o = (Object *)tiargs->data[i];
4756         Object *o = (Object *)tdtypes.data[i];          // initializer for tp
4757
4758         //printf("\ttdtypes[%d] = %p\n", i, o);
4759         tempdecl->declareParameter(sc, tp, o);
4760     }
4761 }
4762
4763 /*****************************************************
4764  * Determine if template instance is really a template function,
4765  * and that template function needs to infer types from the function
4766  * arguments.
4767  */
4768
4769 int TemplateInstance::needsTypeInference(Scope *sc)
4770 {
4771     //printf("TemplateInstance::needsTypeInference() %s\n", toChars());
4772     if (!tempdecl)
4773         tempdecl = findTemplateDeclaration(sc);
4774     int multipleMatches = FALSE;
4775     for (TemplateDeclaration *td = tempdecl; td; td = td->overnext)
4776     {
4777         /* If any of the overloaded template declarations need inference,
4778          * then return TRUE
4779          */
4780         FuncDeclaration *fd;
4781         if (!td->onemember ||
4782             (fd = td->onemember->toAlias()->isFuncDeclaration()) == NULL ||
4783             fd->type->ty != Tfunction)
4784         {
4785             /* Not a template function, therefore type inference is not possible.
4786              */
4787             //printf("false\n");
4788             return FALSE;
4789         }
4790
4791         /* Determine if the instance arguments, tiargs, are all that is necessary
4792          * to instantiate the template.
4793          */
4794         TemplateTupleParameter *tp = td->isVariadic();
4795         //printf("tp = %p, td->parameters->dim = %d, tiargs->dim = %d\n", tp, td->parameters->dim, tiargs->dim);
4796         TypeFunction *fdtype = (TypeFunction *)fd->type;
4797         if (Parameter::dim(fdtype->parameters) &&
4798             (tp || tiargs->dim < td->parameters->dim))
4799             return TRUE;
4800         /* If there is more than one function template which matches, we may
4801          * need type inference (see Bugzilla 4430)
4802          */
4803         if (td != tempdecl)
4804             multipleMatches = TRUE;
4805     }
4806     //printf("false\n");
4807     return multipleMatches;
4808 }
4809
4810 void TemplateInstance::semantic2(Scope *sc)
4811 {   int i;
4812
4813     if (semanticRun >= 2)
4814         return;
4815     semanticRun = 2;
4816 #if LOG
4817     printf("+TemplateInstance::semantic2('%s')\n", toChars());
4818 #endif
4819     if (!errors && members)
4820     {
4821         sc = tempdecl->scope;
4822         assert(sc);
4823         sc = sc->push(argsym);
4824         sc = sc->push(this);
4825         sc->tinst = this;
4826         for (i = 0; i < members->dim; i++)
4827         {
4828             Dsymbol *s = (Dsymbol *)members->data[i];
4829 #if LOG
4830 printf("\tmember '%s', kind = '%s'\n", s->toChars(), s->kind());
4831 #endif
4832             s->semantic2(sc);
4833         }
4834         sc = sc->pop();
4835         sc->pop();
4836     }
4837 #if LOG
4838     printf("-TemplateInstance::semantic2('%s')\n", toChars());
4839 #endif
4840 }
4841
4842 void TemplateInstance::semantic3(Scope *sc)
4843 {
4844 #if LOG
4845     printf("TemplateInstance::semantic3('%s'), semanticRun = %d\n", toChars(), semanticRun);
4846 #endif
4847 //if (toChars()[0] == 'D') *(char*)0=0;
4848     if (semanticRun >= 3)
4849         return;
4850     semanticRun = 3;
4851     if (!errors && members)
4852     {
4853         sc = tempdecl->scope;
4854         sc = sc->push(argsym);
4855         sc = sc->push(this);
4856         sc->tinst = this;
4857         for (int i = 0; i < members->dim; i++)
4858         {
4859             Dsymbol *s = (Dsymbol *)members->data[i];
4860             s->semantic3(sc);
4861         }
4862         sc = sc->pop();
4863         sc->pop();
4864     }
4865 }
4866
4867 /**************************************
4868  * Given an error instantiating the TemplateInstance,
4869  * give the nested TemplateInstance instantiations that got
4870  * us here. Those are a list threaded into the nested scopes.
4871  */
4872 void TemplateInstance::printInstantiationTrace()
4873 {
4874     if (global.gag)
4875         return;
4876
4877     const int max_shown = 6;
4878     const char format[] = "%s:        instantiated from here: %s\n";
4879
4880     // determine instantiation depth and number of recursive instantiations
4881     int n_instantiations = 1;
4882     int n_totalrecursions = 0;
4883     for (TemplateInstance *cur = this; cur; cur = cur->tinst)
4884     {
4885         ++n_instantiations;
4886         // If two instantiations use the same declaration, they are recursive.
4887         // (this works even if they are instantiated from different places in the
4888         // same template).
4889         // In principle, we could also check for multiple-template recursion, but it's
4890         // probably not worthwhile.
4891         if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl
4892             && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc))
4893             ++n_totalrecursions;
4894     }
4895
4896     // show full trace only if it's short or verbose is on
4897     if (n_instantiations <= max_shown || global.params.verbose)
4898     {
4899         for (TemplateInstance *cur = this; cur; cur = cur->tinst)
4900         {
4901             fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars());
4902         }
4903     }
4904     else if (n_instantiations - n_totalrecursions <= max_shown)
4905     {
4906         // By collapsing recursive instantiations into a single line,
4907         // we can stay under the limit.
4908         int recursionDepth=0;
4909         for (TemplateInstance *cur = this; cur; cur = cur->tinst)
4910         {
4911             if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl
4912                     && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc))
4913             {
4914                 ++recursionDepth;
4915             }
4916             else
4917             {
4918                 if (recursionDepth)
4919                     fprintf(stdmsg, "%s:        %d recursive instantiations from here: %s\n", cur->loc.toChars(), recursionDepth+2, cur->toChars());
4920                 else
4921                     fprintf(stdmsg,format, cur->loc.toChars(), cur->toChars());
4922                 recursionDepth = 0;
4923             }
4924         }
4925     }
4926     else
4927     {
4928         // Even after collapsing the recursions, the depth is too deep.
4929         // Just display the first few and last few instantiations.
4930         size_t i = 0;
4931         for (TemplateInstance *cur = this; cur; cur = cur->tinst)
4932         {
4933             if (i == max_shown / 2)
4934                 fprintf(stdmsg,"    ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown);
4935
4936             if (i < max_shown / 2 ||
4937                 i >= n_instantiations - max_shown + max_shown / 2)
4938                 fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars());
4939             ++i;
4940         }
4941     }
4942 }
4943
4944 void TemplateInstance::toObjFile(int multiobj)
4945 {
4946 #if LOG
4947     printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this);
4948 #endif
4949     if (!errors && members)
4950     {
4951         if (multiobj)
4952             // Append to list of object files to be written later
4953             obj_append(this);
4954         else
4955         {
4956             for (int i = 0; i < members->dim; i++)
4957             {
4958                 Dsymbol *s = (Dsymbol *)members->data[i];
4959                 s->toObjFile(multiobj);
4960             }
4961         }
4962     }
4963 }
4964
4965 void TemplateInstance::inlineScan()
4966 {
4967 #if LOG
4968     printf("TemplateInstance::inlineScan('%s')\n", toChars());
4969 #endif
4970     if (!errors && members)
4971     {
4972         for (int i = 0; i < members->dim; i++)
4973         {
4974             Dsymbol *s = (Dsymbol *)members->data[i];
4975             s->inlineScan();
4976         }
4977     }
4978 }
4979
4980 void TemplateInstance::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4981 {
4982     int i;
4983
4984     Identifier *id = name;
4985     buf->writestring(id->toChars());
4986     buf->writestring("!(");
4987     if (nest)
4988         buf->writestring("...");
4989     else
4990     {
4991         nest++;
4992         Objects *args = tiargs;
4993         for (i = 0; i < args->dim; i++)
4994         {
4995             if (i)
4996                 buf->writeByte(',');
4997             Object *oarg = (Object *)args->data[i];
4998             ObjectToCBuffer(buf, hgs, oarg);
4999         }
5000         nest--;
5001     }
5002     buf->writeByte(')');
5003 }
5004
5005
5006 Dsymbol *TemplateInstance::toAlias()
5007 {
5008 #if LOG
5009     printf("TemplateInstance::toAlias()\n");
5010 #endif
5011     if (!inst)
5012     {   error("cannot resolve forward reference");
5013         errors = 1;
5014         return this;
5015     }
5016
5017     if (inst != this)
5018         return inst->toAlias();
5019
5020     if (aliasdecl)
5021     {
5022         return aliasdecl->toAlias();
5023     }
5024
5025     return inst;
5026 }
5027
5028 AliasDeclaration *TemplateInstance::isAliasDeclaration()
5029 {
5030     return aliasdecl;
5031 }
5032
5033 const char *TemplateInstance::kind()
5034 {
5035     return "template instance";
5036 }
5037
5038 int TemplateInstance::oneMember(Dsymbol **ps)
5039 {
5040     *ps = NULL;
5041     return TRUE;
5042 }
5043
5044 char *TemplateInstance::toChars()
5045 {
5046     OutBuffer buf;
5047     HdrGenState hgs;
5048     char *s;
5049
5050     toCBuffer(&buf, &hgs);
5051     s = buf.toChars();
5052     buf.data = NULL;
5053     return s;
5054 }
5055
5056 /* ======================== TemplateMixin ================================ */
5057
5058 TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual,
5059         Array *idents, Objects *tiargs)
5060         : TemplateInstance(loc, (Identifier *)idents->data[idents->dim - 1])
5061 {
5062     //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : "");
5063     this->ident = ident;
5064     this->tqual = tqual;
5065     this->idents = idents;
5066     this->tiargs = tiargs ? tiargs : new Objects();
5067 }
5068
5069 Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s)
5070 {   TemplateMixin *tm;
5071
5072     Array *ids = new Array();
5073     ids->setDim(idents->dim);
5074     for (int i = 0; i < idents->dim; i++)
5075     {   // Matches TypeQualified::syntaxCopyHelper()
5076         Identifier *id = (Identifier *)idents->data[i];
5077         if (id->dyncast() == DYNCAST_DSYMBOL)
5078         {
5079             TemplateInstance *ti = (TemplateInstance *)id;
5080
5081             ti = (TemplateInstance *)ti->syntaxCopy(NULL);
5082             id = (Identifier *)ti;
5083         }
5084         ids->data[i] = id;
5085     }
5086
5087     tm = new TemplateMixin(loc, ident,
5088                 (Type *)(tqual ? tqual->syntaxCopy() : NULL),
5089                 ids, tiargs);
5090     TemplateInstance::syntaxCopy(tm);
5091     return tm;
5092 }
5093
5094 void TemplateMixin::semantic(Scope *sc)
5095 {
5096 #if LOG
5097     printf("+TemplateMixin::semantic('%s', this=%p)\n", toChars(), this);
5098     fflush(stdout);
5099 #endif
5100     if (semanticRun)
5101     {
5102         // This for when a class/struct contains mixin members, and
5103         // is done over because of forward references
5104         if (parent && toParent()->isAggregateDeclaration())
5105             semanticRun = 1;            // do over
5106         else
5107         {
5108 #if LOG
5109             printf("\tsemantic done\n");
5110 #endif
5111             return;
5112         }
5113     }
5114     if (!semanticRun)
5115         semanticRun = 1;
5116 #if LOG
5117     printf("\tdo semantic\n");
5118 #endif
5119     util_progress();
5120
5121     Scope *scx = NULL;
5122     if (scope)
5123     {   sc = scope;
5124         scx = scope;            // save so we don't make redundant copies
5125         scope = NULL;
5126     }
5127
5128     // Follow qualifications to find the TemplateDeclaration
5129     if (!tempdecl)
5130     {   Dsymbol *s;
5131         int i;
5132         Identifier *id;
5133
5134         if (tqual)
5135         {   s = tqual->toDsymbol(sc);
5136             i = 0;
5137         }
5138         else
5139         {
5140             i = 1;
5141             id = (Identifier *)idents->data[0];
5142             switch (id->dyncast())
5143             {
5144                 case DYNCAST_IDENTIFIER:
5145                     s = sc->search(loc, id, NULL);
5146                     break;
5147
5148                 case DYNCAST_DSYMBOL:
5149                 {
5150                     TemplateInstance *ti = (TemplateInstance *)id;
5151                     ti->semantic(sc);
5152                     s = ti;
5153                     break;
5154                 }
5155                 default:
5156                     assert(0);
5157             }
5158         }
5159
5160         for (; i < idents->dim; i++)
5161         {
5162             if (!s)
5163                 break;
5164             id = (Identifier *)idents->data[i];
5165             s = s->searchX(loc, sc, id);
5166         }
5167         if (!s)
5168         {
5169             error("is not defined");
5170             inst = this;
5171             return;
5172         }
5173         tempdecl = s->toAlias()->isTemplateDeclaration();
5174         if (!tempdecl)
5175         {
5176             error("%s isn't a template", s->toChars());
5177             inst = this;
5178             return;
5179         }
5180     }
5181
5182     // Look for forward reference
5183     assert(tempdecl);
5184     for (TemplateDeclaration *td = tempdecl; td; td = td->overnext)
5185     {
5186         if (!td->semanticRun)
5187         {
5188             /* Cannot handle forward references if mixin is a struct member,
5189              * because addField must happen during struct's semantic, not
5190              * during the mixin semantic.
5191              * runDeferred will re-run mixin's semantic outside of the struct's
5192              * semantic.
5193              */
5194             semanticRun = 0;
5195             AggregateDeclaration *ad = toParent()->isAggregateDeclaration();
5196             if (ad)
5197                 ad->sizeok = 2;
5198             else
5199             {
5200                 // Forward reference
5201                 //printf("forward reference - deferring\n");
5202                 scope = scx ? scx : new Scope(*sc);
5203                 scope->setNoFree();
5204                 scope->module->addDeferredSemantic(this);
5205             }
5206             return;
5207         }
5208     }
5209
5210     // Run semantic on each argument, place results in tiargs[]
5211     semanticTiargs(sc);
5212     if (errors)
5213         return;
5214
5215     tempdecl = findBestMatch(sc);
5216     if (!tempdecl)
5217     {   inst = this;
5218         return;         // error recovery
5219     }
5220
5221     if (!ident)
5222         ident = genIdent(tiargs);
5223
5224     inst = this;
5225     parent = sc->parent;
5226
5227     /* Detect recursive mixin instantiations.
5228      */
5229     for (Dsymbol *s = parent; s; s = s->parent)
5230     {
5231         //printf("\ts = '%s'\n", s->toChars());
5232         TemplateMixin *tm = s->isTemplateMixin();
5233         if (!tm || tempdecl != tm->tempdecl)
5234             continue;
5235
5236         /* Different argument list lengths happen with variadic args
5237          */
5238         if (tiargs->dim != tm->tiargs->dim)
5239             continue;
5240
5241         for (int i = 0; i < tiargs->dim; i++)
5242         {   Object *o = (Object *)tiargs->data[i];
5243             Type *ta = isType(o);
5244             Expression *ea = isExpression(o);
5245             Dsymbol *sa = isDsymbol(o);
5246             Object *tmo = (Object *)tm->tiargs->data[i];
5247             if (ta)
5248             {
5249                 Type *tmta = isType(tmo);
5250                 if (!tmta)
5251                     goto Lcontinue;
5252                 if (!ta->equals(tmta))
5253                     goto Lcontinue;
5254             }
5255             else if (ea)
5256             {   Expression *tme = isExpression(tmo);
5257                 if (!tme || !ea->equals(tme))
5258                     goto Lcontinue;
5259             }
5260             else if (sa)
5261             {
5262                 Dsymbol *tmsa = isDsymbol(tmo);
5263                 if (sa != tmsa)
5264                     goto Lcontinue;
5265             }
5266             else
5267                 assert(0);
5268         }
5269         error("recursive mixin instantiation");
5270         return;
5271
5272     Lcontinue:
5273         continue;
5274     }
5275
5276     // Copy the syntax trees from the TemplateDeclaration
5277     members = Dsymbol::arraySyntaxCopy(tempdecl->members);
5278     if (!members)
5279         return;
5280
5281     symtab = new DsymbolTable();
5282
5283     for (Scope *sce = sc; 1; sce = sce->enclosing)
5284     {
5285         ScopeDsymbol *sds = (ScopeDsymbol *)sce->scopesym;
5286         if (sds)
5287         {
5288             sds->importScope(this, PROTpublic);
5289             break;
5290         }
5291     }
5292
5293 #if LOG
5294     printf("\tcreate scope for template parameters '%s'\n", toChars());
5295 #endif
5296     Scope *scy = sc;
5297     scy = sc->push(this);
5298     scy->parent = this;
5299
5300     argsym = new ScopeDsymbol();
5301     argsym->parent = scy->parent;
5302     Scope *argscope = scy->push(argsym);
5303
5304     unsigned errorsave = global.errors;
5305
5306     // Declare each template parameter as an alias for the argument type
5307     declareParameters(argscope);
5308
5309     // Add members to enclosing scope, as well as this scope
5310     for (unsigned i = 0; i < members->dim; i++)
5311     {   Dsymbol *s;
5312
5313         s = (Dsymbol *)members->data[i];
5314         s->addMember(argscope, this, i);
5315         //sc->insert(s);
5316         //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym);
5317         //printf("s->parent = %s\n", s->parent->toChars());
5318     }
5319
5320     // Do semantic() analysis on template instance members
5321 #if LOG
5322     printf("\tdo semantic() on template instance members '%s'\n", toChars());
5323 #endif
5324     Scope *sc2;
5325     sc2 = argscope->push(this);
5326     sc2->offset = sc->offset;
5327
5328     static int nest;
5329     //printf("%d\n", nest);
5330     if (++nest > 500)
5331     {
5332         global.gag = 0;                 // ensure error message gets printed
5333         error("recursive expansion");
5334         fatal();
5335     }
5336
5337     for (int i = 0; i < members->dim; i++)
5338     {
5339         Dsymbol *s = (Dsymbol *)members->data[i];
5340         s->semantic(sc2);
5341     }
5342
5343     nest--;
5344
5345     sc->offset = sc2->offset;
5346
5347     /* The problem is when to parse the initializer for a variable.
5348      * Perhaps VarDeclaration::semantic() should do it like it does
5349      * for initializers inside a function.
5350      */
5351 //    if (sc->parent->isFuncDeclaration())
5352
5353         semantic2(sc2);
5354
5355     if (sc->func)
5356     {
5357         semantic3(sc2);
5358     }
5359
5360     // Give additional context info if error occurred during instantiation
5361     if (global.errors != errorsave)
5362     {
5363         error("error instantiating");
5364     }
5365
5366     sc2->pop();
5367
5368     argscope->pop();
5369
5370 //    if (!isAnonymous())
5371     {
5372         scy->pop();
5373     }
5374 #if LOG
5375     printf("-TemplateMixin::semantic('%s', this=%p)\n", toChars(), this);
5376 #endif
5377 }
5378
5379 void TemplateMixin::semantic2(Scope *sc)
5380 {   int i;
5381
5382     if (semanticRun >= 2)
5383         return;
5384     semanticRun = 2;
5385 #if LOG
5386     printf("+TemplateMixin::semantic2('%s')\n", toChars());
5387 #endif
5388     if (members)
5389     {
5390         assert(sc);
5391         sc = sc->push(argsym);
5392         sc = sc->push(this);
5393         for (i = 0; i < members->dim; i++)
5394         {
5395             Dsymbol *s = (Dsymbol *)members->data[i];
5396 #if LOG
5397             printf("\tmember '%s', kind = '%s'\n", s->toChars(), s->kind());
5398 #endif
5399             s->semantic2(sc);
5400         }
5401         sc = sc->pop();
5402         sc->pop();
5403     }
5404 #if LOG
5405     printf("-TemplateMixin::semantic2('%s')\n", toChars());
5406 #endif
5407 }
5408
5409 void TemplateMixin::semantic3(Scope *sc)
5410 {   int i;
5411
5412     if (semanticRun >= 3)
5413         return;
5414     semanticRun = 3;
5415 #if LOG
5416     printf("TemplateMixin::semantic3('%s')\n", toChars());
5417 #endif
5418     if (members)
5419     {
5420         sc = sc->push(argsym);
5421         sc = sc->push(this);
5422         for (i = 0; i < members->dim; i++)
5423         {
5424             Dsymbol *s = (Dsymbol *)members->data[i];
5425             s->semantic3(sc);
5426         }
5427         sc = sc->pop();
5428         sc->pop();
5429     }
5430 }
5431
5432 void TemplateMixin::inlineScan()
5433 {
5434     TemplateInstance::inlineScan();
5435 }
5436
5437 const char *TemplateMixin::kind()
5438 {
5439     return "mixin";
5440 }
5441
5442 int TemplateMixin::oneMember(Dsymbol **ps)
5443 {
5444     return Dsymbol::oneMember(ps);
5445 }
5446
5447 int TemplateMixin::hasPointers()
5448 {
5449     //printf("TemplateMixin::hasPointers() %s\n", toChars());
5450     for (size_t i = 0; i < members->dim; i++)
5451     {
5452         Dsymbol *s = (Dsymbol *)members->data[i];
5453         //printf(" s = %s %s\n", s->kind(), s->toChars());
5454         if (s->hasPointers())
5455         {
5456             return 1;
5457         }
5458     }
5459     return 0;
5460 }
5461
5462 char *TemplateMixin::toChars()
5463 {
5464     OutBuffer buf;
5465     HdrGenState hgs;
5466     char *s;
5467
5468     TemplateInstance::toCBuffer(&buf, &hgs);
5469     s = buf.toChars();
5470     buf.data = NULL;
5471     return s;
5472 }
5473
5474 void TemplateMixin::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5475 {
5476     buf->writestring("mixin ");
5477
5478     for (int i = 0; i < idents->dim; i++)
5479     {   Identifier *id = (Identifier *)idents->data[i];
5480
5481         if (i)
5482             buf->writeByte('.');
5483         buf->writestring(id->toChars());
5484     }
5485     buf->writestring("!(");
5486     if (tiargs)
5487     {
5488         for (int i = 0; i < tiargs->dim; i++)
5489         {   if (i)
5490                 buf->writebyte(',');
5491             Object *oarg = (Object *)tiargs->data[i];
5492             Type *t = isType(oarg);
5493             Expression *e = isExpression(oarg);
5494             Dsymbol *s = isDsymbol(oarg);
5495             if (t)
5496                 t->toCBuffer(buf, NULL, hgs);
5497             else if (e)
5498                 e->toCBuffer(buf, hgs);
5499             else if (s)
5500             {
5501                 char *p = s->ident ? s->ident->toChars() : s->toChars();
5502                 buf->writestring(p);
5503             }
5504             else if (!oarg)
5505             {
5506                 buf->writestring("NULL");
5507             }
5508             else
5509             {
5510                 assert(0);
5511             }
5512         }
5513     }
5514     buf->writebyte(')');
5515     if (ident)
5516     {
5517         buf->writebyte(' ');
5518         buf->writestring(ident->toChars());
5519     }
5520     buf->writebyte(';');
5521     buf->writenl();
5522 }
5523
5524
5525 void TemplateMixin::toObjFile(int multiobj)
5526 {
5527     //printf("TemplateMixin::toObjFile('%s')\n", toChars());
5528     TemplateInstance::toObjFile(multiobj);
5529 }
Note: See TracBrowser for help on using the browser.