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