2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/template.c
11 // Handle template implementation
13 #include "root/dsystem.h"
14 #include "root/root.h"
16 #include "root/rmem.h"
17 #include "root/stringtable.h"
18 #include "root/hash.h"
24 #include "expression.h"
27 #include "aggregate.h"
28 #include "declaration.h"
32 #include "identifier.h"
39 #define IDX_NOTFOUND (0x12345678) // index is not found
41 Type
*rawTypeMerge(Type
*t1
, Type
*t2
);
42 bool MODimplicitConv(MOD modfrom
, MOD modto
);
43 MATCH
MODmethodConv(MOD modfrom
, MOD modto
);
44 MOD
MODmerge(MOD mod1
, MOD mod2
);
46 static size_t templateParameterLookup(Type
*tparam
, TemplateParameters
*parameters
);
47 static int arrayObjectMatch(Objects
*oa1
, Objects
*oa2
);
48 static unsigned char deduceWildHelper(Type
*t
, Type
**at
, Type
*tparam
);
49 static MATCH
deduceTypeHelper(Type
*t
, Type
**at
, Type
*tparam
);
50 bool reliesOnTident(Type
*t
, TemplateParameters
*tparams
= NULL
, size_t iStart
= 0);
51 bool evalStaticCondition(Scope
*sc
, Expression
*exp
, Expression
*e
, bool &errors
);
53 /********************************************
54 * These functions substitute for dynamic_cast. dynamic_cast does not work
55 * on earlier versions of gcc.
58 Expression
*isExpression(RootObject
*o
)
60 //return dynamic_cast<Expression *>(o);
61 if (!o
|| o
->dyncast() != DYNCAST_EXPRESSION
)
63 return (Expression
*)o
;
66 Dsymbol
*isDsymbol(RootObject
*o
)
68 //return dynamic_cast<Dsymbol *>(o);
69 if (!o
|| o
->dyncast() != DYNCAST_DSYMBOL
)
74 Type
*isType(RootObject
*o
)
76 //return dynamic_cast<Type *>(o);
77 if (!o
|| o
->dyncast() != DYNCAST_TYPE
)
82 Tuple
*isTuple(RootObject
*o
)
84 //return dynamic_cast<Tuple *>(o);
85 if (!o
|| o
->dyncast() != DYNCAST_TUPLE
)
90 Parameter
*isParameter(RootObject
*o
)
92 //return dynamic_cast<Parameter *>(o);
93 if (!o
|| o
->dyncast() != DYNCAST_PARAMETER
)
95 return (Parameter
*)o
;
98 /**************************************
99 * Is this Object an error?
101 bool isError(RootObject
*o
)
105 return (t
->ty
== Terror
);
106 Expression
*e
= isExpression(o
);
108 return (e
->op
== TOKerror
|| !e
->type
|| e
->type
->ty
== Terror
);
109 Tuple
*v
= isTuple(o
);
111 return arrayObjectIsError(&v
->objects
);
112 Dsymbol
*s
= isDsymbol(o
);
116 return s
->parent
? isError(s
->parent
) : false;
119 /**************************************
120 * Are any of the Objects an error?
122 bool arrayObjectIsError(Objects
*args
)
124 for (size_t i
= 0; i
< args
->length
; i
++)
126 RootObject
*o
= (*args
)[i
];
133 /***********************
134 * Try to get arg as a type.
137 Type
*getType(RootObject
*o
)
142 Expression
*e
= isExpression(o
);
149 Dsymbol
*getDsymbol(RootObject
*oarg
)
151 //printf("getDsymbol()\n");
152 //printf("e %p s %p t %p v %p\n", isExpression(oarg), isDsymbol(oarg), isType(oarg), isTuple(oarg));
155 Expression
*ea
= isExpression(oarg
);
158 // Try to convert Expression to symbol
159 if (VarExp
*ve
= ea
->isVarExp())
161 else if (FuncExp
*fe
= ea
->isFuncExp())
162 sa
= fe
->td
? (Dsymbol
*)fe
->td
: (Dsymbol
*)fe
->fd
;
163 else if (TemplateExp
*te
= ea
->isTemplateExp())
165 else if (ScopeExp
*se
= ea
->isScopeExp())
172 // Try to convert Type to symbol
173 Type
*ta
= isType(oarg
);
175 sa
= ta
->toDsymbol(NULL
);
177 sa
= isDsymbol(oarg
); // if already a symbol
182 /***********************
183 * Try to get value from manifest constant
186 static Expression
*getValue(Expression
*e
)
188 if (e
&& e
->op
== TOKvar
)
190 VarDeclaration
*v
= ((VarExp
*)e
)->var
->isVarDeclaration();
191 if (v
&& v
->storage_class
& STCmanifest
)
193 e
= v
->getConstInitializer();
199 static Expression
*getValue(Dsymbol
*&s
)
201 Expression
*e
= NULL
;
204 VarDeclaration
*v
= s
->isVarDeclaration();
205 if (v
&& v
->storage_class
& STCmanifest
)
207 e
= v
->getConstInitializer();
213 /**********************************
214 * Return true if e could be valid only as a template value parameter.
215 * Return false if it might be an alias or tuple.
216 * (Note that even in this case, it could still turn out to be a value).
218 bool definitelyValueParameter(Expression
*e
)
220 // None of these can be value parameters
221 if (e
->op
== TOKtuple
|| e
->op
== TOKscope
||
222 e
->op
== TOKtype
|| e
->op
== TOKdottype
||
223 e
->op
== TOKtemplate
|| e
->op
== TOKdottd
||
224 e
->op
== TOKfunction
|| e
->op
== TOKerror
||
225 e
->op
== TOKthis
|| e
->op
== TOKsuper
)
228 if (e
->op
!= TOKdotvar
)
231 /* Template instantiations involving a DotVar expression are difficult.
232 * In most cases, they should be treated as a value parameter, and interpreted.
233 * But they might also just be a fully qualified name, which should be treated
237 // x.y.f cannot be a value
238 FuncDeclaration
*f
= ((DotVarExp
*)e
)->var
->isFuncDeclaration();
242 while (e
->op
== TOKdotvar
)
244 e
= ((DotVarExp
*)e
)->e1
;
246 // this.x.y and super.x.y couldn't possibly be valid values.
247 if (e
->op
== TOKthis
|| e
->op
== TOKsuper
)
250 // e.type.x could be an alias
251 if (e
->op
== TOKdottype
)
254 // var.x.y is the only other possible form of alias
258 VarDeclaration
*v
= ((VarExp
*)e
)->var
->isVarDeclaration();
260 // func.x.y is not an alias
264 // TODO: Should we force CTFE if it is a global constant?
269 static Expression
*getExpression(RootObject
*o
)
271 Dsymbol
*s
= isDsymbol(o
);
272 return s
? getValue(s
) : getValue(isExpression(o
));
275 /******************************
276 * If o1 matches o2, return true.
277 * Else, return false.
280 static bool match(RootObject
*o1
, RootObject
*o2
)
282 //printf("match() o1 = %p %s (%d), o2 = %p %s (%d)\n",
283 // o1, o1->toChars(), o1->dyncast(), o2, o2->toChars(), o2->dyncast());
285 /* A proper implementation of the various equals() overrides
286 * should make it possible to just do o1->equals(o2), but
287 * we'll do that another day.
290 /* Manifest constants should be compared by their values,
291 * at least in template arguments.
294 if (Type
*t1
= isType(o1
))
296 Type
*t2
= isType(o2
);
300 //printf("\tt1 = %s\n", t1->toChars());
301 //printf("\tt2 = %s\n", t2->toChars());
307 if (Expression
*e1
= getExpression(o1
))
309 Expression
*e2
= getExpression(o2
);
313 //printf("\te1 = %s %s %s\n", e1->type->toChars(), Token::toChars(e1->op), e1->toChars());
314 //printf("\te2 = %s %s %s\n", e2->type->toChars(), Token::toChars(e2->op), e2->toChars());
316 // two expressions can be equal although they do not have the same
317 // type; that happens when they have the same value. So check type
318 // as well as expression equality to ensure templates are properly
320 if (!e1
->type
->equals(e2
->type
) || !e1
->equals(e2
))
325 if (Dsymbol
*s1
= isDsymbol(o1
))
327 Dsymbol
*s2
= isDsymbol(o2
);
331 //printf("\ts1 = %s\n", s1->toChars());
332 //printf("\ts2 = %s\n", s2->toChars());
335 if (s1
->parent
!= s2
->parent
&& !s1
->isFuncDeclaration() && !s2
->isFuncDeclaration())
340 if (Tuple
*u1
= isTuple(o1
))
342 Tuple
*u2
= isTuple(o2
);
346 //printf("\tu1 = %s\n", u1->toChars());
347 //printf("\tu2 = %s\n", u2->toChars());
348 if (!arrayObjectMatch(&u1
->objects
, &u2
->objects
))
354 //printf("\t-> match\n");
358 //printf("\t-> nomatch\n");
363 /************************************
364 * Match an array of them.
366 int arrayObjectMatch(Objects
*oa1
, Objects
*oa2
)
370 if (oa1
->length
!= oa2
->length
)
372 for (size_t j
= 0; j
< oa1
->length
; j
++)
374 RootObject
*o1
= (*oa1
)[j
];
375 RootObject
*o2
= (*oa2
)[j
];
385 /************************************
386 * Computes hash of expression.
387 * Handles all Expression classes and MUST match their equals method,
388 * i.e. e1->equals(e2) implies expressionHash(e1) == expressionHash(e2).
390 static hash_t
expressionHash(Expression
*e
)
395 return (size_t) ((IntegerExp
*)e
)->getInteger();
398 return CTFloat::hash(((RealExp
*)e
)->value
);
402 ComplexExp
*ce
= (ComplexExp
*)e
;
403 return mixHash(CTFloat::hash(ce
->toReal()), CTFloat::hash(ce
->toImaginary()));
407 return (size_t)(void *) ((IdentifierExp
*)e
)->ident
;
410 return (size_t)(void *) ((NullExp
*)e
)->type
;
414 StringExp
*se
= (StringExp
*)e
;
415 return calcHash((const char *)se
->string
, se
->len
* se
->sz
);
420 TupleExp
*te
= (TupleExp
*)e
;
422 hash
+= te
->e0
? expressionHash(te
->e0
) : 0;
423 for (size_t i
= 0; i
< te
->exps
->length
; i
++)
425 Expression
*elem
= (*te
->exps
)[i
];
426 hash
= mixHash(hash
, expressionHash(elem
));
431 case TOKarrayliteral
:
433 ArrayLiteralExp
*ae
= (ArrayLiteralExp
*)e
;
435 for (size_t i
= 0; i
< ae
->elements
->length
; i
++)
436 hash
= mixHash(hash
, expressionHash(ae
->getElement(i
)));
440 case TOKassocarrayliteral
:
442 AssocArrayLiteralExp
*ae
= (AssocArrayLiteralExp
*)e
;
444 for (size_t i
= 0; i
< ae
->keys
->length
; i
++)
445 // reduction needs associative op as keys are unsorted (use XOR)
446 hash
^= mixHash(expressionHash((*ae
->keys
)[i
]), expressionHash((*ae
->values
)[i
]));
450 case TOKstructliteral
:
452 StructLiteralExp
*se
= (StructLiteralExp
*)e
;
454 for (size_t i
= 0; i
< se
->elements
->length
; i
++)
456 Expression
*elem
= (*se
->elements
)[i
];
457 hash
= mixHash(hash
, elem
? expressionHash(elem
) : 0);
463 return (size_t)(void *) ((VarExp
*)e
)->var
;
466 return (size_t)(void *) ((FuncExp
*)e
)->fd
;
469 // no custom equals for this expression
470 // equals based on identity
471 return (size_t)(void *) e
;
476 /************************************
477 * Return hash of Objects.
479 static hash_t
arrayObjectHash(Objects
*oa1
)
482 for (size_t j
= 0; j
< oa1
->length
; j
++)
484 /* Must follow the logic of match()
486 RootObject
*o1
= (*oa1
)[j
];
487 if (Type
*t1
= isType(o1
))
488 hash
= mixHash(hash
, (size_t)t1
->deco
);
489 else if (Expression
*e1
= getExpression(o1
))
490 hash
= mixHash(hash
, expressionHash(e1
));
491 else if (Dsymbol
*s1
= isDsymbol(o1
))
493 FuncAliasDeclaration
*fa1
= s1
->isFuncAliasDeclaration();
495 s1
= fa1
->toAliasFunc();
496 hash
= mixHash(hash
, mixHash((size_t)(void *)s1
->getIdent(), (size_t)(void *)s1
->parent
));
498 else if (Tuple
*u1
= isTuple(o1
))
499 hash
= mixHash(hash
, arrayObjectHash(&u1
->objects
));
504 RootObject
*objectSyntaxCopy(RootObject
*o
)
508 if (Type
*t
= isType(o
))
509 return t
->syntaxCopy();
510 if (Expression
*e
= isExpression(o
))
511 return e
->syntaxCopy();
516 /* ======================== TemplateDeclaration ============================= */
518 TemplateDeclaration::TemplateDeclaration(Loc loc
, Identifier
*id
,
519 TemplateParameters
*parameters
, Expression
*constraint
, Dsymbols
*decldefs
, bool ismixin
, bool literal
)
523 this->parameters
= parameters
;
524 this->origParameters
= parameters
;
525 this->constraint
= constraint
;
526 this->members
= decldefs
;
527 this->overnext
= NULL
;
528 this->overroot
= NULL
;
529 this->funcroot
= NULL
;
530 this->onemember
= NULL
;
531 this->literal
= literal
;
532 this->ismixin
= ismixin
;
533 this->isstatic
= true;
534 this->previous
= NULL
;
535 this->protection
= Prot(Prot::undefined
);
537 this->instances
= NULL
;
539 // Compute in advance for Ddoc's use
540 // Bugzilla 11153: ident could be NULL if parsing fails.
541 if (members
&& ident
)
544 if (Dsymbol::oneMembers(members
, &s
, ident
) && s
)
552 Dsymbol
*TemplateDeclaration::syntaxCopy(Dsymbol
*)
554 //printf("TemplateDeclaration::syntaxCopy()\n");
555 TemplateParameters
*p
= NULL
;
558 p
= new TemplateParameters();
559 p
->setDim(parameters
->length
);
560 for (size_t i
= 0; i
< p
->length
; i
++)
561 (*p
)[i
] = (*parameters
)[i
]->syntaxCopy();
563 return new TemplateDeclaration(loc
, ident
, p
,
564 constraint
? constraint
->syntaxCopy() : NULL
,
565 Dsymbol::arraySyntaxCopy(members
), ismixin
, literal
);
568 const char *TemplateDeclaration::kind() const
570 return (onemember
&& onemember
->isAggregateDeclaration())
575 /**********************************
576 * Overload existing TemplateDeclaration 'this' with the new one 's'.
577 * Return true if successful; i.e. no conflict.
580 bool TemplateDeclaration::overloadInsert(Dsymbol
*s
)
582 FuncDeclaration
*fd
= s
->isFuncDeclaration();
586 return funcroot
->overloadInsert(fd
);
588 return funcroot
->overloadInsert(this);
591 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
595 TemplateDeclaration
*pthis
= this;
596 TemplateDeclaration
**ptd
;
597 for (ptd
= &pthis
; *ptd
; ptd
= &(*ptd
)->overnext
)
606 /****************************
607 * Check to see if constraint is satisfied.
609 bool TemplateDeclaration::evaluateConstraint(
610 TemplateInstance
*ti
, Scope
*sc
, Scope
*paramscope
,
611 Objects
*dedargs
, FuncDeclaration
*fd
)
613 /* Detect recursive attempts to instantiate this template declaration,
615 * void foo(T)(T x) if (is(typeof(foo(x)))) { }
616 * static assert(!is(typeof(foo(7))));
617 * Recursive attempts are regarded as a constraint failure.
619 /* There's a chicken-and-egg problem here. We don't know yet if this template
620 * instantiation will be a local one (enclosing is set), and we won't know until
621 * after selecting the correct template. Thus, function we're nesting inside
622 * is not on the sc scope chain, and this can cause errors in FuncDeclaration::getLevel().
623 * Workaround the problem by setting a flag to relax the checking on frame errors.
626 for (TemplatePrevious
*p
= previous
; p
; p
= p
->prev
)
628 if (arrayObjectMatch(p
->dedargs
, dedargs
))
630 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
631 /* It must be a subscope of p->sc, other scope chains are not recursive
634 for (Scope
*scx
= sc
; scx
; scx
= scx
->enclosing
)
640 /* BUG: should also check for ref param differences
647 pr
.dedargs
= dedargs
;
648 previous
= &pr
; // add this to threaded list
650 Scope
*scx
= paramscope
->push(ti
);
658 /* Declare all the function parameters as variables and add them to the scope
659 * Making parameters is similar to FuncDeclaration::semantic3
661 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
662 assert(tf
->ty
== Tfunction
);
666 Parameters
*fparameters
= tf
->parameterList
.parameters
;
667 VarArg fvarargs
= tf
->parameterList
.varargs
;
669 size_t nfparams
= Parameter::dim(fparameters
);
670 for (size_t i
= 0; i
< nfparams
; i
++)
672 Parameter
*fparam
= Parameter::getNth(fparameters
, i
);
673 fparam
->storageClass
&= (STCin
| STCout
| STCref
| STClazy
| STCfinal
| STC_TYPECTOR
| STCnodtor
);
674 fparam
->storageClass
|= STCparameter
;
675 if (fvarargs
== VARARGtypesafe
&& i
+ 1 == nfparams
)
676 fparam
->storageClass
|= STCvariadic
;
678 for (size_t i
= 0; i
< fparameters
->length
; i
++)
680 Parameter
*fparam
= (*fparameters
)[i
];
682 continue; // don't add it, if it has no name
683 VarDeclaration
*v
= new VarDeclaration(loc
, fparam
->type
, fparam
->ident
, NULL
);
684 v
->storage_class
= fparam
->storageClass
;
685 dsymbolSemantic(v
, scx
);
687 ti
->symtab
= new DsymbolTable();
689 error("parameter %s.%s is already defined", toChars(), v
->toChars());
694 fd
->storage_class
|= STCstatic
;
696 fd
->vthis
= fd
->declareThis(scx
, fd
->isThis());
699 Expression
*e
= constraint
->syntaxCopy();
701 assert(ti
->inst
== NULL
);
702 ti
->inst
= ti
; // temporary instantiation to enable genIdent()
704 scx
->flags
|= SCOPEconstraint
;
706 bool result
= evalStaticCondition(scx
, constraint
, e
, errors
);
710 previous
= pr
.prev
; // unlink from threaded list
716 /***************************************
717 * Given that ti is an instance of this TemplateDeclaration,
718 * deduce the types of the parameters to this, and store
719 * those deduced types in dedtypes[].
721 * flag 1: don't do semantic() because of dummy types
722 * 2: don't change types in matchArg()
724 * dedtypes deduced arguments
725 * Return match level.
728 MATCH
TemplateDeclaration::matchWithInstance(Scope
*sc
, TemplateInstance
*ti
,
729 Objects
*dedtypes
, Expressions
*fargs
, int flag
)
732 size_t dedtypes_dim
= dedtypes
->length
;
739 size_t parameters_dim
= parameters
->length
;
740 int variadic
= isVariadic() != NULL
;
742 // If more arguments than parameters, no match
743 if (ti
->tiargs
->length
> parameters_dim
&& !variadic
)
748 assert(dedtypes_dim
== parameters_dim
);
749 assert(dedtypes_dim
>= ti
->tiargs
->length
|| variadic
);
753 // Set up scope for template parameters
754 ScopeDsymbol
*paramsym
= new ScopeDsymbol();
755 paramsym
->parent
= _scope
->parent
;
756 Scope
*paramscope
= _scope
->push(paramsym
);
757 paramscope
->tinst
= ti
;
758 paramscope
->minst
= sc
->minst
;
759 paramscope
->callsc
= sc
;
762 // Attempt type deduction
764 for (size_t i
= 0; i
< dedtypes_dim
; i
++)
767 TemplateParameter
*tp
= (*parameters
)[i
];
770 //printf("\targument [%d]\n", i);
772 m2
= tp
->matchArg(ti
->loc
, paramscope
, ti
->tiargs
, i
, parameters
, dedtypes
, &sparam
);
774 //printf("\tm2 = %d\n", m2);
776 if (m2
== MATCHnomatch
)
785 dsymbolSemantic(sparam
, paramscope
);
786 if (!paramscope
->insert(sparam
)) // TODO: This check can make more early
787 goto Lnomatch
; // in TemplateDeclaration::semantic, and
788 // then we don't need to make sparam if flags == 0
793 /* Any parameter left without a type gets the type of
794 * its corresponding arg
796 for (size_t i
= 0; i
< dedtypes_dim
; i
++)
800 assert(i
< ti
->tiargs
->length
);
801 (*dedtypes
)[i
] = (Type
*)(*ti
->tiargs
)[i
];
806 if (m
> MATCHnomatch
&& constraint
&& !flag
)
808 if (ti
->hasNestedArgs(ti
->tiargs
, this->isstatic
)) // TODO: should gag error
809 ti
->parent
= ti
->enclosing
;
811 ti
->parent
= this->parent
;
813 // Similar to doHeaderInstantiation
814 FuncDeclaration
*fd
= onemember
? onemember
->isFuncDeclaration() : NULL
;
817 assert(fd
->type
->ty
== Tfunction
);
818 TypeFunction
*tf
= (TypeFunction
*)fd
->type
->syntaxCopy();
820 fd
= new FuncDeclaration(fd
->loc
, fd
->endloc
, fd
->ident
, fd
->storage_class
, tf
);
822 fd
->inferRetType
= true;
824 // Shouldn't run semantic on default arguments and return type.
825 for (size_t i
= 0; i
< tf
->parameterList
.parameters
->length
; i
++)
826 (*tf
->parameterList
.parameters
)[i
]->defaultArg
= NULL
;
829 // Resolve parameter types and 'auto ref's.
831 unsigned olderrors
= global
.startGagging();
832 fd
->type
= typeSemantic(tf
, loc
, paramscope
);
833 if (global
.endGagging(olderrors
))
835 assert(fd
->type
->ty
!= Tfunction
);
838 assert(fd
->type
->ty
== Tfunction
);
839 fd
->originalType
= fd
->type
; // for mangling
842 // TODO: dedtypes => ti->tiargs ?
843 if (!evaluateConstraint(ti
, sc
, paramscope
, dedtypes
, fd
))
857 /********************************************
858 * Determine partial specialization order of 'this' vs td2.
860 * match this is at least as specialized as td2
861 * 0 td2 is more specialized than this
864 MATCH
TemplateDeclaration::leastAsSpecialized(Scope
*sc
, TemplateDeclaration
*td2
, Expressions
*fargs
)
866 /* This works by taking the template parameters to this template
867 * declaration and feeding them to td2 as if it were a template
869 * If it works, then this template is at least as specialized
873 TemplateInstance
ti(Loc(), ident
); // create dummy template instance
874 // Set type arguments to dummy template instance to be types
875 // generated from the parameters to this template declaration
876 ti
.tiargs
= new Objects();
877 ti
.tiargs
->reserve(parameters
->length
);
878 for (size_t i
= 0; i
< parameters
->length
; i
++)
880 TemplateParameter
*tp
= (*parameters
)[i
];
883 RootObject
*p
= (RootObject
*)tp
->dummyArg();
890 // Temporary Array to hold deduced types
892 dedtypes
.setDim(td2
->parameters
->length
);
894 // Attempt a type deduction
895 MATCH m
= td2
->matchWithInstance(sc
, &ti
, &dedtypes
, fargs
, 1);
896 if (m
> MATCHnomatch
)
898 /* A non-variadic template is more specialized than a
901 TemplateTupleParameter
*tp
= isVariadic();
902 if (tp
&& !tp
->dependent
&& !td2
->isVariadic())
911 static Expression
*emptyArrayElement
= NULL
;
913 class TypeDeduced
: public Type
917 Expressions argexps
; // corresponding expressions
918 Types tparams
; // tparams[i]->mod
920 TypeDeduced(Type
*tt
, Expression
*e
, Type
*tparam
)
925 tparams
.push(tparam
);
928 virtual ~TypeDeduced()
932 void update(Expression
*e
, Type
*tparam
)
935 tparams
.push(tparam
);
937 void update(Type
*tt
, Expression
*e
, Type
*tparam
)
941 tparams
.push(tparam
);
943 MATCH
matchAll(Type
*tt
)
945 MATCH match
= MATCHexact
;
946 for (size_t j
= 0; j
< argexps
.length
; j
++)
948 Expression
*e
= argexps
[j
];
950 if (e
== emptyArrayElement
)
953 Type
*t
= tt
->addMod(tparams
[j
]->mod
)->substWildTo(MODconst
);
955 MATCH m
= e
->implicitConvTo(t
);
958 if (match
<= MATCHnomatch
)
965 /*************************************************
966 * Match function arguments against a specific template function.
969 * sc instantiation scope
971 * tthis 'this' argument if !NULL
972 * fargs arguments to function
974 * fd Partially instantiated function declaration
975 * ti->tdtypes Expression/Type deduced template arguments
978 * bit 0-3 Match template parameters by inferred template arguments
979 * bit 4-7 Match template parameters by initial template arguments
982 MATCH
TemplateDeclaration::deduceFunctionTemplateMatch(
983 TemplateInstance
*ti
, Scope
*sc
,
984 FuncDeclaration
*&fd
, Type
*tthis
, Expressions
*fargs
)
988 size_t ntargs
; // array size of tiargs
989 size_t fptupindex
= IDX_NOTFOUND
;
990 MATCH match
= MATCHexact
;
991 MATCH matchTiargs
= MATCHexact
;
992 ParameterList fparameters
; // function parameter list
993 unsigned wildmatch
= 0;
994 size_t inferStart
= 0;
996 Loc instLoc
= ti
->loc
;
997 Objects
*tiargs
= ti
->tiargs
;
998 Objects
*dedargs
= new Objects();
999 Objects
* dedtypes
= &ti
->tdtypes
; // for T:T*, the dedargs is the T*, dedtypes is the T
1003 dedargs
->setDim(parameters
->length
);
1006 dedtypes
->setDim(parameters
->length
);
1009 if (errors
|| fd
->errors
)
1010 return MATCHnomatch
;
1012 // Set up scope for parameters
1013 ScopeDsymbol
*paramsym
= new ScopeDsymbol();
1014 paramsym
->parent
= _scope
->parent
; // should use hasnestedArgs and enclosing?
1015 Scope
*paramscope
= _scope
->push(paramsym
);
1016 paramscope
->tinst
= ti
;
1017 paramscope
->minst
= sc
->minst
;
1018 paramscope
->callsc
= sc
;
1019 paramscope
->stc
= 0;
1021 TemplateTupleParameter
*tp
= isVariadic();
1022 Tuple
*declaredTuple
= NULL
;
1027 // Set initial template arguments
1028 ntargs
= tiargs
->length
;
1029 size_t n
= parameters
->length
;
1037 /* The extra initial template arguments
1038 * now form the tuple argument.
1040 Tuple
*t
= new Tuple();
1041 assert(parameters
->length
);
1042 (*dedargs
)[parameters
->length
- 1] = t
;
1044 t
->objects
.setDim(ntargs
- n
);
1045 for (size_t i
= 0; i
< t
->objects
.length
; i
++)
1047 t
->objects
[i
] = (*tiargs
)[n
+ i
];
1049 declareParameter(paramscope
, tp
, t
);
1055 memcpy(dedargs
->tdata(), tiargs
->tdata(), n
* sizeof(*dedargs
->tdata()));
1057 for (size_t i
= 0; i
< n
; i
++)
1059 assert(i
< parameters
->length
);
1060 Declaration
*sparam
= NULL
;
1061 MATCH m
= (*parameters
)[i
]->matchArg(instLoc
, paramscope
, dedargs
, i
, parameters
, dedtypes
, &sparam
);
1062 //printf("\tdeduceType m = %d\n", m);
1063 if (m
<= MATCHnomatch
)
1065 if (m
< matchTiargs
)
1068 dsymbolSemantic(sparam
, paramscope
);
1069 if (!paramscope
->insert(sparam
))
1072 if (n
< parameters
->length
&& !declaredTuple
)
1077 inferStart
= parameters
->length
;
1078 //printf("tiargs matchTiargs = %d\n", matchTiargs);
1081 fparameters
= fd
->getParameterList();
1082 nfparams
= fparameters
.length(); // number of function parameters
1083 nfargs
= fargs
? fargs
->length
: 0; // number of function arguments
1085 /* Check for match of function arguments with variadic template
1086 * parameter, such as:
1088 * void foo(T, A...)(T t, A a);
1089 * void main() { foo(1,2,3); }
1091 if (tp
) // if variadic
1093 // TemplateTupleParameter always makes most lesser matching.
1094 matchTiargs
= MATCHconvert
;
1096 if (nfparams
== 0 && nfargs
!= 0) // if no function parameters
1100 Tuple
*t
= new Tuple();
1101 //printf("t = %p\n", t);
1102 (*dedargs
)[parameters
->length
- 1] = t
;
1103 declareParameter(paramscope
, tp
, t
);
1109 /* Figure out which of the function parameters matches
1110 * the tuple template parameter. Do this by matching
1112 * Set the index of this function parameter to fptupindex.
1114 for (fptupindex
= 0; fptupindex
< nfparams
; fptupindex
++)
1116 Parameter
*fparam
= (*fparameters
.parameters
)[fptupindex
];
1117 if (fparam
->type
->ty
!= Tident
)
1119 TypeIdentifier
*tid
= (TypeIdentifier
*)fparam
->type
;
1120 if (!tp
->ident
->equals(tid
->ident
) || tid
->idents
.length
)
1123 if (fparameters
.varargs
!= VARARGnone
) // variadic function doesn't
1124 goto Lnomatch
; // go with variadic template
1128 fptupindex
= IDX_NOTFOUND
;
1134 if (toParent()->isModule() || (_scope
->stc
& STCstatic
))
1138 bool hasttp
= false;
1140 // Match 'tthis' to any TemplateThisParameter's
1141 for (size_t i
= 0; i
< parameters
->length
; i
++)
1143 TemplateThisParameter
*ttp
= (*parameters
)[i
]->isTemplateThisParameter();
1148 Type
*t
= new TypeIdentifier(Loc(), ttp
->ident
);
1149 MATCH m
= deduceType(tthis
, paramscope
, t
, parameters
, dedtypes
);
1150 if (m
<= MATCHnomatch
)
1153 match
= m
; // pick worst match
1157 // Match attributes of tthis against attributes of fd
1158 if (fd
->type
&& !fd
->isCtorDeclaration())
1160 StorageClass stc
= _scope
->stc
| fd
->storage_class2
;
1161 // Propagate parent storage class (see bug 5504)
1162 Dsymbol
*p
= parent
;
1163 while (p
->isTemplateDeclaration() || p
->isTemplateInstance())
1165 AggregateDeclaration
*ad
= p
->isAggregateDeclaration();
1167 stc
|= ad
->storage_class
;
1169 unsigned char mod
= fd
->type
->mod
;
1170 if (stc
& STCimmutable
)
1174 if (stc
& (STCshared
| STCsynchronized
))
1182 unsigned char thismod
= tthis
->mod
;
1184 mod
= MODmerge(thismod
, mod
);
1185 MATCH m
= MODmethodConv(thismod
, mod
);
1186 if (m
<= MATCHnomatch
)
1193 // Loop through the function parameters
1195 //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple->objects.length : 0);
1196 //printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple->toChars() : NULL);
1198 size_t nfargs2
= nfargs
; // nfargs + supplied defaultArgs
1199 for (size_t parami
= 0; parami
< nfparams
; parami
++)
1201 Parameter
*fparam
= fparameters
[parami
];
1203 // Apply function parameter storage classes to parameter types
1204 Type
*prmtype
= fparam
->type
->addStorageClass(fparam
->storageClass
);
1208 /* See function parameters which wound up
1209 * as part of a template tuple parameter.
1211 if (fptupindex
!= IDX_NOTFOUND
&& parami
== fptupindex
)
1213 assert(prmtype
->ty
== Tident
);
1214 TypeIdentifier
*tid
= (TypeIdentifier
*)prmtype
;
1217 /* The types of the function arguments
1218 * now form the tuple argument.
1220 declaredTuple
= new Tuple();
1221 (*dedargs
)[parameters
->length
- 1] = declaredTuple
;
1223 /* Count function parameters following a tuple parameter.
1224 * void foo(U, T...)(int y, T, U, int) {} // rem == 2 (U, int)
1227 for (size_t j
= parami
+ 1; j
< nfparams
; j
++)
1229 Parameter
*p
= fparameters
[j
];
1230 if (!reliesOnTident(p
->type
, parameters
, inferStart
))
1232 Type
*pt
= typeSemantic(p
->type
->syntaxCopy(), fd
->loc
, paramscope
);
1233 rem
+= pt
->ty
== Ttuple
? ((TypeTuple
*)pt
)->arguments
->length
: 1;
1241 if (nfargs2
- argi
< rem
)
1243 declaredTuple
->objects
.setDim(nfargs2
- argi
- rem
);
1244 for (size_t i
= 0; i
< declaredTuple
->objects
.length
; i
++)
1246 farg
= (*fargs
)[argi
+ i
];
1248 // Check invalid arguments to detect errors early.
1249 if (farg
->op
== TOKerror
|| farg
->type
->ty
== Terror
)
1252 if (!(fparam
->storageClass
& STClazy
) && farg
->type
->ty
== Tvoid
)
1257 if (unsigned char wm
= deduceWildHelper(farg
->type
, &tt
, tid
))
1264 m
= deduceTypeHelper(farg
->type
, &tt
, tid
);
1266 if (m
<= MATCHnomatch
)
1271 /* Remove top const for dynamic array types and pointer types
1273 if ((tt
->ty
== Tarray
|| tt
->ty
== Tpointer
) &&
1275 (!(fparam
->storageClass
& STCref
) ||
1276 ((fparam
->storageClass
& STCauto
) && !farg
->isLvalue())))
1278 tt
= tt
->mutableOf();
1280 declaredTuple
->objects
[i
] = tt
;
1282 declareParameter(paramscope
, tp
, declaredTuple
);
1286 // Bugzilla 6810: If declared tuple is not a type tuple,
1287 // it cannot be function parameter types.
1288 for (size_t i
= 0; i
< declaredTuple
->objects
.length
; i
++)
1290 if (!isType(declaredTuple
->objects
[i
]))
1294 assert(declaredTuple
);
1295 argi
+= declaredTuple
->objects
.length
;
1299 // If parameter type doesn't depend on inferred template parameters,
1300 // semantic it to get actual type.
1301 if (!reliesOnTident(prmtype
, parameters
, inferStart
))
1303 // should copy prmtype to avoid affecting semantic result
1304 prmtype
= typeSemantic(prmtype
->syntaxCopy(), fd
->loc
, paramscope
);
1306 if (prmtype
->ty
== Ttuple
)
1308 TypeTuple
*tt
= (TypeTuple
*)prmtype
;
1309 size_t tt_dim
= tt
->arguments
->length
;
1310 for (size_t j
= 0; j
< tt_dim
; j
++, ++argi
)
1312 Parameter
*p
= (*tt
->arguments
)[j
];
1313 if (j
== tt_dim
- 1 && fparameters
.varargs
== VARARGtypesafe
&&
1314 parami
+ 1 == nfparams
&& argi
< nfargs
)
1325 farg
= (*fargs
)[argi
];
1326 if (!farg
->implicitConvTo(p
->type
))
1333 if (argi
>= nfargs
) // if not enough arguments
1335 if (!fparam
->defaultArg
)
1338 /* Bugzilla 2803: Before the starting of type deduction from the function
1339 * default arguments, set the already deduced parameters into paramscope.
1340 * It's necessary to avoid breaking existing acceptable code. Cases:
1342 * 1. Already deduced template parameters can appear in fparam->defaultArg:
1343 * auto foo(A, B)(A a, B b = A.stringof);
1345 * // at fparam == 'B b = A.string', A is equivalent with the deduced type 'int'
1347 * 2. If prmtype depends on default-specified template parameter, the
1348 * default type should be preferred.
1349 * auto foo(N = size_t, R)(R r, N start = 0)
1351 * // at fparam `N start = 0`, N should be 'size_t' before
1352 * // the deduction result from fparam->defaultArg.
1356 for (size_t i
= 0; i
< dedtypes
->length
; i
++)
1358 Type
*at
= isType((*dedtypes
)[i
]);
1359 if (at
&& at
->ty
== Tnone
)
1361 TypeDeduced
*xt
= (TypeDeduced
*)at
;
1362 (*dedtypes
)[i
] = xt
->tded
; // 'unbox'
1366 for (size_t i
= ntargs
; i
< dedargs
->length
; i
++)
1368 TemplateParameter
*tparam
= (*parameters
)[i
];
1370 RootObject
*oarg
= (*dedargs
)[i
];
1371 RootObject
*oded
= (*dedtypes
)[i
];
1376 if (tparam
->specialization() || !tparam
->isTemplateTypeParameter())
1378 /* The specialization can work as long as afterwards
1381 (*dedargs
)[i
] = oded
;
1382 MATCH m2
= tparam
->matchArg(instLoc
, paramscope
, dedargs
, i
, parameters
, dedtypes
, NULL
);
1383 //printf("m2 = %d\n", m2);
1384 if (m2
<= MATCHnomatch
)
1386 if (m2
< matchTiargs
)
1387 matchTiargs
= m2
; // pick worst match
1388 if (!(*dedtypes
)[i
]->equals(oded
))
1389 error("specialization not allowed for deduced parameter %s", tparam
->ident
->toChars());
1393 if (MATCHconvert
< matchTiargs
)
1394 matchTiargs
= MATCHconvert
;
1396 (*dedargs
)[i
] = declareParameter(paramscope
, tparam
, oded
);
1401 oded
= tparam
->defaultArg(instLoc
, paramscope
);
1404 (*dedargs
)[i
] = declareParameter(paramscope
, tparam
, oded
);
1411 /* If prmtype does not depend on any template parameters:
1413 * auto foo(T)(T v, double x = 0);
1415 * // at fparam == 'double x = 0'
1417 * or, if all template parameters in the prmtype are already deduced:
1419 * auto foo(R)(R range, ElementType!R sum = 0);
1421 * // at fparam == 'ElementType!R sum = 0'
1423 * Deducing prmtype from fparam->defaultArg is not necessary.
1425 if (prmtype
->deco
||
1426 prmtype
->syntaxCopy()->trySemantic(loc
, paramscope
))
1432 // Deduce prmtype from the defaultArg.
1433 farg
= fparam
->defaultArg
->syntaxCopy();
1434 farg
= expressionSemantic(farg
, paramscope
);
1435 farg
= resolveProperties(paramscope
, farg
);
1439 farg
= (*fargs
)[argi
];
1442 // Check invalid arguments to detect errors early.
1443 if (farg
->op
== TOKerror
|| farg
->type
->ty
== Terror
)
1448 Type
*argtype
= farg
->type
;
1450 if (!(fparam
->storageClass
& STClazy
) && argtype
->ty
== Tvoid
&& farg
->op
!= TOKfunction
)
1453 // Bugzilla 12876: optimize arugument to allow CT-known length matching
1454 farg
= farg
->optimize(WANTvalue
, (fparam
->storageClass
& (STCref
| STCout
)) != 0);
1455 //printf("farg = %s %s\n", farg->type->toChars(), farg->toChars());
1457 RootObject
*oarg
= farg
;
1458 if ((fparam
->storageClass
& STCref
) &&
1459 (!(fparam
->storageClass
& STCauto
) || farg
->isLvalue()))
1461 /* Allow expressions that have CT-known boundaries and type [] to match with [dim]
1464 if (argtype
->ty
== Tarray
&&
1465 (prmtype
->ty
== Tsarray
||
1466 (prmtype
->ty
== Taarray
&& (taai
= ((TypeAArray
*)prmtype
)->index
)->ty
== Tident
&&
1467 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
1469 if (farg
->op
== TOKstring
)
1471 StringExp
*se
= (StringExp
*)farg
;
1472 argtype
= se
->type
->nextOf()->sarrayOf(se
->len
);
1474 else if (farg
->op
== TOKarrayliteral
)
1476 ArrayLiteralExp
*ae
= (ArrayLiteralExp
*)farg
;
1477 argtype
= ae
->type
->nextOf()->sarrayOf(ae
->elements
->length
);
1479 else if (farg
->op
== TOKslice
)
1481 SliceExp
*se
= (SliceExp
*)farg
;
1482 if (Type
*tsa
= toStaticArrayType(se
))
1489 else if ((fparam
->storageClass
& STCout
) == 0 &&
1490 (argtype
->ty
== Tarray
|| argtype
->ty
== Tpointer
) &&
1491 templateParameterLookup(prmtype
, parameters
) != IDX_NOTFOUND
&&
1492 ((TypeIdentifier
*)prmtype
)->idents
.length
== 0)
1494 /* The farg passing to the prmtype always make a copy. Therefore,
1495 * we can shrink the set of the deduced type arguments for prmtype
1496 * by adjusting top-qualifier of the argtype.
1498 * prmtype argtype ta
1499 * T <- const(E)[] const(E)[]
1500 * T <- const(E[]) const(E)[]
1501 * qualifier(T) <- const(E)[] const(E[])
1502 * qualifier(T) <- const(E[]) const(E[])
1504 Type
*ta
= argtype
->castMod(prmtype
->mod
? argtype
->nextOf()->mod
: 0);
1507 Expression
*ea
= farg
->copy();
1513 if (fparameters
.varargs
== VARARGtypesafe
&& parami
+ 1 == nfparams
&& argi
+ 1 < nfargs
)
1517 MATCH m
= deduceType(oarg
, paramscope
, prmtype
, parameters
, dedtypes
, &wm
, inferStart
);
1518 //printf("\tL%d deduceType m = %d, wm = x%x, wildmatch = x%x\n", __LINE__, m, wm, wildmatch);
1521 /* If no match, see if the argument can be matched by using
1522 * implicit conversions.
1524 if (m
== MATCHnomatch
&& prmtype
->deco
)
1525 m
= farg
->implicitConvTo(prmtype
);
1527 if (m
== MATCHnomatch
)
1529 AggregateDeclaration
*ad
= isAggregate(farg
->type
);
1530 if (ad
&& ad
->aliasthis
&& argtype
!= att
)
1532 if (!att
&& argtype
->checkAliasThisRec()) // Bugzilla 12537
1535 /* If a semantic error occurs while doing alias this,
1536 * eg purity(bug 7295), just regard it as not a match.
1538 if (Expression
*e
= resolveAliasThis(sc
, farg
, true))
1546 if (m
> MATCHnomatch
&& (fparam
->storageClass
& (STCref
| STCauto
)) == STCref
)
1548 if (!farg
->isLvalue())
1550 if ((farg
->op
== TOKstring
|| farg
->op
== TOKslice
) &&
1551 (prmtype
->ty
== Tsarray
|| prmtype
->ty
== Taarray
))
1553 // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
1559 if (m
> MATCHnomatch
&& (fparam
->storageClass
& STCout
))
1561 if (!farg
->isLvalue())
1563 if (!farg
->type
->isMutable()) // Bugzilla 11916
1566 if (m
== MATCHnomatch
&& (fparam
->storageClass
& STClazy
) && prmtype
->ty
== Tvoid
&&
1567 farg
->type
->ty
!= Tvoid
)
1570 if (m
!= MATCHnomatch
)
1573 match
= m
; // pick worst match
1580 /* The following code for variadic arguments closely
1581 * matches TypeFunction::callMatch()
1583 if (!(fparameters
.varargs
== VARARGtypesafe
&& parami
+ 1 == nfparams
))
1586 /* Check for match with function parameter T...
1588 Type
*tb
= prmtype
->toBasetype();
1591 // 6764 fix - TypeAArray may be TypeSArray have not yet run semantic().
1594 // Perhaps we can do better with this, see TypeFunction::callMatch()
1595 if (tb
->ty
== Tsarray
)
1597 TypeSArray
*tsa
= (TypeSArray
*)tb
;
1598 dinteger_t sz
= tsa
->dim
->toInteger();
1599 if (sz
!= nfargs
- argi
)
1602 else if (tb
->ty
== Taarray
)
1604 TypeAArray
*taa
= (TypeAArray
*)tb
;
1605 Expression
*dim
= new IntegerExp(instLoc
, nfargs
- argi
, Type::tsize_t
);
1607 size_t i
= templateParameterLookup(taa
->index
, parameters
);
1608 if (i
== IDX_NOTFOUND
)
1615 unsigned errors
= global
.startGagging();
1616 /* ref: https://issues.dlang.org/show_bug.cgi?id=11118
1617 * The parameter isn't part of the template
1618 * ones, let's try to find it in the
1619 * instantiation scope 'sc' and the one
1620 * belonging to the template itself. */
1622 taa
->index
->resolve(instLoc
, sco
, &e
, &t
, &s
);
1626 taa
->index
->resolve(instLoc
, sco
, &e
, &t
, &s
);
1628 global
.endGagging(errors
);
1635 e
= e
->ctfeInterpret();
1636 e
= e
->implicitCastTo(sco
, Type::tsize_t
);
1637 e
= e
->optimize(WANTvalue
);
1638 if (!dim
->equals(e
))
1643 // This code matches code in TypeInstance::deduceType()
1644 TemplateParameter
*tprm
= (*parameters
)[i
];
1645 TemplateValueParameter
*tvp
= tprm
->isTemplateValueParameter();
1648 Expression
*e
= (Expression
*)(*dedtypes
)[i
];
1651 if (!dim
->equals(e
))
1656 Type
*vt
= typeSemantic(tvp
->valType
, Loc(), sc
);
1657 MATCH m
= (MATCH
)dim
->implicitConvTo(vt
);
1658 if (m
<= MATCHnomatch
)
1660 (*dedtypes
)[i
] = dim
;
1667 TypeArray
*ta
= (TypeArray
*)tb
;
1668 Type
*tret
= fparam
->isLazyArray();
1669 for (; argi
< nfargs
; argi
++)
1671 Expression
*arg
= (*fargs
)[argi
];
1675 /* If lazy array of delegates,
1676 * convert arg(s) to delegate(s)
1680 if (ta
->next
->equals(arg
->type
))
1686 m
= arg
->implicitConvTo(tret
);
1687 if (m
== MATCHnomatch
)
1689 if (tret
->toBasetype()->ty
== Tvoid
)
1697 m
= deduceType(arg
, paramscope
, ta
->next
, parameters
, dedtypes
, &wm
, inferStart
);
1700 if (m
== MATCHnomatch
)
1716 //printf("-> argi = %d, nfargs = %d, nfargs2 = %d\n", argi, nfargs, nfargs2);
1717 if (argi
!= nfargs2
&& fparameters
.varargs
== VARARGnone
)
1723 for (size_t i
= 0; i
< dedtypes
->length
; i
++)
1725 Type
*at
= isType((*dedtypes
)[i
]);
1728 if (at
->ty
== Tnone
)
1730 TypeDeduced
*xt
= (TypeDeduced
*)at
;
1731 at
= xt
->tded
; // 'unbox'
1734 (*dedtypes
)[i
] = at
->merge2();
1737 for (size_t i
= ntargs
; i
< dedargs
->length
; i
++)
1739 TemplateParameter
*tparam
= (*parameters
)[i
];
1740 //printf("tparam[%d] = %s\n", i, tparam->ident->toChars());
1741 /* For T:T*, the dedargs is the T*, dedtypes is the T
1742 * But for function templates, we really need them to match
1744 RootObject
*oarg
= (*dedargs
)[i
];
1745 RootObject
*oded
= (*dedtypes
)[i
];
1746 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
1747 //if (oarg) printf("oarg: %s\n", oarg->toChars());
1748 //if (oded) printf("oded: %s\n", oded->toChars());
1753 if (tparam
->specialization() || !tparam
->isTemplateTypeParameter())
1755 /* The specialization can work as long as afterwards
1758 (*dedargs
)[i
] = oded
;
1759 MATCH m2
= tparam
->matchArg(instLoc
, paramscope
, dedargs
, i
, parameters
, dedtypes
, NULL
);
1760 //printf("m2 = %d\n", m2);
1761 if (m2
<= MATCHnomatch
)
1763 if (m2
< matchTiargs
)
1764 matchTiargs
= m2
; // pick worst match
1765 if (!(*dedtypes
)[i
]->equals(oded
))
1766 error("specialization not allowed for deduced parameter %s", tparam
->ident
->toChars());
1770 if (MATCHconvert
< matchTiargs
)
1771 matchTiargs
= MATCHconvert
;
1777 oded
= tparam
->defaultArg(instLoc
, paramscope
);
1781 // if tuple parameter and
1782 // tuple parameter was not in function parameter list and
1783 // we're one or more arguments short (i.e. no tuple argument)
1785 fptupindex
== IDX_NOTFOUND
&&
1786 ntargs
<= dedargs
->length
- 1)
1788 // make tuple argument an empty tuple
1789 oded
= (RootObject
*)new Tuple();
1798 /* At the template parameter T, the picked default template argument
1799 * X!int should be matched to T in order to deduce dependent
1800 * template parameter A.
1801 * auto foo(T : X!A = X!int, A...)() { ... }
1802 * foo(); // T <-- X!int, A <-- (int)
1804 if (tparam
->specialization())
1806 (*dedargs
)[i
] = oded
;
1807 MATCH m2
= tparam
->matchArg(instLoc
, paramscope
, dedargs
, i
, parameters
, dedtypes
, NULL
);
1808 //printf("m2 = %d\n", m2);
1809 if (m2
<= MATCHnomatch
)
1811 if (m2
< matchTiargs
)
1812 matchTiargs
= m2
; // pick worst match
1813 if (!(*dedtypes
)[i
]->equals(oded
))
1814 error("specialization not allowed for deduced parameter %s", tparam
->ident
->toChars());
1817 oded
= declareParameter(paramscope
, tparam
, oded
);
1818 (*dedargs
)[i
] = oded
;
1822 /* Bugzilla 7469: As same as the code for 7469 in findBestMatch,
1823 * expand a Tuple in dedargs to normalize template arguments.
1825 if (size_t d
= dedargs
->length
)
1827 if (Tuple
*va
= isTuple((*dedargs
)[d
- 1]))
1829 if (va
->objects
.length
)
1831 dedargs
->setDim(d
- 1);
1832 dedargs
->insert(d
- 1, &va
->objects
);
1836 ti
->tiargs
= dedargs
; // update to the normalized template arguments.
1838 // Partially instantiate function for constraint and fd->leastAsSpecialized()
1841 Scope
*sc2
= _scope
;
1842 sc2
= sc2
->push(paramsym
);
1843 sc2
= sc2
->push(ti
);
1846 sc2
->minst
= sc
->minst
;
1848 fd
= doHeaderInstantiation(ti
, sc2
, fd
, tthis
, fargs
);
1859 if (!evaluateConstraint(ti
, sc
, paramscope
, dedargs
, fd
))
1864 //printf("\tmatch %d\n", match);
1865 return (MATCH
)(match
| (matchTiargs
<<4));
1869 //printf("\tnomatch\n");
1870 return MATCHnomatch
;
1872 Lerror
: // todo: for the future improvement
1874 //printf("\terror\n");
1875 return MATCHnomatch
;
1878 /**************************************************
1879 * Declare template parameter tp with value o, and install it in the scope sc.
1882 RootObject
*TemplateDeclaration::declareParameter(Scope
*sc
, TemplateParameter
*tp
, RootObject
*o
)
1884 //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o);
1886 Type
*ta
= isType(o
);
1887 Expression
*ea
= isExpression(o
);
1888 Dsymbol
*sa
= isDsymbol(o
);
1889 Tuple
*va
= isTuple(o
);
1892 VarDeclaration
*v
= NULL
;
1894 if (ea
&& ea
->op
== TOKtype
)
1896 else if (ea
&& ea
->op
== TOKscope
)
1897 sa
= ((ScopeExp
*)ea
)->sds
;
1898 else if (ea
&& (ea
->op
== TOKthis
|| ea
->op
== TOKsuper
))
1899 sa
= ((ThisExp
*)ea
)->var
;
1900 else if (ea
&& ea
->op
== TOKfunction
)
1902 if (((FuncExp
*)ea
)->td
)
1903 sa
= ((FuncExp
*)ea
)->td
;
1905 sa
= ((FuncExp
*)ea
)->fd
;
1910 //printf("type %s\n", ta->toChars());
1911 d
= new AliasDeclaration(Loc(), tp
->ident
, ta
);
1915 //printf("Alias %s %s;\n", sa->ident->toChars(), tp->ident->toChars());
1916 d
= new AliasDeclaration(Loc(), tp
->ident
, sa
);
1920 // tdtypes.data[i] always matches ea here
1921 Initializer
*init
= new ExpInitializer(loc
, ea
);
1922 TemplateValueParameter
*tvp
= tp
->isTemplateValueParameter();
1924 Type
*t
= tvp
? tvp
->valType
: NULL
;
1926 v
= new VarDeclaration(loc
, t
, tp
->ident
, init
);
1927 v
->storage_class
= STCmanifest
| STCtemplateparameter
;
1932 //printf("\ttuple\n");
1933 d
= new TupleDeclaration(loc
, tp
->ident
, &va
->objects
);
1940 d
->storage_class
|= STCtemplateparameter
;
1944 // consistent with Type::checkDeprecated()
1945 while (t
->ty
!= Tenum
)
1947 if (!t
->nextOf()) break;
1948 t
= ((TypeNext
*)t
)->next
;
1950 if (Dsymbol
*s
= t
->toDsymbol(sc
))
1952 if (s
->isDeprecated())
1953 d
->storage_class
|= STCdeprecated
;
1958 if (sa
->isDeprecated())
1959 d
->storage_class
|= STCdeprecated
;
1963 error("declaration %s is already defined", tp
->ident
->toChars());
1964 dsymbolSemantic(d
, sc
);
1966 /* So the caller's o gets updated with the result of semantic() being run on o
1969 o
= initializerToExpression(v
->_init
);
1973 /**************************************
1974 * Determine if TemplateDeclaration is variadic.
1977 TemplateTupleParameter
*isVariadic(TemplateParameters
*parameters
)
1979 size_t dim
= parameters
->length
;
1980 TemplateTupleParameter
*tp
= NULL
;
1983 tp
= ((*parameters
)[dim
- 1])->isTemplateTupleParameter();
1987 TemplateTupleParameter
*TemplateDeclaration::isVariadic()
1989 return ::isVariadic(parameters
);
1992 /***********************************
1993 * We can overload templates.
1996 bool TemplateDeclaration::isOverloadable()
2001 /*************************************************
2002 * Given function arguments, figure out which template function
2003 * to expand, and return matching result.
2005 * m = matching result
2006 * dstart = the root of overloaded function templates
2007 * loc = instantiation location
2008 * sc = instantiation scope
2009 * tiargs = initial list of template arguments
2010 * tthis = if !NULL, the 'this' pointer argument
2011 * fargs = arguments to function
2012 * pMessage = address to store error message, or null
2015 void functionResolve(Match
*m
, Dsymbol
*dstart
, Loc loc
, Scope
*sc
,
2016 Objects
*tiargs
, Type
*tthis
, Expressions
*fargs
, const char **pMessage
)
2026 const char **pMessage
;
2029 int property
; // 0: unintialized
2030 // 1: seen @property
2033 TemplateDeclaration
*td_best
;
2034 TemplateInstance
*ti_best
;
2038 static int fp(void *param
, Dsymbol
*s
)
2042 if (FuncDeclaration
*fd
= s
->isFuncDeclaration())
2043 return ((ParamDeduce
*)param
)->applyFunction(fd
);
2044 if (TemplateDeclaration
*td
= s
->isTemplateDeclaration())
2045 return ((ParamDeduce
*)param
)->applyTemplate(td
);
2049 int applyFunction(FuncDeclaration
*fd
)
2054 // explicitly specified tiargs never match to non template function
2055 if (tiargs
&& tiargs
->length
> 0)
2058 // constructors need a valid scope in order to detect semantic errors
2059 if (!fd
->isCtorDeclaration() &&
2060 fd
->semanticRun
< PASSsemanticdone
)
2062 Ungag ungag
= fd
->ungagSpeculative();
2063 dsymbolSemantic(fd
, NULL
);
2065 if (fd
->semanticRun
< PASSsemanticdone
)
2067 ::error(loc
, "forward reference to template %s", fd
->toChars());
2070 //printf("fd = %s %s, fargs = %s\n", fd->toChars(), fd->type->toChars(), fargs->toChars());
2072 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2074 int prop
= (tf
->isproperty
) ? 1 : 2;
2077 else if (property
!= prop
)
2078 error(fd
->loc
, "cannot overload both property and non-property functions");
2080 /* For constructors, qualifier check will be opposite direction.
2081 * Qualified constructor always makes qualified object, then will be checked
2082 * that it is implicitly convertible to tthis.
2084 Type
*tthis_fd
= fd
->needThis() ? tthis
: NULL
;
2085 bool isCtorCall
= tthis_fd
&& fd
->isCtorDeclaration();
2088 //printf("%s tf->mod = x%x tthis_fd->mod = x%x %d\n", tf->toChars(),
2089 // tf->mod, tthis_fd->mod, fd->isolateReturn());
2090 if (MODimplicitConv(tf
->mod
, tthis_fd
->mod
) ||
2091 (tf
->isWild() && tf
->isShared() == tthis_fd
->isShared()) ||
2092 fd
->isolateReturn())
2094 /* && tf->isShared() == tthis_fd->isShared()*/
2095 // Uniquely constructed object can ignore shared qualifier.
2096 // TODO: Is this appropriate?
2100 return 0; // MATCHnomatch
2102 MATCH mfa
= tf
->callMatch(tthis_fd
, fargs
, 0, pMessage
);
2103 //printf("test1: mfa = %d\n", mfa);
2104 if (mfa
> MATCHnomatch
)
2106 if (mfa
> m
->last
) goto LfIsBetter
;
2107 if (mfa
< m
->last
) goto LlastIsBetter
;
2109 /* See if one of the matches overrides the other.
2112 if (m
->lastf
->overrides(fd
)) goto LlastIsBetter
;
2113 if (fd
->overrides(m
->lastf
)) goto LfIsBetter
;
2115 /* Try to disambiguate using template-style partial ordering rules.
2116 * In essence, if f() and g() are ambiguous, if f() can call g(),
2117 * but g() cannot call f(), then pick f().
2118 * This is because f() is "more specialized."
2121 MATCH c1
= fd
->leastAsSpecialized(m
->lastf
);
2122 MATCH c2
= m
->lastf
->leastAsSpecialized(fd
);
2123 //printf("c1 = %d, c2 = %d\n", c1, c2);
2124 if (c1
> c2
) goto LfIsBetter
;
2125 if (c1
< c2
) goto LlastIsBetter
;
2128 /* The 'overrides' check above does covariant checking only
2129 * for virtual member functions. It should do it for all functions,
2130 * but in order to not risk breaking code we put it after
2131 * the 'leastAsSpecialized' check.
2132 * In the future try moving it before.
2133 * I.e. a not-the-same-but-covariant match is preferred,
2134 * as it is more restrictive.
2136 if (!m
->lastf
->type
->equals(fd
->type
))
2138 //printf("cov: %d %d\n", m->lastf->type->covariant(fd->type), fd->type->covariant(m->lastf->type));
2139 if (m
->lastf
->type
->covariant(fd
->type
) == 1) goto LlastIsBetter
;
2140 if (fd
->type
->covariant(m
->lastf
->type
) == 1) goto LfIsBetter
;
2143 /* If the two functions are the same function, like:
2145 * int foo(int x) { ... }
2146 * then pick the one with the body.
2148 if (tf
->equals(m
->lastf
->type
) &&
2149 fd
->storage_class
== m
->lastf
->storage_class
&&
2150 fd
->parent
== m
->lastf
->parent
&&
2151 fd
->protection
== m
->lastf
->protection
&&
2152 fd
->linkage
== m
->lastf
->linkage
)
2154 if ( fd
->fbody
&& !m
->lastf
->fbody
) goto LfIsBetter
;
2155 if (!fd
->fbody
&& m
->lastf
->fbody
) goto LlastIsBetter
;
2158 // Bugzilla 14450: Prefer exact qualified constructor for the creating object type
2159 if (isCtorCall
&& tf
->mod
!= m
->lastf
->type
->mod
)
2161 if (tthis
->mod
== tf
->mod
) goto LfIsBetter
;
2162 if (tthis
->mod
== m
->lastf
->type
->mod
) goto LlastIsBetter
;
2175 ta_last
= MATCHexact
;
2178 tthis_best
= tthis_fd
;
2186 int applyTemplate(TemplateDeclaration
*td
)
2188 //printf("applyTemplate()\n");
2191 td
->error(loc
, "recursive template expansion");
2194 if (td
== td_best
) // skip duplicates
2198 sc
= td
->_scope
; // workaround for Type::aliasthisOf
2200 if (td
->semanticRun
== PASSinit
&& td
->_scope
)
2202 // Try to fix forward reference. Ungag errors while doing so.
2203 Ungag ungag
= td
->ungagSpeculative();
2204 dsymbolSemantic(td
, td
->_scope
);
2206 if (td
->semanticRun
== PASSinit
)
2208 ::error(loc
, "forward reference to template %s", td
->toChars());
2212 m
->last
= MATCHnomatch
;
2215 //printf("td = %s\n", td->toChars());
2218 f
= td
->onemember
? td
->onemember
->isFuncDeclaration() : NULL
;
2222 tiargs
= new Objects();
2223 TemplateInstance
*ti
= new TemplateInstance(loc
, td
, tiargs
);
2225 dedtypes
.setDim(td
->parameters
->length
);
2226 assert(td
->semanticRun
!= PASSinit
);
2227 MATCH mta
= td
->matchWithInstance(sc
, ti
, &dedtypes
, fargs
, 0);
2228 //printf("matchWithInstance = %d\n", mta);
2229 if (mta
<= MATCHnomatch
|| mta
< ta_last
) // no match or less match
2232 templateInstanceSemantic(ti
, sc
, fargs
);
2233 if (!ti
->inst
) // if template failed to expand
2236 Dsymbol
*s
= ti
->inst
->toAlias();
2237 FuncDeclaration
*fd
;
2238 if (TemplateDeclaration
*tdx
= s
->isTemplateDeclaration())
2240 Objects dedtypesX
; // empty tiargs
2242 // Bugzilla 11553: Check for recursive instantiation of tdx.
2243 for (TemplatePrevious
*p
= tdx
->previous
; p
; p
= p
->prev
)
2245 if (arrayObjectMatch(p
->dedargs
, &dedtypesX
))
2247 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
2248 /* It must be a subscope of p->sc, other scope chains are not recursive
2251 for (Scope
*scx
= sc
; scx
; scx
= scx
->enclosing
)
2255 error(loc
, "recursive template expansion while looking for %s.%s", ti
->toChars(), tdx
->toChars());
2260 /* BUG: should also check for ref param differences
2264 TemplatePrevious pr
;
2265 pr
.prev
= tdx
->previous
;
2267 pr
.dedargs
= &dedtypesX
;
2268 tdx
->previous
= &pr
; // add this to threaded list
2270 fd
= resolveFuncCall(loc
, sc
, s
, NULL
, tthis
, fargs
, 1);
2272 tdx
->previous
= pr
.prev
; // unlink from threaded list
2274 else if (s
->isFuncDeclaration())
2276 fd
= resolveFuncCall(loc
, sc
, s
, NULL
, tthis
, fargs
, 1);
2284 if (fd
->type
->ty
!= Tfunction
)
2286 m
->lastf
= fd
; // to propagate "error match"
2288 m
->last
= MATCHnomatch
;
2292 Type
*tthis_fd
= fd
->needThis() && !fd
->isCtorDeclaration() ? tthis
: NULL
;
2294 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2295 MATCH mfa
= tf
->callMatch(tthis_fd
, fargs
);
2299 if (mta
< ta_last
) goto Ltd_best2
;
2300 if (mta
> ta_last
) goto Ltd2
;
2302 if (mfa
< m
->last
) goto Ltd_best2
;
2303 if (mfa
> m
->last
) goto Ltd2
;
2305 //printf("Lambig2\n");
2314 // td is the new best match
2318 property
= 0; // (backward compatibility)
2322 tthis_best
= tthis_fd
;
2329 //printf("td = %s\n", td->toChars());
2330 for (size_t ovi
= 0; f
; f
= f
->overnext0
, ovi
++)
2332 if (f
->type
->ty
!= Tfunction
|| f
->errors
)
2335 /* This is a 'dummy' instance to evaluate constraint properly.
2337 TemplateInstance
*ti
= new TemplateInstance(loc
, td
, tiargs
);
2338 ti
->parent
= td
->parent
; // Maybe calculating valid 'enclosing' is unnecessary.
2340 FuncDeclaration
*fd
= f
;
2341 int x
= td
->deduceFunctionTemplateMatch(ti
, sc
, fd
, tthis
, fargs
);
2342 MATCH mta
= (MATCH
)(x
>> 4);
2343 MATCH mfa
= (MATCH
)(x
& 0xF);
2344 //printf("match:t/f = %d/%d\n", mta, mfa);
2345 if (!fd
|| mfa
== MATCHnomatch
)
2348 Type
*tthis_fd
= fd
->needThis() ? tthis
: NULL
;
2350 bool isCtorCall
= tthis_fd
&& fd
->isCtorDeclaration();
2353 // Constructor call requires additional check.
2355 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2357 if (MODimplicitConv(tf
->mod
, tthis_fd
->mod
) ||
2358 (tf
->isWild() && tf
->isShared() == tthis_fd
->isShared()) ||
2359 fd
->isolateReturn())
2364 continue; // MATCHnomatch
2367 if (mta
< ta_last
) goto Ltd_best
;
2368 if (mta
> ta_last
) goto Ltd
;
2370 if (mfa
< m
->last
) goto Ltd_best
;
2371 if (mfa
> m
->last
) goto Ltd
;
2375 // Disambiguate by picking the most specialized TemplateDeclaration
2376 MATCH c1
= td
->leastAsSpecialized(sc
, td_best
, fargs
);
2377 MATCH c2
= td_best
->leastAsSpecialized(sc
, td
, fargs
);
2378 //printf("1: c1 = %d, c2 = %d\n", c1, c2);
2379 if (c1
> c2
) goto Ltd
;
2380 if (c1
< c2
) goto Ltd_best
;
2382 assert(fd
&& m
->lastf
);
2384 // Disambiguate by tf->callMatch
2385 TypeFunction
*tf1
= (TypeFunction
*)fd
->type
;
2386 assert(tf1
->ty
== Tfunction
);
2387 TypeFunction
*tf2
= (TypeFunction
*)m
->lastf
->type
;
2388 assert(tf2
->ty
== Tfunction
);
2389 MATCH c1
= tf1
->callMatch(tthis_fd
, fargs
);
2390 MATCH c2
= tf2
->callMatch(tthis_best
, fargs
);
2391 //printf("2: c1 = %d, c2 = %d\n", c1, c2);
2392 if (c1
> c2
) goto Ltd
;
2393 if (c1
< c2
) goto Ltd_best
;
2396 // Disambiguate by picking the most specialized FunctionDeclaration
2397 MATCH c1
= fd
->leastAsSpecialized(m
->lastf
);
2398 MATCH c2
= m
->lastf
->leastAsSpecialized(fd
);
2399 //printf("3: c1 = %d, c2 = %d\n", c1, c2);
2400 if (c1
> c2
) goto Ltd
;
2401 if (c1
< c2
) goto Ltd_best
;
2404 // Bugzilla 14450: Prefer exact qualified constructor for the creating object type
2405 if (isCtorCall
&& fd
->type
->mod
!= m
->lastf
->type
->mod
)
2407 if (tthis
->mod
== fd
->type
->mod
) goto Ltd
;
2408 if (tthis
->mod
== m
->lastf
->type
->mod
) goto Ltd_best
;
2415 Ltd_best
: // td_best is the best match so far
2416 //printf("Ltd_best\n");
2419 Ltd
: // td is the new best match
2424 property
= 0; // (backward compatibility)
2428 tthis_best
= tthis_fd
;
2444 p
.pMessage
= pMessage
;
2452 p
.ta_last
= m
->last
!= MATCHnomatch
? MATCHexact
: MATCHnomatch
;
2453 p
.tthis_best
= NULL
;
2455 TemplateDeclaration
*td
= dstart
->isTemplateDeclaration();
2456 if (td
&& td
->funcroot
)
2457 dstart
= td
->funcroot
;
2459 overloadApply(dstart
, &p
, &ParamDeduce::fp
);
2461 //printf("td_best = %p, m->lastf = %p\n", p.td_best, m->lastf);
2462 if (p
.td_best
&& p
.ti_best
&& m
->count
== 1)
2464 // Matches to template function
2465 assert(p
.td_best
->onemember
&& p
.td_best
->onemember
->isFuncDeclaration());
2467 /* The best match is td_best with arguments tdargs.
2468 * Now instantiate the template.
2470 assert(p
.td_best
->_scope
);
2472 sc
= p
.td_best
->_scope
; // workaround for Type::aliasthisOf
2474 TemplateInstance
*ti
= new TemplateInstance(loc
, p
.td_best
, p
.ti_best
->tiargs
);
2475 templateInstanceSemantic(ti
, sc
, fargs
);
2477 m
->lastf
= ti
->toAlias()->isFuncDeclaration();
2485 m
->last
= MATCHnomatch
;
2489 // look forward instantiated overload function
2490 // Dsymbol::oneMembers is alredy called in TemplateInstance::semantic.
2491 // it has filled overnext0d
2492 while (p
.ov_index
--)
2494 m
->lastf
= m
->lastf
->overnext0
;
2498 p
.tthis_best
= m
->lastf
->needThis() && !m
->lastf
->isCtorDeclaration() ? tthis
: NULL
;
2500 TypeFunction
*tf
= (TypeFunction
*)m
->lastf
->type
;
2501 if (tf
->ty
== Terror
)
2503 assert(tf
->ty
== Tfunction
);
2504 if (!tf
->callMatch(p
.tthis_best
, fargs
))
2507 /* As Bugzilla 3682 shows, a template instance can be matched while instantiating
2508 * that same template. Thus, the function type can be incomplete. Complete it.
2510 * Bugzilla 9208: For auto function, completion should be deferred to the end of
2511 * its semantic3. Should not complete it in here.
2513 if (tf
->next
&& !m
->lastf
->inferRetType
)
2515 m
->lastf
->type
= typeSemantic(tf
, loc
, sc
);
2520 // Matches to non template function,
2521 // or found matches were ambiguous.
2522 assert(m
->count
>= 1);
2529 m
->last
= MATCHnomatch
;
2533 /*************************************************
2534 * Limited function template instantiation for using fd->leastAsSpecialized()
2536 FuncDeclaration
*TemplateDeclaration::doHeaderInstantiation(
2537 TemplateInstance
*ti
, Scope
*sc2
,
2538 FuncDeclaration
*fd
, Type
*tthis
, Expressions
*fargs
)
2542 // function body and contracts are not need
2543 if (fd
->isCtorDeclaration())
2544 fd
= new CtorDeclaration(fd
->loc
, fd
->endloc
, fd
->storage_class
, fd
->type
->syntaxCopy());
2546 fd
= new FuncDeclaration(fd
->loc
, fd
->endloc
, fd
->ident
, fd
->storage_class
, fd
->type
->syntaxCopy());
2549 assert(fd
->type
->ty
== Tfunction
);
2550 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2555 // Match 'tthis' to any TemplateThisParameter's
2556 bool hasttp
= false;
2557 for (size_t i
= 0; i
< parameters
->length
; i
++)
2559 TemplateParameter
*tp
= (*parameters
)[i
];
2560 TemplateThisParameter
*ttp
= tp
->isTemplateThisParameter();
2566 tf
= (TypeFunction
*)tf
->addSTC(ModToStc(tthis
->mod
));
2571 Scope
*scx
= sc2
->push();
2573 // Shouldn't run semantic on default arguments and return type.
2574 for (size_t i
= 0; i
< tf
->parameterList
.parameters
->length
; i
++)
2575 (*tf
->parameterList
.parameters
)[i
]->defaultArg
= NULL
;
2576 if (fd
->isCtorDeclaration())
2578 // For constructors, emitting return type is necessary for
2579 // isolateReturn() in functionResolve.
2580 scx
->flags
|= SCOPEctor
;
2582 Dsymbol
*parent
= toParent2();
2584 AggregateDeclaration
*ad
= parent
->isAggregateDeclaration();
2585 if (!ad
|| parent
->isUnionDeclaration())
2591 tret
= ad
->handleType();
2593 tret
= tret
->addStorageClass(fd
->storage_class
| scx
->stc
);
2594 tret
= tret
->addMod(tf
->mod
);
2597 if (ad
&& ad
->isStructDeclaration())
2599 //printf("tf = %s\n", tf->toChars());
2604 fd
->type
= fd
->type
->addSTC(scx
->stc
);
2605 fd
->type
= typeSemantic(fd
->type
, fd
->loc
, scx
);
2608 if (fd
->type
->ty
!= Tfunction
)
2611 fd
->originalType
= fd
->type
; // for mangling
2612 //printf("\t[%s] fd->type = %s, mod = %x, ", loc.toChars(), fd->type->toChars(), fd->type->mod);
2613 //printf("fd->needThis() = %d\n", fd->needThis());
2618 bool TemplateDeclaration::hasStaticCtorOrDtor()
2620 return false; // don't scan uninstantiated templates
2623 const char *TemplateDeclaration::toChars()
2626 return Dsymbol::toChars();
2631 buf
.writestring(ident
->toChars());
2633 for (size_t i
= 0; i
< parameters
->length
; i
++)
2635 TemplateParameter
*tp
= (*parameters
)[i
];
2637 buf
.writestring(", ");
2638 ::toCBuffer(tp
, &buf
, &hgs
);
2644 FuncDeclaration
*fd
= onemember
->isFuncDeclaration();
2647 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2648 buf
.writestring(parametersTypeToChars(tf
->parameterList
));
2654 buf
.writestring(" if (");
2655 ::toCBuffer(constraint
, &buf
, &hgs
);
2658 return buf
.extractChars();
2661 Prot
TemplateDeclaration::prot()
2666 /****************************************************
2667 * Given a new instance tithis of this TemplateDeclaration,
2668 * see if there already exists an instance.
2669 * If so, return that existing instance.
2672 TemplateInstance
*TemplateDeclaration::findExistingInstance(TemplateInstance
*tithis
, Expressions
*fargs
)
2674 //printf("findExistingInstance(%p)\n", tithis);
2675 tithis
->fargs
= fargs
;
2676 TemplateInstances
*tinstances
= (TemplateInstances
*)dmd_aaGetRvalue((AA
*)instances
, (void *)tithis
->toHash());
2679 for (size_t i
= 0; i
< tinstances
->length
; i
++)
2681 TemplateInstance
*ti
= (*tinstances
)[i
];
2682 if (tithis
->compare(ti
) == 0)
2689 /********************************************
2690 * Add instance ti to TemplateDeclaration's table of instances.
2691 * Return a handle we can use to later remove it if it fails instantiation.
2694 TemplateInstance
*TemplateDeclaration::addInstance(TemplateInstance
*ti
)
2696 //printf("addInstance() %p %p\n", instances, ti);
2697 TemplateInstances
**ptinstances
= (TemplateInstances
**)dmd_aaGet((AA
**)&instances
, (void *)ti
->toHash());
2699 *ptinstances
= new TemplateInstances();
2700 (*ptinstances
)->push(ti
);
2704 /*******************************************
2705 * Remove TemplateInstance from table of instances.
2707 * handle returned by addInstance()
2710 void TemplateDeclaration::removeInstance(TemplateInstance
*handle
)
2712 //printf("removeInstance()\n");
2713 TemplateInstances
*tinstances
= (TemplateInstances
*)dmd_aaGetRvalue((AA
*)instances
, (void *)handle
->toHash());
2716 for (size_t i
= 0; i
< tinstances
->length
; i
++)
2718 TemplateInstance
*ti
= (*tinstances
)[i
];
2721 tinstances
->remove(i
);
2728 /* ======================== Type ============================================ */
2731 * Given an identifier, figure out which TemplateParameter it is.
2732 * Return IDX_NOTFOUND if not found.
2735 static size_t templateIdentifierLookup(Identifier
*id
, TemplateParameters
*parameters
)
2737 for (size_t i
= 0; i
< parameters
->length
; i
++)
2739 TemplateParameter
*tp
= (*parameters
)[i
];
2740 if (tp
->ident
->equals(id
))
2743 return IDX_NOTFOUND
;
2746 size_t templateParameterLookup(Type
*tparam
, TemplateParameters
*parameters
)
2748 if (tparam
->ty
== Tident
)
2750 TypeIdentifier
*tident
= (TypeIdentifier
*)tparam
;
2751 //printf("\ttident = '%s'\n", tident->toChars());
2752 return templateIdentifierLookup(tident
->ident
, parameters
);
2754 return IDX_NOTFOUND
;
2757 unsigned char deduceWildHelper(Type
*t
, Type
**at
, Type
*tparam
)
2759 if ((tparam
->mod
& MODwild
) == 0)
2764 #define X(U,T) ((U) << 4) | (T)
2765 switch (X(tparam
->mod
, t
->mod
))
2768 case X(MODwild
, MODconst
):
2769 case X(MODwild
, MODshared
):
2770 case X(MODwild
, MODshared
| MODconst
):
2771 case X(MODwild
, MODimmutable
):
2772 case X(MODwildconst
, 0):
2773 case X(MODwildconst
, MODconst
):
2774 case X(MODwildconst
, MODshared
):
2775 case X(MODwildconst
, MODshared
| MODconst
):
2776 case X(MODwildconst
, MODimmutable
):
2777 case X(MODshared
| MODwild
, MODshared
):
2778 case X(MODshared
| MODwild
, MODshared
| MODconst
):
2779 case X(MODshared
| MODwild
, MODimmutable
):
2780 case X(MODshared
| MODwildconst
, MODshared
):
2781 case X(MODshared
| MODwildconst
, MODshared
| MODconst
):
2782 case X(MODshared
| MODwildconst
, MODimmutable
):
2784 unsigned char wm
= (t
->mod
& ~MODshared
);
2787 unsigned char m
= (t
->mod
& (MODconst
| MODimmutable
)) | (tparam
->mod
& t
->mod
& MODshared
);
2788 *at
= t
->unqualify(m
);
2792 case X(MODwild
, MODwild
):
2793 case X(MODwild
, MODwildconst
):
2794 case X(MODwild
, MODshared
| MODwild
):
2795 case X(MODwild
, MODshared
| MODwildconst
):
2796 case X(MODwildconst
, MODwild
):
2797 case X(MODwildconst
, MODwildconst
):
2798 case X(MODwildconst
, MODshared
| MODwild
):
2799 case X(MODwildconst
, MODshared
| MODwildconst
):
2800 case X(MODshared
| MODwild
, MODshared
| MODwild
):
2801 case X(MODshared
| MODwild
, MODshared
| MODwildconst
):
2802 case X(MODshared
| MODwildconst
, MODshared
| MODwild
):
2803 case X(MODshared
| MODwildconst
, MODshared
| MODwildconst
):
2805 *at
= t
->unqualify(tparam
->mod
& t
->mod
);
2815 MATCH
deduceTypeHelper(Type
*t
, Type
**at
, Type
*tparam
)
2819 #define X(U,T) ((U) << 4) | (T)
2820 switch (X(tparam
->mod
, t
->mod
))
2823 case X(0, MODconst
):
2825 case X(0, MODwildconst
):
2826 case X(0, MODshared
):
2827 case X(0, MODshared
| MODconst
):
2828 case X(0, MODshared
| MODwild
):
2829 case X(0, MODshared
| MODwildconst
):
2830 case X(0, MODimmutable
):
2832 // foo(U) const(T) => const(T)
2833 // foo(U) inout(T) => inout(T)
2834 // foo(U) inout(const(T)) => inout(const(T))
2835 // foo(U) shared(T) => shared(T)
2836 // foo(U) shared(const(T)) => shared(const(T))
2837 // foo(U) shared(inout(T)) => shared(inout(T))
2838 // foo(U) shared(inout(const(T))) => shared(inout(const(T)))
2839 // foo(U) immutable(T) => immutable(T)
2845 case X(MODconst
, MODconst
):
2846 case X(MODwild
, MODwild
):
2847 case X(MODwildconst
, MODwildconst
):
2848 case X(MODshared
, MODshared
):
2849 case X(MODshared
| MODconst
, MODshared
| MODconst
):
2850 case X(MODshared
| MODwild
, MODshared
| MODwild
):
2851 case X(MODshared
| MODwildconst
, MODshared
| MODwildconst
):
2852 case X(MODimmutable
, MODimmutable
):
2853 // foo(const(U)) const(T) => T
2854 // foo(inout(U)) inout(T) => T
2855 // foo(inout(const(U))) inout(const(T)) => T
2856 // foo(shared(U)) shared(T) => T
2857 // foo(shared(const(U))) shared(const(T)) => T
2858 // foo(shared(inout(U))) shared(inout(T)) => T
2859 // foo(shared(inout(const(U)))) shared(inout(const(T))) => T
2860 // foo(immutable(U)) immutable(T) => T
2862 *at
= t
->mutableOf()->unSharedOf();
2866 case X(MODconst
, 0):
2867 case X(MODconst
, MODwild
):
2868 case X(MODconst
, MODwildconst
):
2869 case X(MODconst
, MODshared
| MODconst
):
2870 case X(MODconst
, MODshared
| MODwild
):
2871 case X(MODconst
, MODshared
| MODwildconst
):
2872 case X(MODconst
, MODimmutable
):
2873 case X(MODwild
, MODshared
| MODwild
):
2874 case X(MODwildconst
, MODshared
| MODwildconst
):
2875 case X(MODshared
| MODconst
, MODimmutable
):
2876 // foo(const(U)) T => T
2877 // foo(const(U)) inout(T) => T
2878 // foo(const(U)) inout(const(T)) => T
2879 // foo(const(U)) shared(const(T)) => shared(T)
2880 // foo(const(U)) shared(inout(T)) => shared(T)
2881 // foo(const(U)) shared(inout(const(T))) => shared(T)
2882 // foo(const(U)) immutable(T) => T
2883 // foo(inout(U)) shared(inout(T)) => shared(T)
2884 // foo(inout(const(U))) shared(inout(const(T))) => shared(T)
2885 // foo(shared(const(U))) immutable(T) => T
2887 *at
= t
->mutableOf();
2891 case X(MODconst
, MODshared
):
2892 // foo(const(U)) shared(T) => shared(T)
2898 case X(MODshared
, MODshared
| MODconst
):
2899 case X(MODshared
, MODshared
| MODwild
):
2900 case X(MODshared
, MODshared
| MODwildconst
):
2901 case X(MODshared
| MODconst
, MODshared
):
2902 // foo(shared(U)) shared(const(T)) => const(T)
2903 // foo(shared(U)) shared(inout(T)) => inout(T)
2904 // foo(shared(U)) shared(inout(const(T))) => inout(const(T))
2905 // foo(shared(const(U))) shared(T) => T
2907 *at
= t
->unSharedOf();
2911 case X(MODwildconst
, MODimmutable
):
2912 case X(MODshared
| MODconst
, MODshared
| MODwildconst
):
2913 case X(MODshared
| MODwildconst
, MODimmutable
):
2914 case X(MODshared
| MODwildconst
, MODshared
| MODwild
):
2915 // foo(inout(const(U))) immutable(T) => T
2916 // foo(shared(const(U))) shared(inout(const(T))) => T
2917 // foo(shared(inout(const(U)))) immutable(T) => T
2918 // foo(shared(inout(const(U)))) shared(inout(T)) => T
2920 *at
= t
->unSharedOf()->mutableOf();
2924 case X(MODshared
| MODconst
, MODshared
| MODwild
):
2925 // foo(shared(const(U))) shared(inout(T)) => T
2927 *at
= t
->unSharedOf()->mutableOf();
2932 case X(MODwild
, MODconst
):
2933 case X(MODwild
, MODwildconst
):
2934 case X(MODwild
, MODimmutable
):
2935 case X(MODwild
, MODshared
):
2936 case X(MODwild
, MODshared
| MODconst
):
2937 case X(MODwild
, MODshared
| MODwildconst
):
2938 case X(MODwildconst
, 0):
2939 case X(MODwildconst
, MODconst
):
2940 case X(MODwildconst
, MODwild
):
2941 case X(MODwildconst
, MODshared
):
2942 case X(MODwildconst
, MODshared
| MODconst
):
2943 case X(MODwildconst
, MODshared
| MODwild
):
2944 case X(MODshared
, 0):
2945 case X(MODshared
, MODconst
):
2946 case X(MODshared
, MODwild
):
2947 case X(MODshared
, MODwildconst
):
2948 case X(MODshared
, MODimmutable
):
2949 case X(MODshared
| MODconst
, 0):
2950 case X(MODshared
| MODconst
, MODconst
):
2951 case X(MODshared
| MODconst
, MODwild
):
2952 case X(MODshared
| MODconst
, MODwildconst
):
2953 case X(MODshared
| MODwild
, 0):
2954 case X(MODshared
| MODwild
, MODconst
):
2955 case X(MODshared
| MODwild
, MODwild
):
2956 case X(MODshared
| MODwild
, MODwildconst
):
2957 case X(MODshared
| MODwild
, MODimmutable
):
2958 case X(MODshared
| MODwild
, MODshared
):
2959 case X(MODshared
| MODwild
, MODshared
| MODconst
):
2960 case X(MODshared
| MODwild
, MODshared
| MODwildconst
):
2961 case X(MODshared
| MODwildconst
, 0):
2962 case X(MODshared
| MODwildconst
, MODconst
):
2963 case X(MODshared
| MODwildconst
, MODwild
):
2964 case X(MODshared
| MODwildconst
, MODwildconst
):
2965 case X(MODshared
| MODwildconst
, MODshared
):
2966 case X(MODshared
| MODwildconst
, MODshared
| MODconst
):
2967 case X(MODimmutable
, 0):
2968 case X(MODimmutable
, MODconst
):
2969 case X(MODimmutable
, MODwild
):
2970 case X(MODimmutable
, MODwildconst
):
2971 case X(MODimmutable
, MODshared
):
2972 case X(MODimmutable
, MODshared
| MODconst
):
2973 case X(MODimmutable
, MODshared
| MODwild
):
2974 case X(MODimmutable
, MODshared
| MODwildconst
):
2975 // foo(inout(U)) T => nomatch
2976 // foo(inout(U)) const(T) => nomatch
2977 // foo(inout(U)) inout(const(T)) => nomatch
2978 // foo(inout(U)) immutable(T) => nomatch
2979 // foo(inout(U)) shared(T) => nomatch
2980 // foo(inout(U)) shared(const(T)) => nomatch
2981 // foo(inout(U)) shared(inout(const(T))) => nomatch
2982 // foo(inout(const(U))) T => nomatch
2983 // foo(inout(const(U))) const(T) => nomatch
2984 // foo(inout(const(U))) inout(T) => nomatch
2985 // foo(inout(const(U))) shared(T) => nomatch
2986 // foo(inout(const(U))) shared(const(T)) => nomatch
2987 // foo(inout(const(U))) shared(inout(T)) => nomatch
2988 // foo(shared(U)) T => nomatch
2989 // foo(shared(U)) const(T) => nomatch
2990 // foo(shared(U)) inout(T) => nomatch
2991 // foo(shared(U)) inout(const(T)) => nomatch
2992 // foo(shared(U)) immutable(T) => nomatch
2993 // foo(shared(const(U))) T => nomatch
2994 // foo(shared(const(U))) const(T) => nomatch
2995 // foo(shared(const(U))) inout(T) => nomatch
2996 // foo(shared(const(U))) inout(const(T)) => nomatch
2997 // foo(shared(inout(U))) T => nomatch
2998 // foo(shared(inout(U))) const(T) => nomatch
2999 // foo(shared(inout(U))) inout(T) => nomatch
3000 // foo(shared(inout(U))) inout(const(T)) => nomatch
3001 // foo(shared(inout(U))) immutable(T) => nomatch
3002 // foo(shared(inout(U))) shared(T) => nomatch
3003 // foo(shared(inout(U))) shared(const(T)) => nomatch
3004 // foo(shared(inout(U))) shared(inout(const(T))) => nomatch
3005 // foo(shared(inout(const(U)))) T => nomatch
3006 // foo(shared(inout(const(U)))) const(T) => nomatch
3007 // foo(shared(inout(const(U)))) inout(T) => nomatch
3008 // foo(shared(inout(const(U)))) inout(const(T)) => nomatch
3009 // foo(shared(inout(const(U)))) shared(T) => nomatch
3010 // foo(shared(inout(const(U)))) shared(const(T)) => nomatch
3011 // foo(immutable(U)) T => nomatch
3012 // foo(immutable(U)) const(T) => nomatch
3013 // foo(immutable(U)) inout(T) => nomatch
3014 // foo(immutable(U)) inout(const(T)) => nomatch
3015 // foo(immutable(U)) shared(T) => nomatch
3016 // foo(immutable(U)) shared(const(T)) => nomatch
3017 // foo(immutable(U)) shared(inout(T)) => nomatch
3018 // foo(immutable(U)) shared(inout(const(T))) => nomatch
3019 return MATCHnomatch
;
3023 return MATCHnomatch
; // silence compiler warning about missing return
3028 /* These form the heart of template argument deduction.
3029 * Given 'this' being the type argument to the template instance,
3030 * it is matched against the template declaration parameter specialization
3031 * 'tparam' to determine the type to be used for the parameter.
3033 * template Foo(T:T*) // template declaration
3034 * Foo!(int*) // template instantiation
3038 * parameters = [ T:T* ] // Array of TemplateParameter's
3040 * dedtypes = [ int ] // Array of Expression/Type's
3042 MATCH
deduceType(RootObject
*o
, Scope
*sc
, Type
*tparam
, TemplateParameters
*parameters
,
3043 Objects
*dedtypes
, unsigned *wm
, size_t inferStart
)
3045 class DeduceType
: public Visitor
3050 TemplateParameters
*parameters
;
3056 DeduceType(Scope
*sc
, Type
*tparam
, TemplateParameters
*parameters
, Objects
*dedtypes
, unsigned *wm
, size_t inferStart
)
3057 : sc(sc
), tparam(tparam
), parameters(parameters
), dedtypes(dedtypes
), wm(wm
), inferStart(inferStart
)
3059 result
= MATCHnomatch
;
3070 if (tparam
->ty
== Tident
)
3072 // Determine which parameter tparam is
3073 size_t i
= templateParameterLookup(tparam
, parameters
);
3074 if (i
== IDX_NOTFOUND
)
3079 /* Need a loc to go with the semantic routine.
3082 if (parameters
->length
)
3084 TemplateParameter
*tp
= (*parameters
)[0];
3088 /* BUG: what if tparam is a template instance, that
3089 * has as an argument another Tident?
3091 tparam
= typeSemantic(tparam
, loc
, sc
);
3092 assert(tparam
->ty
!= Tident
);
3093 result
= deduceType(t
, sc
, tparam
, parameters
, dedtypes
, wm
);
3097 TemplateParameter
*tp
= (*parameters
)[i
];
3099 TypeIdentifier
*tident
= (TypeIdentifier
*)tparam
;
3100 if (tident
->idents
.length
> 0)
3102 //printf("matching %s to %s\n", tparam->toChars(), t->toChars());
3103 Dsymbol
*s
= t
->toDsymbol(sc
);
3104 for (size_t j
= tident
->idents
.length
; j
-- > 0; )
3106 RootObject
*id
= tident
->idents
[j
];
3107 if (id
->dyncast() == DYNCAST_IDENTIFIER
)
3109 if (!s
|| !s
->parent
)
3111 Dsymbol
*s2
= s
->parent
->search(Loc(), (Identifier
*)id
);
3115 //printf("[%d] s = %s %s, s2 = %s %s\n", j, s->kind(), s->toChars(), s2->kind(), s2->toChars());
3118 if (Type
*tx
= s2
->getType())
3120 if (s
!= tx
->toDsymbol(sc
))
3131 //printf("[e] s = %s\n", s?s->toChars():"(null)");
3132 if (tp
->isTemplateTypeParameter())
3134 Type
*tt
= s
->getType();
3137 Type
*at
= (Type
*)(*dedtypes
)[i
];
3138 if (at
&& at
->ty
== Tnone
)
3139 at
= ((TypeDeduced
*)at
)->tded
;
3140 if (!at
|| tt
->equals(at
))
3142 (*dedtypes
)[i
] = tt
;
3146 if (tp
->isTemplateAliasParameter())
3148 Dsymbol
*s2
= (Dsymbol
*)(*dedtypes
)[i
];
3158 // Found the corresponding parameter tp
3159 if (!tp
->isTemplateTypeParameter())
3162 Type
*at
= (Type
*)(*dedtypes
)[i
];
3164 if (unsigned char wx
= wm
? deduceWildHelper(t
, &tt
, tparam
) : 0)
3169 (*dedtypes
)[i
] = tt
;
3171 result
= MATCHconst
;
3175 // type vs expressions
3176 if (at
->ty
== Tnone
)
3178 TypeDeduced
*xt
= (TypeDeduced
*)at
;
3179 result
= xt
->matchAll(tt
);
3180 if (result
> MATCHnomatch
)
3182 (*dedtypes
)[i
] = tt
;
3183 if (result
> MATCHconst
)
3184 result
= MATCHconst
; // limit level for inout matches
3193 (*dedtypes
)[i
] = tt
; // Prefer current type match
3196 if (tt
->implicitConvTo(at
->constOf()))
3198 (*dedtypes
)[i
] = at
->constOf()->mutableOf();
3202 if (at
->implicitConvTo(tt
->constOf()))
3204 (*dedtypes
)[i
] = tt
->constOf()->mutableOf();
3210 else if (MATCH m
= deduceTypeHelper(t
, &tt
, tparam
))
3215 (*dedtypes
)[i
] = tt
;
3220 // type vs expressions
3221 if (at
->ty
== Tnone
)
3223 TypeDeduced
*xt
= (TypeDeduced
*)at
;
3224 result
= xt
->matchAll(tt
);
3225 if (result
> MATCHnomatch
)
3227 (*dedtypes
)[i
] = tt
;
3238 if (tt
->ty
== Tclass
&& at
->ty
== Tclass
)
3240 result
= tt
->implicitConvTo(at
);
3243 if (tt
->ty
== Tsarray
&& at
->ty
== Tarray
&&
3244 tt
->nextOf()->implicitConvTo(at
->nextOf()) >= MATCHconst
)
3252 if (tparam
->ty
== Ttypeof
)
3254 /* Need a loc to go with the semantic routine.
3257 if (parameters
->length
)
3259 TemplateParameter
*tp
= (*parameters
)[0];
3263 tparam
= typeSemantic(tparam
, loc
, sc
);
3265 if (t
->ty
!= tparam
->ty
)
3267 if (Dsymbol
*sym
= t
->toDsymbol(sc
))
3269 if (sym
->isforwardRef() && !tparam
->deco
)
3273 MATCH m
= t
->implicitConvTo(tparam
);
3274 if (m
== MATCHnomatch
)
3276 if (t
->ty
== Tclass
)
3278 TypeClass
*tc
= (TypeClass
*)t
;
3279 if (tc
->sym
->aliasthis
&& !(tc
->att
& RECtracingDT
))
3281 tc
->att
= (AliasThisRec
)(tc
->att
| RECtracingDT
);
3282 m
= deduceType(t
->aliasthisOf(), sc
, tparam
, parameters
, dedtypes
, wm
);
3283 tc
->att
= (AliasThisRec
)(tc
->att
& ~RECtracingDT
);
3286 else if (t
->ty
== Tstruct
)
3288 TypeStruct
*ts
= (TypeStruct
*)t
;
3289 if (ts
->sym
->aliasthis
&& !(ts
->att
& RECtracingDT
))
3291 ts
->att
= (AliasThisRec
)(ts
->att
| RECtracingDT
);
3292 m
= deduceType(t
->aliasthisOf(), sc
, tparam
, parameters
, dedtypes
, wm
);
3293 ts
->att
= (AliasThisRec
)(ts
->att
& ~RECtracingDT
);
3303 if (tparam
->deco
&& !tparam
->hasWild())
3305 result
= t
->implicitConvTo(tparam
);
3309 Type
*tpn
= tparam
->nextOf();
3310 if (wm
&& t
->ty
== Taarray
&& tparam
->isWild())
3312 // Bugzilla 12403: In IFTI, stop inout matching on transitive part of AA types.
3313 tpn
= tpn
->substWildTo(MODmutable
);
3316 result
= deduceType(t
->nextOf(), sc
, tpn
, parameters
, dedtypes
, wm
);
3321 result
= MATCHexact
;
3325 result
= MATCHnomatch
;
3329 result
= MATCHconst
;
3332 void visit(TypeVector
*t
)
3334 if (tparam
->ty
== Tvector
)
3336 TypeVector
*tp
= (TypeVector
*)tparam
;
3337 result
= deduceType(t
->basetype
, sc
, tp
->basetype
, parameters
, dedtypes
, wm
);
3343 void visit(TypeDArray
*t
)
3348 void visit(TypeSArray
*t
)
3350 // Extra check that array dimensions must match
3353 if (tparam
->ty
== Tarray
)
3355 MATCH m
= deduceType(t
->next
, sc
, tparam
->nextOf(), parameters
, dedtypes
, wm
);
3356 result
= (m
>= MATCHconst
) ? MATCHconvert
: MATCHnomatch
;
3360 TemplateParameter
*tp
= NULL
;
3361 Expression
*edim
= NULL
;
3363 if (tparam
->ty
== Tsarray
)
3365 TypeSArray
*tsa
= (TypeSArray
*)tparam
;
3366 if (tsa
->dim
->op
== TOKvar
&&
3367 ((VarExp
*)tsa
->dim
)->var
->storage_class
& STCtemplateparameter
)
3369 Identifier
*id
= ((VarExp
*)tsa
->dim
)->var
->ident
;
3370 i
= templateIdentifierLookup(id
, parameters
);
3371 assert(i
!= IDX_NOTFOUND
);
3372 tp
= (*parameters
)[i
];
3377 else if (tparam
->ty
== Taarray
)
3379 TypeAArray
*taa
= (TypeAArray
*)tparam
;
3380 i
= templateParameterLookup(taa
->index
, parameters
);
3381 if (i
!= IDX_NOTFOUND
)
3382 tp
= (*parameters
)[i
];
3388 taa
->index
->resolve(Loc(), sc
, &e
, &tx
, &s
);
3389 edim
= s
? getValue(s
) : getValue(e
);
3392 if ((tp
&& tp
->matchArg(sc
, t
->dim
, i
, parameters
, dedtypes
, NULL
)) ||
3393 (edim
&& edim
->toInteger() == t
->dim
->toInteger()))
3395 result
= deduceType(t
->next
, sc
, tparam
->nextOf(), parameters
, dedtypes
, wm
);
3402 result
= MATCHnomatch
;
3405 void visit(TypeAArray
*t
)
3407 // Extra check that index type must match
3408 if (tparam
&& tparam
->ty
== Taarray
)
3410 TypeAArray
*tp
= (TypeAArray
*)tparam
;
3411 if (!deduceType(t
->index
, sc
, tp
->index
, parameters
, dedtypes
))
3413 result
= MATCHnomatch
;
3420 void visit(TypeFunction
*t
)
3422 //printf("TypeFunction::deduceType()\n");
3423 //printf("\tthis = %d, ", t->ty); t->print();
3424 //printf("\ttparam = %d, ", tparam->ty); tparam->print();
3426 // Extra check that function characteristics must match
3427 if (tparam
&& tparam
->ty
== Tfunction
)
3429 TypeFunction
*tp
= (TypeFunction
*)tparam
;
3430 if (t
->parameterList
.varargs
!= tp
->parameterList
.varargs
||
3431 t
->linkage
!= tp
->linkage
)
3433 result
= MATCHnomatch
;
3437 size_t nfargs
= t
->parameterList
.length();
3438 size_t nfparams
= tp
->parameterList
.length();
3440 // bug 2579 fix: Apply function parameter storage classes to parameter types
3441 for (size_t i
= 0; i
< nfparams
; i
++)
3443 Parameter
*fparam
= tp
->parameterList
[i
];
3444 fparam
->type
= fparam
->type
->addStorageClass(fparam
->storageClass
);
3445 fparam
->storageClass
&= ~(STC_TYPECTOR
| STCin
);
3447 //printf("\t-> this = %d, ", t->ty); t->print();
3448 //printf("\t-> tparam = %d, ", tparam->ty); tparam->print();
3450 /* See if tuple match
3452 if (nfparams
> 0 && nfargs
>= nfparams
- 1)
3454 /* See if 'A' of the template parameter matches 'A'
3455 * of the type of the last function parameter.
3457 Parameter
*fparam
= tp
->parameterList
[nfparams
- 1];
3459 assert(fparam
->type
);
3460 if (fparam
->type
->ty
!= Tident
)
3462 TypeIdentifier
*tid
= (TypeIdentifier
*)fparam
->type
;
3463 if (tid
->idents
.length
)
3466 /* Look through parameters to find tuple matching tid->ident
3471 if (tupi
== parameters
->length
)
3473 TemplateParameter
*tx
= (*parameters
)[tupi
];
3474 TemplateTupleParameter
*tup
= tx
->isTemplateTupleParameter();
3475 if (tup
&& tup
->ident
->equals(tid
->ident
))
3479 /* The types of the function arguments [nfparams - 1 .. nfargs]
3480 * now form the tuple argument.
3482 size_t tuple_dim
= nfargs
- (nfparams
- 1);
3484 /* See if existing tuple, and whether it matches or not
3486 RootObject
*o
= (*dedtypes
)[tupi
];
3489 // Existing deduced argument must be a tuple, and must match
3490 Tuple
*tup
= isTuple(o
);
3491 if (!tup
|| tup
->objects
.length
!= tuple_dim
)
3493 result
= MATCHnomatch
;
3496 for (size_t i
= 0; i
< tuple_dim
; i
++)
3498 Parameter
*arg
= t
->parameterList
[nfparams
- 1 + i
];
3499 if (!arg
->type
->equals(tup
->objects
[i
]))
3501 result
= MATCHnomatch
;
3509 Tuple
*tup
= new Tuple();
3510 tup
->objects
.setDim(tuple_dim
);
3511 for (size_t i
= 0; i
< tuple_dim
; i
++)
3513 Parameter
*arg
= t
->parameterList
[nfparams
- 1 + i
];
3514 tup
->objects
[i
] = arg
->type
;
3516 (*dedtypes
)[tupi
] = tup
;
3518 nfparams
--; // don't consider the last parameter for type deduction
3523 if (nfargs
!= nfparams
)
3525 result
= MATCHnomatch
;
3529 for (size_t i
= 0; i
< nfparams
; i
++)
3531 Parameter
*a
= t
->parameterList
[i
];
3532 Parameter
*ap
= tp
->parameterList
[i
];
3534 if (!a
->isCovariant(t
->isref
, ap
) ||
3535 !deduceType(a
->type
, sc
, ap
->type
, parameters
, dedtypes
))
3537 result
= MATCHnomatch
;
3545 void visit(TypeIdentifier
*t
)
3548 if (tparam
&& tparam
->ty
== Tident
)
3550 TypeIdentifier
*tp
= (TypeIdentifier
*)tparam
;
3552 for (size_t i
= 0; i
< t
->idents
.length
; i
++)
3554 RootObject
*id1
= t
->idents
[i
];
3555 RootObject
*id2
= tp
->idents
[i
];
3557 if (!id1
->equals(id2
))
3559 result
= MATCHnomatch
;
3567 void visit(TypeInstance
*t
)
3570 if (tparam
&& tparam
->ty
== Tinstance
&& t
->tempinst
->tempdecl
)
3572 TemplateDeclaration
*tempdecl
= t
->tempinst
->tempdecl
->isTemplateDeclaration();
3575 TypeInstance
*tp
= (TypeInstance
*)tparam
;
3577 //printf("tempinst->tempdecl = %p\n", tempdecl);
3578 //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl);
3579 if (!tp
->tempinst
->tempdecl
)
3581 //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars());
3584 * template Foo(T : sa!(T), alias sa)
3586 size_t i
= templateIdentifierLookup(tp
->tempinst
->name
, parameters
);
3587 if (i
== IDX_NOTFOUND
)
3589 /* Didn't find it as a parameter identifier. Try looking
3590 * it up and seeing if is an alias. See Bugzilla 1454
3592 TypeIdentifier
*tid
= new TypeIdentifier(tp
->loc
, tp
->tempinst
->name
);
3596 tid
->resolve(tp
->loc
, sc
, &e
, &tx
, &s
);
3599 s
= tx
->toDsymbol(sc
);
3600 if (TemplateInstance
*ti
= s
? s
->parent
->isTemplateInstance() : NULL
)
3602 // Bugzilla 14290: Try to match with ti->tempecl,
3603 // only when ti is an enclosing instance.
3604 Dsymbol
*p
= sc
->parent
;
3605 while (p
&& p
!= ti
)
3614 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
3619 for (; td
; td
= td
->overnext
)
3628 TemplateParameter
*tpx
= (*parameters
)[i
];
3629 if (!tpx
->matchArg(sc
, tempdecl
, i
, parameters
, dedtypes
, NULL
))
3632 else if (tempdecl
!= tp
->tempinst
->tempdecl
)
3637 for (size_t i
= 0; 1; i
++)
3639 //printf("\ttest: tempinst->tiargs[%d]\n", i);
3640 RootObject
*o1
= NULL
;
3641 if (i
< t
->tempinst
->tiargs
->length
)
3642 o1
= (*t
->tempinst
->tiargs
)[i
];
3643 else if (i
< t
->tempinst
->tdtypes
.length
&& i
< tp
->tempinst
->tiargs
->length
)
3645 // Pick up default arg
3646 o1
= t
->tempinst
->tdtypes
[i
];
3648 else if (i
>= tp
->tempinst
->tiargs
->length
)
3651 if (i
>= tp
->tempinst
->tiargs
->length
)
3653 size_t dim
= tempdecl
->parameters
->length
- (tempdecl
->isVariadic() ? 1 : 0);
3654 while (i
< dim
&& ((*tempdecl
->parameters
)[i
]->dependent
||
3655 (*tempdecl
->parameters
)[i
]->hasDefaultArg()))
3660 break; // match if all remained parameters are dependent
3664 RootObject
*o2
= (*tp
->tempinst
->tiargs
)[i
];
3665 Type
*t2
= isType(o2
);
3667 size_t j
= (t2
&& t2
->ty
== Tident
&& i
== tp
->tempinst
->tiargs
->length
- 1)
3668 ? templateParameterLookup(t2
, parameters
) : IDX_NOTFOUND
;
3669 if (j
!= IDX_NOTFOUND
&& j
== parameters
->length
- 1 &&
3670 (*parameters
)[j
]->isTemplateTupleParameter())
3674 * alias A!(int, float) X;
3675 * static if (is(X Y == A!(Z), Z...)) {}
3676 * deduce that Z is a tuple(int, float)
3679 /* Create tuple from remaining args
3681 Tuple
*vt
= new Tuple();
3682 size_t vtdim
= (tempdecl
->isVariadic()
3683 ? t
->tempinst
->tiargs
->length
: t
->tempinst
->tdtypes
.length
) - i
;
3684 vt
->objects
.setDim(vtdim
);
3685 for (size_t k
= 0; k
< vtdim
; k
++)
3688 if (k
< t
->tempinst
->tiargs
->length
)
3689 o
= (*t
->tempinst
->tiargs
)[i
+ k
];
3690 else // Pick up default arg
3691 o
= t
->tempinst
->tdtypes
[i
+ k
];
3695 Tuple
*v
= (Tuple
*)(*dedtypes
)[j
];
3702 (*dedtypes
)[j
] = vt
;
3708 Type
*t1
= isType(o1
);
3709 Dsymbol
*s1
= isDsymbol(o1
);
3710 Dsymbol
*s2
= isDsymbol(o2
);
3711 Expression
*e1
= s1
? getValue(s1
) : getValue(isExpression(o1
));
3712 Expression
*e2
= isExpression(o2
);
3716 if (!deduceType(t1
, sc
, t2
, parameters
, dedtypes
))
3722 e1
= e1
->ctfeInterpret();
3724 /* If it is one of the template parameters for this template,
3725 * we should not attempt to interpret it. It already has a value.
3727 if (e2
->op
== TOKvar
&&
3728 (((VarExp
*)e2
)->var
->storage_class
& STCtemplateparameter
))
3731 * (T:Number!(e2), int e2)
3733 j
= templateIdentifierLookup(((VarExp
*)e2
)->var
->ident
, parameters
);
3734 if (j
!= IDX_NOTFOUND
)
3736 // The template parameter was not from this template
3737 // (it may be from a parent template, for example)
3740 e2
= expressionSemantic(e2
, sc
); // Bugzilla 13417
3741 e2
= e2
->ctfeInterpret();
3743 //printf("e1 = %s, type = %s %d\n", e1->toChars(), e1->type->toChars(), e1->type->ty);
3744 //printf("e2 = %s, type = %s %d\n", e2->toChars(), e2->type->toChars(), e2->type->ty);
3745 if (!e1
->equals(e2
))
3747 if (!e2
->implicitConvTo(e1
->type
))
3750 e2
= e2
->implicitCastTo(sc
, e1
->type
);
3751 e2
= e2
->ctfeInterpret();
3752 if (!e1
->equals(e2
))
3756 else if (e1
&& t2
&& t2
->ty
== Tident
)
3758 j
= templateParameterLookup(t2
, parameters
);
3760 if (j
== IDX_NOTFOUND
)
3762 t2
->resolve(((TypeIdentifier
*)t2
)->loc
, sc
, &e2
, &t2
, &s2
);
3767 if (!(*parameters
)[j
]->matchArg(sc
, e1
, j
, parameters
, dedtypes
, NULL
))
3773 if (!s1
->equals(s2
))
3776 else if (s1
&& t2
&& t2
->ty
== Tident
)
3778 j
= templateParameterLookup(t2
, parameters
);
3779 if (j
== IDX_NOTFOUND
)
3781 t2
->resolve(((TypeIdentifier
*)t2
)->loc
, sc
, &e2
, &t2
, &s2
);
3786 if (!(*parameters
)[j
]->matchArg(sc
, s1
, j
, parameters
, dedtypes
, NULL
))
3797 //printf("no match\n");
3798 result
= MATCHnomatch
;
3801 void visit(TypeStruct
*t
)
3803 /* If this struct is a template struct, and we're matching
3804 * it against a template instance, convert the struct type
3805 * to a template instance, too, and try again.
3807 TemplateInstance
*ti
= t
->sym
->parent
->isTemplateInstance();
3809 if (tparam
&& tparam
->ty
== Tinstance
)
3811 if (ti
&& ti
->toAlias() == t
->sym
)
3813 TypeInstance
*tx
= new TypeInstance(Loc(), ti
);
3814 result
= deduceType(tx
, sc
, tparam
, parameters
, dedtypes
, wm
);
3818 /* Match things like:
3821 TypeInstance
*tpi
= (TypeInstance
*)tparam
;
3822 if (tpi
->idents
.length
)
3824 RootObject
*id
= tpi
->idents
[tpi
->idents
.length
- 1];
3825 if (id
->dyncast() == DYNCAST_IDENTIFIER
&& t
->sym
->ident
->equals((Identifier
*)id
))
3827 Type
*tparent
= t
->sym
->parent
->getType();
3830 /* Slice off the .foo in S!(T).foo
3832 tpi
->idents
.length
--;
3833 result
= deduceType(tparent
, sc
, tpi
, parameters
, dedtypes
, wm
);
3834 tpi
->idents
.length
++;
3842 if (tparam
&& tparam
->ty
== Tstruct
)
3844 TypeStruct
*tp
= (TypeStruct
*)tparam
;
3846 //printf("\t%d\n", (MATCH) t->implicitConvTo(tp));
3847 if (wm
&& t
->deduceWild(tparam
, false))
3849 result
= MATCHconst
;
3852 result
= t
->implicitConvTo(tp
);
3858 void visit(TypeEnum
*t
)
3861 if (tparam
&& tparam
->ty
== Tenum
)
3863 TypeEnum
*tp
= (TypeEnum
*)tparam
;
3864 if (t
->sym
== tp
->sym
)
3867 result
= MATCHnomatch
;
3870 Type
*tb
= t
->toBasetype();
3871 if (tb
->ty
== tparam
->ty
||
3872 (tb
->ty
== Tsarray
&& tparam
->ty
== Taarray
))
3874 result
= deduceType(tb
, sc
, tparam
, parameters
, dedtypes
, wm
);
3880 /* Helper for TypeClass::deduceType().
3881 * Classes can match with implicit conversion to a base class or interface.
3882 * This is complicated, because there may be more than one base class which
3883 * matches. In such cases, one or more parameters remain ambiguous.
3886 * interface I(X, Y) {}
3887 * class C : I(uint, double), I(char, double) {}
3889 * foo(T, U)( I!(T, U) x)
3891 * deduces that U is double, but T remains ambiguous (could be char or uint).
3893 * Given a baseclass b, and initial deduced types 'dedtypes', this function
3894 * tries to match tparam with b, and also tries all base interfaces of b.
3895 * If a match occurs, numBaseClassMatches is incremented, and the new deduced
3896 * types are ANDed with the current 'best' estimate for dedtypes.
3898 static void deduceBaseClassParameters(BaseClass
*b
,
3899 Scope
*sc
, Type
*tparam
, TemplateParameters
*parameters
, Objects
*dedtypes
,
3900 Objects
*best
, int &numBaseClassMatches
)
3902 TemplateInstance
*parti
= b
->sym
? b
->sym
->parent
->isTemplateInstance() : NULL
;
3905 // Make a temporary copy of dedtypes so we don't destroy it
3906 Objects
*tmpdedtypes
= new Objects();
3907 tmpdedtypes
->setDim(dedtypes
->length
);
3908 memcpy(tmpdedtypes
->tdata(), dedtypes
->tdata(), dedtypes
->length
* sizeof(void *));
3910 TypeInstance
*t
= new TypeInstance(Loc(), parti
);
3911 MATCH m
= deduceType(t
, sc
, tparam
, parameters
, tmpdedtypes
);
3912 if (m
> MATCHnomatch
)
3914 // If this is the first ever match, it becomes our best estimate
3915 if (numBaseClassMatches
==0)
3916 memcpy(best
->tdata(), tmpdedtypes
->tdata(), tmpdedtypes
->length
* sizeof(void *));
3917 else for (size_t k
= 0; k
< tmpdedtypes
->length
; ++k
)
3919 // If we've found more than one possible type for a parameter,
3920 // mark it as unknown.
3921 if ((*tmpdedtypes
)[k
] != (*best
)[k
])
3922 (*best
)[k
] = (*dedtypes
)[k
];
3924 ++numBaseClassMatches
;
3927 // Now recursively test the inherited interfaces
3928 for (size_t j
= 0; j
< b
->baseInterfaces
.length
; ++j
)
3930 BaseClass
*bi
= &b
->baseInterfaces
.ptr
[j
];
3931 deduceBaseClassParameters(bi
,
3932 sc
, tparam
, parameters
, dedtypes
,
3933 best
, numBaseClassMatches
);
3938 void visit(TypeClass
*t
)
3940 //printf("TypeClass::deduceType(this = %s)\n", t->toChars());
3942 /* If this class is a template class, and we're matching
3943 * it against a template instance, convert the class type
3944 * to a template instance, too, and try again.
3946 TemplateInstance
*ti
= t
->sym
->parent
->isTemplateInstance();
3948 if (tparam
&& tparam
->ty
== Tinstance
)
3950 if (ti
&& ti
->toAlias() == t
->sym
)
3952 TypeInstance
*tx
= new TypeInstance(Loc(), ti
);
3953 MATCH m
= deduceType(tx
, sc
, tparam
, parameters
, dedtypes
, wm
);
3954 // Even if the match fails, there is still a chance it could match
3956 if (m
!= MATCHnomatch
)
3963 /* Match things like:
3966 TypeInstance
*tpi
= (TypeInstance
*)tparam
;
3967 if (tpi
->idents
.length
)
3969 RootObject
*id
= tpi
->idents
[tpi
->idents
.length
- 1];
3970 if (id
->dyncast() == DYNCAST_IDENTIFIER
&& t
->sym
->ident
->equals((Identifier
*)id
))
3972 Type
*tparent
= t
->sym
->parent
->getType();
3975 /* Slice off the .foo in S!(T).foo
3977 tpi
->idents
.length
--;
3978 result
= deduceType(tparent
, sc
, tpi
, parameters
, dedtypes
, wm
);
3979 tpi
->idents
.length
++;
3985 // If it matches exactly or via implicit conversion, we're done
3987 if (result
!= MATCHnomatch
)
3990 /* There is still a chance to match via implicit conversion to
3991 * a base class or interface. Because there could be more than one such
3992 * match, we need to check them all.
3995 int numBaseClassMatches
= 0; // Have we found an interface match?
3997 // Our best guess at dedtypes
3998 Objects
*best
= new Objects();
3999 best
->setDim(dedtypes
->length
);
4001 ClassDeclaration
*s
= t
->sym
;
4002 while (s
&& s
->baseclasses
->length
> 0)
4004 // Test the base class
4005 deduceBaseClassParameters((*s
->baseclasses
)[0],
4006 sc
, tparam
, parameters
, dedtypes
,
4007 best
, numBaseClassMatches
);
4009 // Test the interfaces inherited by the base class
4010 for (size_t i
= 0; i
< s
->interfaces
.length
; ++i
)
4012 BaseClass
*b
= s
->interfaces
.ptr
[i
];
4013 deduceBaseClassParameters(b
, sc
, tparam
, parameters
, dedtypes
,
4014 best
, numBaseClassMatches
);
4016 s
= (*s
->baseclasses
)[0]->sym
;
4019 if (numBaseClassMatches
== 0)
4021 result
= MATCHnomatch
;
4025 // If we got at least one match, copy the known types into dedtypes
4026 memcpy(dedtypes
->tdata(), best
->tdata(), best
->length
* sizeof(void *));
4027 result
= MATCHconvert
;
4032 if (tparam
&& tparam
->ty
== Tclass
)
4034 TypeClass
*tp
= (TypeClass
*)tparam
;
4036 //printf("\t%d\n", (MATCH) t->implicitConvTo(tp));
4037 if (wm
&& t
->deduceWild(tparam
, false))
4039 result
= MATCHconst
;
4042 result
= t
->implicitConvTo(tp
);
4048 void visit(Expression
*e
)
4050 //printf("Expression::deduceType(e = %s)\n", e->toChars());
4051 size_t i
= templateParameterLookup(tparam
, parameters
);
4052 if (i
== IDX_NOTFOUND
|| ((TypeIdentifier
*)tparam
)->idents
.length
> 0)
4054 if (e
== emptyArrayElement
&& tparam
->ty
== Tarray
)
4056 Type
*tn
= ((TypeNext
*)tparam
)->next
;
4057 result
= deduceType(emptyArrayElement
, sc
, tn
, parameters
, dedtypes
, wm
);
4060 e
->type
->accept(this);
4064 TemplateTypeParameter
*tp
= (*parameters
)[i
]->isTemplateTypeParameter();
4068 if (e
== emptyArrayElement
)
4072 result
= MATCHexact
;
4075 if (tp
->defaultType
)
4077 tp
->defaultType
->accept(this);
4082 Type
*at
= (Type
*)(*dedtypes
)[i
];
4084 if (unsigned char wx
= deduceWildHelper(e
->type
, &tt
, tparam
))
4087 result
= MATCHconst
;
4089 else if (MATCH m
= deduceTypeHelper(e
->type
, &tt
, tparam
))
4096 // expression vs (none)
4099 (*dedtypes
)[i
] = new TypeDeduced(tt
, e
, tparam
);
4103 TypeDeduced
*xt
= NULL
;
4104 if (at
->ty
== Tnone
)
4106 xt
= (TypeDeduced
*)at
;
4110 // From previous matched expressions to current deduced type
4111 MATCH match1
= xt
? xt
->matchAll(tt
) : MATCHnomatch
;
4113 // From current expresssion to previous deduced type
4114 Type
*pt
= at
->addMod(tparam
->mod
);
4116 pt
= pt
->substWildTo(*wm
);
4117 MATCH match2
= e
->implicitConvTo(pt
);
4119 if (match1
> MATCHnomatch
&& match2
> MATCHnomatch
)
4121 if (at
->implicitConvTo(tt
) <= MATCHnomatch
)
4122 match1
= MATCHnomatch
; // Prefer at
4123 else if (tt
->implicitConvTo(at
) <= MATCHnomatch
)
4124 match2
= MATCHnomatch
; // Prefer tt
4125 else if (tt
->isTypeBasic() && tt
->ty
== at
->ty
&& tt
->mod
!= at
->mod
)
4127 if (!tt
->isMutable() && !at
->isMutable())
4128 tt
= tt
->mutableOf()->addMod(MODmerge(tt
->mod
, at
->mod
));
4129 else if (tt
->isMutable())
4131 if (at
->mod
== 0) // Prefer unshared
4132 match1
= MATCHnomatch
;
4134 match2
= MATCHnomatch
;
4136 else if (at
->isMutable())
4138 if (tt
->mod
== 0) // Prefer unshared
4139 match2
= MATCHnomatch
;
4141 match1
= MATCHnomatch
;
4143 //printf("tt = %s, at = %s\n", tt->toChars(), at->toChars());
4147 match1
= MATCHnomatch
;
4148 match2
= MATCHnomatch
;
4151 if (match1
> MATCHnomatch
)
4153 // Prefer current match: tt
4155 xt
->update(tt
, e
, tparam
);
4157 (*dedtypes
)[i
] = tt
;
4161 if (match2
> MATCHnomatch
)
4163 // Prefer previous match: (*dedtypes)[i]
4165 xt
->update(e
, tparam
);
4170 /* Deduce common type
4172 if (Type
*t
= rawTypeMerge(at
, tt
))
4175 xt
->update(t
, e
, tparam
);
4179 pt
= tt
->addMod(tparam
->mod
);
4181 pt
= pt
->substWildTo(*wm
);
4182 result
= e
->implicitConvTo(pt
);
4186 result
= MATCHnomatch
;
4189 MATCH
deduceEmptyArrayElement()
4191 if (!emptyArrayElement
)
4193 emptyArrayElement
= new IdentifierExp(Loc(), Id::p
); // dummy
4194 emptyArrayElement
->type
= Type::tvoid
;
4196 assert(tparam
->ty
== Tarray
);
4198 Type
*tn
= ((TypeNext
*)tparam
)->next
;
4199 return deduceType(emptyArrayElement
, sc
, tn
, parameters
, dedtypes
, wm
);
4202 void visit(NullExp
*e
)
4204 if (tparam
->ty
== Tarray
&& e
->type
->ty
== Tnull
)
4206 // tparam:T[] <- e:null (void[])
4207 result
= deduceEmptyArrayElement();
4210 visit((Expression
*)e
);
4213 void visit(StringExp
*e
)
4216 if (e
->type
->ty
== Tarray
&&
4217 (tparam
->ty
== Tsarray
||
4218 (tparam
->ty
== Taarray
&& (taai
= ((TypeAArray
*)tparam
)->index
)->ty
== Tident
&&
4219 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
4221 // Consider compile-time known boundaries
4222 e
->type
->nextOf()->sarrayOf(e
->len
)->accept(this);
4225 visit((Expression
*)e
);
4228 void visit(ArrayLiteralExp
*e
)
4230 // https://issues.dlang.org/show_bug.cgi?id=20092
4231 if (e
->elements
&& e
->elements
->length
&&
4232 e
->type
->toBasetype()->nextOf()->ty
== Tvoid
)
4234 result
= deduceEmptyArrayElement();
4237 if ((!e
->elements
|| !e
->elements
->length
) &&
4238 e
->type
->toBasetype()->nextOf()->ty
== Tvoid
&&
4239 tparam
->ty
== Tarray
)
4241 // tparam:T[] <- e:[] (void[])
4242 result
= deduceEmptyArrayElement();
4246 if (tparam
->ty
== Tarray
&& e
->elements
&& e
->elements
->length
)
4248 Type
*tn
= ((TypeDArray
*)tparam
)->next
;
4249 result
= MATCHexact
;
4252 MATCH m
= deduceType(e
->basis
, sc
, tn
, parameters
, dedtypes
, wm
);
4256 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
4258 if (result
<= MATCHnomatch
)
4260 Expression
*el
= (*e
->elements
)[i
];
4263 MATCH m
= deduceType(el
, sc
, tn
, parameters
, dedtypes
, wm
);
4271 if (e
->type
->ty
== Tarray
&&
4272 (tparam
->ty
== Tsarray
||
4273 (tparam
->ty
== Taarray
&& (taai
= ((TypeAArray
*)tparam
)->index
)->ty
== Tident
&&
4274 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
4276 // Consider compile-time known boundaries
4277 e
->type
->nextOf()->sarrayOf(e
->elements
->length
)->accept(this);
4280 visit((Expression
*)e
);
4283 void visit(AssocArrayLiteralExp
*e
)
4285 if (tparam
->ty
== Taarray
&& e
->keys
&& e
->keys
->length
)
4287 TypeAArray
*taa
= (TypeAArray
*)tparam
;
4288 result
= MATCHexact
;
4289 for (size_t i
= 0; i
< e
->keys
->length
; i
++)
4291 MATCH m1
= deduceType((*e
->keys
)[i
], sc
, taa
->index
, parameters
, dedtypes
, wm
);
4294 if (result
<= MATCHnomatch
)
4296 MATCH m2
= deduceType((*e
->values
)[i
], sc
, taa
->next
, parameters
, dedtypes
, wm
);
4299 if (result
<= MATCHnomatch
)
4304 visit((Expression
*)e
);
4307 void visit(FuncExp
*e
)
4309 //printf("e->type = %s, tparam = %s\n", e->type->toChars(), tparam->toChars());
4313 if (!to
->nextOf() || to
->nextOf()->ty
!= Tfunction
)
4315 TypeFunction
*tof
= (TypeFunction
*)to
->nextOf();
4317 // Parameter types inference from 'tof'
4318 assert(e
->td
->_scope
);
4319 TypeFunction
*tf
= (TypeFunction
*)e
->fd
->type
;
4320 //printf("\ttof = %s\n", tof->toChars());
4321 //printf("\ttf = %s\n", tf->toChars());
4322 size_t dim
= tf
->parameterList
.length();
4324 if (tof
->parameterList
.length() != dim
||
4325 tof
->parameterList
.varargs
!= tf
->parameterList
.varargs
)
4328 Objects
*tiargs
= new Objects();
4329 tiargs
->reserve(e
->td
->parameters
->length
);
4331 for (size_t i
= 0; i
< e
->td
->parameters
->length
; i
++)
4333 TemplateParameter
*tp
= (*e
->td
->parameters
)[i
];
4335 for (; u
< dim
; u
++)
4337 Parameter
*p
= tf
->parameterList
[u
];
4338 if (p
->type
->ty
== Tident
&&
4339 ((TypeIdentifier
*)p
->type
)->ident
== tp
->ident
)
4345 Parameter
*pto
= tof
->parameterList
[u
];
4348 Type
*t
= pto
->type
->syntaxCopy(); // Bugzilla 11774
4349 if (reliesOnTident(t
, parameters
, inferStart
))
4351 t
= typeSemantic(t
, e
->loc
, sc
);
4352 if (t
->ty
== Terror
)
4357 // Set target of return type inference
4358 if (!tf
->next
&& tof
->next
)
4359 e
->fd
->treq
= tparam
;
4361 TemplateInstance
*ti
= new TemplateInstance(e
->loc
, e
->td
, tiargs
);
4362 Expression
*ex
= new ScopeExp(e
->loc
, ti
);
4363 ex
= expressionSemantic(ex
, e
->td
->_scope
);
4365 // Reset inference target for the later re-semantic
4368 if (ex
->op
== TOKerror
)
4370 if (ex
->op
!= TOKfunction
)
4378 if (t
->ty
== Tdelegate
&& tparam
->ty
== Tpointer
)
4381 // Allow conversion from implicit function pointer to delegate
4382 if (e
->tok
== TOKreserved
&&
4383 t
->ty
== Tpointer
&& tparam
->ty
== Tdelegate
)
4385 TypeFunction
*tf
= (TypeFunction
*)t
->nextOf();
4386 t
= (new TypeDelegate(tf
))->merge();
4388 //printf("tparam = %s <= e->type = %s, t = %s\n", tparam->toChars(), e->type->toChars(), t->toChars());
4392 void visit(SliceExp
*e
)
4395 if (e
->type
->ty
== Tarray
&&
4396 (tparam
->ty
== Tsarray
||
4397 (tparam
->ty
== Taarray
&& (taai
= ((TypeAArray
*)tparam
)->index
)->ty
== Tident
&&
4398 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
4400 // Consider compile-time known boundaries
4401 if (Type
*tsa
= toStaticArrayType(e
))
4407 visit((Expression
*)e
);
4410 void visit(CommaExp
*e
)
4412 ((CommaExp
*)e
)->e2
->accept(this);
4416 DeduceType
v(sc
, tparam
, parameters
, dedtypes
, wm
, inferStart
);
4417 if (Type
*t
= isType(o
))
4421 assert(isExpression(o
) && wm
);
4422 ((Expression
*)o
)->accept(&v
);
4427 /*******************************
4429 * t Tested type, if NULL, returns NULL.
4430 * tparams Optional template parameters.
4432 * If one of the subtypes of this type is a TypeIdentifier,
4433 * i.e. it's an unresolved type, return that type.
4435 * Only when the TypeIdentifier is one of template parameters,
4439 bool reliesOnTident(Type
*t
, TemplateParameters
*tparams
, size_t iStart
)
4441 class ReliesOnTident
: public Visitor
4444 TemplateParameters
*tparams
;
4448 ReliesOnTident(TemplateParameters
*tparams
, size_t iStart
)
4449 : tparams(tparams
), iStart(iStart
)
4458 void visit(TypeNext
*t
)
4460 t
->next
->accept(this);
4463 void visit(TypeVector
*t
)
4465 t
->basetype
->accept(this);
4468 void visit(TypeAArray
*t
)
4470 visit((TypeNext
*)t
);
4472 t
->index
->accept(this);
4475 void visit(TypeFunction
*t
)
4477 size_t dim
= t
->parameterList
.length();
4478 for (size_t i
= 0; i
< dim
; i
++)
4480 Parameter
*fparam
= t
->parameterList
[i
];
4481 fparam
->type
->accept(this);
4486 t
->next
->accept(this);
4489 void visit(TypeIdentifier
*t
)
4497 for (size_t i
= iStart
; i
< tparams
->length
; i
++)
4499 TemplateParameter
*tp
= (*tparams
)[i
];
4500 if (tp
->ident
->equals(t
->ident
))
4508 void visit(TypeInstance
*t
)
4513 for (size_t i
= iStart
; i
< tparams
->length
; i
++)
4515 TemplateParameter
*tp
= (*tparams
)[i
];
4516 if (t
->tempinst
->name
== tp
->ident
)
4522 if (!t
->tempinst
->tiargs
)
4524 for (size_t i
= 0; i
< t
->tempinst
->tiargs
->length
; i
++)
4526 Type
*ta
= isType((*t
->tempinst
->tiargs
)[i
]);
4536 void visit(TypeTypeof
*t
)
4538 //printf("TypeTypeof::reliesOnTident('%s')\n", t->toChars());
4539 t
->exp
->accept(this);
4542 void visit(TypeTuple
*t
)
4546 for (size_t i
= 0; i
< t
->arguments
->length
; i
++)
4548 Parameter
*arg
= (*t
->arguments
)[i
];
4549 arg
->type
->accept(this);
4556 void visit(Expression
*)
4558 //printf("Expression::reliesOnTident('%s')\n", e->toChars());
4561 void visit(IdentifierExp
*e
)
4563 //printf("IdentifierExp::reliesOnTident('%s')\n", e->toChars());
4564 for (size_t i
= iStart
; i
< tparams
->length
; i
++)
4566 TemplateParameter
*tp
= (*tparams
)[i
];
4567 if (e
->ident
== tp
->ident
)
4575 void visit(TupleExp
*e
)
4577 //printf("TupleExp::reliesOnTident('%s')\n", e->toChars());
4580 for (size_t i
= 0; i
< e
->exps
->length
; i
++)
4582 Expression
*ea
= (*e
->exps
)[i
];
4590 void visit(ArrayLiteralExp
*e
)
4592 //printf("ArrayLiteralExp::reliesOnTident('%s')\n", e->toChars());
4595 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
4597 Expression
*el
= (*e
->elements
)[i
];
4605 void visit(AssocArrayLiteralExp
*e
)
4607 //printf("AssocArrayLiteralExp::reliesOnTident('%s')\n", e->toChars());
4608 for (size_t i
= 0; i
< e
->keys
->length
; i
++)
4610 Expression
*ek
= (*e
->keys
)[i
];
4615 for (size_t i
= 0; i
< e
->values
->length
; i
++)
4617 Expression
*ev
= (*e
->values
)[i
];
4624 void visit(StructLiteralExp
*e
)
4626 //printf("StructLiteralExp::reliesOnTident('%s')\n", e->toChars());
4629 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
4631 Expression
*ea
= (*e
->elements
)[i
];
4639 void visit(TypeExp
*e
)
4641 //printf("TypeExp::reliesOnTident('%s')\n", e->toChars());
4642 e
->type
->accept(this);
4645 void visit(NewExp
*e
)
4647 //printf("NewExp::reliesOnTident('%s')\n", e->toChars());
4649 e
->thisexp
->accept(this);
4650 if (!result
&& e
->newargs
)
4652 for (size_t i
= 0; i
< e
->newargs
->length
; i
++)
4654 Expression
*ea
= (*e
->newargs
)[i
];
4660 e
->newtype
->accept(this);
4661 if (!result
&& e
->arguments
)
4663 for (size_t i
= 0; i
< e
->arguments
->length
; i
++)
4665 Expression
*ea
= (*e
->arguments
)[i
];
4673 void visit(NewAnonClassExp
*)
4675 //printf("NewAnonClassExp::reliesOnTident('%s')\n", e->toChars());
4679 void visit(FuncExp
*)
4681 //printf("FuncExp::reliesOnTident('%s')\n", e->toChars());
4685 void visit(TypeidExp
*e
)
4687 //printf("TypeidExp::reliesOnTident('%s')\n", e->toChars());
4688 if (Expression
*ea
= isExpression(e
->obj
))
4690 else if (Type
*ta
= isType(e
->obj
))
4694 void visit(TraitsExp
*e
)
4696 //printf("TraitsExp::reliesOnTident('%s')\n", e->toChars());
4699 for (size_t i
= 0; i
< e
->args
->length
; i
++)
4701 RootObject
*oa
= (*e
->args
)[i
];
4702 if (Expression
*ea
= isExpression(oa
))
4704 else if (Type
*ta
= isType(oa
))
4712 void visit(IsExp
*e
)
4714 //printf("IsExp::reliesOnTident('%s')\n", e->toChars());
4715 e
->targ
->accept(this);
4718 void visit(UnaExp
*e
)
4720 //printf("UnaExp::reliesOnTident('%s')\n", e->toChars());
4721 e
->e1
->accept(this);
4724 void visit(DotTemplateInstanceExp
*e
)
4726 //printf("DotTemplateInstanceExp::reliesOnTident('%s')\n", e->toChars());
4728 if (!result
&& e
->ti
->tiargs
)
4730 for (size_t i
= 0; i
< e
->ti
->tiargs
->length
; i
++)
4732 RootObject
*oa
= (*e
->ti
->tiargs
)[i
];
4733 if (Expression
*ea
= isExpression(oa
))
4735 else if (Type
*ta
= isType(oa
))
4743 void visit(CallExp
*e
)
4745 //printf("CallExp::reliesOnTident('%s')\n", e->toChars());
4747 if (!result
&& e
->arguments
)
4749 for (size_t i
= 0; i
< e
->arguments
->length
; i
++)
4751 Expression
*ea
= (*e
->arguments
)[i
];
4759 void visit(CastExp
*e
)
4761 //printf("CastExp::reliesOnTident('%s')\n", e->toChars());
4763 // e.to can be null for cast() with no type
4764 if (!result
&& e
->to
)
4765 e
->to
->accept(this);
4768 void visit(SliceExp
*e
)
4770 //printf("SliceExp::reliesOnTident('%s')\n", e->toChars());
4772 if (!result
&& e
->lwr
)
4773 e
->lwr
->accept(this);
4774 if (!result
&& e
->upr
)
4775 e
->upr
->accept(this);
4778 void visit(IntervalExp
*e
)
4780 //printf("IntervalExp::reliesOnTident('%s')\n", e->toChars());
4781 e
->lwr
->accept(this);
4783 e
->upr
->accept(this);
4786 void visit(ArrayExp
*e
)
4788 //printf("ArrayExp::reliesOnTident('%s')\n", e->toChars());
4790 if (!result
&& e
->arguments
)
4792 for (size_t i
= 0; i
< e
->arguments
->length
; i
++)
4794 Expression
*ea
= (*e
->arguments
)[i
];
4800 void visit(BinExp
*e
)
4802 //printf("BinExp::reliesOnTident('%s')\n", e->toChars());
4803 e
->e1
->accept(this);
4805 e
->e2
->accept(this);
4808 void visit(CondExp
*e
)
4810 //printf("BinExp::reliesOnTident('%s')\n", e->toChars());
4811 e
->econd
->accept(this);
4820 ReliesOnTident
v(tparams
, iStart
);
4825 /* ======================== TemplateParameter =============================== */
4827 TemplateParameter::TemplateParameter(Loc loc
, Identifier
*ident
)
4830 this->ident
= ident
;
4831 this->dependent
= false;
4834 TemplateTypeParameter
*TemplateParameter::isTemplateTypeParameter()
4839 TemplateValueParameter
*TemplateParameter::isTemplateValueParameter()
4844 TemplateAliasParameter
*TemplateParameter::isTemplateAliasParameter()
4849 TemplateTupleParameter
*TemplateParameter::isTemplateTupleParameter()
4854 TemplateThisParameter
*TemplateParameter::isTemplateThisParameter()
4859 /*******************************************
4860 * Match to a particular TemplateParameter.
4862 * instLoc location that the template is instantiated.
4863 * tiargs[] actual arguments to template instance
4865 * parameters[] template parameters
4866 * dedtypes[] deduced arguments to template instance
4867 * *psparam set to symbol declared and initialized to dedtypes[i]
4869 MATCH
TemplateParameter::matchArg(Loc instLoc
, Scope
*sc
, Objects
*tiargs
,
4870 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
4871 Declaration
**psparam
)
4875 if (i
< tiargs
->length
)
4876 oarg
= (*tiargs
)[i
];
4879 // Get default argument instead
4880 oarg
= defaultArg(instLoc
, sc
);
4883 assert(i
< dedtypes
->length
);
4884 // It might have already been deduced
4885 oarg
= (*dedtypes
)[i
];
4890 return matchArg(sc
, oarg
, i
, parameters
, dedtypes
, psparam
);
4895 return MATCHnomatch
;
4898 /* ======================== TemplateTypeParameter =========================== */
4902 Type
*TemplateTypeParameter::tdummy
= NULL
;
4904 TemplateTypeParameter::TemplateTypeParameter(Loc loc
, Identifier
*ident
, Type
*specType
,
4906 : TemplateParameter(loc
, ident
)
4908 this->ident
= ident
;
4909 this->specType
= specType
;
4910 this->defaultType
= defaultType
;
4913 TemplateTypeParameter
*TemplateTypeParameter::isTemplateTypeParameter()
4918 TemplateParameter
*TemplateTypeParameter::syntaxCopy()
4920 return new TemplateTypeParameter(loc
, ident
,
4921 specType
? specType
->syntaxCopy() : NULL
,
4922 defaultType
? defaultType
->syntaxCopy() : NULL
);
4925 bool TemplateTypeParameter::declareParameter(Scope
*sc
)
4927 //printf("TemplateTypeParameter::declareParameter('%s')\n", ident->toChars());
4928 TypeIdentifier
*ti
= new TypeIdentifier(loc
, ident
);
4929 Declaration
*ad
= new AliasDeclaration(loc
, ident
, ti
);
4930 return sc
->insert(ad
) != NULL
;
4933 MATCH
TemplateTypeParameter::matchArg(Scope
*sc
, RootObject
*oarg
,
4934 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
4935 Declaration
**psparam
)
4937 //printf("TemplateTypeParameter::matchArg('%s')\n", ident->toChars());
4938 MATCH m
= MATCHexact
;
4939 Type
*ta
= isType(oarg
);
4942 //printf("%s %p %p %p\n", oarg->toChars(), isExpression(oarg), isDsymbol(oarg), isTuple(oarg));
4945 //printf("ta is %s\n", ta->toChars());
4949 if (!ta
|| ta
== tdummy
)
4952 //printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta->toChars(), specType->toChars());
4953 MATCH m2
= deduceType(ta
, sc
, specType
, parameters
, dedtypes
);
4954 if (m2
<= MATCHnomatch
)
4956 //printf("\tfailed deduceType\n");
4964 Type
*t
= (Type
*)(*dedtypes
)[i
];
4966 if (dependent
&& !t
->equals(ta
)) // Bugzilla 14357
4969 /* This is a self-dependent parameter. For example:
4970 * template X(T : T*) {}
4971 * template X(T : S!T, alias S) {}
4973 //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
4981 // Must match already deduced type
4982 Type
*t
= (Type
*)(*dedtypes
)[i
];
4986 //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
4992 // So that matches with specializations are better
4996 (*dedtypes
)[i
] = ta
;
4999 *psparam
= new AliasDeclaration(loc
, ident
, ta
);
5000 //printf("\tm = %d\n", m);
5001 return dependent
? MATCHexact
: m
;
5006 //printf("\tm = %d\n", MATCHnomatch);
5007 return MATCHnomatch
;
5011 void TemplateTypeParameter::print(RootObject
*oarg
, RootObject
*oded
)
5013 printf(" %s\n", ident
->toChars());
5015 Type
*t
= isType(oarg
);
5016 Type
*ta
= isType(oded
);
5021 printf("\tSpecialization: %s\n", specType
->toChars());
5023 printf("\tDefault: %s\n", defaultType
->toChars());
5024 printf("\tParameter: %s\n", t
? t
->toChars() : "NULL");
5025 printf("\tDeduced Type: %s\n", ta
->toChars());
5028 void *TemplateTypeParameter::dummyArg()
5033 // Use this for alias-parameter's too (?)
5035 tdummy
= new TypeIdentifier(loc
, ident
);
5042 RootObject
*TemplateTypeParameter::specialization()
5047 RootObject
*TemplateTypeParameter::defaultArg(Loc
, Scope
*sc
)
5049 Type
*t
= defaultType
;
5052 t
= t
->syntaxCopy();
5053 t
= typeSemantic(t
, loc
, sc
); // use the parameter loc
5058 bool TemplateTypeParameter::hasDefaultArg()
5060 return defaultType
!= NULL
;
5063 /* ======================== TemplateThisParameter =========================== */
5067 TemplateThisParameter::TemplateThisParameter(Loc loc
, Identifier
*ident
,
5070 : TemplateTypeParameter(loc
, ident
, specType
, defaultType
)
5074 TemplateThisParameter
*TemplateThisParameter::isTemplateThisParameter()
5079 TemplateParameter
*TemplateThisParameter::syntaxCopy()
5081 return new TemplateThisParameter(loc
, ident
,
5082 specType
? specType
->syntaxCopy() : NULL
,
5083 defaultType
? defaultType
->syntaxCopy() : NULL
);
5086 /* ======================== TemplateAliasParameter ========================== */
5090 Dsymbol
*TemplateAliasParameter::sdummy
= NULL
;
5092 TemplateAliasParameter::TemplateAliasParameter(Loc loc
, Identifier
*ident
,
5093 Type
*specType
, RootObject
*specAlias
, RootObject
*defaultAlias
)
5094 : TemplateParameter(loc
, ident
)
5096 this->ident
= ident
;
5097 this->specType
= specType
;
5098 this->specAlias
= specAlias
;
5099 this->defaultAlias
= defaultAlias
;
5102 TemplateAliasParameter
*TemplateAliasParameter::isTemplateAliasParameter()
5107 TemplateParameter
*TemplateAliasParameter::syntaxCopy()
5109 return new TemplateAliasParameter(loc
, ident
,
5110 specType
? specType
->syntaxCopy() : NULL
,
5111 objectSyntaxCopy(specAlias
),
5112 objectSyntaxCopy(defaultAlias
));
5115 bool TemplateAliasParameter::declareParameter(Scope
*sc
)
5117 TypeIdentifier
*ti
= new TypeIdentifier(loc
, ident
);
5118 Declaration
*ad
= new AliasDeclaration(loc
, ident
, ti
);
5119 return sc
->insert(ad
) != NULL
;
5122 MATCH
TemplateAliasParameter::matchArg(Scope
*sc
, RootObject
*oarg
,
5123 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
5124 Declaration
**psparam
)
5126 //printf("TemplateAliasParameter::matchArg('%s')\n", ident->toChars());
5127 MATCH m
= MATCHexact
;
5128 Type
*ta
= isType(oarg
);
5129 RootObject
*sa
= ta
&& !ta
->deco
? NULL
: getDsymbol(oarg
);
5130 Expression
*ea
= isExpression(oarg
);
5131 if (ea
&& (ea
->op
== TOKthis
|| ea
->op
== TOKsuper
))
5132 sa
= ((ThisExp
*)ea
)->var
;
5133 else if (ea
&& ea
->op
== TOKscope
)
5134 sa
= ((ScopeExp
*)ea
)->sds
;
5137 if (((Dsymbol
*)sa
)->isAggregateDeclaration())
5140 /* specType means the alias must be a declaration with a type
5141 * that matches specType.
5145 Declaration
*d
= ((Dsymbol
*)sa
)->isDeclaration();
5148 if (!d
->type
->equals(specType
))
5159 if (!ea
->type
->equals(specType
))
5163 else if (ta
&& ta
->ty
== Tinstance
&& !specAlias
)
5165 /* Bugzilla xxxxx: Specialized parameter should be prefeerd
5166 * match to the template type parameter.
5167 * template X(alias a) {} // a == this
5168 * template X(alias a : B!A, alias B, A...) {} // B!A => ta
5171 else if (sa
&& sa
== TemplateTypeParameter::tdummy
)
5173 /* Bugzilla 2025: Aggregate Types should preferentially
5174 * match to the template type parameter.
5175 * template X(alias a) {} // a == this
5176 * template X(T) {} // T => sa
5179 else if (ta
&& ta
->ty
!= Tident
)
5181 /* Match any type that's not a TypeIdentifier to alias parameters,
5182 * but prefer type parameter.
5183 * template X(alias a) { } // a == ta
5185 * TypeIdentifiers are excluded because they might be not yet resolved aliases.
5197 Dsymbol
*sx
= isDsymbol(sa
);
5198 if (sa
!= specAlias
&& sx
)
5200 Type
*talias
= isType(specAlias
);
5204 TemplateInstance
*ti
= sx
->isTemplateInstance();
5205 if (!ti
&& sx
->parent
)
5207 ti
= sx
->parent
->isTemplateInstance();
5208 if (ti
&& ti
->name
!= sx
->ident
)
5214 Type
*t
= new TypeInstance(Loc(), ti
);
5215 MATCH m2
= deduceType(t
, sc
, talias
, parameters
, dedtypes
);
5216 if (m2
<= MATCHnomatch
)
5220 else if ((*dedtypes
)[i
])
5222 // Must match already deduced symbol
5223 RootObject
*si
= (*dedtypes
)[i
];
5224 if (!sa
|| si
!= sa
)
5227 (*dedtypes
)[i
] = sa
;
5231 if (Dsymbol
*s
= isDsymbol(sa
))
5233 *psparam
= new AliasDeclaration(loc
, ident
, s
);
5235 else if (Type
*t
= isType(sa
))
5237 *psparam
= new AliasDeclaration(loc
, ident
, t
);
5243 // Declare manifest constant
5244 Initializer
*init
= new ExpInitializer(loc
, ea
);
5245 VarDeclaration
*v
= new VarDeclaration(loc
, NULL
, ident
, init
);
5246 v
->storage_class
= STCmanifest
;
5247 dsymbolSemantic(v
, sc
);
5251 return dependent
? MATCHexact
: m
;
5256 //printf("\tm = %d\n", MATCHnomatch);
5257 return MATCHnomatch
;
5261 void TemplateAliasParameter::print(RootObject
*, RootObject
*oded
)
5263 printf(" %s\n", ident
->toChars());
5265 Dsymbol
*sa
= isDsymbol(oded
);
5268 printf("\tParameter alias: %s\n", sa
->toChars());
5271 void *TemplateAliasParameter::dummyArg()
5273 RootObject
*s
= specAlias
;
5277 sdummy
= new Dsymbol();
5284 RootObject
*TemplateAliasParameter::specialization()
5289 RootObject
*TemplateAliasParameter::defaultArg(Loc
, Scope
*sc
)
5291 RootObject
*da
= defaultAlias
;
5292 Type
*ta
= isType(defaultAlias
);
5295 if (ta
->ty
== Tinstance
)
5297 // If the default arg is a template, instantiate for each type
5298 da
= ta
->syntaxCopy();
5302 RootObject
*o
= aliasParameterSemantic(loc
, sc
, da
, NULL
); // use the parameter loc
5306 bool TemplateAliasParameter::hasDefaultArg()
5308 return defaultAlias
!= NULL
;
5311 /* ======================== TemplateValueParameter ========================== */
5315 AA
*TemplateValueParameter::edummies
= NULL
;
5317 TemplateValueParameter::TemplateValueParameter(Loc loc
, Identifier
*ident
, Type
*valType
,
5318 Expression
*specValue
, Expression
*defaultValue
)
5319 : TemplateParameter(loc
, ident
)
5321 this->ident
= ident
;
5322 this->valType
= valType
;
5323 this->specValue
= specValue
;
5324 this->defaultValue
= defaultValue
;
5327 TemplateValueParameter
*TemplateValueParameter::isTemplateValueParameter()
5332 TemplateParameter
*TemplateValueParameter::syntaxCopy()
5334 return new TemplateValueParameter(loc
, ident
,
5335 valType
->syntaxCopy(),
5336 specValue
? specValue
->syntaxCopy() : NULL
,
5337 defaultValue
? defaultValue
->syntaxCopy() : NULL
);
5340 bool TemplateValueParameter::declareParameter(Scope
*sc
)
5342 VarDeclaration
*v
= new VarDeclaration(loc
, valType
, ident
, NULL
);
5343 v
->storage_class
= STCtemplateparameter
;
5344 return sc
->insert(v
) != NULL
;
5347 MATCH
TemplateValueParameter::matchArg(Scope
*sc
, RootObject
*oarg
,
5348 size_t i
, TemplateParameters
*, Objects
*dedtypes
, Declaration
**psparam
)
5350 //printf("TemplateValueParameter::matchArg('%s')\n", ident->toChars());
5352 MATCH m
= MATCHexact
;
5354 Expression
*ei
= isExpression(oarg
);
5359 Dsymbol
*si
= isDsymbol(oarg
);
5360 FuncDeclaration
*f
= si
? si
->isFuncDeclaration() : NULL
;
5361 if (!f
|| !f
->fbody
|| f
->needThis())
5364 ei
= new VarExp(loc
, f
);
5365 ei
= expressionSemantic(ei
, sc
);
5367 /* If a function is really property-like, and then
5368 * it's CTFEable, ei will be a literal expression.
5370 unsigned int olderrors
= global
.startGagging();
5371 ei
= resolveProperties(sc
, ei
);
5372 ei
= ei
->ctfeInterpret();
5373 if (global
.endGagging(olderrors
) || ei
->op
== TOKerror
)
5376 /* Bugzilla 14520: A property-like function can match to both
5377 * TemplateAlias and ValueParameter. But for template overloads,
5378 * it should always prefer alias parameter to be consistent
5379 * template match result.
5381 * template X(alias f) { enum X = 1; }
5382 * template X(int val) { enum X = 2; }
5383 * int f1() { return 0; } // CTFEable
5384 * int f2(); // body-less function is not CTFEable
5385 * enum x1 = X!f1; // should be 1
5386 * enum x2 = X!f2; // should be 1
5388 * e.g. The x1 value must be same even if the f1 definition will be moved
5389 * into di while stripping body code.
5394 if (ei
&& ei
->op
== TOKvar
)
5396 // Resolve const variables that we had skipped earlier
5397 ei
= ei
->ctfeInterpret();
5400 //printf("\tvalType: %s, ty = %d\n", valType->toChars(), valType->ty);
5401 vt
= typeSemantic(valType
, loc
, sc
);
5402 //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars());
5403 //printf("vt = %s\n", vt->toChars());
5407 MATCH m2
= ei
->implicitConvTo(vt
);
5408 //printf("m: %d\n", m);
5411 if (m
<= MATCHnomatch
)
5413 ei
= ei
->implicitCastTo(sc
, vt
);
5414 ei
= ei
->ctfeInterpret();
5419 if (!ei
|| (Expression
*)dmd_aaGetRvalue(edummies
, (void *)ei
->type
) == ei
)
5422 Expression
*e
= specValue
;
5424 sc
= sc
->startCTFE();
5425 e
= expressionSemantic(e
, sc
);
5426 e
= resolveProperties(sc
, e
);
5428 e
= e
->implicitCastTo(sc
, vt
);
5429 e
= e
->ctfeInterpret();
5431 ei
= ei
->syntaxCopy();
5432 sc
= sc
->startCTFE();
5433 ei
= expressionSemantic(ei
, sc
);
5435 ei
= ei
->implicitCastTo(sc
, vt
);
5436 ei
= ei
->ctfeInterpret();
5437 //printf("\tei: %s, %s\n", ei->toChars(), ei->type->toChars());
5438 //printf("\te : %s, %s\n", e->toChars(), e->type->toChars());
5446 // Must match already deduced value
5447 Expression
*e
= (Expression
*)(*dedtypes
)[i
];
5449 if (!ei
|| !ei
->equals(e
))
5453 (*dedtypes
)[i
] = ei
;
5457 Initializer
*init
= new ExpInitializer(loc
, ei
);
5458 Declaration
*sparam
= new VarDeclaration(loc
, vt
, ident
, init
);
5459 sparam
->storage_class
= STCmanifest
;
5462 return dependent
? MATCHexact
: m
;
5465 //printf("\tno match\n");
5468 return MATCHnomatch
;
5472 void TemplateValueParameter::print(RootObject
*, RootObject
*oded
)
5474 printf(" %s\n", ident
->toChars());
5476 Expression
*ea
= isExpression(oded
);
5479 printf("\tSpecialization: %s\n", specValue
->toChars());
5480 printf("\tParameter Value: %s\n", ea
? ea
->toChars() : "NULL");
5483 void *TemplateValueParameter::dummyArg()
5485 Expression
*e
= specValue
;
5488 // Create a dummy value
5489 Expression
**pe
= (Expression
**)dmd_aaGet(&edummies
, (void *)valType
);
5491 *pe
= valType
->defaultInit();
5498 RootObject
*TemplateValueParameter::specialization()
5503 RootObject
*TemplateValueParameter::defaultArg(Loc instLoc
, Scope
*sc
)
5505 Expression
*e
= defaultValue
;
5508 e
= e
->syntaxCopy();
5509 unsigned olderrs
= global
.errors
;
5510 if ((e
= expressionSemantic(e
, sc
)) == NULL
)
5512 if ((e
= resolveProperties(sc
, e
)) == NULL
)
5514 e
= e
->resolveLoc(instLoc
, sc
); // use the instantiated loc
5515 e
= e
->optimize(WANTvalue
);
5516 if (global
.errors
!= olderrs
)
5522 bool TemplateValueParameter::hasDefaultArg()
5524 return defaultValue
!= NULL
;
5527 /* ======================== TemplateTupleParameter ========================== */
5529 // variadic-parameter
5531 TemplateTupleParameter::TemplateTupleParameter(Loc loc
, Identifier
*ident
)
5532 : TemplateParameter(loc
, ident
)
5534 this->ident
= ident
;
5537 TemplateTupleParameter
*TemplateTupleParameter::isTemplateTupleParameter()
5542 TemplateParameter
*TemplateTupleParameter::syntaxCopy()
5544 return new TemplateTupleParameter(loc
, ident
);
5547 bool TemplateTupleParameter::declareParameter(Scope
*sc
)
5549 TypeIdentifier
*ti
= new TypeIdentifier(loc
, ident
);
5550 Declaration
*ad
= new AliasDeclaration(loc
, ident
, ti
);
5551 return sc
->insert(ad
) != NULL
;
5554 MATCH
TemplateTupleParameter::matchArg(Loc
, Scope
*sc
, Objects
*tiargs
,
5555 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
5556 Declaration
**psparam
)
5558 /* The rest of the actual arguments (tiargs[]) form the match
5559 * for the variadic parameter.
5561 assert(i
+ 1 == dedtypes
->length
); // must be the last one
5564 if (Tuple
*u
= isTuple((*dedtypes
)[i
]))
5566 // It has already been deduced
5569 else if (i
+ 1 == tiargs
->length
&& isTuple((*tiargs
)[i
]))
5570 ovar
= isTuple((*tiargs
)[i
]);
5574 //printf("ovar = %p\n", ovar);
5575 if (i
< tiargs
->length
)
5577 //printf("i = %d, tiargs->length = %d\n", i, tiargs->length);
5578 ovar
->objects
.setDim(tiargs
->length
- i
);
5579 for (size_t j
= 0; j
< ovar
->objects
.length
; j
++)
5580 ovar
->objects
[j
] = (*tiargs
)[i
+ j
];
5583 return matchArg(sc
, ovar
, i
, parameters
, dedtypes
, psparam
);
5586 MATCH
TemplateTupleParameter::matchArg(Scope
*, RootObject
*oarg
,
5587 size_t i
, TemplateParameters
*, Objects
*dedtypes
, Declaration
**psparam
)
5589 //printf("TemplateTupleParameter::matchArg('%s')\n", ident->toChars());
5590 Tuple
*ovar
= isTuple(oarg
);
5592 return MATCHnomatch
;
5595 Tuple
*tup
= isTuple((*dedtypes
)[i
]);
5597 return MATCHnomatch
;
5598 if (!match(tup
, ovar
))
5599 return MATCHnomatch
;
5601 (*dedtypes
)[i
] = ovar
;
5604 *psparam
= new TupleDeclaration(loc
, ident
, &ovar
->objects
);
5605 return dependent
? MATCHexact
: MATCHconvert
;
5609 void TemplateTupleParameter::print(RootObject
*, RootObject
*oded
)
5611 printf(" %s... [", ident
->toChars());
5612 Tuple
*v
= isTuple(oded
);
5615 //printf("|%d| ", v->objects.length);
5616 for (size_t i
= 0; i
< v
->objects
.length
; i
++)
5621 RootObject
*o
= v
->objects
[i
];
5623 Dsymbol
*sa
= isDsymbol(o
);
5625 printf("alias: %s", sa
->toChars());
5627 Type
*ta
= isType(o
);
5629 printf("type: %s", ta
->toChars());
5631 Expression
*ea
= isExpression(o
);
5633 printf("exp: %s", ea
->toChars());
5635 assert(!isTuple(o
)); // no nested Tuple arguments
5641 void *TemplateTupleParameter::dummyArg()
5647 RootObject
*TemplateTupleParameter::specialization()
5652 RootObject
*TemplateTupleParameter::defaultArg(Loc
, Scope
*)
5657 bool TemplateTupleParameter::hasDefaultArg()
5662 /* ======================== TemplateInstance ================================ */
5664 TemplateInstance::TemplateInstance(Loc loc
, Identifier
*ident
)
5665 : ScopeDsymbol(NULL
)
5669 this->tiargs
= NULL
;
5670 this->tempdecl
= NULL
;
5675 this->deferred
= NULL
;
5676 this->memberOf
= NULL
;
5677 this->argsym
= NULL
;
5678 this->aliasdecl
= NULL
;
5679 this->semantictiargsdone
= false;
5682 this->havetempdecl
= false;
5683 this->enclosing
= NULL
;
5684 this->gagged
= false;
5690 * This constructor is only called when we figured out which function
5691 * template to instantiate.
5694 TemplateInstance::TemplateInstance(Loc loc
, TemplateDeclaration
*td
, Objects
*tiargs
)
5695 : ScopeDsymbol(NULL
)
5698 this->name
= td
->ident
;
5699 this->tiargs
= tiargs
;
5700 this->tempdecl
= td
;
5705 this->deferred
= NULL
;
5706 this->memberOf
= NULL
;
5707 this->argsym
= NULL
;
5708 this->aliasdecl
= NULL
;
5709 this->semantictiargsdone
= true;
5712 this->havetempdecl
= true;
5713 this->enclosing
= NULL
;
5714 this->gagged
= false;
5718 assert(tempdecl
->_scope
);
5722 Objects
*TemplateInstance::arraySyntaxCopy(Objects
*objs
)
5728 a
->setDim(objs
->length
);
5729 for (size_t i
= 0; i
< objs
->length
; i
++)
5730 (*a
)[i
] = objectSyntaxCopy((*objs
)[i
]);
5735 Dsymbol
*TemplateInstance::syntaxCopy(Dsymbol
*s
)
5737 TemplateInstance
*ti
=
5738 s
? (TemplateInstance
*)s
5739 : new TemplateInstance(loc
, name
);
5740 ti
->tiargs
= arraySyntaxCopy(tiargs
);
5741 TemplateDeclaration
*td
;
5742 if (inst
&& tempdecl
&& (td
= tempdecl
->isTemplateDeclaration()) != NULL
)
5743 td
->ScopeDsymbol::syntaxCopy(ti
);
5745 ScopeDsymbol::syntaxCopy(ti
);
5749 void TemplateInstance::expandMembers(Scope
*sc2
)
5751 for (size_t i
= 0; i
< members
->length
; i
++)
5753 Dsymbol
*s
= (*members
)[i
];
5757 for (size_t i
= 0; i
< members
->length
; i
++)
5759 Dsymbol
*s
= (*members
)[i
];
5763 for (size_t i
= 0; i
< members
->length
; i
++)
5765 Dsymbol
*s
= (*members
)[i
];
5766 //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars());
5767 //printf("test: enclosing = %d, sc2->parent = %s\n", enclosing, sc2->parent->toChars());
5769 // s->parent = sc->parent;
5770 //printf("test3: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars());
5771 dsymbolSemantic(s
, sc2
);
5772 //printf("test4: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars());
5773 Module::runDeferredSemantic();
5777 void TemplateInstance::tryExpandMembers(Scope
*sc2
)
5780 // extracted to a function to allow windows SEH to work without destructors in the same function
5781 //printf("%d\n", nest);
5782 if (++nest
> global
.recursionLimit
)
5784 global
.gag
= 0; // ensure error message gets printed
5785 error("recursive expansion exceeded allowed nesting limit");
5794 void TemplateInstance::trySemantic3(Scope
*sc2
)
5796 // extracted to a function to allow windows SEH to work without destructors in the same function
5798 //printf("%d\n", nest);
5799 if (++nest
> global
.recursionLimit
)
5801 global
.gag
= 0; // ensure error message gets printed
5802 error("recursive expansion exceeded allowed nesting limit");
5805 semantic3(this, sc2
);
5810 /**********************************************
5811 * Find template declaration corresponding to template instance.
5814 * false if finding fails.
5816 * This function is reentrant against error occurrence. If returns false,
5817 * any members of this object won't be modified, and repetition call will
5818 * reproduce same error.
5821 bool TemplateInstance::findTempDecl(Scope
*sc
, WithScopeSymbol
**pwithsym
)
5829 //printf("TemplateInstance::findTempDecl() %s\n", toChars());
5834 * figure out which TemplateDeclaration foo refers to.
5836 Identifier
*id
= name
;
5838 Dsymbol
*s
= sc
->search(loc
, id
, &scopesym
);
5841 s
= sc
->search_correct(id
);
5843 error("template `%s` is not defined, did you mean %s?", id
->toChars(), s
->toChars());
5845 error("template `%s` is not defined", id
->toChars());
5850 *pwithsym
= scopesym
->isWithScopeSymbol();
5852 /* We might have found an alias within a template when
5853 * we really want the template.
5855 TemplateInstance
*ti
;
5857 (ti
= s
->parent
->isTemplateInstance()) != NULL
)
5859 if (ti
->tempdecl
&& ti
->tempdecl
->ident
== id
)
5861 /* This is so that one can refer to the enclosing
5862 * template, even if it has the same name as a member
5863 * of the template, if it has a !(arguments)
5865 TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration();
5867 if (td
->overroot
) // if not start of overloaded list of TemplateDeclaration's
5868 td
= td
->overroot
; // then get the start
5873 if (!updateTempDecl(sc
, s
))
5882 static int fp(void *param
, Dsymbol
*s
)
5884 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
5888 TemplateInstance
*ti
= (TemplateInstance
*)param
;
5889 if (td
->semanticRun
== PASSinit
)
5893 // Try to fix forward reference. Ungag errors while doing so.
5894 Ungag ungag
= td
->ungagSpeculative();
5895 dsymbolSemantic(td
, td
->_scope
);
5897 if (td
->semanticRun
== PASSinit
)
5899 ti
->error("%s forward references template declaration %s", ti
->toChars(), td
->toChars());
5906 // Look for forward references
5907 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
5908 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
5909 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
5911 if (overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, (void *)this, &ParamFwdTi::fp
))
5917 /**********************************************
5918 * Confirm s is a valid template, then store it.
5921 * s candidate symbol of template. It may be:
5922 * TemplateDeclaration
5923 * FuncDeclaration with findTemplateDeclRoot() != NULL
5924 * OverloadSet which contains candidates
5926 * true if updating succeeds.
5929 bool TemplateInstance::updateTempDecl(Scope
*sc
, Dsymbol
*s
)
5933 Identifier
*id
= name
;
5936 /* If an OverloadSet, look for a unique member that is a template declaration
5938 OverloadSet
*os
= s
->isOverloadSet();
5942 for (size_t i
= 0; i
< os
->a
.length
; i
++)
5944 Dsymbol
*s2
= os
->a
[i
];
5945 if (FuncDeclaration
*f
= s2
->isFuncDeclaration())
5946 s2
= f
->findTemplateDeclRoot();
5948 s2
= s2
->isTemplateDeclaration();
5961 error("template `%s` is not defined", id
->toChars());
5966 OverDeclaration
*od
= s
->isOverDeclaration();
5969 tempdecl
= od
; // TODO: more strict check
5973 /* It should be a TemplateDeclaration, not some other symbol
5975 if (FuncDeclaration
*f
= s
->isFuncDeclaration())
5976 tempdecl
= f
->findTemplateDeclRoot();
5978 tempdecl
= s
->isTemplateDeclaration();
5981 if (!s
->parent
&& global
.errors
)
5983 if (!s
->parent
&& s
->getType())
5985 Dsymbol
*s2
= s
->getType()->toDsymbol(sc
);
5988 error("%s is not a template declaration, it is a %s", id
->toChars(), s
->kind());
5993 //assert(s->parent);
5994 TemplateInstance
*ti
= s
->parent
? s
->parent
->isTemplateInstance() : NULL
;
5996 (ti
->name
== s
->ident
||
5997 ti
->toAlias()->ident
== s
->ident
)
6001 /* This is so that one can refer to the enclosing
6002 * template, even if it has the same name as a member
6003 * of the template, if it has a !(arguments)
6005 TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration();
6007 if (td
->overroot
) // if not start of overloaded list of TemplateDeclaration's
6008 td
= td
->overroot
; // then get the start
6013 error("%s is not a template declaration, it is a %s", id
->toChars(), s
->kind());
6018 return (tempdecl
!= NULL
);
6021 /**********************************
6022 * Run semantic on the elements of tiargs.
6026 * false if one or more arguments have errors.
6028 * This function is reentrant against error occurrence. If returns false,
6029 * all elements of tiargs won't be modified.
6032 bool TemplateInstance::semanticTiargs(Scope
*sc
)
6034 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars());
6035 if (semantictiargsdone
)
6037 if (semanticTiargs(loc
, sc
, tiargs
, 0))
6039 // cache the result iff semantic analysis succeeded entirely
6040 semantictiargsdone
= 1;
6046 /**********************************
6047 * Run semantic of tiargs as arguments of template.
6051 * tiargs array of template arguments
6052 * flags 1: replace const variables with their initializers
6053 * 2: don't devolve Parameter to Type
6055 * false if one or more arguments have errors.
6058 bool TemplateInstance::semanticTiargs(Loc loc
, Scope
*sc
, Objects
*tiargs
, int flags
)
6060 // Run semantic on each argument, place results in tiargs[]
6061 //printf("+TemplateInstance::semanticTiargs()\n");
6065 for (size_t j
= 0; j
< tiargs
->length
; j
++)
6067 RootObject
*o
= (*tiargs
)[j
];
6068 Type
*ta
= isType(o
);
6069 Expression
*ea
= isExpression(o
);
6070 Dsymbol
*sa
= isDsymbol(o
);
6072 //printf("1: (*tiargs)[%d] = %p, s=%p, v=%p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
6075 //printf("type %s\n", ta->toChars());
6077 // It might really be an Expression or an Alias
6078 ta
->resolve(loc
, sc
, &ea
, &ta
, &sa
, (flags
& 1) != 0);
6083 assert(global
.errors
);
6088 if (ta
->ty
== Ttuple
)
6091 TypeTuple
*tt
= (TypeTuple
*)ta
;
6092 size_t dim
= tt
->arguments
->length
;
6096 tiargs
->reserve(dim
);
6097 for (size_t i
= 0; i
< dim
; i
++)
6099 Parameter
*arg
= (*tt
->arguments
)[i
];
6100 if (flags
& 2 && (arg
->ident
|| arg
->userAttribDecl
))
6101 tiargs
->insert(j
+ i
, arg
);
6103 tiargs
->insert(j
+ i
, arg
->type
);
6109 if (ta
->ty
== Terror
)
6114 (*tiargs
)[j
] = ta
->merge2();
6119 //printf("+[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
6120 if (flags
& 1) // only used by __traits
6122 ea
= expressionSemantic(ea
, sc
);
6124 // must not interpret the args, excepting template parameters
6125 if (ea
->op
!= TOKvar
||
6126 (((VarExp
*)ea
)->var
->storage_class
& STCtemplateparameter
))
6128 ea
= ea
->optimize(WANTvalue
);
6133 sc
= sc
->startCTFE();
6134 ea
= expressionSemantic(ea
, sc
);
6137 if (ea
->op
== TOKvar
)
6139 /* This test is to skip substituting a const var with
6140 * its initializer. The problem is the initializer won't
6141 * match with an 'alias' parameter. Instead, do the
6142 * const substitution in TemplateValueParameter::matchArg().
6145 else if (definitelyValueParameter(ea
))
6147 if (ea
->checkValue()) // check void expression
6148 ea
= new ErrorExp();
6149 unsigned int olderrs
= global
.errors
;
6150 ea
= ea
->ctfeInterpret();
6151 if (global
.errors
!= olderrs
)
6152 ea
= new ErrorExp();
6155 //printf("-[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
6156 if (ea
->op
== TOKtuple
)
6159 TupleExp
*te
= (TupleExp
*)ea
;
6160 size_t dim
= te
->exps
->length
;
6164 tiargs
->reserve(dim
);
6165 for (size_t i
= 0; i
< dim
; i
++)
6166 tiargs
->insert(j
+ i
, (*te
->exps
)[i
]);
6171 if (ea
->op
== TOKerror
)
6178 if (ea
->op
== TOKtype
)
6183 if (ea
->op
== TOKscope
)
6185 sa
= ((ScopeExp
*)ea
)->sds
;
6188 if (ea
->op
== TOKfunction
)
6190 FuncExp
*fe
= (FuncExp
*)ea
;
6191 /* A function literal, that is passed to template and
6192 * already semanticed as function pointer, never requires
6193 * outer frame. So convert it to global function is valid.
6195 if (fe
->fd
->tok
== TOKreserved
&& fe
->type
->ty
== Tpointer
)
6197 // change to non-nested
6198 fe
->fd
->tok
= TOKfunction
;
6199 fe
->fd
->vthis
= NULL
;
6203 /* If template argument is a template lambda,
6204 * get template declaration itself. */
6209 if (ea
->op
== TOKdotvar
&& !(flags
& 1))
6211 // translate expression to dsymbol.
6212 sa
= ((DotVarExp
*)ea
)->var
;
6215 if (ea
->op
== TOKtemplate
)
6217 sa
= ((TemplateExp
*)ea
)->td
;
6220 if (ea
->op
== TOKdottd
&& !(flags
& 1))
6222 // translate expression to dsymbol.
6223 sa
= ((DotTemplateExp
*)ea
)->td
;
6230 //printf("dsym %s %s\n", sa->kind(), sa->toChars());
6237 TupleDeclaration
*d
= sa
->toAlias()->isTupleDeclaration();
6242 tiargs
->insert(j
, d
->objects
);
6246 if (FuncAliasDeclaration
*fa
= sa
->isFuncAliasDeclaration())
6248 FuncDeclaration
*f
= fa
->toAliasFunc();
6249 if (!fa
->hasOverloads
&& f
->isUnique())
6251 // Strip FuncAlias only when the aliased function
6252 // does not have any overloads.
6258 TemplateDeclaration
*td
= sa
->isTemplateDeclaration();
6259 if (td
&& td
->semanticRun
== PASSinit
&& td
->literal
)
6261 dsymbolSemantic(td
, sc
);
6263 FuncDeclaration
*fd
= sa
->isFuncDeclaration();
6265 fd
->functionSemantic();
6267 else if (isParameter(o
))
6274 //printf("1: (*tiargs)[%d] = %p\n", j, (*tiargs)[j]);
6279 bool TemplateInstance::findBestMatch(Scope
*sc
, Expressions
*fargs
)
6283 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
6285 assert(tempdecl
->_scope
);
6287 tdtypes
.setDim(tempdecl
->parameters
->length
);
6288 if (!tempdecl
->matchWithInstance(sc
, this, &tdtypes
, fargs
, 2))
6290 error("incompatible arguments for template instantiation");
6293 // TODO: Normalizing tiargs for bugzilla 7469 is necessary?
6297 unsigned errs
= global
.errors
;
6298 TemplateDeclaration
*td_last
= NULL
;
6304 TemplateInstance
*ti
;
6307 TemplateDeclaration
*td_best
;
6308 TemplateDeclaration
*td_ambig
;
6311 static int fp(void *param
, Dsymbol
*s
)
6313 return ((ParamBest
*)param
)->fp(s
);
6317 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
6322 td
->error(ti
->loc
, "recursive template expansion");
6325 if (td
== td_best
) // skip duplicates
6328 //printf("td = %s\n", td->toPrettyChars());
6330 // If more arguments than parameters,
6331 // then this is no match.
6332 if (td
->parameters
->length
< ti
->tiargs
->length
)
6334 if (!td
->isVariadic())
6338 dedtypes
.setDim(td
->parameters
->length
);
6340 assert(td
->semanticRun
!= PASSinit
);
6341 MATCH m
= td
->matchWithInstance(sc
, ti
, &dedtypes
, ti
->fargs
, 0);
6342 //printf("matchWithInstance = %d\n", m);
6343 if (m
<= MATCHnomatch
) // no match at all
6346 if (m
< m_best
) goto Ltd_best
;
6347 if (m
> m_best
) goto Ltd
;
6350 // Disambiguate by picking the most specialized TemplateDeclaration
6351 MATCH c1
= td
->leastAsSpecialized(sc
, td_best
, ti
->fargs
);
6352 MATCH c2
= td_best
->leastAsSpecialized(sc
, td
, ti
->fargs
);
6353 //printf("c1 = %d, c2 = %d\n", c1, c2);
6354 if (c1
> c2
) goto Ltd
;
6355 if (c1
< c2
) goto Ltd_best
;
6361 Ltd_best
: // td_best is the best match so far
6365 Ltd
: // td is the new best match
6369 ti
->tdtypes
.setDim(dedtypes
.length
);
6370 memcpy(ti
->tdtypes
.tdata(), dedtypes
.tdata(), ti
->tdtypes
.length
* sizeof(void *));
6379 /* Since there can be multiple TemplateDeclaration's with the same
6380 * name, look for the best match.
6382 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
6383 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
6384 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
6389 p
.m_best
= MATCHnomatch
;
6391 Dsymbol
*dstart
= tovers
? tovers
->a
[oi
] : tempdecl
;
6392 overloadApply(dstart
, &p
, &ParamBest::fp
);
6396 ::error(loc
, "%s %s.%s matches more than one template declaration:\n%s: %s\nand\n%s: %s",
6397 p
.td_best
->kind(), p
.td_best
->parent
->toPrettyChars(), p
.td_best
->ident
->toChars(),
6398 p
.td_best
->loc
.toChars() , p
.td_best
->toChars(),
6399 p
.td_ambig
->loc
.toChars(), p
.td_ambig
->toChars());
6405 td_last
= p
.td_best
;
6406 else if (td_last
!= p
.td_best
)
6408 ScopeDsymbol::multiplyDefined(loc
, td_last
, p
.td_best
);
6416 /* Bugzilla 7469: Normalize tiargs by using corresponding deduced
6417 * template value parameters and tuples for the correct mangling.
6419 * By doing this before hasNestedArgs, CTFEable local variable will be
6420 * accepted as a value parameter. For example:
6423 * struct S(int n) {} // non-global template
6424 * const int num = 1; // CTFEable local variable
6425 * S!num s; // S!1 is instantiated, not S!num
6428 size_t dim
= td_last
->parameters
->length
- (td_last
->isVariadic() ? 1 : 0);
6429 for (size_t i
= 0; i
< dim
; i
++)
6431 if (tiargs
->length
<= i
)
6432 tiargs
->push(tdtypes
[i
]);
6433 assert(i
< tiargs
->length
);
6435 TemplateValueParameter
*tvp
= (*td_last
->parameters
)[i
]->isTemplateValueParameter();
6439 // tdtypes[i] is already normalized to the required type in matchArg
6441 (*tiargs
)[i
] = tdtypes
[i
];
6443 if (td_last
->isVariadic() && tiargs
->length
== dim
&& tdtypes
[dim
])
6445 Tuple
*va
= isTuple(tdtypes
[dim
]);
6447 for (size_t i
= 0; i
< va
->objects
.length
; i
++)
6448 tiargs
->push(va
->objects
[i
]);
6451 else if (errors
&& inst
)
6453 // instantiation was failed with error reporting
6454 assert(global
.errors
);
6459 TemplateDeclaration
*tdecl
= tempdecl
->isTemplateDeclaration();
6461 if (errs
!= global
.errors
)
6462 errorSupplemental(loc
, "while looking for match for %s", toChars());
6463 else if (tdecl
&& !tdecl
->overnext
)
6465 // Only one template, so we can give better error message
6466 error("does not match template declaration %s", tdecl
->toChars());
6469 ::error(loc
, "%s %s.%s does not match any template declaration",
6470 tempdecl
->kind(), tempdecl
->parent
->toPrettyChars(), tempdecl
->ident
->toChars());
6474 /* The best match is td_last
6478 return (errs
== global
.errors
);
6481 /*****************************************************
6482 * Determine if template instance is really a template function,
6483 * and that template function needs to infer types from the function
6486 * Like findBestMatch, iterate possible template candidates,
6487 * but just looks only the necessity of type inference.
6490 bool TemplateInstance::needsTypeInference(Scope
*sc
, int flag
)
6492 //printf("TemplateInstance::needsTypeInference() %s\n", toChars());
6493 if (semanticRun
!= PASSinit
)
6496 struct ParamNeedsInf
6500 TemplateInstance
*ti
;
6506 static int fp(void *param
, Dsymbol
*s
)
6508 return ((ParamNeedsInf
*)param
)->fp(s
);
6512 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
6517 td
->error(ti
->loc
, "recursive template expansion");
6521 /* If any of the overloaded template declarations need inference,
6524 FuncDeclaration
*fd
;
6527 if (TemplateDeclaration
*td2
= td
->onemember
->isTemplateDeclaration())
6529 if (!td2
->onemember
|| !td2
->onemember
->isFuncDeclaration())
6531 if (ti
->tiargs
->length
>= td
->parameters
->length
- (td
->isVariadic() ? 1 : 0))
6535 if ((fd
= td
->onemember
->isFuncDeclaration()) == NULL
||
6536 fd
->type
->ty
!= Tfunction
)
6541 for (size_t i
= 0; i
< td
->parameters
->length
; i
++)
6543 if ((*td
->parameters
)[i
]->isTemplateThisParameter())
6547 /* Determine if the instance arguments, tiargs, are all that is necessary
6548 * to instantiate the template.
6550 //printf("tp = %p, td->parameters->length = %d, tiargs->length = %d\n", tp, td->parameters->length, ti->tiargs->length);
6551 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
6552 if (size_t dim
= tf
->parameterList
.length())
6554 TemplateParameter
*tp
= td
->isVariadic();
6555 if (tp
&& td
->parameters
->length
> 1)
6558 if (!tp
&& ti
->tiargs
->length
< td
->parameters
->length
)
6560 // Can remain tiargs be filled by default arguments?
6561 for (size_t i
= ti
->tiargs
->length
; i
< td
->parameters
->length
; i
++)
6563 if (!(*td
->parameters
)[i
]->hasDefaultArg())
6568 for (size_t i
= 0; i
< dim
; i
++)
6570 // 'auto ref' needs inference.
6571 if (tf
->parameterList
[i
]->storageClass
& STCauto
)
6578 /* Calculate the need for overload resolution.
6579 * When only one template can match with tiargs, inference is not necessary.
6581 dedtypes
.setDim(td
->parameters
->length
);
6583 if (td
->semanticRun
== PASSinit
)
6587 // Try to fix forward reference. Ungag errors while doing so.
6588 Ungag ungag
= td
->ungagSpeculative();
6589 dsymbolSemantic(td
, td
->_scope
);
6591 if (td
->semanticRun
== PASSinit
)
6593 ti
->error("%s forward references template declaration %s", ti
->toChars(), td
->toChars());
6597 assert(td
->semanticRun
!= PASSinit
);
6598 MATCH m
= td
->matchWithInstance(sc
, ti
, &dedtypes
, NULL
, 0);
6599 if (m
<= MATCHnomatch
)
6603 /* If there is more than one function template which matches, we may
6604 * need type inference (see Bugzilla 4430)
6620 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
6621 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
6622 unsigned olderrs
= global
.errors
;
6623 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
6625 if (overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, &p
, &ParamNeedsInf::fp
))
6628 if (olderrs
!= global
.errors
)
6632 errorSupplemental(loc
, "while looking for match for %s", toChars());
6633 semanticRun
= PASSsemanticdone
;
6638 //printf("false\n");
6643 /*****************************************
6644 * Determines if a TemplateInstance will need a nested
6645 * generation of the TemplateDeclaration.
6646 * Sets enclosing property if so, and returns != 0;
6649 bool TemplateInstance::hasNestedArgs(Objects
*args
, bool isstatic
)
6652 //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());
6654 /* A nested instance happens when an argument references a local
6655 * symbol that is on the stack.
6657 for (size_t i
= 0; i
< args
->length
; i
++)
6659 RootObject
*o
= (*args
)[i
];
6660 Expression
*ea
= isExpression(o
);
6661 Dsymbol
*sa
= isDsymbol(o
);
6662 Tuple
*va
= isTuple(o
);
6665 if (ea
->op
== TOKvar
)
6667 sa
= ((VarExp
*)ea
)->var
;
6670 if (ea
->op
== TOKthis
)
6672 sa
= ((ThisExp
*)ea
)->var
;
6675 if (ea
->op
== TOKfunction
)
6677 if (((FuncExp
*)ea
)->td
)
6678 sa
= ((FuncExp
*)ea
)->td
;
6680 sa
= ((FuncExp
*)ea
)->fd
;
6683 // Emulate Expression::toMangleBuffer call that had exist in TemplateInstance::genIdent.
6684 if (ea
->op
!= TOKint64
&&
6685 ea
->op
!= TOKfloat64
&&
6686 ea
->op
!= TOKcomplex80
&&
6687 ea
->op
!= TOKnull
&&
6688 ea
->op
!= TOKstring
&&
6689 ea
->op
!= TOKarrayliteral
&&
6690 ea
->op
!= TOKassocarrayliteral
&&
6691 ea
->op
!= TOKstructliteral
)
6693 ea
->error("expression %s is not a valid template value argument", ea
->toChars());
6701 TemplateDeclaration
*td
= sa
->isTemplateDeclaration();
6704 TemplateInstance
*ti
= sa
->toParent()->isTemplateInstance();
6705 if (ti
&& ti
->enclosing
)
6708 TemplateInstance
*ti
= sa
->isTemplateInstance();
6709 Declaration
*d
= sa
->isDeclaration();
6710 if ((td
&& td
->literal
) ||
6711 (ti
&& ti
->enclosing
) ||
6712 (d
&& !d
->isDataseg() &&
6713 !(d
->storage_class
& STCmanifest
) &&
6714 (!d
->isFuncDeclaration() || d
->isFuncDeclaration()->isNested()) &&
6718 // if module level template
6721 Dsymbol
*dparent
= sa
->toParent2();
6723 enclosing
= dparent
;
6724 else if (enclosing
!= dparent
)
6726 /* Select the more deeply nested of the two.
6727 * Error if one is not nested inside the other.
6729 for (Dsymbol
*p
= enclosing
; p
; p
= p
->parent
)
6732 goto L1
; // enclosing is most nested
6734 for (Dsymbol
*p
= dparent
; p
; p
= p
->parent
)
6738 enclosing
= dparent
;
6739 goto L1
; // dparent is most nested
6742 error("%s is nested in both %s and %s",
6743 toChars(), enclosing
->toChars(), dparent
->toChars());
6747 //printf("\tnested inside %s\n", enclosing->toChars());
6752 error("cannot use local `%s` as parameter to non-global template %s", sa
->toChars(), tempdecl
->toChars());
6759 nested
|= (int)hasNestedArgs(&va
->objects
, isstatic
);
6762 //printf("-TemplateInstance::hasNestedArgs('%s') = %d\n", tempdecl->ident->toChars(), nested);
6766 /*****************************************
6767 * Append 'this' to the specific module members[]
6769 Dsymbols
*TemplateInstance::appendToModuleMember()
6771 Module
*mi
= minst
; // instantiated -> inserted module
6773 if (global
.params
.useUnitTests
||
6774 global
.params
.debuglevel
)
6776 // Turn all non-root instances to speculative
6777 if (mi
&& !mi
->isRoot())
6781 //printf("%s->appendToModuleMember() enclosing = %s mi = %s\n",
6783 // enclosing ? enclosing->toPrettyChars() : NULL,
6784 // mi ? mi->toPrettyChars() : NULL);
6785 if (!mi
|| mi
->isRoot())
6787 /* If the instantiated module is speculative or root, insert to the
6788 * member of a root module. Then:
6789 * - semantic3 pass will get called on the instance members.
6790 * - codegen pass will get a selection chance to do/skip it.
6795 static Dsymbol
*getStrictEnclosing(TemplateInstance
*ti
)
6800 return ti
->enclosing
;
6801 ti
= ti
->tempdecl
->isInstantiated();
6807 Dsymbol
*enc
= N::getStrictEnclosing(this);
6809 // insert target is made stable by using the module
6810 // where tempdecl is declared.
6811 mi
= (enc
? enc
: tempdecl
)->getModule();
6813 mi
= mi
->importedFrom
;
6814 assert(mi
->isRoot());
6818 /* If the instantiated module is non-root, insert to the member of the
6819 * non-root module. Then:
6820 * - semantic3 pass won't be called on the instance.
6821 * - codegen pass won't reach to the instance.
6824 //printf("\t--> mi = %s\n", mi->toPrettyChars());
6826 if (memberOf
== mi
) // already a member
6831 Dsymbols
*a
= mi
->members
;
6834 if (mi
->semanticRun
>= PASSsemantic2done
&& mi
->isRoot())
6835 Module::addDeferredSemantic2(this);
6836 if (mi
->semanticRun
>= PASSsemantic3done
&& mi
->isRoot())
6837 Module::addDeferredSemantic3(this);
6841 /****************************************
6842 * This instance needs an identifier for name mangling purposes.
6843 * Create one by taking the template declaration name and adding
6844 * the type signature for it.
6847 Identifier
*TemplateInstance::genIdent(Objects
*args
)
6849 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
6850 assert(args
== tiargs
);
6852 mangleToBuffer(this, &buf
);
6853 //printf("\tgenIdent = %s\n", id);
6854 return Identifier::idPool(buf
.peekChars());
6857 /*************************************
6858 * Lazily generate identifier for template instance.
6859 * This is because 75% of the ident's are never needed.
6862 Identifier
*TemplateInstance::getIdent()
6864 if (!ident
&& inst
&& !errors
)
6865 ident
= genIdent(tiargs
); // need an identifier for name mangling purposes.
6869 /****************************************************
6870 * Declare parameters of template instance, initialize them with the
6871 * template instance arguments.
6874 void TemplateInstance::declareParameters(Scope
*sc
)
6876 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
6879 //printf("TemplateInstance::declareParameters()\n");
6880 for (size_t i
= 0; i
< tdtypes
.length
; i
++)
6882 TemplateParameter
*tp
= (*tempdecl
->parameters
)[i
];
6883 //RootObject *o = (*tiargs)[i];
6884 RootObject
*o
= tdtypes
[i
]; // initializer for tp
6886 //printf("\ttdtypes[%d] = %p\n", i, o);
6887 tempdecl
->declareParameter(sc
, tp
, o
);
6891 /**************************************
6892 * Given an error instantiating the TemplateInstance,
6893 * give the nested TemplateInstance instantiations that got
6894 * us here. Those are a list threaded into the nested scopes.
6896 void TemplateInstance::printInstantiationTrace()
6901 const unsigned max_shown
= 6;
6902 const char format
[] = "instantiated from here: %s";
6904 // determine instantiation depth and number of recursive instantiations
6905 unsigned n_instantiations
= 1;
6906 unsigned n_totalrecursions
= 0;
6907 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
6910 // If two instantiations use the same declaration, they are recursive.
6911 // (this works even if they are instantiated from different places in the
6913 // In principle, we could also check for multiple-template recursion, but it's
6914 // probably not worthwhile.
6915 if (cur
->tinst
&& cur
->tempdecl
&& cur
->tinst
->tempdecl
6916 && cur
->tempdecl
->loc
.equals(cur
->tinst
->tempdecl
->loc
))
6917 ++n_totalrecursions
;
6920 // show full trace only if it's short or verbose is on
6921 if (n_instantiations
<= max_shown
|| global
.params
.verbose
)
6923 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
6926 errorSupplemental(cur
->loc
, format
, cur
->toChars());
6929 else if (n_instantiations
- n_totalrecursions
<= max_shown
)
6931 // By collapsing recursive instantiations into a single line,
6932 // we can stay under the limit.
6933 int recursionDepth
=0;
6934 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
6937 if (cur
->tinst
&& cur
->tempdecl
&& cur
->tinst
->tempdecl
6938 && cur
->tempdecl
->loc
.equals(cur
->tinst
->tempdecl
->loc
))
6945 errorSupplemental(cur
->loc
, "%d recursive instantiations from here: %s", recursionDepth
+2, cur
->toChars());
6947 errorSupplemental(cur
->loc
, format
, cur
->toChars());
6954 // Even after collapsing the recursions, the depth is too deep.
6955 // Just display the first few and last few instantiations.
6957 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
6961 if (i
== max_shown
/ 2)
6962 errorSupplemental(cur
->loc
, "... (%d instantiations, -v to show) ...", n_instantiations
- max_shown
);
6964 if (i
< max_shown
/ 2 ||
6965 i
>= n_instantiations
- max_shown
+ max_shown
/ 2)
6966 errorSupplemental(cur
->loc
, format
, cur
->toChars());
6972 Dsymbol
*TemplateInstance::toAlias()
6976 // Maybe we can resolve it
6979 dsymbolSemantic(this, _scope
);
6983 error("cannot resolve forward reference");
6990 return inst
->toAlias();
6994 return aliasdecl
->toAlias();
7000 const char *TemplateInstance::kind() const
7002 return "template instance";
7005 bool TemplateInstance::oneMember(Dsymbol
**ps
, Identifier
*)
7011 const char *TemplateInstance::toChars()
7014 toCBufferInstance(this, &buf
);
7015 return buf
.extractChars();
7018 const char *TemplateInstance::toPrettyCharsHelper()
7021 toCBufferInstance(this, &buf
, true);
7022 return buf
.extractChars();
7025 /*************************************
7026 * Compare proposed template instantiation with existing template instantiation.
7027 * Note that this is not commutative because of the auto ref check.
7029 * this = proposed template instantiation
7030 * o = existing template instantiation
7032 * 0 for match, 1 for no match
7034 int TemplateInstance::compare(RootObject
*o
)
7036 TemplateInstance
*ti
= (TemplateInstance
*)o
;
7038 //printf("this = %p, ti = %p\n", this, ti);
7039 assert(tdtypes
.length
== ti
->tdtypes
.length
);
7041 // Nesting must match
7042 if (enclosing
!= ti
->enclosing
)
7044 //printf("test2 enclosing %s ti->enclosing %s\n", enclosing ? enclosing->toChars() : "", ti->enclosing ? ti->enclosing->toChars() : "");
7047 //printf("parent = %s, ti->parent = %s\n", parent->toPrettyChars(), ti->parent->toPrettyChars());
7049 if (!arrayObjectMatch(&tdtypes
, &ti
->tdtypes
))
7052 /* Template functions may have different instantiations based on
7053 * "auto ref" parameters.
7055 if (FuncDeclaration
*fd
= ti
->toAlias()->isFuncDeclaration())
7059 ParameterList fparameters
= fd
->getParameterList();
7060 size_t nfparams
= fparameters
.length(); // Num function parameters
7061 for (size_t j
= 0; j
< nfparams
; j
++)
7063 Parameter
*fparam
= fparameters
[j
];
7064 if (fparam
->storageClass
& STCautoref
) // if "auto ref"
7068 if (fargs
->length
<= j
)
7070 Expression
*farg
= (*fargs
)[j
];
7071 if (farg
->isLvalue())
7073 if (!(fparam
->storageClass
& STCref
))
7074 goto Lnotequals
; // auto ref's don't match
7078 if (fparam
->storageClass
& STCref
)
7079 goto Lnotequals
; // auto ref's don't match
7091 hash_t
TemplateInstance::toHash()
7095 hash
= (size_t)(void *)enclosing
;
7096 hash
+= arrayObjectHash(&tdtypes
);
7102 /**************************************
7103 * IsExpression can evaluate the specified type speculatively, and even if
7104 * it instantiates any symbols, they are normally unnecessary for the
7106 * However, if those symbols leak to the actual code, compiler should remark
7107 * them as non-speculative to generate their code and link to the final executable.
7109 void unSpeculative(Scope
*sc
, RootObject
*o
)
7114 if (Tuple
*tup
= isTuple(o
))
7116 for (size_t i
= 0; i
< tup
->objects
.length
; i
++)
7118 unSpeculative(sc
, tup
->objects
[i
]);
7123 Dsymbol
*s
= getDsymbol(o
);
7127 if (Declaration
*d
= s
->isDeclaration())
7129 if (VarDeclaration
*vd
= d
->isVarDeclaration())
7131 else if (AliasDeclaration
*ad
= d
->isAliasDeclaration())
7145 if (TemplateInstance
*ti
= s
->isTemplateInstance())
7147 // If the instance is already non-speculative,
7148 // or it is leaked to the speculative scope.
7149 if (ti
->minst
!= NULL
|| sc
->minst
== NULL
)
7152 // Remark as non-speculative instance.
7153 ti
->minst
= sc
->minst
;
7155 ti
->tinst
= sc
->tinst
;
7157 unSpeculative(sc
, ti
->tempdecl
);
7160 if (TemplateInstance
*ti
= s
->isInstantiated())
7161 unSpeculative(sc
, ti
);
7165 Returns: true if the instances' innards are discardable.
7167 The idea of this function is to see if the template instantiation
7168 can be 100% replaced with its eponymous member. All other members
7169 can be discarded, even in the compiler to free memory (for example,
7170 the template could be expanded in a region allocator, deemed trivial,
7171 the end result copied back out independently and the entire region freed),
7172 and can be elided entirely from the binary.
7174 The current implementation affects code that generally looks like:
7177 template foo(args...) {
7178 some_basic_type_or_string helper() { .... }
7179 enum foo = helper();
7183 since it was the easiest starting point of implementation but it can and
7184 should be expanded more later.
7186 static bool isDiscardable(TemplateInstance
*ti
)
7188 if (ti
->aliasdecl
== NULL
)
7191 VarDeclaration
*v
= ti
->aliasdecl
->isVarDeclaration();
7195 if (!(v
->storage_class
& STCmanifest
))
7198 // Currently only doing basic types here because it is the easiest proof-of-concept
7199 // implementation with minimal risk of side effects, but it could likely be
7200 // expanded to any type that already exists outside this particular instance.
7201 if (!(v
->type
->equals(Type::tstring
) || (v
->type
->isTypeBasic() != NULL
)))
7204 // Static ctors and dtors, even in an eponymous enum template, are still run,
7205 // so if any of them are in here, we'd better not assume it is trivial lest
7206 // we break useful code
7207 for (size_t i
= 0; i
< ti
->members
->length
; i
++)
7209 Dsymbol
*member
= (*ti
->members
)[i
];
7210 if (member
->hasStaticCtorOrDtor())
7212 if (member
->isStaticDtorDeclaration())
7214 if (member
->isStaticCtorDeclaration())
7218 // but if it passes through this gauntlet... it should be fine. D code will
7219 // see only the eponymous member, outside stuff can never access it, even through
7220 // reflection; the outside world ought to be none the wiser. Even dmd should be
7221 // able to simply free the memory of everything except the final result.
7226 /***********************************************
7227 * Returns true if this is not instantiated in non-root module, and
7228 * is a part of non-speculative instantiatiation.
7230 * Note: minst does not stabilize until semantic analysis is completed,
7231 * so don't call this function during semantic analysis to return precise result.
7233 bool TemplateInstance::needsCodegen()
7237 // If this is a speculative instantiation,
7238 // 1. do codegen if ancestors really needs codegen.
7239 // 2. become non-speculative if siblings are not speculative
7241 TemplateInstance
*tnext
= this->tnext
;
7242 TemplateInstance
*tinst
= this->tinst
;
7243 // At first, disconnect chain first to prevent infinite recursion.
7247 // Determine necessity of tinst before tnext.
7248 if (tinst
&& tinst
->needsCodegen())
7250 minst
= tinst
->minst
; // cache result
7251 if (global
.params
.allInst
&& minst
)
7256 assert(minst
->isRoot() || minst
->rootImports());
7259 if (tnext
&& (tnext
->needsCodegen() || tnext
->minst
))
7261 minst
= tnext
->minst
; // cache result
7262 if (global
.params
.allInst
&& minst
)
7267 return minst
->isRoot() || minst
->rootImports();
7270 // Elide codegen because this is really speculative.
7274 if (global
.params
.allInst
)
7279 if (isDiscardable(this))
7284 /* Even when this is reached to the codegen pass,
7285 * a non-root nested template should not generate code,
7286 * due to avoid ODR violation.
7288 if (enclosing
&& enclosing
->inNonRoot())
7292 bool r
= tinst
->needsCodegen();
7293 minst
= tinst
->minst
; // cache result
7298 bool r
= tnext
->needsCodegen();
7299 minst
= tnext
->minst
; // cache result
7305 if (global
.params
.useUnitTests
)
7307 // Prefer instantiations from root modules, to maximize link-ability.
7308 if (minst
->isRoot())
7311 TemplateInstance
*tnext
= this->tnext
;
7312 TemplateInstance
*tinst
= this->tinst
;
7316 if (tinst
&& tinst
->needsCodegen())
7318 minst
= tinst
->minst
; // cache result
7320 assert(minst
->isRoot() || minst
->rootImports());
7323 if (tnext
&& tnext
->needsCodegen())
7325 minst
= tnext
->minst
; // cache result
7327 assert(minst
->isRoot() || minst
->rootImports());
7331 // Bugzilla 2500 case
7332 if (minst
->rootImports())
7335 // Elide codegen because this is not included in root instances.
7340 // Prefer instantiations from non-root module, to minimize object code size.
7342 /* If a TemplateInstance is ever instantiated by non-root modules,
7343 * we do not have to generate code for it,
7344 * because it will be generated when the non-root module is compiled.
7346 * But, if the non-root 'minst' imports any root modules, it might still need codegen.
7348 * The problem is if A imports B, and B imports A, and both A
7349 * and B instantiate the same template, does the compilation of A
7350 * or the compilation of B do the actual instantiation?
7352 * See Bugzilla 2500.
7354 if (!minst
->isRoot() && !minst
->rootImports())
7357 TemplateInstance
*tnext
= this->tnext
;
7360 if (tnext
&& !tnext
->needsCodegen() && tnext
->minst
)
7362 minst
= tnext
->minst
; // cache result
7363 assert(!minst
->isRoot());
7367 // Do codegen because this is not included in non-root instances.
7372 /* ======================== TemplateMixin ================================ */
7374 TemplateMixin::TemplateMixin(Loc loc
, Identifier
*ident
, TypeQualified
*tqual
, Objects
*tiargs
)
7375 : TemplateInstance(loc
, tqual
->idents
.length
? (Identifier
*)tqual
->idents
[tqual
->idents
.length
- 1]
7376 : ((TypeIdentifier
*)tqual
)->ident
)
7378 //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : "");
7379 this->ident
= ident
;
7380 this->tqual
= tqual
;
7381 this->tiargs
= tiargs
? tiargs
: new Objects();
7384 Dsymbol
*TemplateMixin::syntaxCopy(Dsymbol
*)
7386 TemplateMixin
*tm
= new TemplateMixin(loc
, ident
,
7387 (TypeQualified
*)tqual
->syntaxCopy(), tiargs
);
7388 return TemplateInstance::syntaxCopy(tm
);
7391 bool TemplateMixin::findTempDecl(Scope
*sc
)
7393 // Follow qualifications to find the TemplateDeclaration
7399 tqual
->resolve(loc
, sc
, &e
, &t
, &s
);
7402 error("is not defined");
7406 tempdecl
= s
->isTemplateDeclaration();
7407 OverloadSet
*os
= s
->isOverloadSet();
7409 /* If an OverloadSet, look for a unique member that is a template declaration
7414 for (size_t i
= 0; i
< os
->a
.length
; i
++)
7416 Dsymbol
*s2
= os
->a
[i
]->isTemplateDeclaration();
7430 error("%s isn't a template", s
->toChars());
7436 struct ParamFwdResTm
7438 static int fp(void *param
, Dsymbol
*s
)
7440 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
7444 TemplateMixin
*tm
= (TemplateMixin
*)param
;
7445 if (td
->semanticRun
== PASSinit
)
7448 dsymbolSemantic(td
, td
->_scope
);
7451 tm
->semanticRun
= PASSinit
;
7458 // Look for forward references
7459 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
7460 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
7461 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
7463 if (overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, (void *)this, &ParamFwdResTm::fp
))
7469 const char *TemplateMixin::kind() const
7474 bool TemplateMixin::oneMember(Dsymbol
**ps
, Identifier
*ident
)
7476 return Dsymbol::oneMember(ps
, ident
);
7479 int TemplateMixin::apply(Dsymbol_apply_ft_t fp
, void *param
)
7481 if (_scope
) // if fwd reference
7482 dsymbolSemantic(this, NULL
); // try to resolve it
7485 for (size_t i
= 0; i
< members
->length
; i
++)
7487 Dsymbol
*s
= (*members
)[i
];
7490 if (s
->apply(fp
, param
))
7498 bool TemplateMixin::hasPointers()
7500 //printf("TemplateMixin::hasPointers() %s\n", toChars());
7504 for (size_t i
= 0; i
< members
->length
; i
++)
7506 Dsymbol
*s
= (*members
)[i
];
7507 //printf(" s = %s %s\n", s->kind(), s->toChars());
7508 if (s
->hasPointers())
7517 void TemplateMixin::setFieldOffset(AggregateDeclaration
*ad
, unsigned *poffset
, bool isunion
)
7519 //printf("TemplateMixin::setFieldOffset() %s\n", toChars());
7520 if (_scope
) // if fwd reference
7521 dsymbolSemantic(this, NULL
); // try to resolve it
7524 for (size_t i
= 0; i
< members
->length
; i
++)
7526 Dsymbol
*s
= (*members
)[i
];
7527 //printf("\t%s\n", s->toChars());
7528 s
->setFieldOffset(ad
, poffset
, isunion
);
7533 const char *TemplateMixin::toChars()
7536 toCBufferInstance(this, &buf
);
7537 return buf
.extractChars();