]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/dtemplate.c
d: Merge upstream dmd 7132b3537
[thirdparty/gcc.git] / gcc / d / dmd / dtemplate.c
1
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/template.c
9 */
10
11 // Handle template implementation
12
13 #include "root/dsystem.h"
14 #include "root/root.h"
15 #include "root/aav.h"
16 #include "root/rmem.h"
17 #include "root/stringtable.h"
18 #include "root/hash.h"
19
20 #include "mangle.h"
21 #include "mtype.h"
22 #include "template.h"
23 #include "init.h"
24 #include "expression.h"
25 #include "scope.h"
26 #include "module.h"
27 #include "aggregate.h"
28 #include "declaration.h"
29 #include "dsymbol.h"
30 #include "mars.h"
31 #include "dsymbol.h"
32 #include "identifier.h"
33 #include "hdrgen.h"
34 #include "id.h"
35 #include "attrib.h"
36 #include "cond.h"
37 #include "tokens.h"
38
39 #define IDX_NOTFOUND (0x12345678) // index is not found
40
41 Type *rawTypeMerge(Type *t1, Type *t2);
42 bool MODimplicitConv(MOD modfrom, MOD modto);
43 MATCH MODmethodConv(MOD modfrom, MOD modto);
44 MOD MODmerge(MOD mod1, MOD mod2);
45
46 static size_t templateParameterLookup(Type *tparam, TemplateParameters *parameters);
47 static int arrayObjectMatch(Objects *oa1, Objects *oa2);
48 static unsigned char deduceWildHelper(Type *t, Type **at, Type *tparam);
49 static MATCH deduceTypeHelper(Type *t, Type **at, Type *tparam);
50 bool reliesOnTident(Type *t, TemplateParameters *tparams = NULL, size_t iStart = 0);
51 bool evalStaticCondition(Scope *sc, Expression *exp, Expression *e, bool &errors);
52
53 /********************************************
54 * These functions substitute for dynamic_cast. dynamic_cast does not work
55 * on earlier versions of gcc.
56 */
57
58 Expression *isExpression(RootObject *o)
59 {
60 //return dynamic_cast<Expression *>(o);
61 if (!o || o->dyncast() != DYNCAST_EXPRESSION)
62 return NULL;
63 return (Expression *)o;
64 }
65
66 Dsymbol *isDsymbol(RootObject *o)
67 {
68 //return dynamic_cast<Dsymbol *>(o);
69 if (!o || o->dyncast() != DYNCAST_DSYMBOL)
70 return NULL;
71 return (Dsymbol *)o;
72 }
73
74 Type *isType(RootObject *o)
75 {
76 //return dynamic_cast<Type *>(o);
77 if (!o || o->dyncast() != DYNCAST_TYPE)
78 return NULL;
79 return (Type *)o;
80 }
81
82 Tuple *isTuple(RootObject *o)
83 {
84 //return dynamic_cast<Tuple *>(o);
85 if (!o || o->dyncast() != DYNCAST_TUPLE)
86 return NULL;
87 return (Tuple *)o;
88 }
89
90 Parameter *isParameter(RootObject *o)
91 {
92 //return dynamic_cast<Parameter *>(o);
93 if (!o || o->dyncast() != DYNCAST_PARAMETER)
94 return NULL;
95 return (Parameter *)o;
96 }
97
98 /**************************************
99 * Is this Object an error?
100 */
101 bool isError(RootObject *o)
102 {
103 Type *t = isType(o);
104 if (t)
105 return (t->ty == Terror);
106 Expression *e = isExpression(o);
107 if (e)
108 return (e->op == TOKerror || !e->type || e->type->ty == Terror);
109 Tuple *v = isTuple(o);
110 if (v)
111 return arrayObjectIsError(&v->objects);
112 Dsymbol *s = isDsymbol(o);
113 assert(s);
114 if (s->errors)
115 return true;
116 return s->parent ? isError(s->parent) : false;
117 }
118
119 /**************************************
120 * Are any of the Objects an error?
121 */
122 bool arrayObjectIsError(Objects *args)
123 {
124 for (size_t i = 0; i < args->length; i++)
125 {
126 RootObject *o = (*args)[i];
127 if (isError(o))
128 return true;
129 }
130 return false;
131 }
132
133 /***********************
134 * Try to get arg as a type.
135 */
136
137 Type *getType(RootObject *o)
138 {
139 Type *t = isType(o);
140 if (!t)
141 {
142 Expression *e = isExpression(o);
143 if (e)
144 t = e->type;
145 }
146 return t;
147 }
148
149 Dsymbol *getDsymbol(RootObject *oarg)
150 {
151 //printf("getDsymbol()\n");
152 //printf("e %p s %p t %p v %p\n", isExpression(oarg), isDsymbol(oarg), isType(oarg), isTuple(oarg));
153
154 Dsymbol *sa;
155 Expression *ea = isExpression(oarg);
156 if (ea)
157 {
158 // Try to convert Expression to symbol
159 if (ea->op == TOKvar)
160 sa = ((VarExp *)ea)->var;
161 else if (ea->op == TOKfunction)
162 {
163 if (((FuncExp *)ea)->td)
164 sa = ((FuncExp *)ea)->td;
165 else
166 sa = ((FuncExp *)ea)->fd;
167 }
168 else if (ea->op == TOKtemplate)
169 sa = ((TemplateExp *)ea)->td;
170 else
171 sa = NULL;
172 }
173 else
174 {
175 // Try to convert Type to symbol
176 Type *ta = isType(oarg);
177 if (ta)
178 sa = ta->toDsymbol(NULL);
179 else
180 sa = isDsymbol(oarg); // if already a symbol
181 }
182 return sa;
183 }
184
185 /***********************
186 * Try to get value from manifest constant
187 */
188
189 static Expression *getValue(Expression *e)
190 {
191 if (e && e->op == TOKvar)
192 {
193 VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration();
194 if (v && v->storage_class & STCmanifest)
195 {
196 e = v->getConstInitializer();
197 }
198 }
199 return e;
200 }
201
202 static Expression *getValue(Dsymbol *&s)
203 {
204 Expression *e = NULL;
205 if (s)
206 {
207 VarDeclaration *v = s->isVarDeclaration();
208 if (v && v->storage_class & STCmanifest)
209 {
210 e = v->getConstInitializer();
211 }
212 }
213 return e;
214 }
215
216 /**********************************
217 * Return true if e could be valid only as a template value parameter.
218 * Return false if it might be an alias or tuple.
219 * (Note that even in this case, it could still turn out to be a value).
220 */
221 bool definitelyValueParameter(Expression *e)
222 {
223 // None of these can be value parameters
224 if (e->op == TOKtuple || e->op == TOKscope ||
225 e->op == TOKtype || e->op == TOKdottype ||
226 e->op == TOKtemplate || e->op == TOKdottd ||
227 e->op == TOKfunction || e->op == TOKerror ||
228 e->op == TOKthis || e->op == TOKsuper)
229 return false;
230
231 if (e->op != TOKdotvar)
232 return true;
233
234 /* Template instantiations involving a DotVar expression are difficult.
235 * In most cases, they should be treated as a value parameter, and interpreted.
236 * But they might also just be a fully qualified name, which should be treated
237 * as an alias.
238 */
239
240 // x.y.f cannot be a value
241 FuncDeclaration *f = ((DotVarExp *)e)->var->isFuncDeclaration();
242 if (f)
243 return false;
244
245 while (e->op == TOKdotvar)
246 {
247 e = ((DotVarExp *)e)->e1;
248 }
249 // this.x.y and super.x.y couldn't possibly be valid values.
250 if (e->op == TOKthis || e->op == TOKsuper)
251 return false;
252
253 // e.type.x could be an alias
254 if (e->op == TOKdottype)
255 return false;
256
257 // var.x.y is the only other possible form of alias
258 if (e->op != TOKvar)
259 return true;
260
261 VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration();
262
263 // func.x.y is not an alias
264 if (!v)
265 return true;
266
267 // TODO: Should we force CTFE if it is a global constant?
268
269 return false;
270 }
271
272 static Expression *getExpression(RootObject *o)
273 {
274 Dsymbol *s = isDsymbol(o);
275 return s ? getValue(s) : getValue(isExpression(o));
276 }
277
278 /******************************
279 * If o1 matches o2, return true.
280 * Else, return false.
281 */
282
283 static bool match(RootObject *o1, RootObject *o2)
284 {
285 //printf("match() o1 = %p %s (%d), o2 = %p %s (%d)\n",
286 // o1, o1->toChars(), o1->dyncast(), o2, o2->toChars(), o2->dyncast());
287
288 /* A proper implementation of the various equals() overrides
289 * should make it possible to just do o1->equals(o2), but
290 * we'll do that another day.
291 */
292
293 /* Manifest constants should be compared by their values,
294 * at least in template arguments.
295 */
296
297 if (Type *t1 = isType(o1))
298 {
299 Type *t2 = isType(o2);
300 if (!t2)
301 goto Lnomatch;
302
303 //printf("\tt1 = %s\n", t1->toChars());
304 //printf("\tt2 = %s\n", t2->toChars());
305 if (!t1->equals(t2))
306 goto Lnomatch;
307
308 goto Lmatch;
309 }
310 if (Expression *e1 = getExpression(o1))
311 {
312 Expression *e2 = getExpression(o2);
313 if (!e2)
314 goto Lnomatch;
315
316 //printf("\te1 = %s %s %s\n", e1->type->toChars(), Token::toChars(e1->op), e1->toChars());
317 //printf("\te2 = %s %s %s\n", e2->type->toChars(), Token::toChars(e2->op), e2->toChars());
318
319 // two expressions can be equal although they do not have the same
320 // type; that happens when they have the same value. So check type
321 // as well as expression equality to ensure templates are properly
322 // matched.
323 if (!e1->type->equals(e2->type) || !e1->equals(e2))
324 goto Lnomatch;
325
326 goto Lmatch;
327 }
328 if (Dsymbol *s1 = isDsymbol(o1))
329 {
330 Dsymbol *s2 = isDsymbol(o2);
331 if (!s2)
332 goto Lnomatch;
333
334 //printf("\ts1 = %s\n", s1->toChars());
335 //printf("\ts2 = %s\n", s2->toChars());
336 if (!s1->equals(s2))
337 goto Lnomatch;
338 if (s1->parent != s2->parent && !s1->isFuncDeclaration() && !s2->isFuncDeclaration())
339 goto Lnomatch;
340
341 goto Lmatch;
342 }
343 if (Tuple *u1 = isTuple(o1))
344 {
345 Tuple *u2 = isTuple(o2);
346 if (!u2)
347 goto Lnomatch;
348
349 //printf("\tu1 = %s\n", u1->toChars());
350 //printf("\tu2 = %s\n", u2->toChars());
351 if (!arrayObjectMatch(&u1->objects, &u2->objects))
352 goto Lnomatch;
353
354 goto Lmatch;
355 }
356 Lmatch:
357 //printf("\t-> match\n");
358 return true;
359
360 Lnomatch:
361 //printf("\t-> nomatch\n");
362 return false;
363 }
364
365
366 /************************************
367 * Match an array of them.
368 */
369 int arrayObjectMatch(Objects *oa1, Objects *oa2)
370 {
371 if (oa1 == oa2)
372 return 1;
373 if (oa1->length != oa2->length)
374 return 0;
375 for (size_t j = 0; j < oa1->length; j++)
376 {
377 RootObject *o1 = (*oa1)[j];
378 RootObject *o2 = (*oa2)[j];
379 if (!match(o1, o2))
380 {
381 return 0;
382 }
383 }
384 return 1;
385 }
386
387
388 /************************************
389 * Computes hash of expression.
390 * Handles all Expression classes and MUST match their equals method,
391 * i.e. e1->equals(e2) implies expressionHash(e1) == expressionHash(e2).
392 */
393 static hash_t expressionHash(Expression *e)
394 {
395 switch (e->op)
396 {
397 case TOKint64:
398 return (size_t) ((IntegerExp *)e)->getInteger();
399
400 case TOKfloat64:
401 return CTFloat::hash(((RealExp *)e)->value);
402
403 case TOKcomplex80:
404 {
405 ComplexExp *ce = (ComplexExp *)e;
406 return mixHash(CTFloat::hash(ce->toReal()), CTFloat::hash(ce->toImaginary()));
407 }
408
409 case TOKidentifier:
410 return (size_t)(void *) ((IdentifierExp *)e)->ident;
411
412 case TOKnull:
413 return (size_t)(void *) ((NullExp *)e)->type;
414
415 case TOKstring:
416 {
417 StringExp *se = (StringExp *)e;
418 return calcHash((const char *)se->string, se->len * se->sz);
419 }
420
421 case TOKtuple:
422 {
423 TupleExp *te = (TupleExp *)e;
424 size_t hash = 0;
425 hash += te->e0 ? expressionHash(te->e0) : 0;
426 for (size_t i = 0; i < te->exps->length; i++)
427 {
428 Expression *elem = (*te->exps)[i];
429 hash = mixHash(hash, expressionHash(elem));
430 }
431 return hash;
432 }
433
434 case TOKarrayliteral:
435 {
436 ArrayLiteralExp *ae = (ArrayLiteralExp *)e;
437 size_t hash = 0;
438 for (size_t i = 0; i < ae->elements->length; i++)
439 hash = mixHash(hash, expressionHash(ae->getElement(i)));
440 return hash;
441 }
442
443 case TOKassocarrayliteral:
444 {
445 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e;
446 size_t hash = 0;
447 for (size_t i = 0; i < ae->keys->length; i++)
448 // reduction needs associative op as keys are unsorted (use XOR)
449 hash ^= mixHash(expressionHash((*ae->keys)[i]), expressionHash((*ae->values)[i]));
450 return hash;
451 }
452
453 case TOKstructliteral:
454 {
455 StructLiteralExp *se = (StructLiteralExp *)e;
456 size_t hash = 0;
457 for (size_t i = 0; i < se->elements->length; i++)
458 {
459 Expression *elem = (*se->elements)[i];
460 hash = mixHash(hash, elem ? expressionHash(elem) : 0);
461 }
462 return hash;
463 }
464
465 case TOKvar:
466 return (size_t)(void *) ((VarExp *)e)->var;
467
468 case TOKfunction:
469 return (size_t)(void *) ((FuncExp *)e)->fd;
470
471 default:
472 // no custom equals for this expression
473 // equals based on identity
474 return (size_t)(void *) e;
475 }
476 }
477
478
479 /************************************
480 * Return hash of Objects.
481 */
482 static hash_t arrayObjectHash(Objects *oa1)
483 {
484 hash_t hash = 0;
485 for (size_t j = 0; j < oa1->length; j++)
486 {
487 /* Must follow the logic of match()
488 */
489 RootObject *o1 = (*oa1)[j];
490 if (Type *t1 = isType(o1))
491 hash = mixHash(hash, (size_t)t1->deco);
492 else if (Expression *e1 = getExpression(o1))
493 hash = mixHash(hash, expressionHash(e1));
494 else if (Dsymbol *s1 = isDsymbol(o1))
495 {
496 FuncAliasDeclaration *fa1 = s1->isFuncAliasDeclaration();
497 if (fa1)
498 s1 = fa1->toAliasFunc();
499 hash = mixHash(hash, mixHash((size_t)(void *)s1->getIdent(), (size_t)(void *)s1->parent));
500 }
501 else if (Tuple *u1 = isTuple(o1))
502 hash = mixHash(hash, arrayObjectHash(&u1->objects));
503 }
504 return hash;
505 }
506
507 RootObject *objectSyntaxCopy(RootObject *o)
508 {
509 if (!o)
510 return NULL;
511 if (Type *t = isType(o))
512 return t->syntaxCopy();
513 if (Expression *e = isExpression(o))
514 return e->syntaxCopy();
515 return o;
516 }
517
518
519 /* ======================== TemplateDeclaration ============================= */
520
521 TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id,
522 TemplateParameters *parameters, Expression *constraint, Dsymbols *decldefs, bool ismixin, bool literal)
523 : ScopeDsymbol(id)
524 {
525 this->loc = loc;
526 this->parameters = parameters;
527 this->origParameters = parameters;
528 this->constraint = constraint;
529 this->members = decldefs;
530 this->overnext = NULL;
531 this->overroot = NULL;
532 this->funcroot = NULL;
533 this->onemember = NULL;
534 this->literal = literal;
535 this->ismixin = ismixin;
536 this->isstatic = true;
537 this->previous = NULL;
538 this->protection = Prot(Prot::undefined);
539 this->instances = NULL;
540
541 // Compute in advance for Ddoc's use
542 // Bugzilla 11153: ident could be NULL if parsing fails.
543 if (members && ident)
544 {
545 Dsymbol *s;
546 if (Dsymbol::oneMembers(members, &s, ident) && s)
547 {
548 onemember = s;
549 s->parent = this;
550 }
551 }
552 }
553
554 Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *)
555 {
556 //printf("TemplateDeclaration::syntaxCopy()\n");
557 TemplateParameters *p = NULL;
558 if (parameters)
559 {
560 p = new TemplateParameters();
561 p->setDim(parameters->length);
562 for (size_t i = 0; i < p->length; i++)
563 (*p)[i] = (*parameters)[i]->syntaxCopy();
564 }
565 return new TemplateDeclaration(loc, ident, p,
566 constraint ? constraint->syntaxCopy() : NULL,
567 Dsymbol::arraySyntaxCopy(members), ismixin, literal);
568 }
569
570 const char *TemplateDeclaration::kind() const
571 {
572 return (onemember && onemember->isAggregateDeclaration())
573 ? onemember->kind()
574 : "template";
575 }
576
577 /**********************************
578 * Overload existing TemplateDeclaration 'this' with the new one 's'.
579 * Return true if successful; i.e. no conflict.
580 */
581
582 bool TemplateDeclaration::overloadInsert(Dsymbol *s)
583 {
584 FuncDeclaration *fd = s->isFuncDeclaration();
585 if (fd)
586 {
587 if (funcroot)
588 return funcroot->overloadInsert(fd);
589 funcroot = fd;
590 return funcroot->overloadInsert(this);
591 }
592
593 TemplateDeclaration *td = s->isTemplateDeclaration();
594 if (!td)
595 return false;
596
597 TemplateDeclaration *pthis = this;
598 TemplateDeclaration **ptd;
599 for (ptd = &pthis; *ptd; ptd = &(*ptd)->overnext)
600 {
601 }
602
603 td->overroot = this;
604 *ptd = td;
605 return true;
606 }
607
608 /****************************
609 * Check to see if constraint is satisfied.
610 */
611 bool TemplateDeclaration::evaluateConstraint(
612 TemplateInstance *ti, Scope *sc, Scope *paramscope,
613 Objects *dedargs, FuncDeclaration *fd)
614 {
615 /* Detect recursive attempts to instantiate this template declaration,
616 * Bugzilla 4072
617 * void foo(T)(T x) if (is(typeof(foo(x)))) { }
618 * static assert(!is(typeof(foo(7))));
619 * Recursive attempts are regarded as a constraint failure.
620 */
621 /* There's a chicken-and-egg problem here. We don't know yet if this template
622 * instantiation will be a local one (enclosing is set), and we won't know until
623 * after selecting the correct template. Thus, function we're nesting inside
624 * is not on the sc scope chain, and this can cause errors in FuncDeclaration::getLevel().
625 * Workaround the problem by setting a flag to relax the checking on frame errors.
626 */
627
628 for (TemplatePrevious *p = previous; p; p = p->prev)
629 {
630 if (arrayObjectMatch(p->dedargs, dedargs))
631 {
632 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
633 /* It must be a subscope of p->sc, other scope chains are not recursive
634 * instantiations.
635 */
636 for (Scope *scx = sc; scx; scx = scx->enclosing)
637 {
638 if (scx == p->sc)
639 return false;
640 }
641 }
642 /* BUG: should also check for ref param differences
643 */
644 }
645
646 TemplatePrevious pr;
647 pr.prev = previous;
648 pr.sc = paramscope;
649 pr.dedargs = dedargs;
650 previous = &pr; // add this to threaded list
651
652 Scope *scx = paramscope->push(ti);
653 scx->parent = ti;
654 scx->tinst = NULL;
655 scx->minst = NULL;
656
657 assert(!ti->symtab);
658 if (fd)
659 {
660 /* Declare all the function parameters as variables and add them to the scope
661 * Making parameters is similar to FuncDeclaration::semantic3
662 */
663 TypeFunction *tf = (TypeFunction *)fd->type;
664 assert(tf->ty == Tfunction);
665
666 scx->parent = fd;
667
668 Parameters *fparameters = tf->parameterList.parameters;
669 VarArg fvarargs = tf->parameterList.varargs;
670
671 size_t nfparams = Parameter::dim(fparameters);
672 for (size_t i = 0; i < nfparams; i++)
673 {
674 Parameter *fparam = Parameter::getNth(fparameters, i);
675 fparam->storageClass &= (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
676 fparam->storageClass |= STCparameter;
677 if (fvarargs == VARARGtypesafe && i + 1 == nfparams)
678 fparam->storageClass |= STCvariadic;
679 }
680 for (size_t i = 0; i < fparameters->length; i++)
681 {
682 Parameter *fparam = (*fparameters)[i];
683 if (!fparam->ident)
684 continue; // don't add it, if it has no name
685 VarDeclaration *v = new VarDeclaration(loc, fparam->type, fparam->ident, NULL);
686 v->storage_class = fparam->storageClass;
687 dsymbolSemantic(v, scx);
688 if (!ti->symtab)
689 ti->symtab = new DsymbolTable();
690 if (!scx->insert(v))
691 error("parameter %s.%s is already defined", toChars(), v->toChars());
692 else
693 v->parent = fd;
694 }
695 if (isstatic)
696 fd->storage_class |= STCstatic;
697
698 fd->vthis = fd->declareThis(scx, fd->isThis());
699 }
700
701 Expression *e = constraint->syntaxCopy();
702
703 assert(ti->inst == NULL);
704 ti->inst = ti; // temporary instantiation to enable genIdent()
705
706 scx->flags |= SCOPEconstraint;
707 bool errors = false;
708 bool result = evalStaticCondition(scx, constraint, e, errors);
709 ti->inst = NULL;
710 ti->symtab = NULL;
711 scx = scx->pop();
712 previous = pr.prev; // unlink from threaded list
713 if (errors)
714 return false;
715 return result;
716 }
717
718 /***************************************
719 * Given that ti is an instance of this TemplateDeclaration,
720 * deduce the types of the parameters to this, and store
721 * those deduced types in dedtypes[].
722 * Input:
723 * flag 1: don't do semantic() because of dummy types
724 * 2: don't change types in matchArg()
725 * Output:
726 * dedtypes deduced arguments
727 * Return match level.
728 */
729
730 MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,
731 Objects *dedtypes, Expressions *fargs, int flag)
732 {
733 MATCH m;
734 size_t dedtypes_dim = dedtypes->length;
735
736 dedtypes->zero();
737
738 if (errors)
739 return MATCHnomatch;
740
741 size_t parameters_dim = parameters->length;
742 int variadic = isVariadic() != NULL;
743
744 // If more arguments than parameters, no match
745 if (ti->tiargs->length > parameters_dim && !variadic)
746 {
747 return MATCHnomatch;
748 }
749
750 assert(dedtypes_dim == parameters_dim);
751 assert(dedtypes_dim >= ti->tiargs->length || variadic);
752
753 assert(_scope);
754
755 // Set up scope for template parameters
756 ScopeDsymbol *paramsym = new ScopeDsymbol();
757 paramsym->parent = _scope->parent;
758 Scope *paramscope = _scope->push(paramsym);
759 paramscope->tinst = ti;
760 paramscope->minst = sc->minst;
761 paramscope->callsc = sc;
762 paramscope->stc = 0;
763
764 // Attempt type deduction
765 m = MATCHexact;
766 for (size_t i = 0; i < dedtypes_dim; i++)
767 {
768 MATCH m2;
769 TemplateParameter *tp = (*parameters)[i];
770 Declaration *sparam;
771
772 //printf("\targument [%d]\n", i);
773 m2 = tp->matchArg(ti->loc, paramscope, ti->tiargs, i, parameters, dedtypes, &sparam);
774 //printf("\tm2 = %d\n", m2);
775
776 if (m2 == MATCHnomatch)
777 {
778 goto Lnomatch;
779 }
780
781 if (m2 < m)
782 m = m2;
783
784 if (!flag)
785 dsymbolSemantic(sparam, paramscope);
786 if (!paramscope->insert(sparam)) // TODO: This check can make more early
787 goto Lnomatch; // in TemplateDeclaration::semantic, and
788 // then we don't need to make sparam if flags == 0
789 }
790
791 if (!flag)
792 {
793 /* Any parameter left without a type gets the type of
794 * its corresponding arg
795 */
796 for (size_t i = 0; i < dedtypes_dim; i++)
797 {
798 if (!(*dedtypes)[i])
799 {
800 assert(i < ti->tiargs->length);
801 (*dedtypes)[i] = (Type *)(*ti->tiargs)[i];
802 }
803 }
804 }
805
806 if (m > MATCHnomatch && constraint && !flag)
807 {
808 if (ti->hasNestedArgs(ti->tiargs, this->isstatic)) // TODO: should gag error
809 ti->parent = ti->enclosing;
810 else
811 ti->parent = this->parent;
812
813 // Similar to doHeaderInstantiation
814 FuncDeclaration *fd = onemember ? onemember->isFuncDeclaration() : NULL;
815 if (fd)
816 {
817 assert(fd->type->ty == Tfunction);
818 TypeFunction *tf = (TypeFunction *)fd->type->syntaxCopy();
819
820 fd = new FuncDeclaration(fd->loc, fd->endloc, fd->ident, fd->storage_class, tf);
821 fd->parent = ti;
822 fd->inferRetType = true;
823
824 // Shouldn't run semantic on default arguments and return type.
825 for (size_t i = 0; i < tf->parameterList.parameters->length; i++)
826 (*tf->parameterList.parameters)[i]->defaultArg = NULL;
827 tf->next = NULL;
828
829 // Resolve parameter types and 'auto ref's.
830 tf->fargs = fargs;
831 unsigned olderrors = global.startGagging();
832 fd->type = typeSemantic(tf, loc, paramscope);
833 if (global.endGagging(olderrors))
834 {
835 assert(fd->type->ty != Tfunction);
836 goto Lnomatch;
837 }
838 assert(fd->type->ty == Tfunction);
839 fd->originalType = fd->type; // for mangling
840 }
841
842 // TODO: dedtypes => ti->tiargs ?
843 if (!evaluateConstraint(ti, sc, paramscope, dedtypes, fd))
844 goto Lnomatch;
845 }
846
847 goto Lret;
848
849 Lnomatch:
850 m = MATCHnomatch;
851
852 Lret:
853 paramscope->pop();
854 return m;
855 }
856
857 /********************************************
858 * Determine partial specialization order of 'this' vs td2.
859 * Returns:
860 * match this is at least as specialized as td2
861 * 0 td2 is more specialized than this
862 */
863
864 MATCH TemplateDeclaration::leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs)
865 {
866 /* This works by taking the template parameters to this template
867 * declaration and feeding them to td2 as if it were a template
868 * instance.
869 * If it works, then this template is at least as specialized
870 * as td2.
871 */
872
873 TemplateInstance ti(Loc(), ident); // create dummy template instance
874 // Set type arguments to dummy template instance to be types
875 // generated from the parameters to this template declaration
876 ti.tiargs = new Objects();
877 ti.tiargs->reserve(parameters->length);
878 for (size_t i = 0; i < parameters->length; i++)
879 {
880 TemplateParameter *tp = (*parameters)[i];
881 if (tp->dependent)
882 break;
883 RootObject *p = (RootObject *)tp->dummyArg();
884 if (!p)
885 break;
886
887 ti.tiargs->push(p);
888 }
889
890 // Temporary Array to hold deduced types
891 Objects dedtypes;
892 dedtypes.setDim(td2->parameters->length);
893
894 // Attempt a type deduction
895 MATCH m = td2->matchWithInstance(sc, &ti, &dedtypes, fargs, 1);
896 if (m > MATCHnomatch)
897 {
898 /* A non-variadic template is more specialized than a
899 * variadic one.
900 */
901 TemplateTupleParameter *tp = isVariadic();
902 if (tp && !tp->dependent && !td2->isVariadic())
903 goto L1;
904
905 return m;
906 }
907 L1:
908 return MATCHnomatch;
909 }
910
911 static Expression *emptyArrayElement = NULL;
912
913 class TypeDeduced : public Type
914 {
915 public:
916 Type *tded;
917 Expressions argexps; // corresponding expressions
918 Types tparams; // tparams[i]->mod
919
920 TypeDeduced(Type *tt, Expression *e, Type *tparam)
921 : Type(Tnone)
922 {
923 tded = tt;
924 argexps.push(e);
925 tparams.push(tparam);
926 }
927
928 virtual ~TypeDeduced()
929 {
930 }
931
932 void update(Expression *e, Type *tparam)
933 {
934 argexps.push(e);
935 tparams.push(tparam);
936 }
937 void update(Type *tt, Expression *e, Type *tparam)
938 {
939 tded = tt;
940 argexps.push(e);
941 tparams.push(tparam);
942 }
943 MATCH matchAll(Type *tt)
944 {
945 MATCH match = MATCHexact;
946 for (size_t j = 0; j < argexps.length; j++)
947 {
948 Expression *e = argexps[j];
949 assert(e);
950 if (e == emptyArrayElement)
951 continue;
952
953 Type *t = tt->addMod(tparams[j]->mod)->substWildTo(MODconst);
954
955 MATCH m = e->implicitConvTo(t);
956 if (match > m)
957 match = m;
958 if (match <= MATCHnomatch)
959 break;
960 }
961 return match;
962 }
963 };
964
965 /*************************************************
966 * Match function arguments against a specific template function.
967 * Input:
968 * ti
969 * sc instantiation scope
970 * fd
971 * tthis 'this' argument if !NULL
972 * fargs arguments to function
973 * Output:
974 * fd Partially instantiated function declaration
975 * ti->tdtypes Expression/Type deduced template arguments
976 * Returns:
977 * match level
978 * bit 0-3 Match template parameters by inferred template arguments
979 * bit 4-7 Match template parameters by initial template arguments
980 */
981
982 MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
983 TemplateInstance *ti, Scope *sc,
984 FuncDeclaration *&fd, Type *tthis, Expressions *fargs)
985 {
986 size_t nfparams;
987 size_t nfargs;
988 size_t ntargs; // array size of tiargs
989 size_t fptupindex = IDX_NOTFOUND;
990 MATCH match = MATCHexact;
991 MATCH matchTiargs = MATCHexact;
992 ParameterList fparameters; // function parameter list
993 unsigned wildmatch = 0;
994 size_t inferStart = 0;
995
996 Loc instLoc = ti->loc;
997 Objects *tiargs = ti->tiargs;
998 Objects *dedargs = new Objects();
999 Objects* dedtypes = &ti->tdtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
1000
1001 assert(_scope);
1002
1003 dedargs->setDim(parameters->length);
1004 dedargs->zero();
1005
1006 dedtypes->setDim(parameters->length);
1007 dedtypes->zero();
1008
1009 if (errors || fd->errors)
1010 return MATCHnomatch;
1011
1012 // Set up scope for parameters
1013 ScopeDsymbol *paramsym = new ScopeDsymbol();
1014 paramsym->parent = _scope->parent; // should use hasnestedArgs and enclosing?
1015 Scope *paramscope = _scope->push(paramsym);
1016 paramscope->tinst = ti;
1017 paramscope->minst = sc->minst;
1018 paramscope->callsc = sc;
1019 paramscope->stc = 0;
1020
1021 TemplateTupleParameter *tp = isVariadic();
1022 Tuple *declaredTuple = NULL;
1023
1024 ntargs = 0;
1025 if (tiargs)
1026 {
1027 // Set initial template arguments
1028 ntargs = tiargs->length;
1029 size_t n = parameters->length;
1030 if (tp)
1031 n--;
1032 if (ntargs > n)
1033 {
1034 if (!tp)
1035 goto Lnomatch;
1036
1037 /* The extra initial template arguments
1038 * now form the tuple argument.
1039 */
1040 Tuple *t = new Tuple();
1041 assert(parameters->length);
1042 (*dedargs)[parameters->length - 1] = t;
1043
1044 t->objects.setDim(ntargs - n);
1045 for (size_t i = 0; i < t->objects.length; i++)
1046 {
1047 t->objects[i] = (*tiargs)[n + i];
1048 }
1049 declareParameter(paramscope, tp, t);
1050 declaredTuple = t;
1051 }
1052 else
1053 n = ntargs;
1054
1055 memcpy(dedargs->tdata(), tiargs->tdata(), n * sizeof(*dedargs->tdata()));
1056
1057 for (size_t i = 0; i < n; i++)
1058 {
1059 assert(i < parameters->length);
1060 Declaration *sparam = NULL;
1061 MATCH m = (*parameters)[i]->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, &sparam);
1062 //printf("\tdeduceType m = %d\n", m);
1063 if (m <= MATCHnomatch)
1064 goto Lnomatch;
1065 if (m < matchTiargs)
1066 matchTiargs = m;
1067
1068 dsymbolSemantic(sparam, paramscope);
1069 if (!paramscope->insert(sparam))
1070 goto Lnomatch;
1071 }
1072 if (n < parameters->length && !declaredTuple)
1073 {
1074 inferStart = n;
1075 }
1076 else
1077 inferStart = parameters->length;
1078 //printf("tiargs matchTiargs = %d\n", matchTiargs);
1079 }
1080
1081 fparameters = fd->getParameterList();
1082 nfparams = fparameters.length(); // number of function parameters
1083 nfargs = fargs ? fargs->length : 0; // number of function arguments
1084
1085 /* Check for match of function arguments with variadic template
1086 * parameter, such as:
1087 *
1088 * void foo(T, A...)(T t, A a);
1089 * void main() { foo(1,2,3); }
1090 */
1091 if (tp) // if variadic
1092 {
1093 // TemplateTupleParameter always makes most lesser matching.
1094 matchTiargs = MATCHconvert;
1095
1096 if (nfparams == 0 && nfargs != 0) // if no function parameters
1097 {
1098 if (!declaredTuple)
1099 {
1100 Tuple *t = new Tuple();
1101 //printf("t = %p\n", t);
1102 (*dedargs)[parameters->length - 1] = t;
1103 declareParameter(paramscope, tp, t);
1104 declaredTuple = t;
1105 }
1106 }
1107 else
1108 {
1109 /* Figure out which of the function parameters matches
1110 * the tuple template parameter. Do this by matching
1111 * type identifiers.
1112 * Set the index of this function parameter to fptupindex.
1113 */
1114 for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
1115 {
1116 Parameter *fparam = (*fparameters.parameters)[fptupindex];
1117 if (fparam->type->ty != Tident)
1118 continue;
1119 TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
1120 if (!tp->ident->equals(tid->ident) || tid->idents.length)
1121 continue;
1122
1123 if (fparameters.varargs != VARARGnone) // variadic function doesn't
1124 goto Lnomatch; // go with variadic template
1125
1126 goto L1;
1127 }
1128 fptupindex = IDX_NOTFOUND;
1129 L1:
1130 ;
1131 }
1132 }
1133
1134 if (toParent()->isModule() || (_scope->stc & STCstatic))
1135 tthis = NULL;
1136 if (tthis)
1137 {
1138 bool hasttp = false;
1139
1140 // Match 'tthis' to any TemplateThisParameter's
1141 for (size_t i = 0; i < parameters->length; i++)
1142 {
1143 TemplateThisParameter *ttp = (*parameters)[i]->isTemplateThisParameter();
1144 if (ttp)
1145 {
1146 hasttp = true;
1147
1148 Type *t = new TypeIdentifier(Loc(), ttp->ident);
1149 MATCH m = deduceType(tthis, paramscope, t, parameters, dedtypes);
1150 if (m <= MATCHnomatch)
1151 goto Lnomatch;
1152 if (m < match)
1153 match = m; // pick worst match
1154 }
1155 }
1156
1157 // Match attributes of tthis against attributes of fd
1158 if (fd->type && !fd->isCtorDeclaration())
1159 {
1160 StorageClass stc = _scope->stc | fd->storage_class2;
1161 // Propagate parent storage class (see bug 5504)
1162 Dsymbol *p = parent;
1163 while (p->isTemplateDeclaration() || p->isTemplateInstance())
1164 p = p->parent;
1165 AggregateDeclaration *ad = p->isAggregateDeclaration();
1166 if (ad)
1167 stc |= ad->storage_class;
1168
1169 unsigned char mod = fd->type->mod;
1170 if (stc & STCimmutable)
1171 mod = MODimmutable;
1172 else
1173 {
1174 if (stc & (STCshared | STCsynchronized))
1175 mod |= MODshared;
1176 if (stc & STCconst)
1177 mod |= MODconst;
1178 if (stc & STCwild)
1179 mod |= MODwild;
1180 }
1181
1182 unsigned char thismod = tthis->mod;
1183 if (hasttp)
1184 mod = MODmerge(thismod, mod);
1185 MATCH m = MODmethodConv(thismod, mod);
1186 if (m <= MATCHnomatch)
1187 goto Lnomatch;
1188 if (m < match)
1189 match = m;
1190 }
1191 }
1192
1193 // Loop through the function parameters
1194 {
1195 //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple->objects.length : 0);
1196 //printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple->toChars() : NULL);
1197 size_t argi = 0;
1198 size_t nfargs2 = nfargs; // nfargs + supplied defaultArgs
1199 for (size_t parami = 0; parami < nfparams; parami++)
1200 {
1201 Parameter *fparam = fparameters[parami];
1202
1203 // Apply function parameter storage classes to parameter types
1204 Type *prmtype = fparam->type->addStorageClass(fparam->storageClass);
1205
1206 Expression *farg;
1207
1208 /* See function parameters which wound up
1209 * as part of a template tuple parameter.
1210 */
1211 if (fptupindex != IDX_NOTFOUND && parami == fptupindex)
1212 {
1213 assert(prmtype->ty == Tident);
1214 TypeIdentifier *tid = (TypeIdentifier *)prmtype;
1215 if (!declaredTuple)
1216 {
1217 /* The types of the function arguments
1218 * now form the tuple argument.
1219 */
1220 declaredTuple = new Tuple();
1221 (*dedargs)[parameters->length - 1] = declaredTuple;
1222
1223 /* Count function parameters following a tuple parameter.
1224 * void foo(U, T...)(int y, T, U, int) {} // rem == 2 (U, int)
1225 */
1226 size_t rem = 0;
1227 for (size_t j = parami + 1; j < nfparams; j++)
1228 {
1229 Parameter *p = fparameters[j];
1230 if (!reliesOnTident(p->type, parameters, inferStart))
1231 {
1232 Type *pt = typeSemantic(p->type->syntaxCopy(), fd->loc, paramscope);
1233 rem += pt->ty == Ttuple ? ((TypeTuple *)pt)->arguments->length : 1;
1234 }
1235 else
1236 {
1237 ++rem;
1238 }
1239 }
1240
1241 if (nfargs2 - argi < rem)
1242 goto Lnomatch;
1243 declaredTuple->objects.setDim(nfargs2 - argi - rem);
1244 for (size_t i = 0; i < declaredTuple->objects.length; i++)
1245 {
1246 farg = (*fargs)[argi + i];
1247
1248 // Check invalid arguments to detect errors early.
1249 if (farg->op == TOKerror || farg->type->ty == Terror)
1250 goto Lnomatch;
1251
1252 if (!(fparam->storageClass & STClazy) && farg->type->ty == Tvoid)
1253 goto Lnomatch;
1254
1255 Type *tt;
1256 MATCH m;
1257 if (unsigned char wm = deduceWildHelper(farg->type, &tt, tid))
1258 {
1259 wildmatch |= wm;
1260 m = MATCHconst;
1261 }
1262 else
1263 {
1264 m = deduceTypeHelper(farg->type, &tt, tid);
1265 }
1266 if (m <= MATCHnomatch)
1267 goto Lnomatch;
1268 if (m < match)
1269 match = m;
1270
1271 /* Remove top const for dynamic array types and pointer types
1272 */
1273 if ((tt->ty == Tarray || tt->ty == Tpointer) &&
1274 !tt->isMutable() &&
1275 (!(fparam->storageClass & STCref) ||
1276 ((fparam->storageClass & STCauto) && !farg->isLvalue())))
1277 {
1278 tt = tt->mutableOf();
1279 }
1280 declaredTuple->objects[i] = tt;
1281 }
1282 declareParameter(paramscope, tp, declaredTuple);
1283 }
1284 else
1285 {
1286 // Bugzilla 6810: If declared tuple is not a type tuple,
1287 // it cannot be function parameter types.
1288 for (size_t i = 0; i < declaredTuple->objects.length; i++)
1289 {
1290 if (!isType(declaredTuple->objects[i]))
1291 goto Lnomatch;
1292 }
1293 }
1294 assert(declaredTuple);
1295 argi += declaredTuple->objects.length;
1296 continue;
1297 }
1298
1299 // If parameter type doesn't depend on inferred template parameters,
1300 // semantic it to get actual type.
1301 if (!reliesOnTident(prmtype, parameters, inferStart))
1302 {
1303 // should copy prmtype to avoid affecting semantic result
1304 prmtype = typeSemantic(prmtype->syntaxCopy(), fd->loc, paramscope);
1305
1306 if (prmtype->ty == Ttuple)
1307 {
1308 TypeTuple *tt = (TypeTuple *)prmtype;
1309 size_t tt_dim = tt->arguments->length;
1310 for (size_t j = 0; j < tt_dim; j++, ++argi)
1311 {
1312 Parameter *p = (*tt->arguments)[j];
1313 if (j == tt_dim - 1 && fparameters.varargs == VARARGtypesafe &&
1314 parami + 1 == nfparams && argi < nfargs)
1315 {
1316 prmtype = p->type;
1317 goto Lvarargs;
1318 }
1319 if (argi >= nfargs)
1320 {
1321 if (p->defaultArg)
1322 continue;
1323 goto Lnomatch;
1324 }
1325 farg = (*fargs)[argi];
1326 if (!farg->implicitConvTo(p->type))
1327 goto Lnomatch;
1328 }
1329 continue;
1330 }
1331 }
1332
1333 if (argi >= nfargs) // if not enough arguments
1334 {
1335 if (!fparam->defaultArg)
1336 goto Lvarargs;
1337
1338 /* Bugzilla 2803: Before the starting of type deduction from the function
1339 * default arguments, set the already deduced parameters into paramscope.
1340 * It's necessary to avoid breaking existing acceptable code. Cases:
1341 *
1342 * 1. Already deduced template parameters can appear in fparam->defaultArg:
1343 * auto foo(A, B)(A a, B b = A.stringof);
1344 * foo(1);
1345 * // at fparam == 'B b = A.string', A is equivalent with the deduced type 'int'
1346 *
1347 * 2. If prmtype depends on default-specified template parameter, the
1348 * default type should be preferred.
1349 * auto foo(N = size_t, R)(R r, N start = 0)
1350 * foo([1,2,3]);
1351 * // at fparam `N start = 0`, N should be 'size_t' before
1352 * // the deduction result from fparam->defaultArg.
1353 */
1354 if (argi == nfargs)
1355 {
1356 for (size_t i = 0; i < dedtypes->length; i++)
1357 {
1358 Type *at = isType((*dedtypes)[i]);
1359 if (at && at->ty == Tnone)
1360 {
1361 TypeDeduced *xt = (TypeDeduced *)at;
1362 (*dedtypes)[i] = xt->tded; // 'unbox'
1363 delete xt;
1364 }
1365 }
1366 for (size_t i = ntargs; i < dedargs->length; i++)
1367 {
1368 TemplateParameter *tparam = (*parameters)[i];
1369
1370 RootObject *oarg = (*dedargs)[i];
1371 RootObject *oded = (*dedtypes)[i];
1372 if (!oarg)
1373 {
1374 if (oded)
1375 {
1376 if (tparam->specialization() || !tparam->isTemplateTypeParameter())
1377 {
1378 /* The specialization can work as long as afterwards
1379 * the oded == oarg
1380 */
1381 (*dedargs)[i] = oded;
1382 MATCH m2 = tparam->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, NULL);
1383 //printf("m2 = %d\n", m2);
1384 if (m2 <= MATCHnomatch)
1385 goto Lnomatch;
1386 if (m2 < matchTiargs)
1387 matchTiargs = m2; // pick worst match
1388 if (!(*dedtypes)[i]->equals(oded))
1389 error("specialization not allowed for deduced parameter %s", tparam->ident->toChars());
1390 }
1391 else
1392 {
1393 if (MATCHconvert < matchTiargs)
1394 matchTiargs = MATCHconvert;
1395 }
1396 (*dedargs)[i] = declareParameter(paramscope, tparam, oded);
1397 }
1398 else
1399 {
1400 oded = tparam->defaultArg(instLoc, paramscope);
1401 if (oded)
1402 (*dedargs)[i] = declareParameter(paramscope, tparam, oded);
1403 }
1404 }
1405 }
1406 }
1407 nfargs2 = argi + 1;
1408
1409 /* If prmtype does not depend on any template parameters:
1410 *
1411 * auto foo(T)(T v, double x = 0);
1412 * foo("str");
1413 * // at fparam == 'double x = 0'
1414 *
1415 * or, if all template parameters in the prmtype are already deduced:
1416 *
1417 * auto foo(R)(R range, ElementType!R sum = 0);
1418 * foo([1,2,3]);
1419 * // at fparam == 'ElementType!R sum = 0'
1420 *
1421 * Deducing prmtype from fparam->defaultArg is not necessary.
1422 */
1423 if (prmtype->deco ||
1424 prmtype->syntaxCopy()->trySemantic(loc, paramscope))
1425 {
1426 ++argi;
1427 continue;
1428 }
1429
1430 // Deduce prmtype from the defaultArg.
1431 farg = fparam->defaultArg->syntaxCopy();
1432 farg = expressionSemantic(farg, paramscope);
1433 farg = resolveProperties(paramscope, farg);
1434 }
1435 else
1436 {
1437 farg = (*fargs)[argi];
1438 }
1439 {
1440 // Check invalid arguments to detect errors early.
1441 if (farg->op == TOKerror || farg->type->ty == Terror)
1442 goto Lnomatch;
1443
1444 Type *att = NULL;
1445 Lretry:
1446 Type *argtype = farg->type;
1447
1448 if (!(fparam->storageClass & STClazy) && argtype->ty == Tvoid && farg->op != TOKfunction)
1449 goto Lnomatch;
1450
1451 // Bugzilla 12876: optimize arugument to allow CT-known length matching
1452 farg = farg->optimize(WANTvalue, (fparam->storageClass & (STCref | STCout)) != 0);
1453 //printf("farg = %s %s\n", farg->type->toChars(), farg->toChars());
1454
1455 RootObject *oarg = farg;
1456 if ((fparam->storageClass & STCref) &&
1457 (!(fparam->storageClass & STCauto) || farg->isLvalue()))
1458 {
1459 /* Allow expressions that have CT-known boundaries and type [] to match with [dim]
1460 */
1461 Type *taai;
1462 if (argtype->ty == Tarray &&
1463 (prmtype->ty == Tsarray ||
1464 (prmtype->ty == Taarray && (taai = ((TypeAArray *)prmtype)->index)->ty == Tident &&
1465 ((TypeIdentifier *)taai)->idents.length == 0)))
1466 {
1467 if (farg->op == TOKstring)
1468 {
1469 StringExp *se = (StringExp *)farg;
1470 argtype = se->type->nextOf()->sarrayOf(se->len);
1471 }
1472 else if (farg->op == TOKarrayliteral)
1473 {
1474 ArrayLiteralExp *ae = (ArrayLiteralExp *)farg;
1475 argtype = ae->type->nextOf()->sarrayOf(ae->elements->length);
1476 }
1477 else if (farg->op == TOKslice)
1478 {
1479 SliceExp *se = (SliceExp *)farg;
1480 if (Type *tsa = toStaticArrayType(se))
1481 argtype = tsa;
1482 }
1483 }
1484
1485 oarg = argtype;
1486 }
1487 else if ((fparam->storageClass & STCout) == 0 &&
1488 (argtype->ty == Tarray || argtype->ty == Tpointer) &&
1489 templateParameterLookup(prmtype, parameters) != IDX_NOTFOUND &&
1490 ((TypeIdentifier *)prmtype)->idents.length == 0)
1491 {
1492 /* The farg passing to the prmtype always make a copy. Therefore,
1493 * we can shrink the set of the deduced type arguments for prmtype
1494 * by adjusting top-qualifier of the argtype.
1495 *
1496 * prmtype argtype ta
1497 * T <- const(E)[] const(E)[]
1498 * T <- const(E[]) const(E)[]
1499 * qualifier(T) <- const(E)[] const(E[])
1500 * qualifier(T) <- const(E[]) const(E[])
1501 */
1502 Type *ta = argtype->castMod(prmtype->mod ? argtype->nextOf()->mod : 0);
1503 if (ta != argtype)
1504 {
1505 Expression *ea = farg->copy();
1506 ea->type = ta;
1507 oarg = ea;
1508 }
1509 }
1510
1511 if (fparameters.varargs == VARARGtypesafe && parami + 1 == nfparams && argi + 1 < nfargs)
1512 goto Lvarargs;
1513
1514 unsigned wm = 0;
1515 MATCH m = deduceType(oarg, paramscope, prmtype, parameters, dedtypes, &wm, inferStart);
1516 //printf("\tL%d deduceType m = %d, wm = x%x, wildmatch = x%x\n", __LINE__, m, wm, wildmatch);
1517 wildmatch |= wm;
1518
1519 /* If no match, see if the argument can be matched by using
1520 * implicit conversions.
1521 */
1522 if (m == MATCHnomatch && prmtype->deco)
1523 m = farg->implicitConvTo(prmtype);
1524
1525 if (m == MATCHnomatch)
1526 {
1527 AggregateDeclaration *ad = isAggregate(farg->type);
1528 if (ad && ad->aliasthis && argtype != att)
1529 {
1530 if (!att && argtype->checkAliasThisRec()) // Bugzilla 12537
1531 att = argtype;
1532
1533 /* If a semantic error occurs while doing alias this,
1534 * eg purity(bug 7295), just regard it as not a match.
1535 */
1536 if (Expression *e = resolveAliasThis(sc, farg, true))
1537 {
1538 farg = e;
1539 goto Lretry;
1540 }
1541 }
1542 }
1543
1544 if (m > MATCHnomatch && (fparam->storageClass & (STCref | STCauto)) == STCref)
1545 {
1546 if (!farg->isLvalue())
1547 {
1548 if ((farg->op == TOKstring || farg->op == TOKslice) &&
1549 (prmtype->ty == Tsarray || prmtype->ty == Taarray))
1550 {
1551 // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
1552 }
1553 else
1554 goto Lnomatch;
1555 }
1556 }
1557 if (m > MATCHnomatch && (fparam->storageClass & STCout))
1558 {
1559 if (!farg->isLvalue())
1560 goto Lnomatch;
1561 if (!farg->type->isMutable()) // Bugzilla 11916
1562 goto Lnomatch;
1563 }
1564 if (m == MATCHnomatch && (fparam->storageClass & STClazy) && prmtype->ty == Tvoid &&
1565 farg->type->ty != Tvoid)
1566 m = MATCHconvert;
1567
1568 if (m != MATCHnomatch)
1569 {
1570 if (m < match)
1571 match = m; // pick worst match
1572 argi++;
1573 continue;
1574 }
1575 }
1576
1577 Lvarargs:
1578 /* The following code for variadic arguments closely
1579 * matches TypeFunction::callMatch()
1580 */
1581 if (!(fparameters.varargs == VARARGtypesafe && parami + 1 == nfparams))
1582 goto Lnomatch;
1583
1584 /* Check for match with function parameter T...
1585 */
1586 Type *tb = prmtype->toBasetype();
1587 switch (tb->ty)
1588 {
1589 // 6764 fix - TypeAArray may be TypeSArray have not yet run semantic().
1590 case Tsarray:
1591 case Taarray:
1592 // Perhaps we can do better with this, see TypeFunction::callMatch()
1593 if (tb->ty == Tsarray)
1594 {
1595 TypeSArray *tsa = (TypeSArray *)tb;
1596 dinteger_t sz = tsa->dim->toInteger();
1597 if (sz != nfargs - argi)
1598 goto Lnomatch;
1599 }
1600 else if (tb->ty == Taarray)
1601 {
1602 TypeAArray *taa = (TypeAArray *)tb;
1603 Expression *dim = new IntegerExp(instLoc, nfargs - argi, Type::tsize_t);
1604
1605 size_t i = templateParameterLookup(taa->index, parameters);
1606 if (i == IDX_NOTFOUND)
1607 {
1608 Expression *e;
1609 Type *t;
1610 Dsymbol *s;
1611 Scope *sco;
1612
1613 unsigned errors = global.startGagging();
1614 /* ref: https://issues.dlang.org/show_bug.cgi?id=11118
1615 * The parameter isn't part of the template
1616 * ones, let's try to find it in the
1617 * instantiation scope 'sc' and the one
1618 * belonging to the template itself. */
1619 sco = sc;
1620 taa->index->resolve(instLoc, sco, &e, &t, &s);
1621 if (!e)
1622 {
1623 sco = paramscope;
1624 taa->index->resolve(instLoc, sco, &e, &t, &s);
1625 }
1626 global.endGagging(errors);
1627
1628 if (!e)
1629 {
1630 goto Lnomatch;
1631 }
1632
1633 e = e->ctfeInterpret();
1634 e = e->implicitCastTo(sco, Type::tsize_t);
1635 e = e->optimize(WANTvalue);
1636 if (!dim->equals(e))
1637 goto Lnomatch;
1638 }
1639 else
1640 {
1641 // This code matches code in TypeInstance::deduceType()
1642 TemplateParameter *tprm = (*parameters)[i];
1643 TemplateValueParameter *tvp = tprm->isTemplateValueParameter();
1644 if (!tvp)
1645 goto Lnomatch;
1646 Expression *e = (Expression *)(*dedtypes)[i];
1647 if (e)
1648 {
1649 if (!dim->equals(e))
1650 goto Lnomatch;
1651 }
1652 else
1653 {
1654 Type *vt = typeSemantic(tvp->valType, Loc(), sc);
1655 MATCH m = (MATCH)dim->implicitConvTo(vt);
1656 if (m <= MATCHnomatch)
1657 goto Lnomatch;
1658 (*dedtypes)[i] = dim;
1659 }
1660 }
1661 }
1662 /* fall through */
1663 case Tarray:
1664 {
1665 TypeArray *ta = (TypeArray *)tb;
1666 Type *tret = fparam->isLazyArray();
1667 for (; argi < nfargs; argi++)
1668 {
1669 Expression *arg = (*fargs)[argi];
1670 assert(arg);
1671
1672 MATCH m;
1673 /* If lazy array of delegates,
1674 * convert arg(s) to delegate(s)
1675 */
1676 if (tret)
1677 {
1678 if (ta->next->equals(arg->type))
1679 {
1680 m = MATCHexact;
1681 }
1682 else
1683 {
1684 m = arg->implicitConvTo(tret);
1685 if (m == MATCHnomatch)
1686 {
1687 if (tret->toBasetype()->ty == Tvoid)
1688 m = MATCHconvert;
1689 }
1690 }
1691 }
1692 else
1693 {
1694 unsigned wm = 0;
1695 m = deduceType(arg, paramscope, ta->next, parameters, dedtypes, &wm, inferStart);
1696 wildmatch |= wm;
1697 }
1698 if (m == MATCHnomatch)
1699 goto Lnomatch;
1700 if (m < match)
1701 match = m;
1702 }
1703 goto Lmatch;
1704 }
1705 case Tclass:
1706 case Tident:
1707 goto Lmatch;
1708
1709 default:
1710 goto Lnomatch;
1711 }
1712 ++argi;
1713 }
1714 //printf("-> argi = %d, nfargs = %d, nfargs2 = %d\n", argi, nfargs, nfargs2);
1715 if (argi != nfargs2 && fparameters.varargs == VARARGnone)
1716 goto Lnomatch;
1717 }
1718
1719 Lmatch:
1720
1721 for (size_t i = 0; i < dedtypes->length; i++)
1722 {
1723 Type *at = isType((*dedtypes)[i]);
1724 if (at)
1725 {
1726 if (at->ty == Tnone)
1727 {
1728 TypeDeduced *xt = (TypeDeduced *)at;
1729 at = xt->tded; // 'unbox'
1730 delete xt;
1731 }
1732 (*dedtypes)[i] = at->merge2();
1733 }
1734 }
1735 for (size_t i = ntargs; i < dedargs->length; i++)
1736 {
1737 TemplateParameter *tparam = (*parameters)[i];
1738 //printf("tparam[%d] = %s\n", i, tparam->ident->toChars());
1739 /* For T:T*, the dedargs is the T*, dedtypes is the T
1740 * But for function templates, we really need them to match
1741 */
1742 RootObject *oarg = (*dedargs)[i];
1743 RootObject *oded = (*dedtypes)[i];
1744 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
1745 //if (oarg) printf("oarg: %s\n", oarg->toChars());
1746 //if (oded) printf("oded: %s\n", oded->toChars());
1747 if (!oarg)
1748 {
1749 if (oded)
1750 {
1751 if (tparam->specialization() || !tparam->isTemplateTypeParameter())
1752 {
1753 /* The specialization can work as long as afterwards
1754 * the oded == oarg
1755 */
1756 (*dedargs)[i] = oded;
1757 MATCH m2 = tparam->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, NULL);
1758 //printf("m2 = %d\n", m2);
1759 if (m2 <= MATCHnomatch)
1760 goto Lnomatch;
1761 if (m2 < matchTiargs)
1762 matchTiargs = m2; // pick worst match
1763 if (!(*dedtypes)[i]->equals(oded))
1764 error("specialization not allowed for deduced parameter %s", tparam->ident->toChars());
1765 }
1766 else
1767 {
1768 if (MATCHconvert < matchTiargs)
1769 matchTiargs = MATCHconvert;
1770 }
1771 }
1772 else
1773 {
1774 oded = tparam->defaultArg(instLoc, paramscope);
1775 if (!oded)
1776 {
1777 // if tuple parameter and
1778 // tuple parameter was not in function parameter list and
1779 // we're one or more arguments short (i.e. no tuple argument)
1780 if (tparam == tp &&
1781 fptupindex == IDX_NOTFOUND &&
1782 ntargs <= dedargs->length - 1)
1783 {
1784 // make tuple argument an empty tuple
1785 oded = (RootObject *)new Tuple();
1786 }
1787 else
1788 goto Lnomatch;
1789 }
1790 if (isError(oded))
1791 goto Lerror;
1792 ntargs++;
1793
1794 /* At the template parameter T, the picked default template argument
1795 * X!int should be matched to T in order to deduce dependent
1796 * template parameter A.
1797 * auto foo(T : X!A = X!int, A...)() { ... }
1798 * foo(); // T <-- X!int, A <-- (int)
1799 */
1800 if (tparam->specialization())
1801 {
1802 (*dedargs)[i] = oded;
1803 MATCH m2 = tparam->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, NULL);
1804 //printf("m2 = %d\n", m2);
1805 if (m2 <= MATCHnomatch)
1806 goto Lnomatch;
1807 if (m2 < matchTiargs)
1808 matchTiargs = m2; // pick worst match
1809 if (!(*dedtypes)[i]->equals(oded))
1810 error("specialization not allowed for deduced parameter %s", tparam->ident->toChars());
1811 }
1812 }
1813 oded = declareParameter(paramscope, tparam, oded);
1814 (*dedargs)[i] = oded;
1815 }
1816 }
1817
1818 /* Bugzilla 7469: As same as the code for 7469 in findBestMatch,
1819 * expand a Tuple in dedargs to normalize template arguments.
1820 */
1821 if (size_t d = dedargs->length)
1822 {
1823 if (Tuple *va = isTuple((*dedargs)[d - 1]))
1824 {
1825 if (va->objects.length)
1826 {
1827 dedargs->setDim(d - 1);
1828 dedargs->insert(d - 1, &va->objects);
1829 }
1830 }
1831 }
1832 ti->tiargs = dedargs; // update to the normalized template arguments.
1833
1834 // Partially instantiate function for constraint and fd->leastAsSpecialized()
1835 {
1836 assert(paramsym);
1837 Scope *sc2 = _scope;
1838 sc2 = sc2->push(paramsym);
1839 sc2 = sc2->push(ti);
1840 sc2->parent = ti;
1841 sc2->tinst = ti;
1842 sc2->minst = sc->minst;
1843
1844 fd = doHeaderInstantiation(ti, sc2, fd, tthis, fargs);
1845
1846 sc2 = sc2->pop();
1847 sc2 = sc2->pop();
1848
1849 if (!fd)
1850 goto Lnomatch;
1851 }
1852
1853 if (constraint)
1854 {
1855 if (!evaluateConstraint(ti, sc, paramscope, dedargs, fd))
1856 goto Lnomatch;
1857 }
1858
1859 paramscope->pop();
1860 //printf("\tmatch %d\n", match);
1861 return (MATCH)(match | (matchTiargs<<4));
1862
1863 Lnomatch:
1864 paramscope->pop();
1865 //printf("\tnomatch\n");
1866 return MATCHnomatch;
1867
1868 Lerror: // todo: for the future improvement
1869 paramscope->pop();
1870 //printf("\terror\n");
1871 return MATCHnomatch;
1872 }
1873
1874 /**************************************************
1875 * Declare template parameter tp with value o, and install it in the scope sc.
1876 */
1877
1878 RootObject *TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o)
1879 {
1880 //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o);
1881
1882 Type *ta = isType(o);
1883 Expression *ea = isExpression(o);
1884 Dsymbol *sa = isDsymbol(o);
1885 Tuple *va = isTuple(o);
1886
1887 Declaration *d;
1888 VarDeclaration *v = NULL;
1889
1890 if (ea && ea->op == TOKtype)
1891 ta = ea->type;
1892 else if (ea && ea->op == TOKscope)
1893 sa = ((ScopeExp *)ea)->sds;
1894 else if (ea && (ea->op == TOKthis || ea->op == TOKsuper))
1895 sa = ((ThisExp *)ea)->var;
1896 else if (ea && ea->op == TOKfunction)
1897 {
1898 if (((FuncExp *)ea)->td)
1899 sa = ((FuncExp *)ea)->td;
1900 else
1901 sa = ((FuncExp *)ea)->fd;
1902 }
1903
1904 if (ta)
1905 {
1906 //printf("type %s\n", ta->toChars());
1907 d = new AliasDeclaration(Loc(), tp->ident, ta);
1908 }
1909 else if (sa)
1910 {
1911 //printf("Alias %s %s;\n", sa->ident->toChars(), tp->ident->toChars());
1912 d = new AliasDeclaration(Loc(), tp->ident, sa);
1913 }
1914 else if (ea)
1915 {
1916 // tdtypes.data[i] always matches ea here
1917 Initializer *init = new ExpInitializer(loc, ea);
1918 TemplateValueParameter *tvp = tp->isTemplateValueParameter();
1919
1920 Type *t = tvp ? tvp->valType : NULL;
1921
1922 v = new VarDeclaration(loc, t, tp->ident, init);
1923 v->storage_class = STCmanifest | STCtemplateparameter;
1924 d = v;
1925 }
1926 else if (va)
1927 {
1928 //printf("\ttuple\n");
1929 d = new TupleDeclaration(loc, tp->ident, &va->objects);
1930 }
1931 else
1932 {
1933 assert(0);
1934 }
1935
1936 d->storage_class |= STCtemplateparameter;
1937 if (ta)
1938 {
1939 Type *t = ta;
1940 // consistent with Type::checkDeprecated()
1941 while (t->ty != Tenum)
1942 {
1943 if (!t->nextOf()) break;
1944 t = ((TypeNext *)t)->next;
1945 }
1946 if (Dsymbol *s = t->toDsymbol(sc))
1947 {
1948 if (s->isDeprecated())
1949 d->storage_class |= STCdeprecated;
1950 }
1951 }
1952 else if (sa)
1953 {
1954 if (sa->isDeprecated())
1955 d->storage_class |= STCdeprecated;
1956 }
1957
1958 if (!sc->insert(d))
1959 error("declaration %s is already defined", tp->ident->toChars());
1960 dsymbolSemantic(d, sc);
1961
1962 /* So the caller's o gets updated with the result of semantic() being run on o
1963 */
1964 if (v)
1965 o = initializerToExpression(v->_init);
1966 return o;
1967 }
1968
1969 /**************************************
1970 * Determine if TemplateDeclaration is variadic.
1971 */
1972
1973 TemplateTupleParameter *isVariadic(TemplateParameters *parameters)
1974 {
1975 size_t dim = parameters->length;
1976 TemplateTupleParameter *tp = NULL;
1977
1978 if (dim)
1979 tp = ((*parameters)[dim - 1])->isTemplateTupleParameter();
1980 return tp;
1981 }
1982
1983 TemplateTupleParameter *TemplateDeclaration::isVariadic()
1984 {
1985 return ::isVariadic(parameters);
1986 }
1987
1988 /***********************************
1989 * We can overload templates.
1990 */
1991
1992 bool TemplateDeclaration::isOverloadable()
1993 {
1994 return true;
1995 }
1996
1997 /*************************************************
1998 * Given function arguments, figure out which template function
1999 * to expand, and return matching result.
2000 * Input:
2001 * m matching result
2002 * dstart the root of overloaded function templates
2003 * loc instantiation location
2004 * sc instantiation scope
2005 * tiargs initial list of template arguments
2006 * tthis if !NULL, the 'this' pointer argument
2007 * fargs arguments to function
2008 */
2009
2010 void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
2011 Objects *tiargs, Type *tthis, Expressions *fargs)
2012 {
2013 struct ParamDeduce
2014 {
2015 // context
2016 Loc loc;
2017 Scope *sc;
2018 Type *tthis;
2019 Objects *tiargs;
2020 Expressions *fargs;
2021 // result
2022 Match *m;
2023 int property; // 0: unintialized
2024 // 1: seen @property
2025 // 2: not @property
2026 size_t ov_index;
2027 TemplateDeclaration *td_best;
2028 TemplateInstance *ti_best;
2029 MATCH ta_last;
2030 Type *tthis_best;
2031
2032 static int fp(void *param, Dsymbol *s)
2033 {
2034 if (s->errors)
2035 return 0;
2036 if (FuncDeclaration *fd = s->isFuncDeclaration())
2037 return ((ParamDeduce *)param)->applyFunction(fd);
2038 if (TemplateDeclaration *td = s->isTemplateDeclaration())
2039 return ((ParamDeduce *)param)->applyTemplate(td);
2040 return 0;
2041 }
2042
2043 int applyFunction(FuncDeclaration *fd)
2044 {
2045 // skip duplicates
2046 if (fd == m->lastf)
2047 return 0;
2048 // explicitly specified tiargs never match to non template function
2049 if (tiargs && tiargs->length > 0)
2050 return 0;
2051
2052 // constructors need a valid scope in order to detect semantic errors
2053 if (!fd->isCtorDeclaration() &&
2054 fd->semanticRun < PASSsemanticdone)
2055 {
2056 Ungag ungag = fd->ungagSpeculative();
2057 dsymbolSemantic(fd, NULL);
2058 }
2059 if (fd->semanticRun < PASSsemanticdone)
2060 {
2061 ::error(loc, "forward reference to template %s", fd->toChars());
2062 return 1;
2063 }
2064 //printf("fd = %s %s, fargs = %s\n", fd->toChars(), fd->type->toChars(), fargs->toChars());
2065 m->anyf = fd;
2066 TypeFunction *tf = (TypeFunction *)fd->type;
2067
2068 int prop = (tf->isproperty) ? 1 : 2;
2069 if (property == 0)
2070 property = prop;
2071 else if (property != prop)
2072 error(fd->loc, "cannot overload both property and non-property functions");
2073
2074 /* For constructors, qualifier check will be opposite direction.
2075 * Qualified constructor always makes qualified object, then will be checked
2076 * that it is implicitly convertible to tthis.
2077 */
2078 Type *tthis_fd = fd->needThis() ? tthis : NULL;
2079 bool isCtorCall = tthis_fd && fd->isCtorDeclaration();
2080 if (isCtorCall)
2081 {
2082 //printf("%s tf->mod = x%x tthis_fd->mod = x%x %d\n", tf->toChars(),
2083 // tf->mod, tthis_fd->mod, fd->isolateReturn());
2084 if (MODimplicitConv(tf->mod, tthis_fd->mod) ||
2085 (tf->isWild() && tf->isShared() == tthis_fd->isShared()) ||
2086 fd->isolateReturn())
2087 {
2088 /* && tf->isShared() == tthis_fd->isShared()*/
2089 // Uniquely constructed object can ignore shared qualifier.
2090 // TODO: Is this appropriate?
2091 tthis_fd = NULL;
2092 }
2093 else
2094 return 0; // MATCHnomatch
2095 }
2096 MATCH mfa = tf->callMatch(tthis_fd, fargs);
2097 //printf("test1: mfa = %d\n", mfa);
2098 if (mfa > MATCHnomatch)
2099 {
2100 if (mfa > m->last) goto LfIsBetter;
2101 if (mfa < m->last) goto LlastIsBetter;
2102
2103 /* See if one of the matches overrides the other.
2104 */
2105 assert(m->lastf);
2106 if (m->lastf->overrides(fd)) goto LlastIsBetter;
2107 if (fd->overrides(m->lastf)) goto LfIsBetter;
2108
2109 /* Try to disambiguate using template-style partial ordering rules.
2110 * In essence, if f() and g() are ambiguous, if f() can call g(),
2111 * but g() cannot call f(), then pick f().
2112 * This is because f() is "more specialized."
2113 */
2114 {
2115 MATCH c1 = fd->leastAsSpecialized(m->lastf);
2116 MATCH c2 = m->lastf->leastAsSpecialized(fd);
2117 //printf("c1 = %d, c2 = %d\n", c1, c2);
2118 if (c1 > c2) goto LfIsBetter;
2119 if (c1 < c2) goto LlastIsBetter;
2120 }
2121
2122 /* The 'overrides' check above does covariant checking only
2123 * for virtual member functions. It should do it for all functions,
2124 * but in order to not risk breaking code we put it after
2125 * the 'leastAsSpecialized' check.
2126 * In the future try moving it before.
2127 * I.e. a not-the-same-but-covariant match is preferred,
2128 * as it is more restrictive.
2129 */
2130 if (!m->lastf->type->equals(fd->type))
2131 {
2132 //printf("cov: %d %d\n", m->lastf->type->covariant(fd->type), fd->type->covariant(m->lastf->type));
2133 if (m->lastf->type->covariant(fd->type) == 1) goto LlastIsBetter;
2134 if (fd->type->covariant(m->lastf->type) == 1) goto LfIsBetter;
2135 }
2136
2137 /* If the two functions are the same function, like:
2138 * int foo(int);
2139 * int foo(int x) { ... }
2140 * then pick the one with the body.
2141 */
2142 if (tf->equals(m->lastf->type) &&
2143 fd->storage_class == m->lastf->storage_class &&
2144 fd->parent == m->lastf->parent &&
2145 fd->protection == m->lastf->protection &&
2146 fd->linkage == m->lastf->linkage)
2147 {
2148 if ( fd->fbody && !m->lastf->fbody) goto LfIsBetter;
2149 if (!fd->fbody && m->lastf->fbody) goto LlastIsBetter;
2150 }
2151
2152 // Bugzilla 14450: Prefer exact qualified constructor for the creating object type
2153 if (isCtorCall && tf->mod != m->lastf->type->mod)
2154 {
2155 if (tthis->mod == tf->mod) goto LfIsBetter;
2156 if (tthis->mod == m->lastf->type->mod) goto LlastIsBetter;
2157 }
2158
2159 m->nextf = fd;
2160 m->count++;
2161 return 0;
2162
2163 LlastIsBetter:
2164 return 0;
2165
2166 LfIsBetter:
2167 td_best = NULL;
2168 ti_best = NULL;
2169 ta_last = MATCHexact;
2170 m->last = mfa;
2171 m->lastf = fd;
2172 tthis_best = tthis_fd;
2173 ov_index = 0;
2174 m->count = 1;
2175 return 0;
2176 }
2177 return 0;
2178 }
2179
2180 int applyTemplate(TemplateDeclaration *td)
2181 {
2182 //printf("applyTemplate()\n");
2183 // skip duplicates
2184 if (td == td_best)
2185 return 0;
2186
2187 if (!sc)
2188 sc = td->_scope; // workaround for Type::aliasthisOf
2189
2190 if (td->semanticRun == PASSinit && td->_scope)
2191 {
2192 // Try to fix forward reference. Ungag errors while doing so.
2193 Ungag ungag = td->ungagSpeculative();
2194 dsymbolSemantic(td, td->_scope);
2195 }
2196 if (td->semanticRun == PASSinit)
2197 {
2198 ::error(loc, "forward reference to template %s", td->toChars());
2199 Lerror:
2200 m->lastf = NULL;
2201 m->count = 0;
2202 m->last = MATCHnomatch;
2203 return 1;
2204 }
2205 //printf("td = %s\n", td->toChars());
2206
2207 FuncDeclaration *f;
2208 f = td->onemember ? td->onemember->isFuncDeclaration() : NULL;
2209 if (!f)
2210 {
2211 if (!tiargs)
2212 tiargs = new Objects();
2213 TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
2214 Objects dedtypes;
2215 dedtypes.setDim(td->parameters->length);
2216 assert(td->semanticRun != PASSinit);
2217 MATCH mta = td->matchWithInstance(sc, ti, &dedtypes, fargs, 0);
2218 //printf("matchWithInstance = %d\n", mta);
2219 if (mta <= MATCHnomatch || mta < ta_last) // no match or less match
2220 return 0;
2221
2222 templateInstanceSemantic(ti, sc, fargs);
2223 if (!ti->inst) // if template failed to expand
2224 return 0;
2225
2226 Dsymbol *s = ti->inst->toAlias();
2227 FuncDeclaration *fd;
2228 if (TemplateDeclaration *tdx = s->isTemplateDeclaration())
2229 {
2230 Objects dedtypesX; // empty tiargs
2231
2232 // Bugzilla 11553: Check for recursive instantiation of tdx.
2233 for (TemplatePrevious *p = tdx->previous; p; p = p->prev)
2234 {
2235 if (arrayObjectMatch(p->dedargs, &dedtypesX))
2236 {
2237 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
2238 /* It must be a subscope of p->sc, other scope chains are not recursive
2239 * instantiations.
2240 */
2241 for (Scope *scx = sc; scx; scx = scx->enclosing)
2242 {
2243 if (scx == p->sc)
2244 {
2245 error(loc, "recursive template expansion while looking for %s.%s", ti->toChars(), tdx->toChars());
2246 goto Lerror;
2247 }
2248 }
2249 }
2250 /* BUG: should also check for ref param differences
2251 */
2252 }
2253
2254 TemplatePrevious pr;
2255 pr.prev = tdx->previous;
2256 pr.sc = sc;
2257 pr.dedargs = &dedtypesX;
2258 tdx->previous = &pr; // add this to threaded list
2259
2260 fd = resolveFuncCall(loc, sc, s, NULL, tthis, fargs, 1);
2261
2262 tdx->previous = pr.prev; // unlink from threaded list
2263 }
2264 else if (s->isFuncDeclaration())
2265 {
2266 fd = resolveFuncCall(loc, sc, s, NULL, tthis, fargs, 1);
2267 }
2268 else
2269 goto Lerror;
2270
2271 if (!fd)
2272 return 0;
2273
2274 if (fd->type->ty != Tfunction)
2275 {
2276 m->lastf = fd; // to propagate "error match"
2277 m->count = 1;
2278 m->last = MATCHnomatch;
2279 return 1;
2280 }
2281
2282 Type *tthis_fd = fd->needThis() && !fd->isCtorDeclaration() ? tthis : NULL;
2283
2284 TypeFunction *tf = (TypeFunction *)fd->type;
2285 MATCH mfa = tf->callMatch(tthis_fd, fargs);
2286 if (mfa < m->last)
2287 return 0;
2288
2289 if (mta < ta_last) goto Ltd_best2;
2290 if (mta > ta_last) goto Ltd2;
2291
2292 if (mfa < m->last) goto Ltd_best2;
2293 if (mfa > m->last) goto Ltd2;
2294
2295 //printf("Lambig2\n");
2296 m->nextf = fd;
2297 m->count++;
2298 return 0;
2299
2300 Ltd_best2:
2301 return 0;
2302
2303 Ltd2:
2304 // td is the new best match
2305 assert(td->_scope);
2306 td_best = td;
2307 ti_best = NULL;
2308 property = 0; // (backward compatibility)
2309 ta_last = mta;
2310 m->last = mfa;
2311 m->lastf = fd;
2312 tthis_best = tthis_fd;
2313 ov_index = 0;
2314 m->nextf = NULL;
2315 m->count = 1;
2316 return 0;
2317 }
2318
2319 //printf("td = %s\n", td->toChars());
2320 for (size_t ovi = 0; f; f = f->overnext0, ovi++)
2321 {
2322 if (f->type->ty != Tfunction || f->errors)
2323 goto Lerror;
2324
2325 /* This is a 'dummy' instance to evaluate constraint properly.
2326 */
2327 TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
2328 ti->parent = td->parent; // Maybe calculating valid 'enclosing' is unnecessary.
2329
2330 FuncDeclaration *fd = f;
2331 int x = td->deduceFunctionTemplateMatch(ti, sc, fd, tthis, fargs);
2332 MATCH mta = (MATCH)(x >> 4);
2333 MATCH mfa = (MATCH)(x & 0xF);
2334 //printf("match:t/f = %d/%d\n", mta, mfa);
2335 if (!fd || mfa == MATCHnomatch)
2336 continue;
2337
2338 Type *tthis_fd = fd->needThis() ? tthis : NULL;
2339
2340 bool isCtorCall = tthis_fd && fd->isCtorDeclaration();
2341 if (isCtorCall)
2342 {
2343 // Constructor call requires additional check.
2344
2345 TypeFunction *tf = (TypeFunction *)fd->type;
2346 assert(tf->next);
2347 if (MODimplicitConv(tf->mod, tthis_fd->mod) ||
2348 (tf->isWild() && tf->isShared() == tthis_fd->isShared()) ||
2349 fd->isolateReturn())
2350 {
2351 tthis_fd = NULL;
2352 }
2353 else
2354 continue; // MATCHnomatch
2355 }
2356
2357 if (mta < ta_last) goto Ltd_best;
2358 if (mta > ta_last) goto Ltd;
2359
2360 if (mfa < m->last) goto Ltd_best;
2361 if (mfa > m->last) goto Ltd;
2362
2363 if (td_best)
2364 {
2365 // Disambiguate by picking the most specialized TemplateDeclaration
2366 MATCH c1 = td->leastAsSpecialized(sc, td_best, fargs);
2367 MATCH c2 = td_best->leastAsSpecialized(sc, td, fargs);
2368 //printf("1: c1 = %d, c2 = %d\n", c1, c2);
2369 if (c1 > c2) goto Ltd;
2370 if (c1 < c2) goto Ltd_best;
2371 }
2372 assert(fd && m->lastf);
2373 {
2374 // Disambiguate by tf->callMatch
2375 TypeFunction *tf1 = (TypeFunction *)fd->type;
2376 assert(tf1->ty == Tfunction);
2377 TypeFunction *tf2 = (TypeFunction *)m->lastf->type;
2378 assert(tf2->ty == Tfunction);
2379 MATCH c1 = tf1->callMatch(tthis_fd, fargs);
2380 MATCH c2 = tf2->callMatch(tthis_best, fargs);
2381 //printf("2: c1 = %d, c2 = %d\n", c1, c2);
2382 if (c1 > c2) goto Ltd;
2383 if (c1 < c2) goto Ltd_best;
2384 }
2385 {
2386 // Disambiguate by picking the most specialized FunctionDeclaration
2387 MATCH c1 = fd->leastAsSpecialized(m->lastf);
2388 MATCH c2 = m->lastf->leastAsSpecialized(fd);
2389 //printf("3: c1 = %d, c2 = %d\n", c1, c2);
2390 if (c1 > c2) goto Ltd;
2391 if (c1 < c2) goto Ltd_best;
2392 }
2393
2394 // Bugzilla 14450: Prefer exact qualified constructor for the creating object type
2395 if (isCtorCall && fd->type->mod != m->lastf->type->mod)
2396 {
2397 if (tthis->mod == fd->type->mod) goto Ltd;
2398 if (tthis->mod == m->lastf->type->mod) goto Ltd_best;
2399 }
2400
2401 m->nextf = fd;
2402 m->count++;
2403 continue;
2404
2405 Ltd_best: // td_best is the best match so far
2406 //printf("Ltd_best\n");
2407 continue;
2408
2409 Ltd: // td is the new best match
2410 //printf("Ltd\n");
2411 assert(td->_scope);
2412 td_best = td;
2413 ti_best = ti;
2414 property = 0; // (backward compatibility)
2415 ta_last = mta;
2416 m->last = mfa;
2417 m->lastf = fd;
2418 tthis_best = tthis_fd;
2419 ov_index = ovi;
2420 m->nextf = NULL;
2421 m->count = 1;
2422 continue;
2423 }
2424 return 0;
2425 }
2426 };
2427 ParamDeduce p;
2428 // context
2429 p.loc = loc;
2430 p.sc = sc;
2431 p.tthis = tthis;
2432 p.tiargs = tiargs;
2433 p.fargs = fargs;
2434
2435 // result
2436 p.m = m;
2437 p.property = 0;
2438 p.ov_index = 0;
2439 p.td_best = NULL;
2440 p.ti_best = NULL;
2441 p.ta_last = m->last != MATCHnomatch ? MATCHexact : MATCHnomatch;
2442 p.tthis_best = NULL;
2443
2444 TemplateDeclaration *td = dstart->isTemplateDeclaration();
2445 if (td && td->funcroot)
2446 dstart = td->funcroot;
2447
2448 overloadApply(dstart, &p, &ParamDeduce::fp);
2449
2450 //printf("td_best = %p, m->lastf = %p\n", p.td_best, m->lastf);
2451 if (p.td_best && p.ti_best && m->count == 1)
2452 {
2453 // Matches to template function
2454 assert(p.td_best->onemember && p.td_best->onemember->isFuncDeclaration());
2455
2456 /* The best match is td_best with arguments tdargs.
2457 * Now instantiate the template.
2458 */
2459 assert(p.td_best->_scope);
2460 if (!sc)
2461 sc = p.td_best->_scope; // workaround for Type::aliasthisOf
2462
2463 TemplateInstance *ti = new TemplateInstance(loc, p.td_best, p.ti_best->tiargs);
2464 templateInstanceSemantic(ti, sc, fargs);
2465
2466 m->lastf = ti->toAlias()->isFuncDeclaration();
2467 if (!m->lastf)
2468 goto Lnomatch;
2469 if (ti->errors)
2470 {
2471 Lerror:
2472 m->count = 1;
2473 assert(m->lastf);
2474 m->last = MATCHnomatch;
2475 return;
2476 }
2477
2478 // look forward instantiated overload function
2479 // Dsymbol::oneMembers is alredy called in TemplateInstance::semantic.
2480 // it has filled overnext0d
2481 while (p.ov_index--)
2482 {
2483 m->lastf = m->lastf->overnext0;
2484 assert(m->lastf);
2485 }
2486
2487 p.tthis_best = m->lastf->needThis() && !m->lastf->isCtorDeclaration() ? tthis : NULL;
2488
2489 TypeFunction *tf = (TypeFunction *)m->lastf->type;
2490 if (tf->ty == Terror)
2491 goto Lerror;
2492 assert(tf->ty == Tfunction);
2493 if (!tf->callMatch(p.tthis_best, fargs))
2494 goto Lnomatch;
2495
2496 /* As Bugzilla 3682 shows, a template instance can be matched while instantiating
2497 * that same template. Thus, the function type can be incomplete. Complete it.
2498 *
2499 * Bugzilla 9208: For auto function, completion should be deferred to the end of
2500 * its semantic3. Should not complete it in here.
2501 */
2502 if (tf->next && !m->lastf->inferRetType)
2503 {
2504 m->lastf->type = typeSemantic(tf, loc, sc);
2505 }
2506 }
2507 else if (m->lastf)
2508 {
2509 // Matches to non template function,
2510 // or found matches were ambiguous.
2511 assert(m->count >= 1);
2512 }
2513 else
2514 {
2515 Lnomatch:
2516 m->count = 0;
2517 m->lastf = NULL;
2518 m->last = MATCHnomatch;
2519 }
2520 }
2521
2522 /*************************************************
2523 * Limited function template instantiation for using fd->leastAsSpecialized()
2524 */
2525 FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(
2526 TemplateInstance *ti, Scope *sc2,
2527 FuncDeclaration *fd, Type *tthis, Expressions *fargs)
2528 {
2529 assert(fd);
2530
2531 // function body and contracts are not need
2532 if (fd->isCtorDeclaration())
2533 fd = new CtorDeclaration(fd->loc, fd->endloc, fd->storage_class, fd->type->syntaxCopy());
2534 else
2535 fd = new FuncDeclaration(fd->loc, fd->endloc, fd->ident, fd->storage_class, fd->type->syntaxCopy());
2536 fd->parent = ti;
2537
2538 assert(fd->type->ty == Tfunction);
2539 TypeFunction *tf = (TypeFunction *)fd->type;
2540 tf->fargs = fargs;
2541
2542 if (tthis)
2543 {
2544 // Match 'tthis' to any TemplateThisParameter's
2545 bool hasttp = false;
2546 for (size_t i = 0; i < parameters->length; i++)
2547 {
2548 TemplateParameter *tp = (*parameters)[i];
2549 TemplateThisParameter *ttp = tp->isTemplateThisParameter();
2550 if (ttp)
2551 hasttp = true;
2552 }
2553 if (hasttp)
2554 {
2555 tf = (TypeFunction *)tf->addSTC(ModToStc(tthis->mod));
2556 assert(!tf->deco);
2557 }
2558 }
2559
2560 Scope *scx = sc2->push();
2561
2562 // Shouldn't run semantic on default arguments and return type.
2563 for (size_t i = 0; i < tf->parameterList.parameters->length; i++)
2564 (*tf->parameterList.parameters)[i]->defaultArg = NULL;
2565 if (fd->isCtorDeclaration())
2566 {
2567 // For constructors, emitting return type is necessary for
2568 // isolateReturn() in functionResolve.
2569 scx->flags |= SCOPEctor;
2570
2571 Dsymbol *parent = toParent2();
2572 Type *tret;
2573 AggregateDeclaration *ad = parent->isAggregateDeclaration();
2574 if (!ad || parent->isUnionDeclaration())
2575 {
2576 tret = Type::tvoid;
2577 }
2578 else
2579 {
2580 tret = ad->handleType();
2581 assert(tret);
2582 tret = tret->addStorageClass(fd->storage_class | scx->stc);
2583 tret = tret->addMod(tf->mod);
2584 }
2585 tf->next = tret;
2586 if (ad && ad->isStructDeclaration())
2587 tf->isref = 1;
2588 //printf("tf = %s\n", tf->toChars());
2589 }
2590 else
2591 tf->next = NULL;
2592 fd->type = tf;
2593 fd->type = fd->type->addSTC(scx->stc);
2594 fd->type = typeSemantic(fd->type, fd->loc, scx);
2595 scx = scx->pop();
2596
2597 if (fd->type->ty != Tfunction)
2598 return NULL;
2599
2600 fd->originalType = fd->type; // for mangling
2601 //printf("\t[%s] fd->type = %s, mod = %x, ", loc.toChars(), fd->type->toChars(), fd->type->mod);
2602 //printf("fd->needThis() = %d\n", fd->needThis());
2603
2604 return fd;
2605 }
2606
2607 bool TemplateDeclaration::hasStaticCtorOrDtor()
2608 {
2609 return false; // don't scan uninstantiated templates
2610 }
2611
2612 const char *TemplateDeclaration::toChars()
2613 {
2614 if (literal)
2615 return Dsymbol::toChars();
2616
2617 OutBuffer buf;
2618 HdrGenState hgs;
2619
2620 buf.writestring(ident->toChars());
2621 buf.writeByte('(');
2622 for (size_t i = 0; i < parameters->length; i++)
2623 {
2624 TemplateParameter *tp = (*parameters)[i];
2625 if (i)
2626 buf.writestring(", ");
2627 ::toCBuffer(tp, &buf, &hgs);
2628 }
2629 buf.writeByte(')');
2630
2631 if (onemember)
2632 {
2633 FuncDeclaration *fd = onemember->isFuncDeclaration();
2634 if (fd && fd->type)
2635 {
2636 TypeFunction *tf = (TypeFunction *)fd->type;
2637 buf.writestring(parametersTypeToChars(tf->parameterList));
2638 }
2639 }
2640
2641 if (constraint)
2642 {
2643 buf.writestring(" if (");
2644 ::toCBuffer(constraint, &buf, &hgs);
2645 buf.writeByte(')');
2646 }
2647 return buf.extractChars();
2648 }
2649
2650 Prot TemplateDeclaration::prot()
2651 {
2652 return protection;
2653 }
2654
2655 /****************************************************
2656 * Given a new instance tithis of this TemplateDeclaration,
2657 * see if there already exists an instance.
2658 * If so, return that existing instance.
2659 */
2660
2661 TemplateInstance *TemplateDeclaration::findExistingInstance(TemplateInstance *tithis, Expressions *fargs)
2662 {
2663 //printf("findExistingInstance(%p)\n", tithis);
2664 tithis->fargs = fargs;
2665 TemplateInstances *tinstances = (TemplateInstances *)dmd_aaGetRvalue((AA *)instances, (void *)tithis->toHash());
2666 if (tinstances)
2667 {
2668 for (size_t i = 0; i < tinstances->length; i++)
2669 {
2670 TemplateInstance *ti = (*tinstances)[i];
2671 if (tithis->compare(ti) == 0)
2672 return ti;
2673 }
2674 }
2675 return NULL;
2676 }
2677
2678 /********************************************
2679 * Add instance ti to TemplateDeclaration's table of instances.
2680 * Return a handle we can use to later remove it if it fails instantiation.
2681 */
2682
2683 TemplateInstance *TemplateDeclaration::addInstance(TemplateInstance *ti)
2684 {
2685 //printf("addInstance() %p %p\n", instances, ti);
2686 TemplateInstances **ptinstances = (TemplateInstances **)dmd_aaGet((AA **)&instances, (void *)ti->toHash());
2687 if (!*ptinstances)
2688 *ptinstances = new TemplateInstances();
2689 (*ptinstances)->push(ti);
2690 return ti;
2691 }
2692
2693 /*******************************************
2694 * Remove TemplateInstance from table of instances.
2695 * Input:
2696 * handle returned by addInstance()
2697 */
2698
2699 void TemplateDeclaration::removeInstance(TemplateInstance *handle)
2700 {
2701 //printf("removeInstance()\n");
2702 TemplateInstances *tinstances = (TemplateInstances *)dmd_aaGetRvalue((AA *)instances, (void *)handle->toHash());
2703 if (tinstances)
2704 {
2705 for (size_t i = 0; i < tinstances->length; i++)
2706 {
2707 TemplateInstance *ti = (*tinstances)[i];
2708 if (handle == ti)
2709 {
2710 tinstances->remove(i);
2711 break;
2712 }
2713 }
2714 }
2715 }
2716
2717 /* ======================== Type ============================================ */
2718
2719 /****
2720 * Given an identifier, figure out which TemplateParameter it is.
2721 * Return IDX_NOTFOUND if not found.
2722 */
2723
2724 static size_t templateIdentifierLookup(Identifier *id, TemplateParameters *parameters)
2725 {
2726 for (size_t i = 0; i < parameters->length; i++)
2727 {
2728 TemplateParameter *tp = (*parameters)[i];
2729 if (tp->ident->equals(id))
2730 return i;
2731 }
2732 return IDX_NOTFOUND;
2733 }
2734
2735 size_t templateParameterLookup(Type *tparam, TemplateParameters *parameters)
2736 {
2737 if (tparam->ty == Tident)
2738 {
2739 TypeIdentifier *tident = (TypeIdentifier *)tparam;
2740 //printf("\ttident = '%s'\n", tident->toChars());
2741 return templateIdentifierLookup(tident->ident, parameters);
2742 }
2743 return IDX_NOTFOUND;
2744 }
2745
2746 unsigned char deduceWildHelper(Type *t, Type **at, Type *tparam)
2747 {
2748 if ((tparam->mod & MODwild) == 0)
2749 return 0;
2750
2751 *at = NULL;
2752
2753 #define X(U,T) ((U) << 4) | (T)
2754 switch (X(tparam->mod, t->mod))
2755 {
2756 case X(MODwild, 0):
2757 case X(MODwild, MODconst):
2758 case X(MODwild, MODshared):
2759 case X(MODwild, MODshared | MODconst):
2760 case X(MODwild, MODimmutable):
2761 case X(MODwildconst, 0):
2762 case X(MODwildconst, MODconst):
2763 case X(MODwildconst, MODshared):
2764 case X(MODwildconst, MODshared | MODconst):
2765 case X(MODwildconst, MODimmutable):
2766 case X(MODshared | MODwild, MODshared):
2767 case X(MODshared | MODwild, MODshared | MODconst):
2768 case X(MODshared | MODwild, MODimmutable):
2769 case X(MODshared | MODwildconst, MODshared):
2770 case X(MODshared | MODwildconst, MODshared | MODconst):
2771 case X(MODshared | MODwildconst, MODimmutable):
2772 {
2773 unsigned char wm = (t->mod & ~MODshared);
2774 if (wm == 0)
2775 wm = MODmutable;
2776 unsigned char m = (t->mod & (MODconst | MODimmutable)) | (tparam->mod & t->mod & MODshared);
2777 *at = t->unqualify(m);
2778 return wm;
2779 }
2780
2781 case X(MODwild, MODwild):
2782 case X(MODwild, MODwildconst):
2783 case X(MODwild, MODshared | MODwild):
2784 case X(MODwild, MODshared | MODwildconst):
2785 case X(MODwildconst, MODwild):
2786 case X(MODwildconst, MODwildconst):
2787 case X(MODwildconst, MODshared | MODwild):
2788 case X(MODwildconst, MODshared | MODwildconst):
2789 case X(MODshared | MODwild, MODshared | MODwild):
2790 case X(MODshared | MODwild, MODshared | MODwildconst):
2791 case X(MODshared | MODwildconst, MODshared | MODwild):
2792 case X(MODshared | MODwildconst, MODshared | MODwildconst):
2793 {
2794 *at = t->unqualify(tparam->mod & t->mod);
2795 return MODwild;
2796 }
2797
2798 default:
2799 return 0;
2800 }
2801 #undef X
2802 }
2803
2804 MATCH deduceTypeHelper(Type *t, Type **at, Type *tparam)
2805 {
2806 // 9*9 == 81 cases
2807
2808 #define X(U,T) ((U) << 4) | (T)
2809 switch (X(tparam->mod, t->mod))
2810 {
2811 case X(0, 0):
2812 case X(0, MODconst):
2813 case X(0, MODwild):
2814 case X(0, MODwildconst):
2815 case X(0, MODshared):
2816 case X(0, MODshared | MODconst):
2817 case X(0, MODshared | MODwild):
2818 case X(0, MODshared | MODwildconst):
2819 case X(0, MODimmutable):
2820 // foo(U) T => T
2821 // foo(U) const(T) => const(T)
2822 // foo(U) inout(T) => inout(T)
2823 // foo(U) inout(const(T)) => inout(const(T))
2824 // foo(U) shared(T) => shared(T)
2825 // foo(U) shared(const(T)) => shared(const(T))
2826 // foo(U) shared(inout(T)) => shared(inout(T))
2827 // foo(U) shared(inout(const(T))) => shared(inout(const(T)))
2828 // foo(U) immutable(T) => immutable(T)
2829 {
2830 *at = t;
2831 return MATCHexact;
2832 }
2833
2834 case X(MODconst, MODconst):
2835 case X(MODwild, MODwild):
2836 case X(MODwildconst, MODwildconst):
2837 case X(MODshared, MODshared):
2838 case X(MODshared | MODconst, MODshared | MODconst):
2839 case X(MODshared | MODwild, MODshared | MODwild):
2840 case X(MODshared | MODwildconst, MODshared | MODwildconst):
2841 case X(MODimmutable, MODimmutable):
2842 // foo(const(U)) const(T) => T
2843 // foo(inout(U)) inout(T) => T
2844 // foo(inout(const(U))) inout(const(T)) => T
2845 // foo(shared(U)) shared(T) => T
2846 // foo(shared(const(U))) shared(const(T)) => T
2847 // foo(shared(inout(U))) shared(inout(T)) => T
2848 // foo(shared(inout(const(U)))) shared(inout(const(T))) => T
2849 // foo(immutable(U)) immutable(T) => T
2850 {
2851 *at = t->mutableOf()->unSharedOf();
2852 return MATCHexact;
2853 }
2854
2855 case X(MODconst, 0):
2856 case X(MODconst, MODwild):
2857 case X(MODconst, MODwildconst):
2858 case X(MODconst, MODshared | MODconst):
2859 case X(MODconst, MODshared | MODwild):
2860 case X(MODconst, MODshared | MODwildconst):
2861 case X(MODconst, MODimmutable):
2862 case X(MODwild, MODshared | MODwild):
2863 case X(MODwildconst, MODshared | MODwildconst):
2864 case X(MODshared | MODconst, MODimmutable):
2865 // foo(const(U)) T => T
2866 // foo(const(U)) inout(T) => T
2867 // foo(const(U)) inout(const(T)) => T
2868 // foo(const(U)) shared(const(T)) => shared(T)
2869 // foo(const(U)) shared(inout(T)) => shared(T)
2870 // foo(const(U)) shared(inout(const(T))) => shared(T)
2871 // foo(const(U)) immutable(T) => T
2872 // foo(inout(U)) shared(inout(T)) => shared(T)
2873 // foo(inout(const(U))) shared(inout(const(T))) => shared(T)
2874 // foo(shared(const(U))) immutable(T) => T
2875 {
2876 *at = t->mutableOf();
2877 return MATCHconst;
2878 }
2879
2880 case X(MODconst, MODshared):
2881 // foo(const(U)) shared(T) => shared(T)
2882 {
2883 *at = t;
2884 return MATCHconst;
2885 }
2886
2887 case X(MODshared, MODshared | MODconst):
2888 case X(MODshared, MODshared | MODwild):
2889 case X(MODshared, MODshared | MODwildconst):
2890 case X(MODshared | MODconst, MODshared):
2891 // foo(shared(U)) shared(const(T)) => const(T)
2892 // foo(shared(U)) shared(inout(T)) => inout(T)
2893 // foo(shared(U)) shared(inout(const(T))) => inout(const(T))
2894 // foo(shared(const(U))) shared(T) => T
2895 {
2896 *at = t->unSharedOf();
2897 return MATCHconst;
2898 }
2899
2900 case X(MODwildconst, MODimmutable):
2901 case X(MODshared | MODconst, MODshared | MODwildconst):
2902 case X(MODshared | MODwildconst, MODimmutable):
2903 case X(MODshared | MODwildconst, MODshared | MODwild):
2904 // foo(inout(const(U))) immutable(T) => T
2905 // foo(shared(const(U))) shared(inout(const(T))) => T
2906 // foo(shared(inout(const(U)))) immutable(T) => T
2907 // foo(shared(inout(const(U)))) shared(inout(T)) => T
2908 {
2909 *at = t->unSharedOf()->mutableOf();
2910 return MATCHconst;
2911 }
2912
2913 case X(MODshared | MODconst, MODshared | MODwild):
2914 // foo(shared(const(U))) shared(inout(T)) => T
2915 {
2916 *at = t->unSharedOf()->mutableOf();
2917 return MATCHconst;
2918 }
2919
2920 case X(MODwild, 0):
2921 case X(MODwild, MODconst):
2922 case X(MODwild, MODwildconst):
2923 case X(MODwild, MODimmutable):
2924 case X(MODwild, MODshared):
2925 case X(MODwild, MODshared | MODconst):
2926 case X(MODwild, MODshared | MODwildconst):
2927 case X(MODwildconst, 0):
2928 case X(MODwildconst, MODconst):
2929 case X(MODwildconst, MODwild):
2930 case X(MODwildconst, MODshared):
2931 case X(MODwildconst, MODshared | MODconst):
2932 case X(MODwildconst, MODshared | MODwild):
2933 case X(MODshared, 0):
2934 case X(MODshared, MODconst):
2935 case X(MODshared, MODwild):
2936 case X(MODshared, MODwildconst):
2937 case X(MODshared, MODimmutable):
2938 case X(MODshared | MODconst, 0):
2939 case X(MODshared | MODconst, MODconst):
2940 case X(MODshared | MODconst, MODwild):
2941 case X(MODshared | MODconst, MODwildconst):
2942 case X(MODshared | MODwild, 0):
2943 case X(MODshared | MODwild, MODconst):
2944 case X(MODshared | MODwild, MODwild):
2945 case X(MODshared | MODwild, MODwildconst):
2946 case X(MODshared | MODwild, MODimmutable):
2947 case X(MODshared | MODwild, MODshared):
2948 case X(MODshared | MODwild, MODshared | MODconst):
2949 case X(MODshared | MODwild, MODshared | MODwildconst):
2950 case X(MODshared | MODwildconst, 0):
2951 case X(MODshared | MODwildconst, MODconst):
2952 case X(MODshared | MODwildconst, MODwild):
2953 case X(MODshared | MODwildconst, MODwildconst):
2954 case X(MODshared | MODwildconst, MODshared):
2955 case X(MODshared | MODwildconst, MODshared | MODconst):
2956 case X(MODimmutable, 0):
2957 case X(MODimmutable, MODconst):
2958 case X(MODimmutable, MODwild):
2959 case X(MODimmutable, MODwildconst):
2960 case X(MODimmutable, MODshared):
2961 case X(MODimmutable, MODshared | MODconst):
2962 case X(MODimmutable, MODshared | MODwild):
2963 case X(MODimmutable, MODshared | MODwildconst):
2964 // foo(inout(U)) T => nomatch
2965 // foo(inout(U)) const(T) => nomatch
2966 // foo(inout(U)) inout(const(T)) => nomatch
2967 // foo(inout(U)) immutable(T) => nomatch
2968 // foo(inout(U)) shared(T) => nomatch
2969 // foo(inout(U)) shared(const(T)) => nomatch
2970 // foo(inout(U)) shared(inout(const(T))) => nomatch
2971 // foo(inout(const(U))) T => nomatch
2972 // foo(inout(const(U))) const(T) => nomatch
2973 // foo(inout(const(U))) inout(T) => nomatch
2974 // foo(inout(const(U))) shared(T) => nomatch
2975 // foo(inout(const(U))) shared(const(T)) => nomatch
2976 // foo(inout(const(U))) shared(inout(T)) => nomatch
2977 // foo(shared(U)) T => nomatch
2978 // foo(shared(U)) const(T) => nomatch
2979 // foo(shared(U)) inout(T) => nomatch
2980 // foo(shared(U)) inout(const(T)) => nomatch
2981 // foo(shared(U)) immutable(T) => nomatch
2982 // foo(shared(const(U))) T => nomatch
2983 // foo(shared(const(U))) const(T) => nomatch
2984 // foo(shared(const(U))) inout(T) => nomatch
2985 // foo(shared(const(U))) inout(const(T)) => nomatch
2986 // foo(shared(inout(U))) T => nomatch
2987 // foo(shared(inout(U))) const(T) => nomatch
2988 // foo(shared(inout(U))) inout(T) => nomatch
2989 // foo(shared(inout(U))) inout(const(T)) => nomatch
2990 // foo(shared(inout(U))) immutable(T) => nomatch
2991 // foo(shared(inout(U))) shared(T) => nomatch
2992 // foo(shared(inout(U))) shared(const(T)) => nomatch
2993 // foo(shared(inout(U))) shared(inout(const(T))) => nomatch
2994 // foo(shared(inout(const(U)))) T => nomatch
2995 // foo(shared(inout(const(U)))) const(T) => nomatch
2996 // foo(shared(inout(const(U)))) inout(T) => nomatch
2997 // foo(shared(inout(const(U)))) inout(const(T)) => nomatch
2998 // foo(shared(inout(const(U)))) shared(T) => nomatch
2999 // foo(shared(inout(const(U)))) shared(const(T)) => nomatch
3000 // foo(immutable(U)) T => nomatch
3001 // foo(immutable(U)) const(T) => nomatch
3002 // foo(immutable(U)) inout(T) => nomatch
3003 // foo(immutable(U)) inout(const(T)) => nomatch
3004 // foo(immutable(U)) shared(T) => nomatch
3005 // foo(immutable(U)) shared(const(T)) => nomatch
3006 // foo(immutable(U)) shared(inout(T)) => nomatch
3007 // foo(immutable(U)) shared(inout(const(T))) => nomatch
3008 return MATCHnomatch;
3009
3010 default:
3011 assert(0);
3012 return MATCHnomatch; // silence compiler warning about missing return
3013 }
3014 #undef X
3015 }
3016
3017 /* These form the heart of template argument deduction.
3018 * Given 'this' being the type argument to the template instance,
3019 * it is matched against the template declaration parameter specialization
3020 * 'tparam' to determine the type to be used for the parameter.
3021 * Example:
3022 * template Foo(T:T*) // template declaration
3023 * Foo!(int*) // template instantiation
3024 * Input:
3025 * this = int*
3026 * tparam = T*
3027 * parameters = [ T:T* ] // Array of TemplateParameter's
3028 * Output:
3029 * dedtypes = [ int ] // Array of Expression/Type's
3030 */
3031 MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *parameters,
3032 Objects *dedtypes, unsigned *wm, size_t inferStart)
3033 {
3034 class DeduceType : public Visitor
3035 {
3036 public:
3037 Scope *sc;
3038 Type *tparam;
3039 TemplateParameters *parameters;
3040 Objects *dedtypes;
3041 unsigned *wm;
3042 size_t inferStart;
3043 MATCH result;
3044
3045 DeduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm, size_t inferStart)
3046 : sc(sc), tparam(tparam), parameters(parameters), dedtypes(dedtypes), wm(wm), inferStart(inferStart)
3047 {
3048 result = MATCHnomatch;
3049 }
3050
3051 void visit(Type *t)
3052 {
3053 if (!tparam)
3054 goto Lnomatch;
3055
3056 if (t == tparam)
3057 goto Lexact;
3058
3059 if (tparam->ty == Tident)
3060 {
3061 // Determine which parameter tparam is
3062 size_t i = templateParameterLookup(tparam, parameters);
3063 if (i == IDX_NOTFOUND)
3064 {
3065 if (!sc)
3066 goto Lnomatch;
3067
3068 /* Need a loc to go with the semantic routine.
3069 */
3070 Loc loc;
3071 if (parameters->length)
3072 {
3073 TemplateParameter *tp = (*parameters)[0];
3074 loc = tp->loc;
3075 }
3076
3077 /* BUG: what if tparam is a template instance, that
3078 * has as an argument another Tident?
3079 */
3080 tparam = typeSemantic(tparam, loc, sc);
3081 assert(tparam->ty != Tident);
3082 result = deduceType(t, sc, tparam, parameters, dedtypes, wm);
3083 return;
3084 }
3085
3086 TemplateParameter *tp = (*parameters)[i];
3087
3088 TypeIdentifier *tident = (TypeIdentifier *)tparam;
3089 if (tident->idents.length > 0)
3090 {
3091 //printf("matching %s to %s\n", tparam->toChars(), t->toChars());
3092 Dsymbol *s = t->toDsymbol(sc);
3093 for (size_t j = tident->idents.length; j-- > 0; )
3094 {
3095 RootObject *id = tident->idents[j];
3096 if (id->dyncast() == DYNCAST_IDENTIFIER)
3097 {
3098 if (!s || !s->parent)
3099 goto Lnomatch;
3100 Dsymbol *s2 = s->parent->search(Loc(), (Identifier *)id);
3101 if (!s2)
3102 goto Lnomatch;
3103 s2 = s2->toAlias();
3104 //printf("[%d] s = %s %s, s2 = %s %s\n", j, s->kind(), s->toChars(), s2->kind(), s2->toChars());
3105 if (s != s2)
3106 {
3107 if (Type *tx = s2->getType())
3108 {
3109 if (s != tx->toDsymbol(sc))
3110 goto Lnomatch;
3111 }
3112 else
3113 goto Lnomatch;
3114 }
3115 s = s->parent;
3116 }
3117 else
3118 goto Lnomatch;
3119 }
3120 //printf("[e] s = %s\n", s?s->toChars():"(null)");
3121 if (tp->isTemplateTypeParameter())
3122 {
3123 Type *tt = s->getType();
3124 if (!tt)
3125 goto Lnomatch;
3126 Type *at = (Type *)(*dedtypes)[i];
3127 if (at && at->ty == Tnone)
3128 at = ((TypeDeduced *)at)->tded;
3129 if (!at || tt->equals(at))
3130 {
3131 (*dedtypes)[i] = tt;
3132 goto Lexact;
3133 }
3134 }
3135 if (tp->isTemplateAliasParameter())
3136 {
3137 Dsymbol *s2 = (Dsymbol *)(*dedtypes)[i];
3138 if (!s2 || s == s2)
3139 {
3140 (*dedtypes)[i] = s;
3141 goto Lexact;
3142 }
3143 }
3144 goto Lnomatch;
3145 }
3146
3147 // Found the corresponding parameter tp
3148 if (!tp->isTemplateTypeParameter())
3149 goto Lnomatch;
3150
3151 Type *at = (Type *)(*dedtypes)[i];
3152 Type *tt;
3153 if (unsigned char wx = wm ? deduceWildHelper(t, &tt, tparam) : 0)
3154 {
3155 // type vs (none)
3156 if (!at)
3157 {
3158 (*dedtypes)[i] = tt;
3159 *wm |= wx;
3160 result = MATCHconst;
3161 return;
3162 }
3163
3164 // type vs expressions
3165 if (at->ty == Tnone)
3166 {
3167 TypeDeduced *xt = (TypeDeduced *)at;
3168 result = xt->matchAll(tt);
3169 if (result > MATCHnomatch)
3170 {
3171 (*dedtypes)[i] = tt;
3172 if (result > MATCHconst)
3173 result = MATCHconst; // limit level for inout matches
3174 delete xt;
3175 }
3176 return;
3177 }
3178
3179 // type vs type
3180 if (tt->equals(at))
3181 {
3182 (*dedtypes)[i] = tt; // Prefer current type match
3183 goto Lconst;
3184 }
3185 if (tt->implicitConvTo(at->constOf()))
3186 {
3187 (*dedtypes)[i] = at->constOf()->mutableOf();
3188 *wm |= MODconst;
3189 goto Lconst;
3190 }
3191 if (at->implicitConvTo(tt->constOf()))
3192 {
3193 (*dedtypes)[i] = tt->constOf()->mutableOf();
3194 *wm |= MODconst;
3195 goto Lconst;
3196 }
3197 goto Lnomatch;
3198 }
3199 else if (MATCH m = deduceTypeHelper(t, &tt, tparam))
3200 {
3201 // type vs (none)
3202 if (!at)
3203 {
3204 (*dedtypes)[i] = tt;
3205 result = m;
3206 return;
3207 }
3208
3209 // type vs expressions
3210 if (at->ty == Tnone)
3211 {
3212 TypeDeduced *xt = (TypeDeduced *)at;
3213 result = xt->matchAll(tt);
3214 if (result > MATCHnomatch)
3215 {
3216 (*dedtypes)[i] = tt;
3217 delete xt;
3218 }
3219 return;
3220 }
3221
3222 // type vs type
3223 if (tt->equals(at))
3224 {
3225 goto Lexact;
3226 }
3227 if (tt->ty == Tclass && at->ty == Tclass)
3228 {
3229 result = tt->implicitConvTo(at);
3230 return;
3231 }
3232 if (tt->ty == Tsarray && at->ty == Tarray &&
3233 tt->nextOf()->implicitConvTo(at->nextOf()) >= MATCHconst)
3234 {
3235 goto Lexact;
3236 }
3237 }
3238 goto Lnomatch;
3239 }
3240
3241 if (tparam->ty == Ttypeof)
3242 {
3243 /* Need a loc to go with the semantic routine.
3244 */
3245 Loc loc;
3246 if (parameters->length)
3247 {
3248 TemplateParameter *tp = (*parameters)[0];
3249 loc = tp->loc;
3250 }
3251
3252 tparam = typeSemantic(tparam, loc, sc);
3253 }
3254 if (t->ty != tparam->ty)
3255 {
3256 if (Dsymbol *sym = t->toDsymbol(sc))
3257 {
3258 if (sym->isforwardRef() && !tparam->deco)
3259 goto Lnomatch;
3260 }
3261
3262 MATCH m = t->implicitConvTo(tparam);
3263 if (m == MATCHnomatch)
3264 {
3265 if (t->ty == Tclass)
3266 {
3267 TypeClass *tc = (TypeClass *)t;
3268 if (tc->sym->aliasthis && !(tc->att & RECtracingDT))
3269 {
3270 tc->att = (AliasThisRec)(tc->att | RECtracingDT);
3271 m = deduceType(t->aliasthisOf(), sc, tparam, parameters, dedtypes, wm);
3272 tc->att = (AliasThisRec)(tc->att & ~RECtracingDT);
3273 }
3274 }
3275 else if (t->ty == Tstruct)
3276 {
3277 TypeStruct *ts = (TypeStruct *)t;
3278 if (ts->sym->aliasthis && !(ts->att & RECtracingDT))
3279 {
3280 ts->att = (AliasThisRec)(ts->att | RECtracingDT);
3281 m = deduceType(t->aliasthisOf(), sc, tparam, parameters, dedtypes, wm);
3282 ts->att = (AliasThisRec)(ts->att & ~RECtracingDT);
3283 }
3284 }
3285 }
3286 result = m;
3287 return;
3288 }
3289
3290 if (t->nextOf())
3291 {
3292 if (tparam->deco && !tparam->hasWild())
3293 {
3294 result = t->implicitConvTo(tparam);
3295 return;
3296 }
3297
3298 Type *tpn = tparam->nextOf();
3299 if (wm && t->ty == Taarray && tparam->isWild())
3300 {
3301 // Bugzilla 12403: In IFTI, stop inout matching on transitive part of AA types.
3302 tpn = tpn->substWildTo(MODmutable);
3303 }
3304
3305 result = deduceType(t->nextOf(), sc, tpn, parameters, dedtypes, wm);
3306 return;
3307 }
3308
3309 Lexact:
3310 result = MATCHexact;
3311 return;
3312
3313 Lnomatch:
3314 result = MATCHnomatch;
3315 return;
3316
3317 Lconst:
3318 result = MATCHconst;
3319 }
3320
3321 void visit(TypeVector *t)
3322 {
3323 if (tparam->ty == Tvector)
3324 {
3325 TypeVector *tp = (TypeVector *)tparam;
3326 result = deduceType(t->basetype, sc, tp->basetype, parameters, dedtypes, wm);
3327 return;
3328 }
3329 visit((Type *)t);
3330 }
3331
3332 void visit(TypeDArray *t)
3333 {
3334 visit((Type *)t);
3335 }
3336
3337 void visit(TypeSArray *t)
3338 {
3339 // Extra check that array dimensions must match
3340 if (tparam)
3341 {
3342 if (tparam->ty == Tarray)
3343 {
3344 MATCH m = deduceType(t->next, sc, tparam->nextOf(), parameters, dedtypes, wm);
3345 result = (m >= MATCHconst) ? MATCHconvert : MATCHnomatch;
3346 return;
3347 }
3348
3349 TemplateParameter *tp = NULL;
3350 Expression *edim = NULL;
3351 size_t i;
3352 if (tparam->ty == Tsarray)
3353 {
3354 TypeSArray *tsa = (TypeSArray *)tparam;
3355 if (tsa->dim->op == TOKvar &&
3356 ((VarExp *)tsa->dim)->var->storage_class & STCtemplateparameter)
3357 {
3358 Identifier *id = ((VarExp *)tsa->dim)->var->ident;
3359 i = templateIdentifierLookup(id, parameters);
3360 assert(i != IDX_NOTFOUND);
3361 tp = (*parameters)[i];
3362 }
3363 else
3364 edim = tsa->dim;
3365 }
3366 else if (tparam->ty == Taarray)
3367 {
3368 TypeAArray *taa = (TypeAArray *)tparam;
3369 i = templateParameterLookup(taa->index, parameters);
3370 if (i != IDX_NOTFOUND)
3371 tp = (*parameters)[i];
3372 else
3373 {
3374 Expression *e;
3375 Type *tx;
3376 Dsymbol *s;
3377 taa->index->resolve(Loc(), sc, &e, &tx, &s);
3378 edim = s ? getValue(s) : getValue(e);
3379 }
3380 }
3381 if ((tp && tp->matchArg(sc, t->dim, i, parameters, dedtypes, NULL)) ||
3382 (edim && edim->toInteger() == t->dim->toInteger()))
3383 {
3384 result = deduceType(t->next, sc, tparam->nextOf(), parameters, dedtypes, wm);
3385 return;
3386 }
3387 }
3388 visit((Type *)t);
3389 return;
3390
3391 result = MATCHnomatch;
3392 }
3393
3394 void visit(TypeAArray *t)
3395 {
3396 // Extra check that index type must match
3397 if (tparam && tparam->ty == Taarray)
3398 {
3399 TypeAArray *tp = (TypeAArray *)tparam;
3400 if (!deduceType(t->index, sc, tp->index, parameters, dedtypes))
3401 {
3402 result = MATCHnomatch;
3403 return;
3404 }
3405 }
3406 visit((Type *)t);
3407 }
3408
3409 void visit(TypeFunction *t)
3410 {
3411 //printf("TypeFunction::deduceType()\n");
3412 //printf("\tthis = %d, ", t->ty); t->print();
3413 //printf("\ttparam = %d, ", tparam->ty); tparam->print();
3414
3415 // Extra check that function characteristics must match
3416 if (tparam && tparam->ty == Tfunction)
3417 {
3418 TypeFunction *tp = (TypeFunction *)tparam;
3419 if (t->parameterList.varargs != tp->parameterList.varargs ||
3420 t->linkage != tp->linkage)
3421 {
3422 result = MATCHnomatch;
3423 return;
3424 }
3425
3426 size_t nfargs = t->parameterList.length();
3427 size_t nfparams = tp->parameterList.length();
3428
3429 // bug 2579 fix: Apply function parameter storage classes to parameter types
3430 for (size_t i = 0; i < nfparams; i++)
3431 {
3432 Parameter *fparam = tp->parameterList[i];
3433 fparam->type = fparam->type->addStorageClass(fparam->storageClass);
3434 fparam->storageClass &= ~(STC_TYPECTOR | STCin);
3435 }
3436 //printf("\t-> this = %d, ", t->ty); t->print();
3437 //printf("\t-> tparam = %d, ", tparam->ty); tparam->print();
3438
3439 /* See if tuple match
3440 */
3441 if (nfparams > 0 && nfargs >= nfparams - 1)
3442 {
3443 /* See if 'A' of the template parameter matches 'A'
3444 * of the type of the last function parameter.
3445 */
3446 Parameter *fparam = tp->parameterList[nfparams - 1];
3447 assert(fparam);
3448 assert(fparam->type);
3449 if (fparam->type->ty != Tident)
3450 goto L1;
3451 TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
3452 if (tid->idents.length)
3453 goto L1;
3454
3455 /* Look through parameters to find tuple matching tid->ident
3456 */
3457 size_t tupi = 0;
3458 for (; 1; tupi++)
3459 {
3460 if (tupi == parameters->length)
3461 goto L1;
3462 TemplateParameter *tx = (*parameters)[tupi];
3463 TemplateTupleParameter *tup = tx->isTemplateTupleParameter();
3464 if (tup && tup->ident->equals(tid->ident))
3465 break;
3466 }
3467
3468 /* The types of the function arguments [nfparams - 1 .. nfargs]
3469 * now form the tuple argument.
3470 */
3471 size_t tuple_dim = nfargs - (nfparams - 1);
3472
3473 /* See if existing tuple, and whether it matches or not
3474 */
3475 RootObject *o = (*dedtypes)[tupi];
3476 if (o)
3477 {
3478 // Existing deduced argument must be a tuple, and must match
3479 Tuple *tup = isTuple(o);
3480 if (!tup || tup->objects.length != tuple_dim)
3481 {
3482 result = MATCHnomatch;
3483 return;
3484 }
3485 for (size_t i = 0; i < tuple_dim; i++)
3486 {
3487 Parameter *arg = t->parameterList[nfparams - 1 + i];
3488 if (!arg->type->equals(tup->objects[i]))
3489 {
3490 result = MATCHnomatch;
3491 return;
3492 }
3493 }
3494 }
3495 else
3496 {
3497 // Create new tuple
3498 Tuple *tup = new Tuple();
3499 tup->objects.setDim(tuple_dim);
3500 for (size_t i = 0; i < tuple_dim; i++)
3501 {
3502 Parameter *arg = t->parameterList[nfparams - 1 + i];
3503 tup->objects[i] = arg->type;
3504 }
3505 (*dedtypes)[tupi] = tup;
3506 }
3507 nfparams--; // don't consider the last parameter for type deduction
3508 goto L2;
3509 }
3510
3511 L1:
3512 if (nfargs != nfparams)
3513 {
3514 result = MATCHnomatch;
3515 return;
3516 }
3517 L2:
3518 for (size_t i = 0; i < nfparams; i++)
3519 {
3520 Parameter *a = t->parameterList[i];
3521 Parameter *ap = tp->parameterList[i];
3522
3523 if (!a->isCovariant(t->isref, ap) ||
3524 !deduceType(a->type, sc, ap->type, parameters, dedtypes))
3525 {
3526 result = MATCHnomatch;
3527 return;
3528 }
3529 }
3530 }
3531 visit((Type *)t);
3532 }
3533
3534 void visit(TypeIdentifier *t)
3535 {
3536 // Extra check
3537 if (tparam && tparam->ty == Tident)
3538 {
3539 TypeIdentifier *tp = (TypeIdentifier *)tparam;
3540
3541 for (size_t i = 0; i < t->idents.length; i++)
3542 {
3543 RootObject *id1 = t->idents[i];
3544 RootObject *id2 = tp->idents[i];
3545
3546 if (!id1->equals(id2))
3547 {
3548 result = MATCHnomatch;
3549 return;
3550 }
3551 }
3552 }
3553 visit((Type *)t);
3554 }
3555
3556 void visit(TypeInstance *t)
3557 {
3558 // Extra check
3559 if (tparam && tparam->ty == Tinstance && t->tempinst->tempdecl)
3560 {
3561 TemplateDeclaration *tempdecl = t->tempinst->tempdecl->isTemplateDeclaration();
3562 assert(tempdecl);
3563
3564 TypeInstance *tp = (TypeInstance *)tparam;
3565
3566 //printf("tempinst->tempdecl = %p\n", tempdecl);
3567 //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl);
3568 if (!tp->tempinst->tempdecl)
3569 {
3570 //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars());
3571
3572 /* Handle case of:
3573 * template Foo(T : sa!(T), alias sa)
3574 */
3575 size_t i = templateIdentifierLookup(tp->tempinst->name, parameters);
3576 if (i == IDX_NOTFOUND)
3577 {
3578 /* Didn't find it as a parameter identifier. Try looking
3579 * it up and seeing if is an alias. See Bugzilla 1454
3580 */
3581 TypeIdentifier *tid = new TypeIdentifier(tp->loc, tp->tempinst->name);
3582 Type *tx;
3583 Expression *e;
3584 Dsymbol *s;
3585 tid->resolve(tp->loc, sc, &e, &tx, &s);
3586 if (tx)
3587 {
3588 s = tx->toDsymbol(sc);
3589 if (TemplateInstance *ti = s ? s->parent->isTemplateInstance() : NULL)
3590 {
3591 // Bugzilla 14290: Try to match with ti->tempecl,
3592 // only when ti is an enclosing instance.
3593 Dsymbol *p = sc->parent;
3594 while (p && p != ti)
3595 p = p->parent;
3596 if (p)
3597 s = ti->tempdecl;
3598 }
3599 }
3600 if (s)
3601 {
3602 s = s->toAlias();
3603 TemplateDeclaration *td = s->isTemplateDeclaration();
3604 if (td)
3605 {
3606 if (td->overroot)
3607 td = td->overroot;
3608 for (; td; td = td->overnext)
3609 {
3610 if (td == tempdecl)
3611 goto L2;
3612 }
3613 }
3614 }
3615 goto Lnomatch;
3616 }
3617 TemplateParameter *tpx = (*parameters)[i];
3618 if (!tpx->matchArg(sc, tempdecl, i, parameters, dedtypes, NULL))
3619 goto Lnomatch;
3620 }
3621 else if (tempdecl != tp->tempinst->tempdecl)
3622 goto Lnomatch;
3623
3624 L2:
3625
3626 for (size_t i = 0; 1; i++)
3627 {
3628 //printf("\ttest: tempinst->tiargs[%d]\n", i);
3629 RootObject *o1 = NULL;
3630 if (i < t->tempinst->tiargs->length)
3631 o1 = (*t->tempinst->tiargs)[i];
3632 else if (i < t->tempinst->tdtypes.length && i < tp->tempinst->tiargs->length)
3633 {
3634 // Pick up default arg
3635 o1 = t->tempinst->tdtypes[i];
3636 }
3637 else if (i >= tp->tempinst->tiargs->length)
3638 break;
3639
3640 if (i >= tp->tempinst->tiargs->length)
3641 {
3642 size_t dim = tempdecl->parameters->length - (tempdecl->isVariadic() ? 1 : 0);
3643 while (i < dim && ((*tempdecl->parameters)[i]->dependent ||
3644 (*tempdecl->parameters)[i]->hasDefaultArg()))
3645 {
3646 i++;
3647 }
3648 if (i >= dim)
3649 break; // match if all remained parameters are dependent
3650 goto Lnomatch;
3651 }
3652
3653 RootObject *o2 = (*tp->tempinst->tiargs)[i];
3654 Type *t2 = isType(o2);
3655
3656 size_t j = (t2 && t2->ty == Tident && i == tp->tempinst->tiargs->length - 1)
3657 ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
3658 if (j != IDX_NOTFOUND && j == parameters->length - 1 &&
3659 (*parameters)[j]->isTemplateTupleParameter())
3660 {
3661 /* Given:
3662 * struct A(B...) {}
3663 * alias A!(int, float) X;
3664 * static if (is(X Y == A!(Z), Z...)) {}
3665 * deduce that Z is a tuple(int, float)
3666 */
3667
3668 /* Create tuple from remaining args
3669 */
3670 Tuple *vt = new Tuple();
3671 size_t vtdim = (tempdecl->isVariadic()
3672 ? t->tempinst->tiargs->length : t->tempinst->tdtypes.length) - i;
3673 vt->objects.setDim(vtdim);
3674 for (size_t k = 0; k < vtdim; k++)
3675 {
3676 RootObject *o;
3677 if (k < t->tempinst->tiargs->length)
3678 o = (*t->tempinst->tiargs)[i + k];
3679 else // Pick up default arg
3680 o = t->tempinst->tdtypes[i + k];
3681 vt->objects[k] = o;
3682 }
3683
3684 Tuple *v = (Tuple *)(*dedtypes)[j];
3685 if (v)
3686 {
3687 if (!match(v, vt))
3688 goto Lnomatch;
3689 }
3690 else
3691 (*dedtypes)[j] = vt;
3692 break;
3693 }
3694 else if (!o1)
3695 break;
3696
3697 Type *t1 = isType(o1);
3698 Dsymbol *s1 = isDsymbol(o1);
3699 Dsymbol *s2 = isDsymbol(o2);
3700 Expression *e1 = s1 ? getValue(s1) : getValue(isExpression(o1));
3701 Expression *e2 = isExpression(o2);
3702
3703 if (t1 && t2)
3704 {
3705 if (!deduceType(t1, sc, t2, parameters, dedtypes))
3706 goto Lnomatch;
3707 }
3708 else if (e1 && e2)
3709 {
3710 Le:
3711 e1 = e1->ctfeInterpret();
3712
3713 /* If it is one of the template parameters for this template,
3714 * we should not attempt to interpret it. It already has a value.
3715 */
3716 if (e2->op == TOKvar &&
3717 (((VarExp *)e2)->var->storage_class & STCtemplateparameter))
3718 {
3719 /*
3720 * (T:Number!(e2), int e2)
3721 */
3722 j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters);
3723 if (j != IDX_NOTFOUND)
3724 goto L1;
3725 // The template parameter was not from this template
3726 // (it may be from a parent template, for example)
3727 }
3728
3729 e2 = expressionSemantic(e2, sc); // Bugzilla 13417
3730 e2 = e2->ctfeInterpret();
3731
3732 //printf("e1 = %s, type = %s %d\n", e1->toChars(), e1->type->toChars(), e1->type->ty);
3733 //printf("e2 = %s, type = %s %d\n", e2->toChars(), e2->type->toChars(), e2->type->ty);
3734 if (!e1->equals(e2))
3735 {
3736 if (!e2->implicitConvTo(e1->type))
3737 goto Lnomatch;
3738
3739 e2 = e2->implicitCastTo(sc, e1->type);
3740 e2 = e2->ctfeInterpret();
3741 if (!e1->equals(e2))
3742 goto Lnomatch;
3743 }
3744 }
3745 else if (e1 && t2 && t2->ty == Tident)
3746 {
3747 j = templateParameterLookup(t2, parameters);
3748 L1:
3749 if (j == IDX_NOTFOUND)
3750 {
3751 t2->resolve(((TypeIdentifier *)t2)->loc, sc, &e2, &t2, &s2);
3752 if (e2)
3753 goto Le;
3754 goto Lnomatch;
3755 }
3756 if (!(*parameters)[j]->matchArg(sc, e1, j, parameters, dedtypes, NULL))
3757 goto Lnomatch;
3758 }
3759 else if (s1 && s2)
3760 {
3761 Ls:
3762 if (!s1->equals(s2))
3763 goto Lnomatch;
3764 }
3765 else if (s1 && t2 && t2->ty == Tident)
3766 {
3767 j = templateParameterLookup(t2, parameters);
3768 if (j == IDX_NOTFOUND)
3769 {
3770 t2->resolve(((TypeIdentifier *)t2)->loc, sc, &e2, &t2, &s2);
3771 if (s2)
3772 goto Ls;
3773 goto Lnomatch;
3774 }
3775 if (!(*parameters)[j]->matchArg(sc, s1, j, parameters, dedtypes, NULL))
3776 goto Lnomatch;
3777 }
3778 else
3779 goto Lnomatch;
3780 }
3781 }
3782 visit((Type *)t);
3783 return;
3784
3785 Lnomatch:
3786 //printf("no match\n");
3787 result = MATCHnomatch;
3788 }
3789
3790 void visit(TypeStruct *t)
3791 {
3792 /* If this struct is a template struct, and we're matching
3793 * it against a template instance, convert the struct type
3794 * to a template instance, too, and try again.
3795 */
3796 TemplateInstance *ti = t->sym->parent->isTemplateInstance();
3797
3798 if (tparam && tparam->ty == Tinstance)
3799 {
3800 if (ti && ti->toAlias() == t->sym)
3801 {
3802 TypeInstance *tx = new TypeInstance(Loc(), ti);
3803 result = deduceType(tx, sc, tparam, parameters, dedtypes, wm);
3804 return;
3805 }
3806
3807 /* Match things like:
3808 * S!(T).foo
3809 */
3810 TypeInstance *tpi = (TypeInstance *)tparam;
3811 if (tpi->idents.length)
3812 {
3813 RootObject *id = tpi->idents[tpi->idents.length - 1];
3814 if (id->dyncast() == DYNCAST_IDENTIFIER && t->sym->ident->equals((Identifier *)id))
3815 {
3816 Type *tparent = t->sym->parent->getType();
3817 if (tparent)
3818 {
3819 /* Slice off the .foo in S!(T).foo
3820 */
3821 tpi->idents.length--;
3822 result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm);
3823 tpi->idents.length++;
3824 return;
3825 }
3826 }
3827 }
3828 }
3829
3830 // Extra check
3831 if (tparam && tparam->ty == Tstruct)
3832 {
3833 TypeStruct *tp = (TypeStruct *)tparam;
3834
3835 //printf("\t%d\n", (MATCH) t->implicitConvTo(tp));
3836 if (wm && t->deduceWild(tparam, false))
3837 {
3838 result = MATCHconst;
3839 return;
3840 }
3841 result = t->implicitConvTo(tp);
3842 return;
3843 }
3844 visit((Type *)t);
3845 }
3846
3847 void visit(TypeEnum *t)
3848 {
3849 // Extra check
3850 if (tparam && tparam->ty == Tenum)
3851 {
3852 TypeEnum *tp = (TypeEnum *)tparam;
3853 if (t->sym == tp->sym)
3854 visit((Type *)t);
3855 else
3856 result = MATCHnomatch;
3857 return;
3858 }
3859 Type *tb = t->toBasetype();
3860 if (tb->ty == tparam->ty ||
3861 (tb->ty == Tsarray && tparam->ty == Taarray))
3862 {
3863 result = deduceType(tb, sc, tparam, parameters, dedtypes, wm);
3864 return;
3865 }
3866 visit((Type *)t);
3867 }
3868
3869 /* Helper for TypeClass::deduceType().
3870 * Classes can match with implicit conversion to a base class or interface.
3871 * This is complicated, because there may be more than one base class which
3872 * matches. In such cases, one or more parameters remain ambiguous.
3873 * For example,
3874 *
3875 * interface I(X, Y) {}
3876 * class C : I(uint, double), I(char, double) {}
3877 * C x;
3878 * foo(T, U)( I!(T, U) x)
3879 *
3880 * deduces that U is double, but T remains ambiguous (could be char or uint).
3881 *
3882 * Given a baseclass b, and initial deduced types 'dedtypes', this function
3883 * tries to match tparam with b, and also tries all base interfaces of b.
3884 * If a match occurs, numBaseClassMatches is incremented, and the new deduced
3885 * types are ANDed with the current 'best' estimate for dedtypes.
3886 */
3887 static void deduceBaseClassParameters(BaseClass *b,
3888 Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes,
3889 Objects *best, int &numBaseClassMatches)
3890 {
3891 TemplateInstance *parti = b->sym ? b->sym->parent->isTemplateInstance() : NULL;
3892 if (parti)
3893 {
3894 // Make a temporary copy of dedtypes so we don't destroy it
3895 Objects *tmpdedtypes = new Objects();
3896 tmpdedtypes->setDim(dedtypes->length);
3897 memcpy(tmpdedtypes->tdata(), dedtypes->tdata(), dedtypes->length * sizeof(void *));
3898
3899 TypeInstance *t = new TypeInstance(Loc(), parti);
3900 MATCH m = deduceType(t, sc, tparam, parameters, tmpdedtypes);
3901 if (m > MATCHnomatch)
3902 {
3903 // If this is the first ever match, it becomes our best estimate
3904 if (numBaseClassMatches==0)
3905 memcpy(best->tdata(), tmpdedtypes->tdata(), tmpdedtypes->length * sizeof(void *));
3906 else for (size_t k = 0; k < tmpdedtypes->length; ++k)
3907 {
3908 // If we've found more than one possible type for a parameter,
3909 // mark it as unknown.
3910 if ((*tmpdedtypes)[k] != (*best)[k])
3911 (*best)[k] = (*dedtypes)[k];
3912 }
3913 ++numBaseClassMatches;
3914 }
3915 }
3916 // Now recursively test the inherited interfaces
3917 for (size_t j = 0; j < b->baseInterfaces.length; ++j)
3918 {
3919 BaseClass *bi = &b->baseInterfaces.ptr[j];
3920 deduceBaseClassParameters(bi,
3921 sc, tparam, parameters, dedtypes,
3922 best, numBaseClassMatches);
3923 }
3924
3925 }
3926
3927 void visit(TypeClass *t)
3928 {
3929 //printf("TypeClass::deduceType(this = %s)\n", t->toChars());
3930
3931 /* If this class is a template class, and we're matching
3932 * it against a template instance, convert the class type
3933 * to a template instance, too, and try again.
3934 */
3935 TemplateInstance *ti = t->sym->parent->isTemplateInstance();
3936
3937 if (tparam && tparam->ty == Tinstance)
3938 {
3939 if (ti && ti->toAlias() == t->sym)
3940 {
3941 TypeInstance *tx = new TypeInstance(Loc(), ti);
3942 MATCH m = deduceType(tx, sc, tparam, parameters, dedtypes, wm);
3943 // Even if the match fails, there is still a chance it could match
3944 // a base class.
3945 if (m != MATCHnomatch)
3946 {
3947 result = m;
3948 return;
3949 }
3950 }
3951
3952 /* Match things like:
3953 * S!(T).foo
3954 */
3955 TypeInstance *tpi = (TypeInstance *)tparam;
3956 if (tpi->idents.length)
3957 {
3958 RootObject *id = tpi->idents[tpi->idents.length - 1];
3959 if (id->dyncast() == DYNCAST_IDENTIFIER && t->sym->ident->equals((Identifier *)id))
3960 {
3961 Type *tparent = t->sym->parent->getType();
3962 if (tparent)
3963 {
3964 /* Slice off the .foo in S!(T).foo
3965 */
3966 tpi->idents.length--;
3967 result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm);
3968 tpi->idents.length++;
3969 return;
3970 }
3971 }
3972 }
3973
3974 // If it matches exactly or via implicit conversion, we're done
3975 visit((Type *)t);
3976 if (result != MATCHnomatch)
3977 return;
3978
3979 /* There is still a chance to match via implicit conversion to
3980 * a base class or interface. Because there could be more than one such
3981 * match, we need to check them all.
3982 */
3983
3984 int numBaseClassMatches = 0; // Have we found an interface match?
3985
3986 // Our best guess at dedtypes
3987 Objects *best = new Objects();
3988 best->setDim(dedtypes->length);
3989
3990 ClassDeclaration *s = t->sym;
3991 while (s && s->baseclasses->length > 0)
3992 {
3993 // Test the base class
3994 deduceBaseClassParameters((*s->baseclasses)[0],
3995 sc, tparam, parameters, dedtypes,
3996 best, numBaseClassMatches);
3997
3998 // Test the interfaces inherited by the base class
3999 for (size_t i = 0; i < s->interfaces.length; ++i)
4000 {
4001 BaseClass *b = s->interfaces.ptr[i];
4002 deduceBaseClassParameters(b, sc, tparam, parameters, dedtypes,
4003 best, numBaseClassMatches);
4004 }
4005 s = (*s->baseclasses)[0]->sym;
4006 }
4007
4008 if (numBaseClassMatches == 0)
4009 {
4010 result = MATCHnomatch;
4011 return;
4012 }
4013
4014 // If we got at least one match, copy the known types into dedtypes
4015 memcpy(dedtypes->tdata(), best->tdata(), best->length * sizeof(void *));
4016 result = MATCHconvert;
4017 return;
4018 }
4019
4020 // Extra check
4021 if (tparam && tparam->ty == Tclass)
4022 {
4023 TypeClass *tp = (TypeClass *)tparam;
4024
4025 //printf("\t%d\n", (MATCH) t->implicitConvTo(tp));
4026 if (wm && t->deduceWild(tparam, false))
4027 {
4028 result = MATCHconst;
4029 return;
4030 }
4031 result = t->implicitConvTo(tp);
4032 return;
4033 }
4034 visit((Type *)t);
4035 }
4036
4037 void visit(Expression *e)
4038 {
4039 //printf("Expression::deduceType(e = %s)\n", e->toChars());
4040 size_t i = templateParameterLookup(tparam, parameters);
4041 if (i == IDX_NOTFOUND || ((TypeIdentifier *)tparam)->idents.length > 0)
4042 {
4043 if (e == emptyArrayElement && tparam->ty == Tarray)
4044 {
4045 Type *tn = ((TypeNext *)tparam)->next;
4046 result = deduceType(emptyArrayElement, sc, tn, parameters, dedtypes, wm);
4047 return;
4048 }
4049 e->type->accept(this);
4050 return;
4051 }
4052
4053 TemplateTypeParameter *tp = (*parameters)[i]->isTemplateTypeParameter();
4054 if (!tp)
4055 return; // nomatch
4056
4057 if (e == emptyArrayElement)
4058 {
4059 if ((*dedtypes)[i])
4060 {
4061 result = MATCHexact;
4062 return;
4063 }
4064 if (tp->defaultType)
4065 {
4066 tp->defaultType->accept(this);
4067 return;
4068 }
4069 }
4070
4071 Type *at = (Type *)(*dedtypes)[i];
4072 Type *tt;
4073 if (unsigned char wx = deduceWildHelper(e->type, &tt, tparam))
4074 {
4075 *wm |= wx;
4076 result = MATCHconst;
4077 }
4078 else if (MATCH m = deduceTypeHelper(e->type, &tt, tparam))
4079 {
4080 result = m;
4081 }
4082 else
4083 return; // nomatch
4084
4085 // expression vs (none)
4086 if (!at)
4087 {
4088 (*dedtypes)[i] = new TypeDeduced(tt, e, tparam);
4089 return;
4090 }
4091
4092 TypeDeduced *xt = NULL;
4093 if (at->ty == Tnone)
4094 {
4095 xt = (TypeDeduced *)at;
4096 at = xt->tded;
4097 }
4098
4099 // From previous matched expressions to current deduced type
4100 MATCH match1 = xt ? xt->matchAll(tt) : MATCHnomatch;
4101
4102 // From current expresssion to previous deduced type
4103 Type *pt = at->addMod(tparam->mod);
4104 if (*wm)
4105 pt = pt->substWildTo(*wm);
4106 MATCH match2 = e->implicitConvTo(pt);
4107
4108 if (match1 > MATCHnomatch && match2 > MATCHnomatch)
4109 {
4110 if (at->implicitConvTo(tt) <= MATCHnomatch)
4111 match1 = MATCHnomatch; // Prefer at
4112 else if (tt->implicitConvTo(at) <= MATCHnomatch)
4113 match2 = MATCHnomatch; // Prefer tt
4114 else if (tt->isTypeBasic() && tt->ty == at->ty && tt->mod != at->mod)
4115 {
4116 if (!tt->isMutable() && !at->isMutable())
4117 tt = tt->mutableOf()->addMod(MODmerge(tt->mod, at->mod));
4118 else if (tt->isMutable())
4119 {
4120 if (at->mod == 0) // Prefer unshared
4121 match1 = MATCHnomatch;
4122 else
4123 match2 = MATCHnomatch;
4124 }
4125 else if (at->isMutable())
4126 {
4127 if (tt->mod == 0) // Prefer unshared
4128 match2 = MATCHnomatch;
4129 else
4130 match1 = MATCHnomatch;
4131 }
4132 //printf("tt = %s, at = %s\n", tt->toChars(), at->toChars());
4133 }
4134 else
4135 {
4136 match1 = MATCHnomatch;
4137 match2 = MATCHnomatch;
4138 }
4139 }
4140 if (match1 > MATCHnomatch)
4141 {
4142 // Prefer current match: tt
4143 if (xt)
4144 xt->update(tt, e, tparam);
4145 else
4146 (*dedtypes)[i] = tt;
4147 result = match1;
4148 return;
4149 }
4150 if (match2 > MATCHnomatch)
4151 {
4152 // Prefer previous match: (*dedtypes)[i]
4153 if (xt)
4154 xt->update(e, tparam);
4155 result = match2;
4156 return;
4157 }
4158
4159 /* Deduce common type
4160 */
4161 if (Type *t = rawTypeMerge(at, tt))
4162 {
4163 if (xt)
4164 xt->update(t, e, tparam);
4165 else
4166 (*dedtypes)[i] = t;
4167
4168 pt = tt->addMod(tparam->mod);
4169 if (*wm)
4170 pt = pt->substWildTo(*wm);
4171 result = e->implicitConvTo(pt);
4172 return;
4173 }
4174
4175 result = MATCHnomatch;
4176 }
4177
4178 MATCH deduceEmptyArrayElement()
4179 {
4180 if (!emptyArrayElement)
4181 {
4182 emptyArrayElement = new IdentifierExp(Loc(), Id::p); // dummy
4183 emptyArrayElement->type = Type::tvoid;
4184 }
4185 assert(tparam->ty == Tarray);
4186
4187 Type *tn = ((TypeNext *)tparam)->next;
4188 return deduceType(emptyArrayElement, sc, tn, parameters, dedtypes, wm);
4189 }
4190
4191 void visit(NullExp *e)
4192 {
4193 if (tparam->ty == Tarray && e->type->ty == Tnull)
4194 {
4195 // tparam:T[] <- e:null (void[])
4196 result = deduceEmptyArrayElement();
4197 return;
4198 }
4199 visit((Expression *)e);
4200 }
4201
4202 void visit(StringExp *e)
4203 {
4204 Type *taai;
4205 if (e->type->ty == Tarray &&
4206 (tparam->ty == Tsarray ||
4207 (tparam->ty == Taarray && (taai = ((TypeAArray *)tparam)->index)->ty == Tident &&
4208 ((TypeIdentifier *)taai)->idents.length == 0)))
4209 {
4210 // Consider compile-time known boundaries
4211 e->type->nextOf()->sarrayOf(e->len)->accept(this);
4212 return;
4213 }
4214 visit((Expression *)e);
4215 }
4216
4217 void visit(ArrayLiteralExp *e)
4218 {
4219 // https://issues.dlang.org/show_bug.cgi?id=20092
4220 if (e->elements && e->elements->length &&
4221 e->type->toBasetype()->nextOf()->ty == Tvoid)
4222 {
4223 result = deduceEmptyArrayElement();
4224 return;
4225 }
4226 if ((!e->elements || !e->elements->length) &&
4227 e->type->toBasetype()->nextOf()->ty == Tvoid &&
4228 tparam->ty == Tarray)
4229 {
4230 // tparam:T[] <- e:[] (void[])
4231 result = deduceEmptyArrayElement();
4232 return;
4233 }
4234
4235 if (tparam->ty == Tarray && e->elements && e->elements->length)
4236 {
4237 Type *tn = ((TypeDArray *)tparam)->next;
4238 result = MATCHexact;
4239 if (e->basis)
4240 {
4241 MATCH m = deduceType(e->basis, sc, tn, parameters, dedtypes, wm);
4242 if (m < result)
4243 result = m;
4244 }
4245 for (size_t i = 0; i < e->elements->length; i++)
4246 {
4247 if (result <= MATCHnomatch)
4248 break;
4249 Expression *el = (*e->elements)[i];
4250 if (!el)
4251 continue;
4252 MATCH m = deduceType(el, sc, tn, parameters, dedtypes, wm);
4253 if (m < result)
4254 result = m;
4255 }
4256 return;
4257 }
4258
4259 Type *taai;
4260 if (e->type->ty == Tarray &&
4261 (tparam->ty == Tsarray ||
4262 (tparam->ty == Taarray && (taai = ((TypeAArray *)tparam)->index)->ty == Tident &&
4263 ((TypeIdentifier *)taai)->idents.length == 0)))
4264 {
4265 // Consider compile-time known boundaries
4266 e->type->nextOf()->sarrayOf(e->elements->length)->accept(this);
4267 return;
4268 }
4269 visit((Expression *)e);
4270 }
4271
4272 void visit(AssocArrayLiteralExp *e)
4273 {
4274 if (tparam->ty == Taarray && e->keys && e->keys->length)
4275 {
4276 TypeAArray *taa = (TypeAArray *)tparam;
4277 result = MATCHexact;
4278 for (size_t i = 0; i < e->keys->length; i++)
4279 {
4280 MATCH m1 = deduceType((*e->keys)[i], sc, taa->index, parameters, dedtypes, wm);
4281 if (m1 < result)
4282 result = m1;
4283 if (result <= MATCHnomatch)
4284 break;
4285 MATCH m2 = deduceType((*e->values)[i], sc, taa->next, parameters, dedtypes, wm);
4286 if (m2 < result)
4287 result = m2;
4288 if (result <= MATCHnomatch)
4289 break;
4290 }
4291 return;
4292 }
4293 visit((Expression *)e);
4294 }
4295
4296 void visit(FuncExp *e)
4297 {
4298 //printf("e->type = %s, tparam = %s\n", e->type->toChars(), tparam->toChars());
4299 if (e->td)
4300 {
4301 Type *to = tparam;
4302 if (!to->nextOf() || to->nextOf()->ty != Tfunction)
4303 return;
4304 TypeFunction *tof = (TypeFunction *)to->nextOf();
4305
4306 // Parameter types inference from 'tof'
4307 assert(e->td->_scope);
4308 TypeFunction *tf = (TypeFunction *)e->fd->type;
4309 //printf("\ttof = %s\n", tof->toChars());
4310 //printf("\ttf = %s\n", tf->toChars());
4311 size_t dim = tf->parameterList.length();
4312
4313 if (tof->parameterList.length() != dim ||
4314 tof->parameterList.varargs != tf->parameterList.varargs)
4315 return;
4316
4317 Objects *tiargs = new Objects();
4318 tiargs->reserve(e->td->parameters->length);
4319
4320 for (size_t i = 0; i < e->td->parameters->length; i++)
4321 {
4322 TemplateParameter *tp = (*e->td->parameters)[i];
4323 size_t u = 0;
4324 for (; u < dim; u++)
4325 {
4326 Parameter *p = tf->parameterList[u];
4327 if (p->type->ty == Tident &&
4328 ((TypeIdentifier *)p->type)->ident == tp->ident)
4329 {
4330 break;
4331 }
4332 }
4333 assert(u < dim);
4334 Parameter *pto = tof->parameterList[u];
4335 if (!pto)
4336 break;
4337 Type *t = pto->type->syntaxCopy(); // Bugzilla 11774
4338 if (reliesOnTident(t, parameters, inferStart))
4339 return;
4340 t = typeSemantic(t, e->loc, sc);
4341 if (t->ty == Terror)
4342 return;
4343 tiargs->push(t);
4344 }
4345
4346 // Set target of return type inference
4347 if (!tf->next && tof->next)
4348 e->fd->treq = tparam;
4349
4350 TemplateInstance *ti = new TemplateInstance(e->loc, e->td, tiargs);
4351 Expression *ex = new ScopeExp(e->loc, ti);
4352 ex = expressionSemantic(ex, e->td->_scope);
4353
4354 // Reset inference target for the later re-semantic
4355 e->fd->treq = NULL;
4356
4357 if (ex->op == TOKerror)
4358 return;
4359 if (ex->op != TOKfunction)
4360 return;
4361 visit(ex->type);
4362 return;
4363 }
4364
4365 Type *t = e->type;
4366
4367 if (t->ty == Tdelegate && tparam->ty == Tpointer)
4368 return;
4369
4370 // Allow conversion from implicit function pointer to delegate
4371 if (e->tok == TOKreserved &&
4372 t->ty == Tpointer && tparam->ty == Tdelegate)
4373 {
4374 TypeFunction *tf = (TypeFunction *)t->nextOf();
4375 t = (new TypeDelegate(tf))->merge();
4376 }
4377 //printf("tparam = %s <= e->type = %s, t = %s\n", tparam->toChars(), e->type->toChars(), t->toChars());
4378 visit(t);
4379 }
4380
4381 void visit(SliceExp *e)
4382 {
4383 Type *taai;
4384 if (e->type->ty == Tarray &&
4385 (tparam->ty == Tsarray ||
4386 (tparam->ty == Taarray && (taai = ((TypeAArray *)tparam)->index)->ty == Tident &&
4387 ((TypeIdentifier *)taai)->idents.length == 0)))
4388 {
4389 // Consider compile-time known boundaries
4390 if (Type *tsa = toStaticArrayType(e))
4391 {
4392 tsa->accept(this);
4393 return;
4394 }
4395 }
4396 visit((Expression *)e);
4397 }
4398
4399 void visit(CommaExp *e)
4400 {
4401 ((CommaExp *)e)->e2->accept(this);
4402 }
4403 };
4404
4405 DeduceType v(sc, tparam, parameters, dedtypes, wm, inferStart);
4406 if (Type *t = isType(o))
4407 t->accept(&v);
4408 else
4409 {
4410 assert(isExpression(o) && wm);
4411 ((Expression *)o)->accept(&v);
4412 }
4413 return v.result;
4414 }
4415
4416 /*******************************
4417 * Input:
4418 * t Tested type, if NULL, returns NULL.
4419 * tparams Optional template parameters.
4420 * == NULL:
4421 * If one of the subtypes of this type is a TypeIdentifier,
4422 * i.e. it's an unresolved type, return that type.
4423 * != NULL:
4424 * Only when the TypeIdentifier is one of template parameters,
4425 * return that type.
4426 */
4427
4428 bool reliesOnTident(Type *t, TemplateParameters *tparams, size_t iStart)
4429 {
4430 class ReliesOnTident : public Visitor
4431 {
4432 public:
4433 TemplateParameters *tparams;
4434 size_t iStart;
4435 bool result;
4436
4437 ReliesOnTident(TemplateParameters *tparams, size_t iStart)
4438 : tparams(tparams), iStart(iStart)
4439 {
4440 result = false;
4441 }
4442
4443 void visit(Type *)
4444 {
4445 }
4446
4447 void visit(TypeNext *t)
4448 {
4449 t->next->accept(this);
4450 }
4451
4452 void visit(TypeVector *t)
4453 {
4454 t->basetype->accept(this);
4455 }
4456
4457 void visit(TypeAArray *t)
4458 {
4459 visit((TypeNext *)t);
4460 if (!result)
4461 t->index->accept(this);
4462 }
4463
4464 void visit(TypeFunction *t)
4465 {
4466 size_t dim = t->parameterList.length();
4467 for (size_t i = 0; i < dim; i++)
4468 {
4469 Parameter *fparam = t->parameterList[i];
4470 fparam->type->accept(this);
4471 if (result)
4472 return;
4473 }
4474 if (t->next)
4475 t->next->accept(this);
4476 }
4477
4478 void visit(TypeIdentifier *t)
4479 {
4480 if (!tparams)
4481 {
4482 result = true;
4483 return;
4484 }
4485
4486 for (size_t i = iStart; i < tparams->length; i++)
4487 {
4488 TemplateParameter *tp = (*tparams)[i];
4489 if (tp->ident->equals(t->ident))
4490 {
4491 result = true;
4492 return;
4493 }
4494 }
4495 }
4496
4497 void visit(TypeInstance *t)
4498 {
4499 if (!tparams)
4500 return;
4501
4502 for (size_t i = iStart; i < tparams->length; i++)
4503 {
4504 TemplateParameter *tp = (*tparams)[i];
4505 if (t->tempinst->name == tp->ident)
4506 {
4507 result = true;
4508 return;
4509 }
4510 }
4511 if (!t->tempinst->tiargs)
4512 return;
4513 for (size_t i = 0; i < t->tempinst->tiargs->length; i++)
4514 {
4515 Type *ta = isType((*t->tempinst->tiargs)[i]);
4516 if (ta)
4517 {
4518 ta->accept(this);
4519 if (result)
4520 return;
4521 }
4522 }
4523 }
4524
4525 void visit(TypeTypeof *t)
4526 {
4527 //printf("TypeTypeof::reliesOnTident('%s')\n", t->toChars());
4528 t->exp->accept(this);
4529 }
4530
4531 void visit(TypeTuple *t)
4532 {
4533 if (t->arguments)
4534 {
4535 for (size_t i = 0; i < t->arguments->length; i++)
4536 {
4537 Parameter *arg = (*t->arguments)[i];
4538 arg->type->accept(this);
4539 if (result)
4540 return;
4541 }
4542 }
4543 }
4544
4545 void visit(Expression *)
4546 {
4547 //printf("Expression::reliesOnTident('%s')\n", e->toChars());
4548 }
4549
4550 void visit(IdentifierExp *e)
4551 {
4552 //printf("IdentifierExp::reliesOnTident('%s')\n", e->toChars());
4553 for (size_t i = iStart; i < tparams->length; i++)
4554 {
4555 TemplateParameter *tp = (*tparams)[i];
4556 if (e->ident == tp->ident)
4557 {
4558 result = true;
4559 return;
4560 }
4561 }
4562 }
4563
4564 void visit(TupleExp *e)
4565 {
4566 //printf("TupleExp::reliesOnTident('%s')\n", e->toChars());
4567 if (e->exps)
4568 {
4569 for (size_t i = 0; i < e->exps->length; i++)
4570 {
4571 Expression *ea = (*e->exps)[i];
4572 ea->accept(this);
4573 if (result)
4574 return;
4575 }
4576 }
4577 }
4578
4579 void visit(ArrayLiteralExp *e)
4580 {
4581 //printf("ArrayLiteralExp::reliesOnTident('%s')\n", e->toChars());
4582 if (e->elements)
4583 {
4584 for (size_t i = 0; i < e->elements->length; i++)
4585 {
4586 Expression *el = (*e->elements)[i];
4587 el->accept(this);
4588 if (result)
4589 return;
4590 }
4591 }
4592 }
4593
4594 void visit(AssocArrayLiteralExp *e)
4595 {
4596 //printf("AssocArrayLiteralExp::reliesOnTident('%s')\n", e->toChars());
4597 for (size_t i = 0; i < e->keys->length; i++)
4598 {
4599 Expression *ek = (*e->keys)[i];
4600 ek->accept(this);
4601 if (result)
4602 return;
4603 }
4604 for (size_t i = 0; i < e->values->length; i++)
4605 {
4606 Expression *ev = (*e->values)[i];
4607 ev->accept(this);
4608 if (result)
4609 return;
4610 }
4611 }
4612
4613 void visit(StructLiteralExp *e)
4614 {
4615 //printf("StructLiteralExp::reliesOnTident('%s')\n", e->toChars());
4616 if (e->elements)
4617 {
4618 for (size_t i = 0; i < e->elements->length; i++)
4619 {
4620 Expression *ea = (*e->elements)[i];
4621 ea->accept(this);
4622 if (result)
4623 return;
4624 }
4625 }
4626 }
4627
4628 void visit(TypeExp *e)
4629 {
4630 //printf("TypeExp::reliesOnTident('%s')\n", e->toChars());
4631 e->type->accept(this);
4632 }
4633
4634 void visit(NewExp *e)
4635 {
4636 //printf("NewExp::reliesOnTident('%s')\n", e->toChars());
4637 if (e->thisexp)
4638 e->thisexp->accept(this);
4639 if (!result && e->newargs)
4640 {
4641 for (size_t i = 0; i < e->newargs->length; i++)
4642 {
4643 Expression *ea = (*e->newargs)[i];
4644 ea->accept(this);
4645 if (result)
4646 return;
4647 }
4648 }
4649 e->newtype->accept(this);
4650 if (!result && e->arguments)
4651 {
4652 for (size_t i = 0; i < e->arguments->length; i++)
4653 {
4654 Expression *ea = (*e->arguments)[i];
4655 ea->accept(this);
4656 if (result)
4657 return;
4658 }
4659 }
4660 }
4661
4662 void visit(NewAnonClassExp *)
4663 {
4664 //printf("NewAnonClassExp::reliesOnTident('%s')\n", e->toChars());
4665 result = true;
4666 }
4667
4668 void visit(FuncExp *)
4669 {
4670 //printf("FuncExp::reliesOnTident('%s')\n", e->toChars());
4671 result = true;
4672 }
4673
4674 void visit(TypeidExp *e)
4675 {
4676 //printf("TypeidExp::reliesOnTident('%s')\n", e->toChars());
4677 if (Expression *ea = isExpression(e->obj))
4678 ea->accept(this);
4679 else if (Type *ta = isType(e->obj))
4680 ta->accept(this);
4681 }
4682
4683 void visit(TraitsExp *e)
4684 {
4685 //printf("TraitsExp::reliesOnTident('%s')\n", e->toChars());
4686 if (e->args)
4687 {
4688 for (size_t i = 0; i < e->args->length; i++)
4689 {
4690 RootObject *oa = (*e->args)[i];
4691 if (Expression *ea = isExpression(oa))
4692 ea->accept(this);
4693 else if (Type *ta = isType(oa))
4694 ta->accept(this);
4695 if (result)
4696 return;
4697 }
4698 }
4699 }
4700
4701 void visit(IsExp *e)
4702 {
4703 //printf("IsExp::reliesOnTident('%s')\n", e->toChars());
4704 e->targ->accept(this);
4705 }
4706
4707 void visit(UnaExp *e)
4708 {
4709 //printf("UnaExp::reliesOnTident('%s')\n", e->toChars());
4710 e->e1->accept(this);
4711 }
4712
4713 void visit(DotTemplateInstanceExp *e)
4714 {
4715 //printf("DotTemplateInstanceExp::reliesOnTident('%s')\n", e->toChars());
4716 visit((UnaExp *)e);
4717 if (!result && e->ti->tiargs)
4718 {
4719 for (size_t i = 0; i < e->ti->tiargs->length; i++)
4720 {
4721 RootObject *oa = (*e->ti->tiargs)[i];
4722 if (Expression *ea = isExpression(oa))
4723 ea->accept(this);
4724 else if (Type *ta = isType(oa))
4725 ta->accept(this);
4726 if (result)
4727 return;
4728 }
4729 }
4730 }
4731
4732 void visit(CallExp *e)
4733 {
4734 //printf("CallExp::reliesOnTident('%s')\n", e->toChars());
4735 visit((UnaExp *)e);
4736 if (!result && e->arguments)
4737 {
4738 for (size_t i = 0; i < e->arguments->length; i++)
4739 {
4740 Expression *ea = (*e->arguments)[i];
4741 ea->accept(this);
4742 if (result)
4743 return;
4744 }
4745 }
4746 }
4747
4748 void visit(CastExp *e)
4749 {
4750 //printf("CastExp::reliesOnTident('%s')\n", e->toChars());
4751 visit((UnaExp *)e);
4752 // e.to can be null for cast() with no type
4753 if (!result && e->to)
4754 e->to->accept(this);
4755 }
4756
4757 void visit(SliceExp *e)
4758 {
4759 //printf("SliceExp::reliesOnTident('%s')\n", e->toChars());
4760 visit((UnaExp *)e);
4761 if (!result && e->lwr)
4762 e->lwr->accept(this);
4763 if (!result && e->upr)
4764 e->upr->accept(this);
4765 }
4766
4767 void visit(IntervalExp *e)
4768 {
4769 //printf("IntervalExp::reliesOnTident('%s')\n", e->toChars());
4770 e->lwr->accept(this);
4771 if (!result)
4772 e->upr->accept(this);
4773 }
4774
4775 void visit(ArrayExp *e)
4776 {
4777 //printf("ArrayExp::reliesOnTident('%s')\n", e->toChars());
4778 visit((UnaExp *)e);
4779 if (!result && e->arguments)
4780 {
4781 for (size_t i = 0; i < e->arguments->length; i++)
4782 {
4783 Expression *ea = (*e->arguments)[i];
4784 ea->accept(this);
4785 }
4786 }
4787 }
4788
4789 void visit(BinExp *e)
4790 {
4791 //printf("BinExp::reliesOnTident('%s')\n", e->toChars());
4792 e->e1->accept(this);
4793 if (!result)
4794 e->e2->accept(this);
4795 }
4796
4797 void visit(CondExp *e)
4798 {
4799 //printf("BinExp::reliesOnTident('%s')\n", e->toChars());
4800 e->econd->accept(this);
4801 if (!result)
4802 visit((BinExp *)e);
4803 }
4804 };
4805
4806 if (!t)
4807 return false;
4808
4809 ReliesOnTident v(tparams, iStart);
4810 t->accept(&v);
4811 return v.result;
4812 }
4813
4814 /* ======================== TemplateParameter =============================== */
4815
4816 TemplateParameter::TemplateParameter(Loc loc, Identifier *ident)
4817 {
4818 this->loc = loc;
4819 this->ident = ident;
4820 this->dependent = false;
4821 }
4822
4823 TemplateTypeParameter *TemplateParameter::isTemplateTypeParameter()
4824 {
4825 return NULL;
4826 }
4827
4828 TemplateValueParameter *TemplateParameter::isTemplateValueParameter()
4829 {
4830 return NULL;
4831 }
4832
4833 TemplateAliasParameter *TemplateParameter::isTemplateAliasParameter()
4834 {
4835 return NULL;
4836 }
4837
4838 TemplateTupleParameter *TemplateParameter::isTemplateTupleParameter()
4839 {
4840 return NULL;
4841 }
4842
4843 TemplateThisParameter *TemplateParameter::isTemplateThisParameter()
4844 {
4845 return NULL;
4846 }
4847
4848 /*******************************************
4849 * Match to a particular TemplateParameter.
4850 * Input:
4851 * instLoc location that the template is instantiated.
4852 * tiargs[] actual arguments to template instance
4853 * i i'th argument
4854 * parameters[] template parameters
4855 * dedtypes[] deduced arguments to template instance
4856 * *psparam set to symbol declared and initialized to dedtypes[i]
4857 */
4858 MATCH TemplateParameter::matchArg(Loc instLoc, Scope *sc, Objects *tiargs,
4859 size_t i, TemplateParameters *parameters, Objects *dedtypes,
4860 Declaration **psparam)
4861 {
4862 RootObject *oarg;
4863
4864 if (i < tiargs->length)
4865 oarg = (*tiargs)[i];
4866 else
4867 {
4868 // Get default argument instead
4869 oarg = defaultArg(instLoc, sc);
4870 if (!oarg)
4871 {
4872 assert(i < dedtypes->length);
4873 // It might have already been deduced
4874 oarg = (*dedtypes)[i];
4875 if (!oarg)
4876 goto Lnomatch;
4877 }
4878 }
4879 return matchArg(sc, oarg, i, parameters, dedtypes, psparam);
4880
4881 Lnomatch:
4882 if (psparam)
4883 *psparam = NULL;
4884 return MATCHnomatch;
4885 }
4886
4887 /* ======================== TemplateTypeParameter =========================== */
4888
4889 // type-parameter
4890
4891 Type *TemplateTypeParameter::tdummy = NULL;
4892
4893 TemplateTypeParameter::TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType,
4894 Type *defaultType)
4895 : TemplateParameter(loc, ident)
4896 {
4897 this->ident = ident;
4898 this->specType = specType;
4899 this->defaultType = defaultType;
4900 }
4901
4902 TemplateTypeParameter *TemplateTypeParameter::isTemplateTypeParameter()
4903 {
4904 return this;
4905 }
4906
4907 TemplateParameter *TemplateTypeParameter::syntaxCopy()
4908 {
4909 return new TemplateTypeParameter(loc, ident,
4910 specType ? specType->syntaxCopy() : NULL,
4911 defaultType ? defaultType->syntaxCopy() : NULL);
4912 }
4913
4914 bool TemplateTypeParameter::declareParameter(Scope *sc)
4915 {
4916 //printf("TemplateTypeParameter::declareParameter('%s')\n", ident->toChars());
4917 TypeIdentifier *ti = new TypeIdentifier(loc, ident);
4918 Declaration *ad = new AliasDeclaration(loc, ident, ti);
4919 return sc->insert(ad) != NULL;
4920 }
4921
4922 MATCH TemplateTypeParameter::matchArg(Scope *sc, RootObject *oarg,
4923 size_t i, TemplateParameters *parameters, Objects *dedtypes,
4924 Declaration **psparam)
4925 {
4926 //printf("TemplateTypeParameter::matchArg('%s')\n", ident->toChars());
4927 MATCH m = MATCHexact;
4928 Type *ta = isType(oarg);
4929 if (!ta)
4930 {
4931 //printf("%s %p %p %p\n", oarg->toChars(), isExpression(oarg), isDsymbol(oarg), isTuple(oarg));
4932 goto Lnomatch;
4933 }
4934 //printf("ta is %s\n", ta->toChars());
4935
4936 if (specType)
4937 {
4938 if (!ta || ta == tdummy)
4939 goto Lnomatch;
4940
4941 //printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta->toChars(), specType->toChars());
4942 MATCH m2 = deduceType(ta, sc, specType, parameters, dedtypes);
4943 if (m2 <= MATCHnomatch)
4944 {
4945 //printf("\tfailed deduceType\n");
4946 goto Lnomatch;
4947 }
4948
4949 if (m2 < m)
4950 m = m2;
4951 if ((*dedtypes)[i])
4952 {
4953 Type *t = (Type *)(*dedtypes)[i];
4954
4955 if (dependent && !t->equals(ta)) // Bugzilla 14357
4956 goto Lnomatch;
4957
4958 /* This is a self-dependent parameter. For example:
4959 * template X(T : T*) {}
4960 * template X(T : S!T, alias S) {}
4961 */
4962 //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
4963 ta = t;
4964 }
4965 }
4966 else
4967 {
4968 if ((*dedtypes)[i])
4969 {
4970 // Must match already deduced type
4971 Type *t = (Type *)(*dedtypes)[i];
4972
4973 if (!t->equals(ta))
4974 {
4975 //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
4976 goto Lnomatch;
4977 }
4978 }
4979 else
4980 {
4981 // So that matches with specializations are better
4982 m = MATCHconvert;
4983 }
4984 }
4985 (*dedtypes)[i] = ta;
4986
4987 if (psparam)
4988 *psparam = new AliasDeclaration(loc, ident, ta);
4989 //printf("\tm = %d\n", m);
4990 return dependent ? MATCHexact : m;
4991
4992 Lnomatch:
4993 if (psparam)
4994 *psparam = NULL;
4995 //printf("\tm = %d\n", MATCHnomatch);
4996 return MATCHnomatch;
4997 }
4998
4999
5000 void TemplateTypeParameter::print(RootObject *oarg, RootObject *oded)
5001 {
5002 printf(" %s\n", ident->toChars());
5003
5004 Type *t = isType(oarg);
5005 Type *ta = isType(oded);
5006
5007 assert(ta);
5008
5009 if (specType)
5010 printf("\tSpecialization: %s\n", specType->toChars());
5011 if (defaultType)
5012 printf("\tDefault: %s\n", defaultType->toChars());
5013 printf("\tParameter: %s\n", t ? t->toChars() : "NULL");
5014 printf("\tDeduced Type: %s\n", ta->toChars());
5015 }
5016
5017 void *TemplateTypeParameter::dummyArg()
5018 {
5019 Type *t = specType;
5020 if (!t)
5021 {
5022 // Use this for alias-parameter's too (?)
5023 if (!tdummy)
5024 tdummy = new TypeIdentifier(loc, ident);
5025 t = tdummy;
5026 }
5027 return (void *)t;
5028 }
5029
5030
5031 RootObject *TemplateTypeParameter::specialization()
5032 {
5033 return specType;
5034 }
5035
5036 RootObject *TemplateTypeParameter::defaultArg(Loc, Scope *sc)
5037 {
5038 Type *t = defaultType;
5039 if (t)
5040 {
5041 t = t->syntaxCopy();
5042 t = typeSemantic(t, loc, sc); // use the parameter loc
5043 }
5044 return t;
5045 }
5046
5047 bool TemplateTypeParameter::hasDefaultArg()
5048 {
5049 return defaultType != NULL;
5050 }
5051
5052 /* ======================== TemplateThisParameter =========================== */
5053
5054 // this-parameter
5055
5056 TemplateThisParameter::TemplateThisParameter(Loc loc, Identifier *ident,
5057 Type *specType,
5058 Type *defaultType)
5059 : TemplateTypeParameter(loc, ident, specType, defaultType)
5060 {
5061 }
5062
5063 TemplateThisParameter *TemplateThisParameter::isTemplateThisParameter()
5064 {
5065 return this;
5066 }
5067
5068 TemplateParameter *TemplateThisParameter::syntaxCopy()
5069 {
5070 return new TemplateThisParameter(loc, ident,
5071 specType ? specType->syntaxCopy() : NULL,
5072 defaultType ? defaultType->syntaxCopy() : NULL);
5073 }
5074
5075 /* ======================== TemplateAliasParameter ========================== */
5076
5077 // alias-parameter
5078
5079 Dsymbol *TemplateAliasParameter::sdummy = NULL;
5080
5081 TemplateAliasParameter::TemplateAliasParameter(Loc loc, Identifier *ident,
5082 Type *specType, RootObject *specAlias, RootObject *defaultAlias)
5083 : TemplateParameter(loc, ident)
5084 {
5085 this->ident = ident;
5086 this->specType = specType;
5087 this->specAlias = specAlias;
5088 this->defaultAlias = defaultAlias;
5089 }
5090
5091 TemplateAliasParameter *TemplateAliasParameter::isTemplateAliasParameter()
5092 {
5093 return this;
5094 }
5095
5096 TemplateParameter *TemplateAliasParameter::syntaxCopy()
5097 {
5098 return new TemplateAliasParameter(loc, ident,
5099 specType ? specType->syntaxCopy() : NULL,
5100 objectSyntaxCopy(specAlias),
5101 objectSyntaxCopy(defaultAlias));
5102 }
5103
5104 bool TemplateAliasParameter::declareParameter(Scope *sc)
5105 {
5106 TypeIdentifier *ti = new TypeIdentifier(loc, ident);
5107 Declaration *ad = new AliasDeclaration(loc, ident, ti);
5108 return sc->insert(ad) != NULL;
5109 }
5110
5111 MATCH TemplateAliasParameter::matchArg(Scope *sc, RootObject *oarg,
5112 size_t i, TemplateParameters *parameters, Objects *dedtypes,
5113 Declaration **psparam)
5114 {
5115 //printf("TemplateAliasParameter::matchArg('%s')\n", ident->toChars());
5116 MATCH m = MATCHexact;
5117 Type *ta = isType(oarg);
5118 RootObject *sa = ta && !ta->deco ? NULL : getDsymbol(oarg);
5119 Expression *ea = isExpression(oarg);
5120 if (ea && (ea->op == TOKthis || ea->op == TOKsuper))
5121 sa = ((ThisExp *)ea)->var;
5122 else if (ea && ea->op == TOKscope)
5123 sa = ((ScopeExp *)ea)->sds;
5124 if (sa)
5125 {
5126 if (((Dsymbol *)sa)->isAggregateDeclaration())
5127 m = MATCHconvert;
5128
5129 /* specType means the alias must be a declaration with a type
5130 * that matches specType.
5131 */
5132 if (specType)
5133 {
5134 Declaration *d = ((Dsymbol *)sa)->isDeclaration();
5135 if (!d)
5136 goto Lnomatch;
5137 if (!d->type->equals(specType))
5138 goto Lnomatch;
5139 }
5140 }
5141 else
5142 {
5143 sa = oarg;
5144 if (ea)
5145 {
5146 if (specType)
5147 {
5148 if (!ea->type->equals(specType))
5149 goto Lnomatch;
5150 }
5151 }
5152 else if (ta && ta->ty == Tinstance && !specAlias)
5153 {
5154 /* Bugzilla xxxxx: Specialized parameter should be prefeerd
5155 * match to the template type parameter.
5156 * template X(alias a) {} // a == this
5157 * template X(alias a : B!A, alias B, A...) {} // B!A => ta
5158 */
5159 }
5160 else if (sa && sa == TemplateTypeParameter::tdummy)
5161 {
5162 /* Bugzilla 2025: Aggregate Types should preferentially
5163 * match to the template type parameter.
5164 * template X(alias a) {} // a == this
5165 * template X(T) {} // T => sa
5166 */
5167 }
5168 else
5169 goto Lnomatch;
5170 }
5171
5172 if (specAlias)
5173 {
5174 if (sa == sdummy)
5175 goto Lnomatch;
5176 Dsymbol *sx = isDsymbol(sa);
5177 if (sa != specAlias && sx)
5178 {
5179 Type *talias = isType(specAlias);
5180 if (!talias)
5181 goto Lnomatch;
5182
5183 TemplateInstance *ti = sx->isTemplateInstance();
5184 if (!ti && sx->parent)
5185 {
5186 ti = sx->parent->isTemplateInstance();
5187 if (ti && ti->name != sx->ident)
5188 goto Lnomatch;
5189 }
5190 if (!ti)
5191 goto Lnomatch;
5192
5193 Type *t = new TypeInstance(Loc(), ti);
5194 MATCH m2 = deduceType(t, sc, talias, parameters, dedtypes);
5195 if (m2 <= MATCHnomatch)
5196 goto Lnomatch;
5197 }
5198 }
5199 else if ((*dedtypes)[i])
5200 {
5201 // Must match already deduced symbol
5202 RootObject *si = (*dedtypes)[i];
5203 if (!sa || si != sa)
5204 goto Lnomatch;
5205 }
5206 (*dedtypes)[i] = sa;
5207
5208 if (psparam)
5209 {
5210 if (Dsymbol *s = isDsymbol(sa))
5211 {
5212 *psparam = new AliasDeclaration(loc, ident, s);
5213 }
5214 else if (Type *t = isType(sa))
5215 {
5216 *psparam = new AliasDeclaration(loc, ident, t);
5217 }
5218 else
5219 {
5220 assert(ea);
5221
5222 // Declare manifest constant
5223 Initializer *init = new ExpInitializer(loc, ea);
5224 VarDeclaration *v = new VarDeclaration(loc, NULL, ident, init);
5225 v->storage_class = STCmanifest;
5226 dsymbolSemantic(v, sc);
5227 *psparam = v;
5228 }
5229 }
5230 return dependent ? MATCHexact : m;
5231
5232 Lnomatch:
5233 if (psparam)
5234 *psparam = NULL;
5235 //printf("\tm = %d\n", MATCHnomatch);
5236 return MATCHnomatch;
5237 }
5238
5239
5240 void TemplateAliasParameter::print(RootObject *, RootObject *oded)
5241 {
5242 printf(" %s\n", ident->toChars());
5243
5244 Dsymbol *sa = isDsymbol(oded);
5245 assert(sa);
5246
5247 printf("\tParameter alias: %s\n", sa->toChars());
5248 }
5249
5250 void *TemplateAliasParameter::dummyArg()
5251 {
5252 RootObject *s = specAlias;
5253 if (!s)
5254 {
5255 if (!sdummy)
5256 sdummy = new Dsymbol();
5257 s = sdummy;
5258 }
5259 return (void*)s;
5260 }
5261
5262
5263 RootObject *TemplateAliasParameter::specialization()
5264 {
5265 return specAlias;
5266 }
5267
5268 RootObject *TemplateAliasParameter::defaultArg(Loc, Scope *sc)
5269 {
5270 RootObject *da = defaultAlias;
5271 Type *ta = isType(defaultAlias);
5272 if (ta)
5273 {
5274 if (ta->ty == Tinstance)
5275 {
5276 // If the default arg is a template, instantiate for each type
5277 da = ta->syntaxCopy();
5278 }
5279 }
5280
5281 RootObject *o = aliasParameterSemantic(loc, sc, da, NULL); // use the parameter loc
5282 return o;
5283 }
5284
5285 bool TemplateAliasParameter::hasDefaultArg()
5286 {
5287 return defaultAlias != NULL;
5288 }
5289
5290 /* ======================== TemplateValueParameter ========================== */
5291
5292 // value-parameter
5293
5294 AA *TemplateValueParameter::edummies = NULL;
5295
5296 TemplateValueParameter::TemplateValueParameter(Loc loc, Identifier *ident, Type *valType,
5297 Expression *specValue, Expression *defaultValue)
5298 : TemplateParameter(loc, ident)
5299 {
5300 this->ident = ident;
5301 this->valType = valType;
5302 this->specValue = specValue;
5303 this->defaultValue = defaultValue;
5304 }
5305
5306 TemplateValueParameter *TemplateValueParameter::isTemplateValueParameter()
5307 {
5308 return this;
5309 }
5310
5311 TemplateParameter *TemplateValueParameter::syntaxCopy()
5312 {
5313 return new TemplateValueParameter(loc, ident,
5314 valType->syntaxCopy(),
5315 specValue ? specValue->syntaxCopy() : NULL,
5316 defaultValue ? defaultValue->syntaxCopy() : NULL);
5317 }
5318
5319 bool TemplateValueParameter::declareParameter(Scope *sc)
5320 {
5321 VarDeclaration *v = new VarDeclaration(loc, valType, ident, NULL);
5322 v->storage_class = STCtemplateparameter;
5323 return sc->insert(v) != NULL;
5324 }
5325
5326 MATCH TemplateValueParameter::matchArg(Scope *sc, RootObject *oarg,
5327 size_t i, TemplateParameters *, Objects *dedtypes, Declaration **psparam)
5328 {
5329 //printf("TemplateValueParameter::matchArg('%s')\n", ident->toChars());
5330
5331 MATCH m = MATCHexact;
5332
5333 Expression *ei = isExpression(oarg);
5334 Type *vt;
5335
5336 if (!ei && oarg)
5337 {
5338 Dsymbol *si = isDsymbol(oarg);
5339 FuncDeclaration *f = si ? si->isFuncDeclaration() : NULL;
5340 if (!f || !f->fbody || f->needThis())
5341 goto Lnomatch;
5342
5343 ei = new VarExp(loc, f);
5344 ei = expressionSemantic(ei, sc);
5345
5346 /* If a function is really property-like, and then
5347 * it's CTFEable, ei will be a literal expression.
5348 */
5349 unsigned int olderrors = global.startGagging();
5350 ei = resolveProperties(sc, ei);
5351 ei = ei->ctfeInterpret();
5352 if (global.endGagging(olderrors) || ei->op == TOKerror)
5353 goto Lnomatch;
5354
5355 /* Bugzilla 14520: A property-like function can match to both
5356 * TemplateAlias and ValueParameter. But for template overloads,
5357 * it should always prefer alias parameter to be consistent
5358 * template match result.
5359 *
5360 * template X(alias f) { enum X = 1; }
5361 * template X(int val) { enum X = 2; }
5362 * int f1() { return 0; } // CTFEable
5363 * int f2(); // body-less function is not CTFEable
5364 * enum x1 = X!f1; // should be 1
5365 * enum x2 = X!f2; // should be 1
5366 *
5367 * e.g. The x1 value must be same even if the f1 definition will be moved
5368 * into di while stripping body code.
5369 */
5370 m = MATCHconvert;
5371 }
5372
5373 if (ei && ei->op == TOKvar)
5374 {
5375 // Resolve const variables that we had skipped earlier
5376 ei = ei->ctfeInterpret();
5377 }
5378
5379 //printf("\tvalType: %s, ty = %d\n", valType->toChars(), valType->ty);
5380 vt = typeSemantic(valType, loc, sc);
5381 //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars());
5382 //printf("vt = %s\n", vt->toChars());
5383
5384 if (ei->type)
5385 {
5386 MATCH m2 = ei->implicitConvTo(vt);
5387 //printf("m: %d\n", m);
5388 if (m2 < m)
5389 m = m2;
5390 if (m <= MATCHnomatch)
5391 goto Lnomatch;
5392 ei = ei->implicitCastTo(sc, vt);
5393 ei = ei->ctfeInterpret();
5394 }
5395
5396 if (specValue)
5397 {
5398 if (!ei || (Expression *)dmd_aaGetRvalue(edummies, (void *)ei->type) == ei)
5399 goto Lnomatch;
5400
5401 Expression *e = specValue;
5402
5403 sc = sc->startCTFE();
5404 e = expressionSemantic(e, sc);
5405 e = resolveProperties(sc, e);
5406 sc = sc->endCTFE();
5407 e = e->implicitCastTo(sc, vt);
5408 e = e->ctfeInterpret();
5409
5410 ei = ei->syntaxCopy();
5411 sc = sc->startCTFE();
5412 ei = expressionSemantic(ei, sc);
5413 sc = sc->endCTFE();
5414 ei = ei->implicitCastTo(sc, vt);
5415 ei = ei->ctfeInterpret();
5416 //printf("\tei: %s, %s\n", ei->toChars(), ei->type->toChars());
5417 //printf("\te : %s, %s\n", e->toChars(), e->type->toChars());
5418 if (!ei->equals(e))
5419 goto Lnomatch;
5420 }
5421 else
5422 {
5423 if ((*dedtypes)[i])
5424 {
5425 // Must match already deduced value
5426 Expression *e = (Expression *)(*dedtypes)[i];
5427
5428 if (!ei || !ei->equals(e))
5429 goto Lnomatch;
5430 }
5431 }
5432 (*dedtypes)[i] = ei;
5433
5434 if (psparam)
5435 {
5436 Initializer *init = new ExpInitializer(loc, ei);
5437 Declaration *sparam = new VarDeclaration(loc, vt, ident, init);
5438 sparam->storage_class = STCmanifest;
5439 *psparam = sparam;
5440 }
5441 return dependent ? MATCHexact : m;
5442
5443 Lnomatch:
5444 //printf("\tno match\n");
5445 if (psparam)
5446 *psparam = NULL;
5447 return MATCHnomatch;
5448 }
5449
5450
5451 void TemplateValueParameter::print(RootObject *, RootObject *oded)
5452 {
5453 printf(" %s\n", ident->toChars());
5454
5455 Expression *ea = isExpression(oded);
5456
5457 if (specValue)
5458 printf("\tSpecialization: %s\n", specValue->toChars());
5459 printf("\tParameter Value: %s\n", ea ? ea->toChars() : "NULL");
5460 }
5461
5462 void *TemplateValueParameter::dummyArg()
5463 {
5464 Expression *e = specValue;
5465 if (!e)
5466 {
5467 // Create a dummy value
5468 Expression **pe = (Expression **)dmd_aaGet(&edummies, (void *)valType);
5469 if (!*pe)
5470 *pe = valType->defaultInit();
5471 e = *pe;
5472 }
5473 return (void *)e;
5474 }
5475
5476
5477 RootObject *TemplateValueParameter::specialization()
5478 {
5479 return specValue;
5480 }
5481
5482 RootObject *TemplateValueParameter::defaultArg(Loc instLoc, Scope *sc)
5483 {
5484 Expression *e = defaultValue;
5485 if (e)
5486 {
5487 e = e->syntaxCopy();
5488 if ((e = expressionSemantic(e, sc)) == NULL)
5489 return NULL;
5490 if ((e = resolveProperties(sc, e)) == NULL)
5491 return NULL;
5492 e = e->resolveLoc(instLoc, sc); // use the instantiated loc
5493 e = e->optimize(WANTvalue);
5494 }
5495 return e;
5496 }
5497
5498 bool TemplateValueParameter::hasDefaultArg()
5499 {
5500 return defaultValue != NULL;
5501 }
5502
5503 /* ======================== TemplateTupleParameter ========================== */
5504
5505 // variadic-parameter
5506
5507 TemplateTupleParameter::TemplateTupleParameter(Loc loc, Identifier *ident)
5508 : TemplateParameter(loc, ident)
5509 {
5510 this->ident = ident;
5511 }
5512
5513 TemplateTupleParameter *TemplateTupleParameter::isTemplateTupleParameter()
5514 {
5515 return this;
5516 }
5517
5518 TemplateParameter *TemplateTupleParameter::syntaxCopy()
5519 {
5520 return new TemplateTupleParameter(loc, ident);
5521 }
5522
5523 bool TemplateTupleParameter::declareParameter(Scope *sc)
5524 {
5525 TypeIdentifier *ti = new TypeIdentifier(loc, ident);
5526 Declaration *ad = new AliasDeclaration(loc, ident, ti);
5527 return sc->insert(ad) != NULL;
5528 }
5529
5530 MATCH TemplateTupleParameter::matchArg(Loc, Scope *sc, Objects *tiargs,
5531 size_t i, TemplateParameters *parameters, Objects *dedtypes,
5532 Declaration **psparam)
5533 {
5534 /* The rest of the actual arguments (tiargs[]) form the match
5535 * for the variadic parameter.
5536 */
5537 assert(i + 1 == dedtypes->length); // must be the last one
5538 Tuple *ovar;
5539
5540 if (Tuple *u = isTuple((*dedtypes)[i]))
5541 {
5542 // It has already been deduced
5543 ovar = u;
5544 }
5545 else if (i + 1 == tiargs->length && isTuple((*tiargs)[i]))
5546 ovar = isTuple((*tiargs)[i]);
5547 else
5548 {
5549 ovar = new Tuple();
5550 //printf("ovar = %p\n", ovar);
5551 if (i < tiargs->length)
5552 {
5553 //printf("i = %d, tiargs->length = %d\n", i, tiargs->length);
5554 ovar->objects.setDim(tiargs->length - i);
5555 for (size_t j = 0; j < ovar->objects.length; j++)
5556 ovar->objects[j] = (*tiargs)[i + j];
5557 }
5558 }
5559 return matchArg(sc, ovar, i, parameters, dedtypes, psparam);
5560 }
5561
5562 MATCH TemplateTupleParameter::matchArg(Scope *, RootObject *oarg,
5563 size_t i, TemplateParameters *, Objects *dedtypes, Declaration **psparam)
5564 {
5565 //printf("TemplateTupleParameter::matchArg('%s')\n", ident->toChars());
5566 Tuple *ovar = isTuple(oarg);
5567 if (!ovar)
5568 return MATCHnomatch;
5569 if ((*dedtypes)[i])
5570 {
5571 Tuple *tup = isTuple((*dedtypes)[i]);
5572 if (!tup)
5573 return MATCHnomatch;
5574 if (!match(tup, ovar))
5575 return MATCHnomatch;
5576 }
5577 (*dedtypes)[i] = ovar;
5578
5579 if (psparam)
5580 *psparam = new TupleDeclaration(loc, ident, &ovar->objects);
5581 return dependent ? MATCHexact : MATCHconvert;
5582 }
5583
5584
5585 void TemplateTupleParameter::print(RootObject *, RootObject *oded)
5586 {
5587 printf(" %s... [", ident->toChars());
5588 Tuple *v = isTuple(oded);
5589 assert(v);
5590
5591 //printf("|%d| ", v->objects.length);
5592 for (size_t i = 0; i < v->objects.length; i++)
5593 {
5594 if (i)
5595 printf(", ");
5596
5597 RootObject *o = v->objects[i];
5598
5599 Dsymbol *sa = isDsymbol(o);
5600 if (sa)
5601 printf("alias: %s", sa->toChars());
5602
5603 Type *ta = isType(o);
5604 if (ta)
5605 printf("type: %s", ta->toChars());
5606
5607 Expression *ea = isExpression(o);
5608 if (ea)
5609 printf("exp: %s", ea->toChars());
5610
5611 assert(!isTuple(o)); // no nested Tuple arguments
5612 }
5613
5614 printf("]\n");
5615 }
5616
5617 void *TemplateTupleParameter::dummyArg()
5618 {
5619 return NULL;
5620 }
5621
5622
5623 RootObject *TemplateTupleParameter::specialization()
5624 {
5625 return NULL;
5626 }
5627
5628 RootObject *TemplateTupleParameter::defaultArg(Loc, Scope *)
5629 {
5630 return NULL;
5631 }
5632
5633 bool TemplateTupleParameter::hasDefaultArg()
5634 {
5635 return false;
5636 }
5637
5638 /* ======================== TemplateInstance ================================ */
5639
5640 TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
5641 : ScopeDsymbol(NULL)
5642 {
5643 this->loc = loc;
5644 this->name = ident;
5645 this->tiargs = NULL;
5646 this->tempdecl = NULL;
5647 this->inst = NULL;
5648 this->tinst = NULL;
5649 this->tnext = NULL;
5650 this->minst = NULL;
5651 this->deferred = NULL;
5652 this->memberOf = NULL;
5653 this->argsym = NULL;
5654 this->aliasdecl = NULL;
5655 this->semantictiargsdone = false;
5656 this->inuse = 0;
5657 this->nest = 0;
5658 this->havetempdecl = false;
5659 this->enclosing = NULL;
5660 this->gagged = false;
5661 this->hash = 0;
5662 this->fargs = NULL;
5663 }
5664
5665 /*****************
5666 * This constructor is only called when we figured out which function
5667 * template to instantiate.
5668 */
5669
5670 TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs)
5671 : ScopeDsymbol(NULL)
5672 {
5673 this->loc = loc;
5674 this->name = td->ident;
5675 this->tiargs = tiargs;
5676 this->tempdecl = td;
5677 this->inst = NULL;
5678 this->tinst = NULL;
5679 this->tnext = NULL;
5680 this->minst = NULL;
5681 this->deferred = NULL;
5682 this->memberOf = NULL;
5683 this->argsym = NULL;
5684 this->aliasdecl = NULL;
5685 this->semantictiargsdone = true;
5686 this->inuse = 0;
5687 this->nest = 0;
5688 this->havetempdecl = true;
5689 this->enclosing = NULL;
5690 this->gagged = false;
5691 this->hash = 0;
5692 this->fargs = NULL;
5693
5694 assert(tempdecl->_scope);
5695 }
5696
5697
5698 Objects *TemplateInstance::arraySyntaxCopy(Objects *objs)
5699 {
5700 Objects *a = NULL;
5701 if (objs)
5702 {
5703 a = new Objects();
5704 a->setDim(objs->length);
5705 for (size_t i = 0; i < objs->length; i++)
5706 (*a)[i] = objectSyntaxCopy((*objs)[i]);
5707 }
5708 return a;
5709 }
5710
5711 Dsymbol *TemplateInstance::syntaxCopy(Dsymbol *s)
5712 {
5713 TemplateInstance *ti =
5714 s ? (TemplateInstance *)s
5715 : new TemplateInstance(loc, name);
5716 ti->tiargs = arraySyntaxCopy(tiargs);
5717 TemplateDeclaration *td;
5718 if (inst && tempdecl && (td = tempdecl->isTemplateDeclaration()) != NULL)
5719 td->ScopeDsymbol::syntaxCopy(ti);
5720 else
5721 ScopeDsymbol::syntaxCopy(ti);
5722 return ti;
5723 }
5724
5725 void TemplateInstance::expandMembers(Scope *sc2)
5726 {
5727 for (size_t i = 0; i < members->length; i++)
5728 {
5729 Dsymbol *s = (*members)[i];
5730 s->setScope(sc2);
5731 }
5732
5733 for (size_t i = 0; i < members->length; i++)
5734 {
5735 Dsymbol *s = (*members)[i];
5736 s->importAll(sc2);
5737 }
5738
5739 for (size_t i = 0; i < members->length; i++)
5740 {
5741 Dsymbol *s = (*members)[i];
5742 //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars());
5743 //printf("test: enclosing = %d, sc2->parent = %s\n", enclosing, sc2->parent->toChars());
5744 // if (enclosing)
5745 // s->parent = sc->parent;
5746 //printf("test3: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars());
5747 dsymbolSemantic(s, sc2);
5748 //printf("test4: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars());
5749 Module::runDeferredSemantic();
5750 }
5751 }
5752
5753 void TemplateInstance::tryExpandMembers(Scope *sc2)
5754 {
5755 static int nest;
5756 // extracted to a function to allow windows SEH to work without destructors in the same function
5757 //printf("%d\n", nest);
5758 if (++nest > global.recursionLimit)
5759 {
5760 global.gag = 0; // ensure error message gets printed
5761 error("recursive expansion exceeded allowed nesting limit");
5762 fatal();
5763 }
5764
5765 expandMembers(sc2);
5766
5767 nest--;
5768 }
5769
5770 void TemplateInstance::trySemantic3(Scope *sc2)
5771 {
5772 // extracted to a function to allow windows SEH to work without destructors in the same function
5773 static int nest;
5774 //printf("%d\n", nest);
5775 if (++nest > global.recursionLimit)
5776 {
5777 global.gag = 0; // ensure error message gets printed
5778 error("recursive expansion exceeded allowed nesting limit");
5779 fatal();
5780 }
5781 semantic3(this, sc2);
5782
5783 --nest;
5784 }
5785
5786 /**********************************************
5787 * Find template declaration corresponding to template instance.
5788 *
5789 * Returns:
5790 * false if finding fails.
5791 * Note:
5792 * This function is reentrant against error occurrence. If returns false,
5793 * any members of this object won't be modified, and repetition call will
5794 * reproduce same error.
5795 */
5796
5797 bool TemplateInstance::findTempDecl(Scope *sc, WithScopeSymbol **pwithsym)
5798 {
5799 if (pwithsym)
5800 *pwithsym = NULL;
5801
5802 if (havetempdecl)
5803 return true;
5804
5805 //printf("TemplateInstance::findTempDecl() %s\n", toChars());
5806 if (!tempdecl)
5807 {
5808 /* Given:
5809 * foo!( ... )
5810 * figure out which TemplateDeclaration foo refers to.
5811 */
5812 Identifier *id = name;
5813 Dsymbol *scopesym;
5814 Dsymbol *s = sc->search(loc, id, &scopesym);
5815 if (!s)
5816 {
5817 s = sc->search_correct(id);
5818 if (s)
5819 error("template `%s` is not defined, did you mean %s?", id->toChars(), s->toChars());
5820 else
5821 error("template `%s` is not defined", id->toChars());
5822 return false;
5823 }
5824
5825 if (pwithsym)
5826 *pwithsym = scopesym->isWithScopeSymbol();
5827
5828 /* We might have found an alias within a template when
5829 * we really want the template.
5830 */
5831 TemplateInstance *ti;
5832 if (s->parent &&
5833 (ti = s->parent->isTemplateInstance()) != NULL)
5834 {
5835 if (ti->tempdecl && ti->tempdecl->ident == id)
5836 {
5837 /* This is so that one can refer to the enclosing
5838 * template, even if it has the same name as a member
5839 * of the template, if it has a !(arguments)
5840 */
5841 TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration();
5842 assert(td);
5843 if (td->overroot) // if not start of overloaded list of TemplateDeclaration's
5844 td = td->overroot; // then get the start
5845 s = td;
5846 }
5847 }
5848
5849 if (!updateTempDecl(sc, s))
5850 {
5851 return false;
5852 }
5853 }
5854 assert(tempdecl);
5855
5856 struct ParamFwdTi
5857 {
5858 static int fp(void *param, Dsymbol *s)
5859 {
5860 TemplateDeclaration *td = s->isTemplateDeclaration();
5861 if (!td)
5862 return 0;
5863
5864 TemplateInstance *ti = (TemplateInstance *)param;
5865 if (td->semanticRun == PASSinit)
5866 {
5867 if (td->_scope)
5868 {
5869 // Try to fix forward reference. Ungag errors while doing so.
5870 Ungag ungag = td->ungagSpeculative();
5871 dsymbolSemantic(td, td->_scope);
5872 }
5873 if (td->semanticRun == PASSinit)
5874 {
5875 ti->error("%s forward references template declaration %s", ti->toChars(), td->toChars());
5876 return 1;
5877 }
5878 }
5879 return 0;
5880 }
5881 };
5882 // Look for forward references
5883 OverloadSet *tovers = tempdecl->isOverloadSet();
5884 size_t overs_dim = tovers ? tovers->a.length : 1;
5885 for (size_t oi = 0; oi < overs_dim; oi++)
5886 {
5887 if (overloadApply(tovers ? tovers->a[oi] : tempdecl, (void *)this, &ParamFwdTi::fp))
5888 return false;
5889 }
5890 return true;
5891 }
5892
5893 /**********************************************
5894 * Confirm s is a valid template, then store it.
5895 * Input:
5896 * sc
5897 * s candidate symbol of template. It may be:
5898 * TemplateDeclaration
5899 * FuncDeclaration with findTemplateDeclRoot() != NULL
5900 * OverloadSet which contains candidates
5901 * Returns:
5902 * true if updating succeeds.
5903 */
5904
5905 bool TemplateInstance::updateTempDecl(Scope *sc, Dsymbol *s)
5906 {
5907 if (s)
5908 {
5909 Identifier *id = name;
5910 s = s->toAlias();
5911
5912 /* If an OverloadSet, look for a unique member that is a template declaration
5913 */
5914 OverloadSet *os = s->isOverloadSet();
5915 if (os)
5916 {
5917 s = NULL;
5918 for (size_t i = 0; i < os->a.length; i++)
5919 {
5920 Dsymbol *s2 = os->a[i];
5921 if (FuncDeclaration *f = s2->isFuncDeclaration())
5922 s2 = f->findTemplateDeclRoot();
5923 else
5924 s2 = s2->isTemplateDeclaration();
5925 if (s2)
5926 {
5927 if (s)
5928 {
5929 tempdecl = os;
5930 return true;
5931 }
5932 s = s2;
5933 }
5934 }
5935 if (!s)
5936 {
5937 error("template `%s` is not defined", id->toChars());
5938 return false;
5939 }
5940 }
5941
5942 OverDeclaration *od = s->isOverDeclaration();
5943 if (od)
5944 {
5945 tempdecl = od; // TODO: more strict check
5946 return true;
5947 }
5948
5949 /* It should be a TemplateDeclaration, not some other symbol
5950 */
5951 if (FuncDeclaration *f = s->isFuncDeclaration())
5952 tempdecl = f->findTemplateDeclRoot();
5953 else
5954 tempdecl = s->isTemplateDeclaration();
5955 if (!tempdecl)
5956 {
5957 if (!s->parent && global.errors)
5958 return false;
5959 if (!s->parent && s->getType())
5960 {
5961 Dsymbol *s2 = s->getType()->toDsymbol(sc);
5962 if (!s2)
5963 {
5964 error("%s is not a template declaration, it is a %s", id->toChars(), s->kind());
5965 return false;
5966 }
5967 s = s2;
5968 }
5969 //assert(s->parent);
5970 TemplateInstance *ti = s->parent ? s->parent->isTemplateInstance() : NULL;
5971 if (ti &&
5972 (ti->name == s->ident ||
5973 ti->toAlias()->ident == s->ident)
5974 &&
5975 ti->tempdecl)
5976 {
5977 /* This is so that one can refer to the enclosing
5978 * template, even if it has the same name as a member
5979 * of the template, if it has a !(arguments)
5980 */
5981 TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration();
5982 assert(td);
5983 if (td->overroot) // if not start of overloaded list of TemplateDeclaration's
5984 td = td->overroot; // then get the start
5985 tempdecl = td;
5986 }
5987 else
5988 {
5989 error("%s is not a template declaration, it is a %s", id->toChars(), s->kind());
5990 return false;
5991 }
5992 }
5993 }
5994 return (tempdecl != NULL);
5995 }
5996
5997 /**********************************
5998 * Run semantic on the elements of tiargs.
5999 * Input:
6000 * sc
6001 * Returns:
6002 * false if one or more arguments have errors.
6003 * Note:
6004 * This function is reentrant against error occurrence. If returns false,
6005 * all elements of tiargs won't be modified.
6006 */
6007
6008 bool TemplateInstance::semanticTiargs(Scope *sc)
6009 {
6010 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars());
6011 if (semantictiargsdone)
6012 return true;
6013 if (semanticTiargs(loc, sc, tiargs, 0))
6014 {
6015 // cache the result iff semantic analysis succeeded entirely
6016 semantictiargsdone = 1;
6017 return true;
6018 }
6019 return false;
6020 }
6021
6022 /**********************************
6023 * Run semantic of tiargs as arguments of template.
6024 * Input:
6025 * loc
6026 * sc
6027 * tiargs array of template arguments
6028 * flags 1: replace const variables with their initializers
6029 * 2: don't devolve Parameter to Type
6030 * Returns:
6031 * false if one or more arguments have errors.
6032 */
6033
6034 bool TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags)
6035 {
6036 // Run semantic on each argument, place results in tiargs[]
6037 //printf("+TemplateInstance::semanticTiargs()\n");
6038 if (!tiargs)
6039 return true;
6040 bool err = false;
6041 for (size_t j = 0; j < tiargs->length; j++)
6042 {
6043 RootObject *o = (*tiargs)[j];
6044 Type *ta = isType(o);
6045 Expression *ea = isExpression(o);
6046 Dsymbol *sa = isDsymbol(o);
6047
6048 //printf("1: (*tiargs)[%d] = %p, s=%p, v=%p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
6049 if (ta)
6050 {
6051 //printf("type %s\n", ta->toChars());
6052 // It might really be an Expression or an Alias
6053 ta->resolve(loc, sc, &ea, &ta, &sa, (flags & 1) != 0);
6054 if (ea) goto Lexpr;
6055 if (sa) goto Ldsym;
6056 if (ta == NULL)
6057 {
6058 assert(global.errors);
6059 ta = Type::terror;
6060 }
6061
6062 Ltype:
6063 if (ta->ty == Ttuple)
6064 {
6065 // Expand tuple
6066 TypeTuple *tt = (TypeTuple *)ta;
6067 size_t dim = tt->arguments->length;
6068 tiargs->remove(j);
6069 if (dim)
6070 {
6071 tiargs->reserve(dim);
6072 for (size_t i = 0; i < dim; i++)
6073 {
6074 Parameter *arg = (*tt->arguments)[i];
6075 if (flags & 2 && (arg->ident || arg->userAttribDecl))
6076 tiargs->insert(j + i, arg);
6077 else
6078 tiargs->insert(j + i, arg->type);
6079 }
6080 }
6081 j--;
6082 continue;
6083 }
6084 if (ta->ty == Terror)
6085 {
6086 err = true;
6087 continue;
6088 }
6089 (*tiargs)[j] = ta->merge2();
6090 }
6091 else if (ea)
6092 {
6093 Lexpr:
6094 //printf("+[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
6095 if (flags & 1) // only used by __traits
6096 {
6097 ea = expressionSemantic(ea, sc);
6098
6099 // must not interpret the args, excepting template parameters
6100 if (ea->op != TOKvar ||
6101 (((VarExp *)ea)->var->storage_class & STCtemplateparameter))
6102 {
6103 ea = ea->optimize(WANTvalue);
6104 }
6105 }
6106 else
6107 {
6108 sc = sc->startCTFE();
6109 ea = expressionSemantic(ea, sc);
6110 sc = sc->endCTFE();
6111
6112 if (ea->op == TOKvar)
6113 {
6114 /* This test is to skip substituting a const var with
6115 * its initializer. The problem is the initializer won't
6116 * match with an 'alias' parameter. Instead, do the
6117 * const substitution in TemplateValueParameter::matchArg().
6118 */
6119 }
6120 else if (definitelyValueParameter(ea))
6121 {
6122 if (ea->checkValue()) // check void expression
6123 ea = new ErrorExp();
6124 unsigned int olderrs = global.errors;
6125 ea = ea->ctfeInterpret();
6126 if (global.errors != olderrs)
6127 ea = new ErrorExp();
6128 }
6129 }
6130 //printf("-[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
6131 if (ea->op == TOKtuple)
6132 {
6133 // Expand tuple
6134 TupleExp *te = (TupleExp *)ea;
6135 size_t dim = te->exps->length;
6136 tiargs->remove(j);
6137 if (dim)
6138 {
6139 tiargs->reserve(dim);
6140 for (size_t i = 0; i < dim; i++)
6141 tiargs->insert(j + i, (*te->exps)[i]);
6142 }
6143 j--;
6144 continue;
6145 }
6146 if (ea->op == TOKerror)
6147 {
6148 err = true;
6149 continue;
6150 }
6151 (*tiargs)[j] = ea;
6152
6153 if (ea->op == TOKtype)
6154 {
6155 ta = ea->type;
6156 goto Ltype;
6157 }
6158 if (ea->op == TOKscope)
6159 {
6160 sa = ((ScopeExp *)ea)->sds;
6161 goto Ldsym;
6162 }
6163 if (ea->op == TOKfunction)
6164 {
6165 FuncExp *fe = (FuncExp *)ea;
6166 /* A function literal, that is passed to template and
6167 * already semanticed as function pointer, never requires
6168 * outer frame. So convert it to global function is valid.
6169 */
6170 if (fe->fd->tok == TOKreserved && fe->type->ty == Tpointer)
6171 {
6172 // change to non-nested
6173 fe->fd->tok = TOKfunction;
6174 fe->fd->vthis = NULL;
6175 }
6176 else if (fe->td)
6177 {
6178 /* If template argument is a template lambda,
6179 * get template declaration itself. */
6180 //sa = fe->td;
6181 //goto Ldsym;
6182 }
6183 }
6184 if (ea->op == TOKdotvar && !(flags & 1))
6185 {
6186 // translate expression to dsymbol.
6187 sa = ((DotVarExp *)ea)->var;
6188 goto Ldsym;
6189 }
6190 if (ea->op == TOKtemplate)
6191 {
6192 sa = ((TemplateExp *)ea)->td;
6193 goto Ldsym;
6194 }
6195 if (ea->op == TOKdottd && !(flags & 1))
6196 {
6197 // translate expression to dsymbol.
6198 sa = ((DotTemplateExp *)ea)->td;
6199 goto Ldsym;
6200 }
6201 }
6202 else if (sa)
6203 {
6204 Ldsym:
6205 //printf("dsym %s %s\n", sa->kind(), sa->toChars());
6206 if (sa->errors)
6207 {
6208 err = true;
6209 continue;
6210 }
6211
6212 TupleDeclaration *d = sa->toAlias()->isTupleDeclaration();
6213 if (d)
6214 {
6215 // Expand tuple
6216 tiargs->remove(j);
6217 tiargs->insert(j, d->objects);
6218 j--;
6219 continue;
6220 }
6221 if (FuncAliasDeclaration *fa = sa->isFuncAliasDeclaration())
6222 {
6223 FuncDeclaration *f = fa->toAliasFunc();
6224 if (!fa->hasOverloads && f->isUnique())
6225 {
6226 // Strip FuncAlias only when the aliased function
6227 // does not have any overloads.
6228 sa = f;
6229 }
6230 }
6231 (*tiargs)[j] = sa;
6232
6233 TemplateDeclaration *td = sa->isTemplateDeclaration();
6234 if (td && td->semanticRun == PASSinit && td->literal)
6235 {
6236 dsymbolSemantic(td, sc);
6237 }
6238 FuncDeclaration *fd = sa->isFuncDeclaration();
6239 if (fd)
6240 fd->functionSemantic();
6241 }
6242 else if (isParameter(o))
6243 {
6244 }
6245 else
6246 {
6247 assert(0);
6248 }
6249 //printf("1: (*tiargs)[%d] = %p\n", j, (*tiargs)[j]);
6250 }
6251 return !err;
6252 }
6253
6254 bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs)
6255 {
6256 if (havetempdecl)
6257 {
6258 TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration();
6259 assert(tempdecl);
6260 assert(tempdecl->_scope);
6261 // Deduce tdtypes
6262 tdtypes.setDim(tempdecl->parameters->length);
6263 if (!tempdecl->matchWithInstance(sc, this, &tdtypes, fargs, 2))
6264 {
6265 error("incompatible arguments for template instantiation");
6266 return false;
6267 }
6268 // TODO: Normalizing tiargs for bugzilla 7469 is necessary?
6269 return true;
6270 }
6271
6272 unsigned errs = global.errors;
6273
6274 struct ParamBest
6275 {
6276 // context
6277 Scope *sc;
6278 TemplateInstance *ti;
6279 Objects dedtypes;
6280 // result
6281 TemplateDeclaration *td_best;
6282 TemplateDeclaration *td_ambig;
6283 MATCH m_best;
6284
6285 static int fp(void *param, Dsymbol *s)
6286 {
6287 return ((ParamBest *)param)->fp(s);
6288 }
6289 int fp(Dsymbol *s)
6290 {
6291 TemplateDeclaration *td = s->isTemplateDeclaration();
6292 if (!td)
6293 return 0;
6294
6295 if (td == td_best) // skip duplicates
6296 return 0;
6297
6298 //printf("td = %s\n", td->toPrettyChars());
6299
6300 // If more arguments than parameters,
6301 // then this is no match.
6302 if (td->parameters->length < ti->tiargs->length)
6303 {
6304 if (!td->isVariadic())
6305 return 0;
6306 }
6307
6308 dedtypes.setDim(td->parameters->length);
6309 dedtypes.zero();
6310 assert(td->semanticRun != PASSinit);
6311 MATCH m = td->matchWithInstance(sc, ti, &dedtypes, ti->fargs, 0);
6312 //printf("matchWithInstance = %d\n", m);
6313 if (m <= MATCHnomatch) // no match at all
6314 return 0;
6315
6316 if (m < m_best) goto Ltd_best;
6317 if (m > m_best) goto Ltd;
6318
6319 {
6320 // Disambiguate by picking the most specialized TemplateDeclaration
6321 MATCH c1 = td->leastAsSpecialized(sc, td_best, ti->fargs);
6322 MATCH c2 = td_best->leastAsSpecialized(sc, td, ti->fargs);
6323 //printf("c1 = %d, c2 = %d\n", c1, c2);
6324 if (c1 > c2) goto Ltd;
6325 if (c1 < c2) goto Ltd_best;
6326 }
6327
6328 td_ambig = td;
6329 return 0;
6330
6331 Ltd_best: // td_best is the best match so far
6332 td_ambig = NULL;
6333 return 0;
6334
6335 Ltd: // td is the new best match
6336 td_ambig = NULL;
6337 td_best = td;
6338 m_best = m;
6339 ti->tdtypes.setDim(dedtypes.length);
6340 memcpy(ti->tdtypes.tdata(), dedtypes.tdata(), ti->tdtypes.length * sizeof(void *));
6341 return 0;
6342 }
6343 };
6344 ParamBest p;
6345 // context
6346 p.ti = this;
6347 p.sc = sc;
6348
6349 /* Since there can be multiple TemplateDeclaration's with the same
6350 * name, look for the best match.
6351 */
6352 TemplateDeclaration *td_last = NULL;
6353
6354 OverloadSet *tovers = tempdecl->isOverloadSet();
6355 size_t overs_dim = tovers ? tovers->a.length : 1;
6356 for (size_t oi = 0; oi < overs_dim; oi++)
6357 {
6358 // result
6359 p.td_best = NULL;
6360 p.td_ambig = NULL;
6361 p.m_best = MATCHnomatch;
6362 overloadApply(tovers ? tovers->a[oi] : tempdecl, &p, &ParamBest::fp);
6363
6364 if (p.td_ambig)
6365 {
6366 ::error(loc, "%s %s.%s matches more than one template declaration:\n%s: %s\nand\n%s: %s",
6367 p.td_best->kind(), p.td_best->parent->toPrettyChars(), p.td_best->ident->toChars(),
6368 p.td_best->loc.toChars() , p.td_best->toChars(),
6369 p.td_ambig->loc.toChars(), p.td_ambig->toChars());
6370 return false;
6371 }
6372 if (p.td_best)
6373 {
6374 if (!td_last)
6375 td_last = p.td_best;
6376 else if (td_last != p.td_best)
6377 {
6378 ScopeDsymbol::multiplyDefined(loc, td_last, p.td_best);
6379 return false;
6380 }
6381 }
6382 }
6383
6384 if (td_last)
6385 {
6386 /* Bugzilla 7469: Normalize tiargs by using corresponding deduced
6387 * template value parameters and tuples for the correct mangling.
6388 *
6389 * By doing this before hasNestedArgs, CTFEable local variable will be
6390 * accepted as a value parameter. For example:
6391 *
6392 * void foo() {
6393 * struct S(int n) {} // non-global template
6394 * const int num = 1; // CTFEable local variable
6395 * S!num s; // S!1 is instantiated, not S!num
6396 * }
6397 */
6398 size_t dim = td_last->parameters->length - (td_last->isVariadic() ? 1 : 0);
6399 for (size_t i = 0; i < dim; i++)
6400 {
6401 if (tiargs->length <= i)
6402 tiargs->push(tdtypes[i]);
6403 assert(i < tiargs->length);
6404
6405 TemplateValueParameter *tvp = (*td_last->parameters)[i]->isTemplateValueParameter();
6406 if (!tvp)
6407 continue;
6408 assert(tdtypes[i]);
6409 // tdtypes[i] is already normalized to the required type in matchArg
6410
6411 (*tiargs)[i] = tdtypes[i];
6412 }
6413 if (td_last->isVariadic() && tiargs->length == dim && tdtypes[dim])
6414 {
6415 Tuple *va = isTuple(tdtypes[dim]);
6416 assert(va);
6417 for (size_t i = 0; i < va->objects.length; i++)
6418 tiargs->push(va->objects[i]);
6419 }
6420 }
6421 else if (errors && inst)
6422 {
6423 // instantiation was failed with error reporting
6424 assert(global.errors);
6425 return false;
6426 }
6427 else
6428 {
6429 TemplateDeclaration *tdecl = tempdecl->isTemplateDeclaration();
6430
6431 if (errs != global.errors)
6432 errorSupplemental(loc, "while looking for match for %s", toChars());
6433 else if (tdecl && !tdecl->overnext)
6434 {
6435 // Only one template, so we can give better error message
6436 error("does not match template declaration %s", tdecl->toChars());
6437 }
6438 else
6439 ::error(loc, "%s %s.%s does not match any template declaration",
6440 tempdecl->kind(), tempdecl->parent->toPrettyChars(), tempdecl->ident->toChars());
6441 return false;
6442 }
6443
6444 /* The best match is td_last
6445 */
6446 tempdecl = td_last;
6447
6448 return (errs == global.errors);
6449 }
6450
6451 /*****************************************************
6452 * Determine if template instance is really a template function,
6453 * and that template function needs to infer types from the function
6454 * arguments.
6455 *
6456 * Like findBestMatch, iterate possible template candidates,
6457 * but just looks only the necessity of type inference.
6458 */
6459
6460 bool TemplateInstance::needsTypeInference(Scope *sc, int flag)
6461 {
6462 //printf("TemplateInstance::needsTypeInference() %s\n", toChars());
6463 if (semanticRun != PASSinit)
6464 return false;
6465
6466 struct ParamNeedsInf
6467 {
6468 // context
6469 Scope *sc;
6470 TemplateInstance *ti;
6471 int flag;
6472 // result
6473 Objects dedtypes;
6474 size_t count;
6475
6476 static int fp(void *param, Dsymbol *s)
6477 {
6478 return ((ParamNeedsInf *)param)->fp(s);
6479 }
6480 int fp(Dsymbol *s)
6481 {
6482 TemplateDeclaration *td = s->isTemplateDeclaration();
6483 if (!td)
6484 {
6485 return 0;
6486 }
6487
6488 /* If any of the overloaded template declarations need inference,
6489 * then return true
6490 */
6491 FuncDeclaration *fd;
6492 if (!td->onemember)
6493 return 0;
6494 if (TemplateDeclaration *td2 = td->onemember->isTemplateDeclaration())
6495 {
6496 if (!td2->onemember || !td2->onemember->isFuncDeclaration())
6497 return 0;
6498 if (ti->tiargs->length >= td->parameters->length - (td->isVariadic() ? 1 : 0))
6499 return 0;
6500 return 1;
6501 }
6502 if ((fd = td->onemember->isFuncDeclaration()) == NULL ||
6503 fd->type->ty != Tfunction)
6504 {
6505 return 0;
6506 }
6507
6508 for (size_t i = 0; i < td->parameters->length; i++)
6509 {
6510 if ((*td->parameters)[i]->isTemplateThisParameter())
6511 return 1;
6512 }
6513
6514 /* Determine if the instance arguments, tiargs, are all that is necessary
6515 * to instantiate the template.
6516 */
6517 //printf("tp = %p, td->parameters->length = %d, tiargs->length = %d\n", tp, td->parameters->length, ti->tiargs->length);
6518 TypeFunction *tf = (TypeFunction *)fd->type;
6519 if (size_t dim = tf->parameterList.length())
6520 {
6521 TemplateParameter *tp = td->isVariadic();
6522 if (tp && td->parameters->length > 1)
6523 return 1;
6524
6525 if (!tp && ti->tiargs->length < td->parameters->length)
6526 {
6527 // Can remain tiargs be filled by default arguments?
6528 for (size_t i = ti->tiargs->length; i < td->parameters->length; i++)
6529 {
6530 if (!(*td->parameters)[i]->hasDefaultArg())
6531 return 1;
6532 }
6533 }
6534
6535 for (size_t i = 0; i < dim; i++)
6536 {
6537 // 'auto ref' needs inference.
6538 if (tf->parameterList[i]->storageClass & STCauto)
6539 return 1;
6540 }
6541 }
6542
6543 if (!flag)
6544 {
6545 /* Calculate the need for overload resolution.
6546 * When only one template can match with tiargs, inference is not necessary.
6547 */
6548 dedtypes.setDim(td->parameters->length);
6549 dedtypes.zero();
6550 if (td->semanticRun == PASSinit)
6551 {
6552 if (td->_scope)
6553 {
6554 // Try to fix forward reference. Ungag errors while doing so.
6555 Ungag ungag = td->ungagSpeculative();
6556 dsymbolSemantic(td, td->_scope);
6557 }
6558 if (td->semanticRun == PASSinit)
6559 {
6560 ti->error("%s forward references template declaration %s", ti->toChars(), td->toChars());
6561 return 1;
6562 }
6563 }
6564 assert(td->semanticRun != PASSinit);
6565 MATCH m = td->matchWithInstance(sc, ti, &dedtypes, NULL, 0);
6566 if (m <= MATCHnomatch)
6567 return 0;
6568 }
6569
6570 /* If there is more than one function template which matches, we may
6571 * need type inference (see Bugzilla 4430)
6572 */
6573 if (++count > 1)
6574 return 1;
6575
6576 return 0;
6577 }
6578 };
6579 ParamNeedsInf p;
6580 // context
6581 p.ti = this;
6582 p.sc = sc;
6583 p.flag = flag;
6584 // result
6585 p.count = 0;
6586
6587 OverloadSet *tovers = tempdecl->isOverloadSet();
6588 size_t overs_dim = tovers ? tovers->a.length : 1;
6589 unsigned olderrs = global.errors;
6590 for (size_t oi = 0; oi < overs_dim; oi++)
6591 {
6592 if (overloadApply(tovers ? tovers->a[oi] : tempdecl, &p, &ParamNeedsInf::fp))
6593 return true;
6594 }
6595 if (olderrs != global.errors)
6596 {
6597 if (!global.gag)
6598 {
6599 errorSupplemental(loc, "while looking for match for %s", toChars());
6600 semanticRun = PASSsemanticdone;
6601 inst = this;
6602 }
6603 errors = true;
6604 }
6605 //printf("false\n");
6606 return false;
6607 }
6608
6609
6610 /*****************************************
6611 * Determines if a TemplateInstance will need a nested
6612 * generation of the TemplateDeclaration.
6613 * Sets enclosing property if so, and returns != 0;
6614 */
6615
6616 bool TemplateInstance::hasNestedArgs(Objects *args, bool isstatic)
6617 {
6618 int nested = 0;
6619 //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());
6620
6621 /* A nested instance happens when an argument references a local
6622 * symbol that is on the stack.
6623 */
6624 for (size_t i = 0; i < args->length; i++)
6625 {
6626 RootObject *o = (*args)[i];
6627 Expression *ea = isExpression(o);
6628 Dsymbol *sa = isDsymbol(o);
6629 Tuple *va = isTuple(o);
6630 if (ea)
6631 {
6632 if (ea->op == TOKvar)
6633 {
6634 sa = ((VarExp *)ea)->var;
6635 goto Lsa;
6636 }
6637 if (ea->op == TOKthis)
6638 {
6639 sa = ((ThisExp *)ea)->var;
6640 goto Lsa;
6641 }
6642 if (ea->op == TOKfunction)
6643 {
6644 if (((FuncExp *)ea)->td)
6645 sa = ((FuncExp *)ea)->td;
6646 else
6647 sa = ((FuncExp *)ea)->fd;
6648 goto Lsa;
6649 }
6650 // Emulate Expression::toMangleBuffer call that had exist in TemplateInstance::genIdent.
6651 if (ea->op != TOKint64 &&
6652 ea->op != TOKfloat64 &&
6653 ea->op != TOKcomplex80 &&
6654 ea->op != TOKnull &&
6655 ea->op != TOKstring &&
6656 ea->op != TOKarrayliteral &&
6657 ea->op != TOKassocarrayliteral &&
6658 ea->op != TOKstructliteral)
6659 {
6660 ea->error("expression %s is not a valid template value argument", ea->toChars());
6661 errors = true;
6662 }
6663 }
6664 else if (sa)
6665 {
6666 Lsa:
6667 sa = sa->toAlias();
6668 TemplateDeclaration *td = sa->isTemplateDeclaration();
6669 if (td)
6670 {
6671 TemplateInstance *ti = sa->toParent()->isTemplateInstance();
6672 if (ti && ti->enclosing)
6673 sa = ti;
6674 }
6675 TemplateInstance *ti = sa->isTemplateInstance();
6676 Declaration *d = sa->isDeclaration();
6677 if ((td && td->literal) ||
6678 (ti && ti->enclosing) ||
6679 (d && !d->isDataseg() &&
6680 !(d->storage_class & STCmanifest) &&
6681 (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) &&
6682 !isTemplateMixin()
6683 ))
6684 {
6685 // if module level template
6686 if (isstatic)
6687 {
6688 Dsymbol *dparent = sa->toParent2();
6689 if (!enclosing)
6690 enclosing = dparent;
6691 else if (enclosing != dparent)
6692 {
6693 /* Select the more deeply nested of the two.
6694 * Error if one is not nested inside the other.
6695 */
6696 for (Dsymbol *p = enclosing; p; p = p->parent)
6697 {
6698 if (p == dparent)
6699 goto L1; // enclosing is most nested
6700 }
6701 for (Dsymbol *p = dparent; p; p = p->parent)
6702 {
6703 if (p == enclosing)
6704 {
6705 enclosing = dparent;
6706 goto L1; // dparent is most nested
6707 }
6708 }
6709 error("%s is nested in both %s and %s",
6710 toChars(), enclosing->toChars(), dparent->toChars());
6711 errors = true;
6712 }
6713 L1:
6714 //printf("\tnested inside %s\n", enclosing->toChars());
6715 nested |= 1;
6716 }
6717 else
6718 {
6719 error("cannot use local `%s` as parameter to non-global template %s", sa->toChars(), tempdecl->toChars());
6720 errors = true;
6721 }
6722 }
6723 }
6724 else if (va)
6725 {
6726 nested |= (int)hasNestedArgs(&va->objects, isstatic);
6727 }
6728 }
6729 //printf("-TemplateInstance::hasNestedArgs('%s') = %d\n", tempdecl->ident->toChars(), nested);
6730 return nested != 0;
6731 }
6732
6733 /*****************************************
6734 * Append 'this' to the specific module members[]
6735 */
6736 Dsymbols *TemplateInstance::appendToModuleMember()
6737 {
6738 Module *mi = minst; // instantiated -> inserted module
6739
6740 if (global.params.useUnitTests ||
6741 global.params.debuglevel)
6742 {
6743 // Turn all non-root instances to speculative
6744 if (mi && !mi->isRoot())
6745 mi = NULL;
6746 }
6747
6748 //printf("%s->appendToModuleMember() enclosing = %s mi = %s\n",
6749 // toPrettyChars(),
6750 // enclosing ? enclosing->toPrettyChars() : NULL,
6751 // mi ? mi->toPrettyChars() : NULL);
6752 if (!mi || mi->isRoot())
6753 {
6754 /* If the instantiated module is speculative or root, insert to the
6755 * member of a root module. Then:
6756 * - semantic3 pass will get called on the instance members.
6757 * - codegen pass will get a selection chance to do/skip it.
6758 */
6759
6760 struct N
6761 {
6762 static Dsymbol *getStrictEnclosing(TemplateInstance *ti)
6763 {
6764 do
6765 {
6766 if (ti->enclosing)
6767 return ti->enclosing;
6768 ti = ti->tempdecl->isInstantiated();
6769 }
6770 while (ti);
6771 return NULL;
6772 }
6773 };
6774 Dsymbol *enc = N::getStrictEnclosing(this);
6775
6776 // insert target is made stable by using the module
6777 // where tempdecl is declared.
6778 mi = (enc ? enc : tempdecl)->getModule();
6779 if (!mi->isRoot())
6780 mi = mi->importedFrom;
6781 assert(mi->isRoot());
6782 }
6783 else
6784 {
6785 /* If the instantiated module is non-root, insert to the member of the
6786 * non-root module. Then:
6787 * - semantic3 pass won't be called on the instance.
6788 * - codegen pass won't reach to the instance.
6789 */
6790 }
6791 //printf("\t--> mi = %s\n", mi->toPrettyChars());
6792
6793 if (memberOf == mi) // already a member
6794 {
6795 return NULL;
6796 }
6797
6798 Dsymbols *a = mi->members;
6799 a->push(this);
6800 memberOf = mi;
6801 if (mi->semanticRun >= PASSsemantic2done && mi->isRoot())
6802 Module::addDeferredSemantic2(this);
6803 if (mi->semanticRun >= PASSsemantic3done && mi->isRoot())
6804 Module::addDeferredSemantic3(this);
6805 return a;
6806 }
6807
6808 /****************************************
6809 * This instance needs an identifier for name mangling purposes.
6810 * Create one by taking the template declaration name and adding
6811 * the type signature for it.
6812 */
6813
6814 Identifier *TemplateInstance::genIdent(Objects *args)
6815 {
6816 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
6817 assert(args == tiargs);
6818 OutBuffer buf;
6819 mangleToBuffer(this, &buf);
6820 //printf("\tgenIdent = %s\n", id);
6821 return Identifier::idPool(buf.peekChars());
6822 }
6823
6824 /*************************************
6825 * Lazily generate identifier for template instance.
6826 * This is because 75% of the ident's are never needed.
6827 */
6828
6829 Identifier *TemplateInstance::getIdent()
6830 {
6831 if (!ident && inst && !errors)
6832 ident = genIdent(tiargs); // need an identifier for name mangling purposes.
6833 return ident;
6834 }
6835
6836 /****************************************************
6837 * Declare parameters of template instance, initialize them with the
6838 * template instance arguments.
6839 */
6840
6841 void TemplateInstance::declareParameters(Scope *sc)
6842 {
6843 TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration();
6844 assert(tempdecl);
6845
6846 //printf("TemplateInstance::declareParameters()\n");
6847 for (size_t i = 0; i < tdtypes.length; i++)
6848 {
6849 TemplateParameter *tp = (*tempdecl->parameters)[i];
6850 //RootObject *o = (*tiargs)[i];
6851 RootObject *o = tdtypes[i]; // initializer for tp
6852
6853 //printf("\ttdtypes[%d] = %p\n", i, o);
6854 tempdecl->declareParameter(sc, tp, o);
6855 }
6856 }
6857
6858 /**************************************
6859 * Given an error instantiating the TemplateInstance,
6860 * give the nested TemplateInstance instantiations that got
6861 * us here. Those are a list threaded into the nested scopes.
6862 */
6863 void TemplateInstance::printInstantiationTrace()
6864 {
6865 if (global.gag)
6866 return;
6867
6868 const unsigned max_shown = 6;
6869 const char format[] = "instantiated from here: %s";
6870
6871 // determine instantiation depth and number of recursive instantiations
6872 unsigned n_instantiations = 1;
6873 unsigned n_totalrecursions = 0;
6874 for (TemplateInstance *cur = this; cur; cur = cur->tinst)
6875 {
6876 ++n_instantiations;
6877 // If two instantiations use the same declaration, they are recursive.
6878 // (this works even if they are instantiated from different places in the
6879 // same template).
6880 // In principle, we could also check for multiple-template recursion, but it's
6881 // probably not worthwhile.
6882 if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl
6883 && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc))
6884 ++n_totalrecursions;
6885 }
6886
6887 // show full trace only if it's short or verbose is on
6888 if (n_instantiations <= max_shown || global.params.verbose)
6889 {
6890 for (TemplateInstance *cur = this; cur; cur = cur->tinst)
6891 {
6892 cur->errors = true;
6893 errorSupplemental(cur->loc, format, cur->toChars());
6894 }
6895 }
6896 else if (n_instantiations - n_totalrecursions <= max_shown)
6897 {
6898 // By collapsing recursive instantiations into a single line,
6899 // we can stay under the limit.
6900 int recursionDepth=0;
6901 for (TemplateInstance *cur = this; cur; cur = cur->tinst)
6902 {
6903 cur->errors = true;
6904 if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl
6905 && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc))
6906 {
6907 ++recursionDepth;
6908 }
6909 else
6910 {
6911 if (recursionDepth)
6912 errorSupplemental(cur->loc, "%d recursive instantiations from here: %s", recursionDepth+2, cur->toChars());
6913 else
6914 errorSupplemental(cur->loc, format, cur->toChars());
6915 recursionDepth = 0;
6916 }
6917 }
6918 }
6919 else
6920 {
6921 // Even after collapsing the recursions, the depth is too deep.
6922 // Just display the first few and last few instantiations.
6923 unsigned i = 0;
6924 for (TemplateInstance *cur = this; cur; cur = cur->tinst)
6925 {
6926 cur->errors = true;
6927
6928 if (i == max_shown / 2)
6929 errorSupplemental(cur->loc, "... (%d instantiations, -v to show) ...", n_instantiations - max_shown);
6930
6931 if (i < max_shown / 2 ||
6932 i >= n_instantiations - max_shown + max_shown / 2)
6933 errorSupplemental(cur->loc, format, cur->toChars());
6934 ++i;
6935 }
6936 }
6937 }
6938
6939 Dsymbol *TemplateInstance::toAlias()
6940 {
6941 if (!inst)
6942 {
6943 // Maybe we can resolve it
6944 if (_scope)
6945 {
6946 dsymbolSemantic(this, _scope);
6947 }
6948 if (!inst)
6949 {
6950 error("cannot resolve forward reference");
6951 errors = true;
6952 return this;
6953 }
6954 }
6955
6956 if (inst != this)
6957 return inst->toAlias();
6958
6959 if (aliasdecl)
6960 {
6961 return aliasdecl->toAlias();
6962 }
6963
6964 return inst;
6965 }
6966
6967 const char *TemplateInstance::kind() const
6968 {
6969 return "template instance";
6970 }
6971
6972 bool TemplateInstance::oneMember(Dsymbol **ps, Identifier *)
6973 {
6974 *ps = NULL;
6975 return true;
6976 }
6977
6978 const char *TemplateInstance::toChars()
6979 {
6980 OutBuffer buf;
6981 toCBufferInstance(this, &buf);
6982 return buf.extractChars();
6983 }
6984
6985 const char *TemplateInstance::toPrettyCharsHelper()
6986 {
6987 OutBuffer buf;
6988 toCBufferInstance(this, &buf, true);
6989 return buf.extractChars();
6990 }
6991
6992 /*************************************
6993 * Compare proposed template instantiation with existing template instantiation.
6994 * Note that this is not commutative because of the auto ref check.
6995 * Params:
6996 * this = proposed template instantiation
6997 * o = existing template instantiation
6998 * Returns:
6999 * 0 for match, 1 for no match
7000 */
7001 int TemplateInstance::compare(RootObject *o)
7002 {
7003 TemplateInstance *ti = (TemplateInstance *)o;
7004
7005 //printf("this = %p, ti = %p\n", this, ti);
7006 assert(tdtypes.length == ti->tdtypes.length);
7007
7008 // Nesting must match
7009 if (enclosing != ti->enclosing)
7010 {
7011 //printf("test2 enclosing %s ti->enclosing %s\n", enclosing ? enclosing->toChars() : "", ti->enclosing ? ti->enclosing->toChars() : "");
7012 goto Lnotequals;
7013 }
7014 //printf("parent = %s, ti->parent = %s\n", parent->toPrettyChars(), ti->parent->toPrettyChars());
7015
7016 if (!arrayObjectMatch(&tdtypes, &ti->tdtypes))
7017 goto Lnotequals;
7018
7019 /* Template functions may have different instantiations based on
7020 * "auto ref" parameters.
7021 */
7022 if (FuncDeclaration *fd = ti->toAlias()->isFuncDeclaration())
7023 {
7024 if (!fd->errors)
7025 {
7026 ParameterList fparameters = fd->getParameterList();
7027 size_t nfparams = fparameters.length(); // Num function parameters
7028 for (size_t j = 0; j < nfparams; j++)
7029 {
7030 Parameter *fparam = fparameters[j];
7031 if (fparam->storageClass & STCautoref) // if "auto ref"
7032 {
7033 if (!fargs)
7034 goto Lnotequals;
7035 if (fargs->length <= j)
7036 break;
7037 Expression *farg = (*fargs)[j];
7038 if (farg->isLvalue())
7039 {
7040 if (!(fparam->storageClass & STCref))
7041 goto Lnotequals; // auto ref's don't match
7042 }
7043 else
7044 {
7045 if (fparam->storageClass & STCref)
7046 goto Lnotequals; // auto ref's don't match
7047 }
7048 }
7049 }
7050 }
7051 }
7052 return 0;
7053
7054 Lnotequals:
7055 return 1;
7056 }
7057
7058 hash_t TemplateInstance::toHash()
7059 {
7060 if (!hash)
7061 {
7062 hash = (size_t)(void *)enclosing;
7063 hash += arrayObjectHash(&tdtypes);
7064 hash += hash == 0;
7065 }
7066 return hash;
7067 }
7068
7069 /**************************************
7070 * IsExpression can evaluate the specified type speculatively, and even if
7071 * it instantiates any symbols, they are normally unnecessary for the
7072 * final executable.
7073 * However, if those symbols leak to the actual code, compiler should remark
7074 * them as non-speculative to generate their code and link to the final executable.
7075 */
7076 void unSpeculative(Scope *sc, RootObject *o)
7077 {
7078 if (!o)
7079 return;
7080
7081 if (Tuple *tup = isTuple(o))
7082 {
7083 for (size_t i = 0; i < tup->objects.length; i++)
7084 {
7085 unSpeculative(sc, tup->objects[i]);
7086 }
7087 return;
7088 }
7089
7090 Dsymbol *s = getDsymbol(o);
7091 if (!s)
7092 return;
7093
7094 if (Declaration *d = s->isDeclaration())
7095 {
7096 if (VarDeclaration *vd = d->isVarDeclaration())
7097 o = vd->type;
7098 else if (AliasDeclaration *ad = d->isAliasDeclaration())
7099 {
7100 o = ad->getType();
7101 if (!o)
7102 o = ad->toAlias();
7103 }
7104 else
7105 o = d->toAlias();
7106
7107 s = getDsymbol(o);
7108 if (!s)
7109 return;
7110 }
7111
7112 if (TemplateInstance *ti = s->isTemplateInstance())
7113 {
7114 // If the instance is already non-speculative,
7115 // or it is leaked to the speculative scope.
7116 if (ti->minst != NULL || sc->minst == NULL)
7117 return;
7118
7119 // Remark as non-speculative instance.
7120 ti->minst = sc->minst;
7121 if (!ti->tinst)
7122 ti->tinst = sc->tinst;
7123
7124 unSpeculative(sc, ti->tempdecl);
7125 }
7126
7127 if (TemplateInstance *ti = s->isInstantiated())
7128 unSpeculative(sc, ti);
7129 }
7130
7131 /***********************************************
7132 * Returns true if this is not instantiated in non-root module, and
7133 * is a part of non-speculative instantiatiation.
7134 *
7135 * Note: minst does not stabilize until semantic analysis is completed,
7136 * so don't call this function during semantic analysis to return precise result.
7137 */
7138 bool TemplateInstance::needsCodegen()
7139 {
7140 // Now -allInst is just for the backward compatibility.
7141 if (global.params.allInst)
7142 {
7143 //printf("%s minst = %s, enclosing (%s)->isNonRoot = %d\n",
7144 // toPrettyChars(), minst ? minst->toChars() : NULL,
7145 // enclosing ? enclosing->toPrettyChars() : NULL, enclosing && enclosing->inNonRoot());
7146 if (enclosing)
7147 {
7148 // Bugzilla 14588: If the captured context is not a function
7149 // (e.g. class), the instance layout determination is guaranteed,
7150 // because the semantic/semantic2 pass will be executed
7151 // even for non-root instances.
7152 if (!enclosing->isFuncDeclaration())
7153 return true;
7154
7155 // Bugzilla 14834: If the captured context is a function,
7156 // this excessive instantiation may cause ODR violation, because
7157 // -allInst and others doesn't guarantee the semantic3 execution
7158 // for that function.
7159
7160 // If the enclosing is also an instantiated function,
7161 // we have to rely on the ancestor's needsCodegen() result.
7162 if (TemplateInstance *ti = enclosing->isInstantiated())
7163 return ti->needsCodegen();
7164
7165 // Bugzilla 13415: If and only if the enclosing scope needs codegen,
7166 // this nested templates would also need code generation.
7167 return !enclosing->inNonRoot();
7168 }
7169 return true;
7170 }
7171
7172 if (!minst)
7173 {
7174 // If this is a speculative instantiation,
7175 // 1. do codegen if ancestors really needs codegen.
7176 // 2. become non-speculative if siblings are not speculative
7177
7178 TemplateInstance *tnext = this->tnext;
7179 TemplateInstance *tinst = this->tinst;
7180 // At first, disconnect chain first to prevent infinite recursion.
7181 this->tnext = NULL;
7182 this->tinst = NULL;
7183
7184 // Determine necessity of tinst before tnext.
7185 if (tinst && tinst->needsCodegen())
7186 {
7187 minst = tinst->minst; // cache result
7188 assert(minst);
7189 assert(minst->isRoot() || minst->rootImports());
7190 return true;
7191 }
7192 if (tnext && (tnext->needsCodegen() || tnext->minst))
7193 {
7194 minst = tnext->minst; // cache result
7195 assert(minst);
7196 return minst->isRoot() || minst->rootImports();
7197 }
7198
7199 // Elide codegen because this is really speculative.
7200 return false;
7201 }
7202
7203 /* Even when this is reached to the codegen pass,
7204 * a non-root nested template should not generate code,
7205 * due to avoid ODR violation.
7206 */
7207 if (enclosing && enclosing->inNonRoot())
7208 {
7209 if (tinst)
7210 {
7211 bool r = tinst->needsCodegen();
7212 minst = tinst->minst; // cache result
7213 return r;
7214 }
7215 if (tnext)
7216 {
7217 bool r = tnext->needsCodegen();
7218 minst = tnext->minst; // cache result
7219 return r;
7220 }
7221 return false;
7222 }
7223
7224 /* The issue is that if the importee is compiled with a different -debug
7225 * setting than the importer, the importer may believe it exists
7226 * in the compiled importee when it does not, when the instantiation
7227 * is behind a conditional debug declaration.
7228 */
7229 // workaround for Bugzilla 11239
7230 if (global.params.useUnitTests ||
7231 global.params.debuglevel)
7232 {
7233 // Prefer instantiations from root modules, to maximize link-ability.
7234 if (minst->isRoot())
7235 return true;
7236
7237 TemplateInstance *tnext = this->tnext;
7238 TemplateInstance *tinst = this->tinst;
7239 this->tnext = NULL;
7240 this->tinst = NULL;
7241
7242 if (tinst && tinst->needsCodegen())
7243 {
7244 minst = tinst->minst; // cache result
7245 assert(minst);
7246 assert(minst->isRoot() || minst->rootImports());
7247 return true;
7248 }
7249 if (tnext && tnext->needsCodegen())
7250 {
7251 minst = tnext->minst; // cache result
7252 assert(minst);
7253 assert(minst->isRoot() || minst->rootImports());
7254 return true;
7255 }
7256
7257 // Bugzilla 2500 case
7258 if (minst->rootImports())
7259 return true;
7260
7261 // Elide codegen because this is not included in root instances.
7262 return false;
7263 }
7264 else
7265 {
7266 // Prefer instantiations from non-root module, to minimize object code size.
7267
7268 /* If a TemplateInstance is ever instantiated by non-root modules,
7269 * we do not have to generate code for it,
7270 * because it will be generated when the non-root module is compiled.
7271 *
7272 * But, if the non-root 'minst' imports any root modules, it might still need codegen.
7273 *
7274 * The problem is if A imports B, and B imports A, and both A
7275 * and B instantiate the same template, does the compilation of A
7276 * or the compilation of B do the actual instantiation?
7277 *
7278 * See Bugzilla 2500.
7279 */
7280 if (!minst->isRoot() && !minst->rootImports())
7281 return false;
7282
7283 TemplateInstance *tnext = this->tnext;
7284 this->tnext = NULL;
7285
7286 if (tnext && !tnext->needsCodegen() && tnext->minst)
7287 {
7288 minst = tnext->minst; // cache result
7289 assert(!minst->isRoot());
7290 return false;
7291 }
7292
7293 // Do codegen because this is not included in non-root instances.
7294 return true;
7295 }
7296 }
7297
7298 /* ======================== TemplateMixin ================================ */
7299
7300 TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, TypeQualified *tqual, Objects *tiargs)
7301 : TemplateInstance(loc, tqual->idents.length ? (Identifier *)tqual->idents[tqual->idents.length - 1]
7302 : ((TypeIdentifier *)tqual)->ident)
7303 {
7304 //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : "");
7305 this->ident = ident;
7306 this->tqual = tqual;
7307 this->tiargs = tiargs ? tiargs : new Objects();
7308 }
7309
7310 Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *)
7311 {
7312 TemplateMixin *tm = new TemplateMixin(loc, ident,
7313 (TypeQualified *)tqual->syntaxCopy(), tiargs);
7314 return TemplateInstance::syntaxCopy(tm);
7315 }
7316
7317 bool TemplateMixin::findTempDecl(Scope *sc)
7318 {
7319 // Follow qualifications to find the TemplateDeclaration
7320 if (!tempdecl)
7321 {
7322 Expression *e;
7323 Type *t;
7324 Dsymbol *s;
7325 tqual->resolve(loc, sc, &e, &t, &s);
7326 if (!s)
7327 {
7328 error("is not defined");
7329 return false;
7330 }
7331 s = s->toAlias();
7332 tempdecl = s->isTemplateDeclaration();
7333 OverloadSet *os = s->isOverloadSet();
7334
7335 /* If an OverloadSet, look for a unique member that is a template declaration
7336 */
7337 if (os)
7338 {
7339 Dsymbol *ds = NULL;
7340 for (size_t i = 0; i < os->a.length; i++)
7341 {
7342 Dsymbol *s2 = os->a[i]->isTemplateDeclaration();
7343 if (s2)
7344 {
7345 if (ds)
7346 {
7347 tempdecl = os;
7348 break;
7349 }
7350 ds = s2;
7351 }
7352 }
7353 }
7354 if (!tempdecl)
7355 {
7356 error("%s isn't a template", s->toChars());
7357 return false;
7358 }
7359 }
7360 assert(tempdecl);
7361
7362 struct ParamFwdResTm
7363 {
7364 static int fp(void *param, Dsymbol *s)
7365 {
7366 TemplateDeclaration *td = s->isTemplateDeclaration();
7367 if (!td)
7368 return 0;
7369
7370 TemplateMixin *tm = (TemplateMixin *)param;
7371 if (td->semanticRun == PASSinit)
7372 {
7373 if (td->_scope)
7374 dsymbolSemantic(td, td->_scope);
7375 else
7376 {
7377 tm->semanticRun = PASSinit;
7378 return 1;
7379 }
7380 }
7381 return 0;
7382 }
7383 };
7384 // Look for forward references
7385 OverloadSet *tovers = tempdecl->isOverloadSet();
7386 size_t overs_dim = tovers ? tovers->a.length : 1;
7387 for (size_t oi = 0; oi < overs_dim; oi++)
7388 {
7389 if (overloadApply(tovers ? tovers->a[oi] : tempdecl, (void *)this, &ParamFwdResTm::fp))
7390 return false;
7391 }
7392 return true;
7393 }
7394
7395 const char *TemplateMixin::kind() const
7396 {
7397 return "mixin";
7398 }
7399
7400 bool TemplateMixin::oneMember(Dsymbol **ps, Identifier *ident)
7401 {
7402 return Dsymbol::oneMember(ps, ident);
7403 }
7404
7405 int TemplateMixin::apply(Dsymbol_apply_ft_t fp, void *param)
7406 {
7407 if (_scope) // if fwd reference
7408 dsymbolSemantic(this, NULL); // try to resolve it
7409 if (members)
7410 {
7411 for (size_t i = 0; i < members->length; i++)
7412 {
7413 Dsymbol *s = (*members)[i];
7414 if (s)
7415 {
7416 if (s->apply(fp, param))
7417 return 1;
7418 }
7419 }
7420 }
7421 return 0;
7422 }
7423
7424 bool TemplateMixin::hasPointers()
7425 {
7426 //printf("TemplateMixin::hasPointers() %s\n", toChars());
7427
7428 if (members)
7429 {
7430 for (size_t i = 0; i < members->length; i++)
7431 {
7432 Dsymbol *s = (*members)[i];
7433 //printf(" s = %s %s\n", s->kind(), s->toChars());
7434 if (s->hasPointers())
7435 {
7436 return true;
7437 }
7438 }
7439 }
7440 return false;
7441 }
7442
7443 void TemplateMixin::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
7444 {
7445 //printf("TemplateMixin::setFieldOffset() %s\n", toChars());
7446 if (_scope) // if fwd reference
7447 dsymbolSemantic(this, NULL); // try to resolve it
7448 if (members)
7449 {
7450 for (size_t i = 0; i < members->length; i++)
7451 {
7452 Dsymbol *s = (*members)[i];
7453 //printf("\t%s\n", s->toChars());
7454 s->setFieldOffset(ad, poffset, isunion);
7455 }
7456 }
7457 }
7458
7459 const char *TemplateMixin::toChars()
7460 {
7461 OutBuffer buf;
7462 toCBufferInstance(this, &buf);
7463 return buf.extractChars();
7464 }