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