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