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 (ea
->op
== TOKvar
)
160 sa
= ((VarExp
*)ea
)->var
;
161 else if (ea
->op
== TOKfunction
)
163 if (((FuncExp
*)ea
)->td
)
164 sa
= ((FuncExp
*)ea
)->td
;
166 sa
= ((FuncExp
*)ea
)->fd
;
168 else if (ea
->op
== TOKtemplate
)
169 sa
= ((TemplateExp
*)ea
)->td
;
175 // Try to convert Type to symbol
176 Type
*ta
= isType(oarg
);
178 sa
= ta
->toDsymbol(NULL
);
180 sa
= isDsymbol(oarg
); // if already a symbol
185 /***********************
186 * Try to get value from manifest constant
189 static Expression
*getValue(Expression
*e
)
191 if (e
&& e
->op
== TOKvar
)
193 VarDeclaration
*v
= ((VarExp
*)e
)->var
->isVarDeclaration();
194 if (v
&& v
->storage_class
& STCmanifest
)
196 e
= v
->getConstInitializer();
202 static Expression
*getValue(Dsymbol
*&s
)
204 Expression
*e
= NULL
;
207 VarDeclaration
*v
= s
->isVarDeclaration();
208 if (v
&& v
->storage_class
& STCmanifest
)
210 e
= v
->getConstInitializer();
216 /**********************************
217 * Return true if e could be valid only as a template value parameter.
218 * Return false if it might be an alias or tuple.
219 * (Note that even in this case, it could still turn out to be a value).
221 bool definitelyValueParameter(Expression
*e
)
223 // None of these can be value parameters
224 if (e
->op
== TOKtuple
|| e
->op
== TOKscope
||
225 e
->op
== TOKtype
|| e
->op
== TOKdottype
||
226 e
->op
== TOKtemplate
|| e
->op
== TOKdottd
||
227 e
->op
== TOKfunction
|| e
->op
== TOKerror
||
228 e
->op
== TOKthis
|| e
->op
== TOKsuper
)
231 if (e
->op
!= TOKdotvar
)
234 /* Template instantiations involving a DotVar expression are difficult.
235 * In most cases, they should be treated as a value parameter, and interpreted.
236 * But they might also just be a fully qualified name, which should be treated
240 // x.y.f cannot be a value
241 FuncDeclaration
*f
= ((DotVarExp
*)e
)->var
->isFuncDeclaration();
245 while (e
->op
== TOKdotvar
)
247 e
= ((DotVarExp
*)e
)->e1
;
249 // this.x.y and super.x.y couldn't possibly be valid values.
250 if (e
->op
== TOKthis
|| e
->op
== TOKsuper
)
253 // e.type.x could be an alias
254 if (e
->op
== TOKdottype
)
257 // var.x.y is the only other possible form of alias
261 VarDeclaration
*v
= ((VarExp
*)e
)->var
->isVarDeclaration();
263 // func.x.y is not an alias
267 // TODO: Should we force CTFE if it is a global constant?
272 static Expression
*getExpression(RootObject
*o
)
274 Dsymbol
*s
= isDsymbol(o
);
275 return s
? getValue(s
) : getValue(isExpression(o
));
278 /******************************
279 * If o1 matches o2, return true.
280 * Else, return false.
283 static bool match(RootObject
*o1
, RootObject
*o2
)
285 //printf("match() o1 = %p %s (%d), o2 = %p %s (%d)\n",
286 // o1, o1->toChars(), o1->dyncast(), o2, o2->toChars(), o2->dyncast());
288 /* A proper implementation of the various equals() overrides
289 * should make it possible to just do o1->equals(o2), but
290 * we'll do that another day.
293 /* Manifest constants should be compared by their values,
294 * at least in template arguments.
297 if (Type
*t1
= isType(o1
))
299 Type
*t2
= isType(o2
);
303 //printf("\tt1 = %s\n", t1->toChars());
304 //printf("\tt2 = %s\n", t2->toChars());
310 if (Expression
*e1
= getExpression(o1
))
312 Expression
*e2
= getExpression(o2
);
316 //printf("\te1 = %s %s %s\n", e1->type->toChars(), Token::toChars(e1->op), e1->toChars());
317 //printf("\te2 = %s %s %s\n", e2->type->toChars(), Token::toChars(e2->op), e2->toChars());
319 // two expressions can be equal although they do not have the same
320 // type; that happens when they have the same value. So check type
321 // as well as expression equality to ensure templates are properly
323 if (!e1
->type
->equals(e2
->type
) || !e1
->equals(e2
))
328 if (Dsymbol
*s1
= isDsymbol(o1
))
330 Dsymbol
*s2
= isDsymbol(o2
);
334 //printf("\ts1 = %s\n", s1->toChars());
335 //printf("\ts2 = %s\n", s2->toChars());
338 if (s1
->parent
!= s2
->parent
&& !s1
->isFuncDeclaration() && !s2
->isFuncDeclaration())
343 if (Tuple
*u1
= isTuple(o1
))
345 Tuple
*u2
= isTuple(o2
);
349 //printf("\tu1 = %s\n", u1->toChars());
350 //printf("\tu2 = %s\n", u2->toChars());
351 if (!arrayObjectMatch(&u1
->objects
, &u2
->objects
))
357 //printf("\t-> match\n");
361 //printf("\t-> nomatch\n");
366 /************************************
367 * Match an array of them.
369 int arrayObjectMatch(Objects
*oa1
, Objects
*oa2
)
373 if (oa1
->length
!= oa2
->length
)
375 for (size_t j
= 0; j
< oa1
->length
; j
++)
377 RootObject
*o1
= (*oa1
)[j
];
378 RootObject
*o2
= (*oa2
)[j
];
388 /************************************
389 * Computes hash of expression.
390 * Handles all Expression classes and MUST match their equals method,
391 * i.e. e1->equals(e2) implies expressionHash(e1) == expressionHash(e2).
393 static hash_t
expressionHash(Expression
*e
)
398 return (size_t) ((IntegerExp
*)e
)->getInteger();
401 return CTFloat::hash(((RealExp
*)e
)->value
);
405 ComplexExp
*ce
= (ComplexExp
*)e
;
406 return mixHash(CTFloat::hash(ce
->toReal()), CTFloat::hash(ce
->toImaginary()));
410 return (size_t)(void *) ((IdentifierExp
*)e
)->ident
;
413 return (size_t)(void *) ((NullExp
*)e
)->type
;
417 StringExp
*se
= (StringExp
*)e
;
418 return calcHash((const char *)se
->string
, se
->len
* se
->sz
);
423 TupleExp
*te
= (TupleExp
*)e
;
425 hash
+= te
->e0
? expressionHash(te
->e0
) : 0;
426 for (size_t i
= 0; i
< te
->exps
->length
; i
++)
428 Expression
*elem
= (*te
->exps
)[i
];
429 hash
= mixHash(hash
, expressionHash(elem
));
434 case TOKarrayliteral
:
436 ArrayLiteralExp
*ae
= (ArrayLiteralExp
*)e
;
438 for (size_t i
= 0; i
< ae
->elements
->length
; i
++)
439 hash
= mixHash(hash
, expressionHash(ae
->getElement(i
)));
443 case TOKassocarrayliteral
:
445 AssocArrayLiteralExp
*ae
= (AssocArrayLiteralExp
*)e
;
447 for (size_t i
= 0; i
< ae
->keys
->length
; i
++)
448 // reduction needs associative op as keys are unsorted (use XOR)
449 hash
^= mixHash(expressionHash((*ae
->keys
)[i
]), expressionHash((*ae
->values
)[i
]));
453 case TOKstructliteral
:
455 StructLiteralExp
*se
= (StructLiteralExp
*)e
;
457 for (size_t i
= 0; i
< se
->elements
->length
; i
++)
459 Expression
*elem
= (*se
->elements
)[i
];
460 hash
= mixHash(hash
, elem
? expressionHash(elem
) : 0);
466 return (size_t)(void *) ((VarExp
*)e
)->var
;
469 return (size_t)(void *) ((FuncExp
*)e
)->fd
;
472 // no custom equals for this expression
473 // equals based on identity
474 return (size_t)(void *) e
;
479 /************************************
480 * Return hash of Objects.
482 static hash_t
arrayObjectHash(Objects
*oa1
)
485 for (size_t j
= 0; j
< oa1
->length
; j
++)
487 /* Must follow the logic of match()
489 RootObject
*o1
= (*oa1
)[j
];
490 if (Type
*t1
= isType(o1
))
491 hash
= mixHash(hash
, (size_t)t1
->deco
);
492 else if (Expression
*e1
= getExpression(o1
))
493 hash
= mixHash(hash
, expressionHash(e1
));
494 else if (Dsymbol
*s1
= isDsymbol(o1
))
496 FuncAliasDeclaration
*fa1
= s1
->isFuncAliasDeclaration();
498 s1
= fa1
->toAliasFunc();
499 hash
= mixHash(hash
, mixHash((size_t)(void *)s1
->getIdent(), (size_t)(void *)s1
->parent
));
501 else if (Tuple
*u1
= isTuple(o1
))
502 hash
= mixHash(hash
, arrayObjectHash(&u1
->objects
));
507 RootObject
*objectSyntaxCopy(RootObject
*o
)
511 if (Type
*t
= isType(o
))
512 return t
->syntaxCopy();
513 if (Expression
*e
= isExpression(o
))
514 return e
->syntaxCopy();
519 /* ======================== TemplateDeclaration ============================= */
521 TemplateDeclaration::TemplateDeclaration(Loc loc
, Identifier
*id
,
522 TemplateParameters
*parameters
, Expression
*constraint
, Dsymbols
*decldefs
, bool ismixin
, bool literal
)
526 this->parameters
= parameters
;
527 this->origParameters
= parameters
;
528 this->constraint
= constraint
;
529 this->members
= decldefs
;
530 this->overnext
= NULL
;
531 this->overroot
= NULL
;
532 this->funcroot
= NULL
;
533 this->onemember
= NULL
;
534 this->literal
= literal
;
535 this->ismixin
= ismixin
;
536 this->isstatic
= true;
537 this->previous
= NULL
;
538 this->protection
= Prot(Prot::undefined
);
539 this->instances
= NULL
;
541 // Compute in advance for Ddoc's use
542 // Bugzilla 11153: ident could be NULL if parsing fails.
543 if (members
&& ident
)
546 if (Dsymbol::oneMembers(members
, &s
, ident
) && s
)
554 Dsymbol
*TemplateDeclaration::syntaxCopy(Dsymbol
*)
556 //printf("TemplateDeclaration::syntaxCopy()\n");
557 TemplateParameters
*p
= NULL
;
560 p
= new TemplateParameters();
561 p
->setDim(parameters
->length
);
562 for (size_t i
= 0; i
< p
->length
; i
++)
563 (*p
)[i
] = (*parameters
)[i
]->syntaxCopy();
565 return new TemplateDeclaration(loc
, ident
, p
,
566 constraint
? constraint
->syntaxCopy() : NULL
,
567 Dsymbol::arraySyntaxCopy(members
), ismixin
, literal
);
570 const char *TemplateDeclaration::kind() const
572 return (onemember
&& onemember
->isAggregateDeclaration())
577 /**********************************
578 * Overload existing TemplateDeclaration 'this' with the new one 's'.
579 * Return true if successful; i.e. no conflict.
582 bool TemplateDeclaration::overloadInsert(Dsymbol
*s
)
584 FuncDeclaration
*fd
= s
->isFuncDeclaration();
588 return funcroot
->overloadInsert(fd
);
590 return funcroot
->overloadInsert(this);
593 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
597 TemplateDeclaration
*pthis
= this;
598 TemplateDeclaration
**ptd
;
599 for (ptd
= &pthis
; *ptd
; ptd
= &(*ptd
)->overnext
)
608 /****************************
609 * Check to see if constraint is satisfied.
611 bool TemplateDeclaration::evaluateConstraint(
612 TemplateInstance
*ti
, Scope
*sc
, Scope
*paramscope
,
613 Objects
*dedargs
, FuncDeclaration
*fd
)
615 /* Detect recursive attempts to instantiate this template declaration,
617 * void foo(T)(T x) if (is(typeof(foo(x)))) { }
618 * static assert(!is(typeof(foo(7))));
619 * Recursive attempts are regarded as a constraint failure.
621 /* There's a chicken-and-egg problem here. We don't know yet if this template
622 * instantiation will be a local one (enclosing is set), and we won't know until
623 * after selecting the correct template. Thus, function we're nesting inside
624 * is not on the sc scope chain, and this can cause errors in FuncDeclaration::getLevel().
625 * Workaround the problem by setting a flag to relax the checking on frame errors.
628 for (TemplatePrevious
*p
= previous
; p
; p
= p
->prev
)
630 if (arrayObjectMatch(p
->dedargs
, dedargs
))
632 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
633 /* It must be a subscope of p->sc, other scope chains are not recursive
636 for (Scope
*scx
= sc
; scx
; scx
= scx
->enclosing
)
642 /* BUG: should also check for ref param differences
649 pr
.dedargs
= dedargs
;
650 previous
= &pr
; // add this to threaded list
652 Scope
*scx
= paramscope
->push(ti
);
660 /* Declare all the function parameters as variables and add them to the scope
661 * Making parameters is similar to FuncDeclaration::semantic3
663 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
664 assert(tf
->ty
== Tfunction
);
668 Parameters
*fparameters
= tf
->parameterList
.parameters
;
669 VarArg fvarargs
= tf
->parameterList
.varargs
;
671 size_t nfparams
= Parameter::dim(fparameters
);
672 for (size_t i
= 0; i
< nfparams
; i
++)
674 Parameter
*fparam
= Parameter::getNth(fparameters
, i
);
675 fparam
->storageClass
&= (STCin
| STCout
| STCref
| STClazy
| STCfinal
| STC_TYPECTOR
| STCnodtor
);
676 fparam
->storageClass
|= STCparameter
;
677 if (fvarargs
== VARARGtypesafe
&& i
+ 1 == nfparams
)
678 fparam
->storageClass
|= STCvariadic
;
680 for (size_t i
= 0; i
< fparameters
->length
; i
++)
682 Parameter
*fparam
= (*fparameters
)[i
];
684 continue; // don't add it, if it has no name
685 VarDeclaration
*v
= new VarDeclaration(loc
, fparam
->type
, fparam
->ident
, NULL
);
686 v
->storage_class
= fparam
->storageClass
;
687 dsymbolSemantic(v
, scx
);
689 ti
->symtab
= new DsymbolTable();
691 error("parameter %s.%s is already defined", toChars(), v
->toChars());
696 fd
->storage_class
|= STCstatic
;
698 fd
->vthis
= fd
->declareThis(scx
, fd
->isThis());
701 Expression
*e
= constraint
->syntaxCopy();
703 assert(ti
->inst
== NULL
);
704 ti
->inst
= ti
; // temporary instantiation to enable genIdent()
706 scx
->flags
|= SCOPEconstraint
;
708 bool result
= evalStaticCondition(scx
, constraint
, e
, errors
);
712 previous
= pr
.prev
; // unlink from threaded list
718 /***************************************
719 * Given that ti is an instance of this TemplateDeclaration,
720 * deduce the types of the parameters to this, and store
721 * those deduced types in dedtypes[].
723 * flag 1: don't do semantic() because of dummy types
724 * 2: don't change types in matchArg()
726 * dedtypes deduced arguments
727 * Return match level.
730 MATCH
TemplateDeclaration::matchWithInstance(Scope
*sc
, TemplateInstance
*ti
,
731 Objects
*dedtypes
, Expressions
*fargs
, int flag
)
734 size_t dedtypes_dim
= dedtypes
->length
;
741 size_t parameters_dim
= parameters
->length
;
742 int variadic
= isVariadic() != NULL
;
744 // If more arguments than parameters, no match
745 if (ti
->tiargs
->length
> parameters_dim
&& !variadic
)
750 assert(dedtypes_dim
== parameters_dim
);
751 assert(dedtypes_dim
>= ti
->tiargs
->length
|| variadic
);
755 // Set up scope for template parameters
756 ScopeDsymbol
*paramsym
= new ScopeDsymbol();
757 paramsym
->parent
= _scope
->parent
;
758 Scope
*paramscope
= _scope
->push(paramsym
);
759 paramscope
->tinst
= ti
;
760 paramscope
->minst
= sc
->minst
;
761 paramscope
->callsc
= sc
;
764 // Attempt type deduction
766 for (size_t i
= 0; i
< dedtypes_dim
; i
++)
769 TemplateParameter
*tp
= (*parameters
)[i
];
772 //printf("\targument [%d]\n", i);
773 m2
= tp
->matchArg(ti
->loc
, paramscope
, ti
->tiargs
, i
, parameters
, dedtypes
, &sparam
);
774 //printf("\tm2 = %d\n", m2);
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
);
1400 oded
= tparam
->defaultArg(instLoc
, paramscope
);
1402 (*dedargs
)[i
] = declareParameter(paramscope
, tparam
, oded
);
1409 /* If prmtype does not depend on any template parameters:
1411 * auto foo(T)(T v, double x = 0);
1413 * // at fparam == 'double x = 0'
1415 * or, if all template parameters in the prmtype are already deduced:
1417 * auto foo(R)(R range, ElementType!R sum = 0);
1419 * // at fparam == 'ElementType!R sum = 0'
1421 * Deducing prmtype from fparam->defaultArg is not necessary.
1423 if (prmtype
->deco
||
1424 prmtype
->syntaxCopy()->trySemantic(loc
, paramscope
))
1430 // Deduce prmtype from the defaultArg.
1431 farg
= fparam
->defaultArg
->syntaxCopy();
1432 farg
= expressionSemantic(farg
, paramscope
);
1433 farg
= resolveProperties(paramscope
, farg
);
1437 farg
= (*fargs
)[argi
];
1440 // Check invalid arguments to detect errors early.
1441 if (farg
->op
== TOKerror
|| farg
->type
->ty
== Terror
)
1446 Type
*argtype
= farg
->type
;
1448 if (!(fparam
->storageClass
& STClazy
) && argtype
->ty
== Tvoid
&& farg
->op
!= TOKfunction
)
1451 // Bugzilla 12876: optimize arugument to allow CT-known length matching
1452 farg
= farg
->optimize(WANTvalue
, (fparam
->storageClass
& (STCref
| STCout
)) != 0);
1453 //printf("farg = %s %s\n", farg->type->toChars(), farg->toChars());
1455 RootObject
*oarg
= farg
;
1456 if ((fparam
->storageClass
& STCref
) &&
1457 (!(fparam
->storageClass
& STCauto
) || farg
->isLvalue()))
1459 /* Allow expressions that have CT-known boundaries and type [] to match with [dim]
1462 if (argtype
->ty
== Tarray
&&
1463 (prmtype
->ty
== Tsarray
||
1464 (prmtype
->ty
== Taarray
&& (taai
= ((TypeAArray
*)prmtype
)->index
)->ty
== Tident
&&
1465 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
1467 if (farg
->op
== TOKstring
)
1469 StringExp
*se
= (StringExp
*)farg
;
1470 argtype
= se
->type
->nextOf()->sarrayOf(se
->len
);
1472 else if (farg
->op
== TOKarrayliteral
)
1474 ArrayLiteralExp
*ae
= (ArrayLiteralExp
*)farg
;
1475 argtype
= ae
->type
->nextOf()->sarrayOf(ae
->elements
->length
);
1477 else if (farg
->op
== TOKslice
)
1479 SliceExp
*se
= (SliceExp
*)farg
;
1480 if (Type
*tsa
= toStaticArrayType(se
))
1487 else if ((fparam
->storageClass
& STCout
) == 0 &&
1488 (argtype
->ty
== Tarray
|| argtype
->ty
== Tpointer
) &&
1489 templateParameterLookup(prmtype
, parameters
) != IDX_NOTFOUND
&&
1490 ((TypeIdentifier
*)prmtype
)->idents
.length
== 0)
1492 /* The farg passing to the prmtype always make a copy. Therefore,
1493 * we can shrink the set of the deduced type arguments for prmtype
1494 * by adjusting top-qualifier of the argtype.
1496 * prmtype argtype ta
1497 * T <- const(E)[] const(E)[]
1498 * T <- const(E[]) const(E)[]
1499 * qualifier(T) <- const(E)[] const(E[])
1500 * qualifier(T) <- const(E[]) const(E[])
1502 Type
*ta
= argtype
->castMod(prmtype
->mod
? argtype
->nextOf()->mod
: 0);
1505 Expression
*ea
= farg
->copy();
1511 if (fparameters
.varargs
== VARARGtypesafe
&& parami
+ 1 == nfparams
&& argi
+ 1 < nfargs
)
1515 MATCH m
= deduceType(oarg
, paramscope
, prmtype
, parameters
, dedtypes
, &wm
, inferStart
);
1516 //printf("\tL%d deduceType m = %d, wm = x%x, wildmatch = x%x\n", __LINE__, m, wm, wildmatch);
1519 /* If no match, see if the argument can be matched by using
1520 * implicit conversions.
1522 if (m
== MATCHnomatch
&& prmtype
->deco
)
1523 m
= farg
->implicitConvTo(prmtype
);
1525 if (m
== MATCHnomatch
)
1527 AggregateDeclaration
*ad
= isAggregate(farg
->type
);
1528 if (ad
&& ad
->aliasthis
&& argtype
!= att
)
1530 if (!att
&& argtype
->checkAliasThisRec()) // Bugzilla 12537
1533 /* If a semantic error occurs while doing alias this,
1534 * eg purity(bug 7295), just regard it as not a match.
1536 if (Expression
*e
= resolveAliasThis(sc
, farg
, true))
1544 if (m
> MATCHnomatch
&& (fparam
->storageClass
& (STCref
| STCauto
)) == STCref
)
1546 if (!farg
->isLvalue())
1548 if ((farg
->op
== TOKstring
|| farg
->op
== TOKslice
) &&
1549 (prmtype
->ty
== Tsarray
|| prmtype
->ty
== Taarray
))
1551 // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
1557 if (m
> MATCHnomatch
&& (fparam
->storageClass
& STCout
))
1559 if (!farg
->isLvalue())
1561 if (!farg
->type
->isMutable()) // Bugzilla 11916
1564 if (m
== MATCHnomatch
&& (fparam
->storageClass
& STClazy
) && prmtype
->ty
== Tvoid
&&
1565 farg
->type
->ty
!= Tvoid
)
1568 if (m
!= MATCHnomatch
)
1571 match
= m
; // pick worst match
1578 /* The following code for variadic arguments closely
1579 * matches TypeFunction::callMatch()
1581 if (!(fparameters
.varargs
== VARARGtypesafe
&& parami
+ 1 == nfparams
))
1584 /* Check for match with function parameter T...
1586 Type
*tb
= prmtype
->toBasetype();
1589 // 6764 fix - TypeAArray may be TypeSArray have not yet run semantic().
1592 // Perhaps we can do better with this, see TypeFunction::callMatch()
1593 if (tb
->ty
== Tsarray
)
1595 TypeSArray
*tsa
= (TypeSArray
*)tb
;
1596 dinteger_t sz
= tsa
->dim
->toInteger();
1597 if (sz
!= nfargs
- argi
)
1600 else if (tb
->ty
== Taarray
)
1602 TypeAArray
*taa
= (TypeAArray
*)tb
;
1603 Expression
*dim
= new IntegerExp(instLoc
, nfargs
- argi
, Type::tsize_t
);
1605 size_t i
= templateParameterLookup(taa
->index
, parameters
);
1606 if (i
== IDX_NOTFOUND
)
1613 unsigned errors
= global
.startGagging();
1614 /* ref: https://issues.dlang.org/show_bug.cgi?id=11118
1615 * The parameter isn't part of the template
1616 * ones, let's try to find it in the
1617 * instantiation scope 'sc' and the one
1618 * belonging to the template itself. */
1620 taa
->index
->resolve(instLoc
, sco
, &e
, &t
, &s
);
1624 taa
->index
->resolve(instLoc
, sco
, &e
, &t
, &s
);
1626 global
.endGagging(errors
);
1633 e
= e
->ctfeInterpret();
1634 e
= e
->implicitCastTo(sco
, Type::tsize_t
);
1635 e
= e
->optimize(WANTvalue
);
1636 if (!dim
->equals(e
))
1641 // This code matches code in TypeInstance::deduceType()
1642 TemplateParameter
*tprm
= (*parameters
)[i
];
1643 TemplateValueParameter
*tvp
= tprm
->isTemplateValueParameter();
1646 Expression
*e
= (Expression
*)(*dedtypes
)[i
];
1649 if (!dim
->equals(e
))
1654 Type
*vt
= typeSemantic(tvp
->valType
, Loc(), sc
);
1655 MATCH m
= (MATCH
)dim
->implicitConvTo(vt
);
1656 if (m
<= MATCHnomatch
)
1658 (*dedtypes
)[i
] = dim
;
1665 TypeArray
*ta
= (TypeArray
*)tb
;
1666 Type
*tret
= fparam
->isLazyArray();
1667 for (; argi
< nfargs
; argi
++)
1669 Expression
*arg
= (*fargs
)[argi
];
1673 /* If lazy array of delegates,
1674 * convert arg(s) to delegate(s)
1678 if (ta
->next
->equals(arg
->type
))
1684 m
= arg
->implicitConvTo(tret
);
1685 if (m
== MATCHnomatch
)
1687 if (tret
->toBasetype()->ty
== Tvoid
)
1695 m
= deduceType(arg
, paramscope
, ta
->next
, parameters
, dedtypes
, &wm
, inferStart
);
1698 if (m
== MATCHnomatch
)
1714 //printf("-> argi = %d, nfargs = %d, nfargs2 = %d\n", argi, nfargs, nfargs2);
1715 if (argi
!= nfargs2
&& fparameters
.varargs
== VARARGnone
)
1721 for (size_t i
= 0; i
< dedtypes
->length
; i
++)
1723 Type
*at
= isType((*dedtypes
)[i
]);
1726 if (at
->ty
== Tnone
)
1728 TypeDeduced
*xt
= (TypeDeduced
*)at
;
1729 at
= xt
->tded
; // 'unbox'
1732 (*dedtypes
)[i
] = at
->merge2();
1735 for (size_t i
= ntargs
; i
< dedargs
->length
; i
++)
1737 TemplateParameter
*tparam
= (*parameters
)[i
];
1738 //printf("tparam[%d] = %s\n", i, tparam->ident->toChars());
1739 /* For T:T*, the dedargs is the T*, dedtypes is the T
1740 * But for function templates, we really need them to match
1742 RootObject
*oarg
= (*dedargs
)[i
];
1743 RootObject
*oded
= (*dedtypes
)[i
];
1744 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
1745 //if (oarg) printf("oarg: %s\n", oarg->toChars());
1746 //if (oded) printf("oded: %s\n", oded->toChars());
1751 if (tparam
->specialization() || !tparam
->isTemplateTypeParameter())
1753 /* The specialization can work as long as afterwards
1756 (*dedargs
)[i
] = oded
;
1757 MATCH m2
= tparam
->matchArg(instLoc
, paramscope
, dedargs
, i
, parameters
, dedtypes
, NULL
);
1758 //printf("m2 = %d\n", m2);
1759 if (m2
<= MATCHnomatch
)
1761 if (m2
< matchTiargs
)
1762 matchTiargs
= m2
; // pick worst match
1763 if (!(*dedtypes
)[i
]->equals(oded
))
1764 error("specialization not allowed for deduced parameter %s", tparam
->ident
->toChars());
1768 if (MATCHconvert
< matchTiargs
)
1769 matchTiargs
= MATCHconvert
;
1774 oded
= tparam
->defaultArg(instLoc
, paramscope
);
1777 // if tuple parameter and
1778 // tuple parameter was not in function parameter list and
1779 // we're one or more arguments short (i.e. no tuple argument)
1781 fptupindex
== IDX_NOTFOUND
&&
1782 ntargs
<= dedargs
->length
- 1)
1784 // make tuple argument an empty tuple
1785 oded
= (RootObject
*)new Tuple();
1794 /* At the template parameter T, the picked default template argument
1795 * X!int should be matched to T in order to deduce dependent
1796 * template parameter A.
1797 * auto foo(T : X!A = X!int, A...)() { ... }
1798 * foo(); // T <-- X!int, A <-- (int)
1800 if (tparam
->specialization())
1802 (*dedargs
)[i
] = oded
;
1803 MATCH m2
= tparam
->matchArg(instLoc
, paramscope
, dedargs
, i
, parameters
, dedtypes
, NULL
);
1804 //printf("m2 = %d\n", m2);
1805 if (m2
<= MATCHnomatch
)
1807 if (m2
< matchTiargs
)
1808 matchTiargs
= m2
; // pick worst match
1809 if (!(*dedtypes
)[i
]->equals(oded
))
1810 error("specialization not allowed for deduced parameter %s", tparam
->ident
->toChars());
1813 oded
= declareParameter(paramscope
, tparam
, oded
);
1814 (*dedargs
)[i
] = oded
;
1818 /* Bugzilla 7469: As same as the code for 7469 in findBestMatch,
1819 * expand a Tuple in dedargs to normalize template arguments.
1821 if (size_t d
= dedargs
->length
)
1823 if (Tuple
*va
= isTuple((*dedargs
)[d
- 1]))
1825 if (va
->objects
.length
)
1827 dedargs
->setDim(d
- 1);
1828 dedargs
->insert(d
- 1, &va
->objects
);
1832 ti
->tiargs
= dedargs
; // update to the normalized template arguments.
1834 // Partially instantiate function for constraint and fd->leastAsSpecialized()
1837 Scope
*sc2
= _scope
;
1838 sc2
= sc2
->push(paramsym
);
1839 sc2
= sc2
->push(ti
);
1842 sc2
->minst
= sc
->minst
;
1844 fd
= doHeaderInstantiation(ti
, sc2
, fd
, tthis
, fargs
);
1855 if (!evaluateConstraint(ti
, sc
, paramscope
, dedargs
, fd
))
1860 //printf("\tmatch %d\n", match);
1861 return (MATCH
)(match
| (matchTiargs
<<4));
1865 //printf("\tnomatch\n");
1866 return MATCHnomatch
;
1868 Lerror
: // todo: for the future improvement
1870 //printf("\terror\n");
1871 return MATCHnomatch
;
1874 /**************************************************
1875 * Declare template parameter tp with value o, and install it in the scope sc.
1878 RootObject
*TemplateDeclaration::declareParameter(Scope
*sc
, TemplateParameter
*tp
, RootObject
*o
)
1880 //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o);
1882 Type
*ta
= isType(o
);
1883 Expression
*ea
= isExpression(o
);
1884 Dsymbol
*sa
= isDsymbol(o
);
1885 Tuple
*va
= isTuple(o
);
1888 VarDeclaration
*v
= NULL
;
1890 if (ea
&& ea
->op
== TOKtype
)
1892 else if (ea
&& ea
->op
== TOKscope
)
1893 sa
= ((ScopeExp
*)ea
)->sds
;
1894 else if (ea
&& (ea
->op
== TOKthis
|| ea
->op
== TOKsuper
))
1895 sa
= ((ThisExp
*)ea
)->var
;
1896 else if (ea
&& ea
->op
== TOKfunction
)
1898 if (((FuncExp
*)ea
)->td
)
1899 sa
= ((FuncExp
*)ea
)->td
;
1901 sa
= ((FuncExp
*)ea
)->fd
;
1906 //printf("type %s\n", ta->toChars());
1907 d
= new AliasDeclaration(Loc(), tp
->ident
, ta
);
1911 //printf("Alias %s %s;\n", sa->ident->toChars(), tp->ident->toChars());
1912 d
= new AliasDeclaration(Loc(), tp
->ident
, sa
);
1916 // tdtypes.data[i] always matches ea here
1917 Initializer
*init
= new ExpInitializer(loc
, ea
);
1918 TemplateValueParameter
*tvp
= tp
->isTemplateValueParameter();
1920 Type
*t
= tvp
? tvp
->valType
: NULL
;
1922 v
= new VarDeclaration(loc
, t
, tp
->ident
, init
);
1923 v
->storage_class
= STCmanifest
| STCtemplateparameter
;
1928 //printf("\ttuple\n");
1929 d
= new TupleDeclaration(loc
, tp
->ident
, &va
->objects
);
1936 d
->storage_class
|= STCtemplateparameter
;
1940 // consistent with Type::checkDeprecated()
1941 while (t
->ty
!= Tenum
)
1943 if (!t
->nextOf()) break;
1944 t
= ((TypeNext
*)t
)->next
;
1946 if (Dsymbol
*s
= t
->toDsymbol(sc
))
1948 if (s
->isDeprecated())
1949 d
->storage_class
|= STCdeprecated
;
1954 if (sa
->isDeprecated())
1955 d
->storage_class
|= STCdeprecated
;
1959 error("declaration %s is already defined", tp
->ident
->toChars());
1960 dsymbolSemantic(d
, sc
);
1962 /* So the caller's o gets updated with the result of semantic() being run on o
1965 o
= initializerToExpression(v
->_init
);
1969 /**************************************
1970 * Determine if TemplateDeclaration is variadic.
1973 TemplateTupleParameter
*isVariadic(TemplateParameters
*parameters
)
1975 size_t dim
= parameters
->length
;
1976 TemplateTupleParameter
*tp
= NULL
;
1979 tp
= ((*parameters
)[dim
- 1])->isTemplateTupleParameter();
1983 TemplateTupleParameter
*TemplateDeclaration::isVariadic()
1985 return ::isVariadic(parameters
);
1988 /***********************************
1989 * We can overload templates.
1992 bool TemplateDeclaration::isOverloadable()
1997 /*************************************************
1998 * Given function arguments, figure out which template function
1999 * to expand, and return matching result.
2002 * dstart the root of overloaded function templates
2003 * loc instantiation location
2004 * sc instantiation scope
2005 * tiargs initial list of template arguments
2006 * tthis if !NULL, the 'this' pointer argument
2007 * fargs arguments to function
2010 void functionResolve(Match
*m
, Dsymbol
*dstart
, Loc loc
, Scope
*sc
,
2011 Objects
*tiargs
, Type
*tthis
, Expressions
*fargs
)
2023 int property
; // 0: unintialized
2024 // 1: seen @property
2027 TemplateDeclaration
*td_best
;
2028 TemplateInstance
*ti_best
;
2032 static int fp(void *param
, Dsymbol
*s
)
2036 if (FuncDeclaration
*fd
= s
->isFuncDeclaration())
2037 return ((ParamDeduce
*)param
)->applyFunction(fd
);
2038 if (TemplateDeclaration
*td
= s
->isTemplateDeclaration())
2039 return ((ParamDeduce
*)param
)->applyTemplate(td
);
2043 int applyFunction(FuncDeclaration
*fd
)
2048 // explicitly specified tiargs never match to non template function
2049 if (tiargs
&& tiargs
->length
> 0)
2052 // constructors need a valid scope in order to detect semantic errors
2053 if (!fd
->isCtorDeclaration() &&
2054 fd
->semanticRun
< PASSsemanticdone
)
2056 Ungag ungag
= fd
->ungagSpeculative();
2057 dsymbolSemantic(fd
, NULL
);
2059 if (fd
->semanticRun
< PASSsemanticdone
)
2061 ::error(loc
, "forward reference to template %s", fd
->toChars());
2064 //printf("fd = %s %s, fargs = %s\n", fd->toChars(), fd->type->toChars(), fargs->toChars());
2066 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2068 int prop
= (tf
->isproperty
) ? 1 : 2;
2071 else if (property
!= prop
)
2072 error(fd
->loc
, "cannot overload both property and non-property functions");
2074 /* For constructors, qualifier check will be opposite direction.
2075 * Qualified constructor always makes qualified object, then will be checked
2076 * that it is implicitly convertible to tthis.
2078 Type
*tthis_fd
= fd
->needThis() ? tthis
: NULL
;
2079 bool isCtorCall
= tthis_fd
&& fd
->isCtorDeclaration();
2082 //printf("%s tf->mod = x%x tthis_fd->mod = x%x %d\n", tf->toChars(),
2083 // tf->mod, tthis_fd->mod, fd->isolateReturn());
2084 if (MODimplicitConv(tf
->mod
, tthis_fd
->mod
) ||
2085 (tf
->isWild() && tf
->isShared() == tthis_fd
->isShared()) ||
2086 fd
->isolateReturn())
2088 /* && tf->isShared() == tthis_fd->isShared()*/
2089 // Uniquely constructed object can ignore shared qualifier.
2090 // TODO: Is this appropriate?
2094 return 0; // MATCHnomatch
2096 MATCH mfa
= tf
->callMatch(tthis_fd
, fargs
);
2097 //printf("test1: mfa = %d\n", mfa);
2098 if (mfa
> MATCHnomatch
)
2100 if (mfa
> m
->last
) goto LfIsBetter
;
2101 if (mfa
< m
->last
) goto LlastIsBetter
;
2103 /* See if one of the matches overrides the other.
2106 if (m
->lastf
->overrides(fd
)) goto LlastIsBetter
;
2107 if (fd
->overrides(m
->lastf
)) goto LfIsBetter
;
2109 /* Try to disambiguate using template-style partial ordering rules.
2110 * In essence, if f() and g() are ambiguous, if f() can call g(),
2111 * but g() cannot call f(), then pick f().
2112 * This is because f() is "more specialized."
2115 MATCH c1
= fd
->leastAsSpecialized(m
->lastf
);
2116 MATCH c2
= m
->lastf
->leastAsSpecialized(fd
);
2117 //printf("c1 = %d, c2 = %d\n", c1, c2);
2118 if (c1
> c2
) goto LfIsBetter
;
2119 if (c1
< c2
) goto LlastIsBetter
;
2122 /* The 'overrides' check above does covariant checking only
2123 * for virtual member functions. It should do it for all functions,
2124 * but in order to not risk breaking code we put it after
2125 * the 'leastAsSpecialized' check.
2126 * In the future try moving it before.
2127 * I.e. a not-the-same-but-covariant match is preferred,
2128 * as it is more restrictive.
2130 if (!m
->lastf
->type
->equals(fd
->type
))
2132 //printf("cov: %d %d\n", m->lastf->type->covariant(fd->type), fd->type->covariant(m->lastf->type));
2133 if (m
->lastf
->type
->covariant(fd
->type
) == 1) goto LlastIsBetter
;
2134 if (fd
->type
->covariant(m
->lastf
->type
) == 1) goto LfIsBetter
;
2137 /* If the two functions are the same function, like:
2139 * int foo(int x) { ... }
2140 * then pick the one with the body.
2142 if (tf
->equals(m
->lastf
->type
) &&
2143 fd
->storage_class
== m
->lastf
->storage_class
&&
2144 fd
->parent
== m
->lastf
->parent
&&
2145 fd
->protection
== m
->lastf
->protection
&&
2146 fd
->linkage
== m
->lastf
->linkage
)
2148 if ( fd
->fbody
&& !m
->lastf
->fbody
) goto LfIsBetter
;
2149 if (!fd
->fbody
&& m
->lastf
->fbody
) goto LlastIsBetter
;
2152 // Bugzilla 14450: Prefer exact qualified constructor for the creating object type
2153 if (isCtorCall
&& tf
->mod
!= m
->lastf
->type
->mod
)
2155 if (tthis
->mod
== tf
->mod
) goto LfIsBetter
;
2156 if (tthis
->mod
== m
->lastf
->type
->mod
) goto LlastIsBetter
;
2169 ta_last
= MATCHexact
;
2172 tthis_best
= tthis_fd
;
2180 int applyTemplate(TemplateDeclaration
*td
)
2182 //printf("applyTemplate()\n");
2188 sc
= td
->_scope
; // workaround for Type::aliasthisOf
2190 if (td
->semanticRun
== PASSinit
&& td
->_scope
)
2192 // Try to fix forward reference. Ungag errors while doing so.
2193 Ungag ungag
= td
->ungagSpeculative();
2194 dsymbolSemantic(td
, td
->_scope
);
2196 if (td
->semanticRun
== PASSinit
)
2198 ::error(loc
, "forward reference to template %s", td
->toChars());
2202 m
->last
= MATCHnomatch
;
2205 //printf("td = %s\n", td->toChars());
2208 f
= td
->onemember
? td
->onemember
->isFuncDeclaration() : NULL
;
2212 tiargs
= new Objects();
2213 TemplateInstance
*ti
= new TemplateInstance(loc
, td
, tiargs
);
2215 dedtypes
.setDim(td
->parameters
->length
);
2216 assert(td
->semanticRun
!= PASSinit
);
2217 MATCH mta
= td
->matchWithInstance(sc
, ti
, &dedtypes
, fargs
, 0);
2218 //printf("matchWithInstance = %d\n", mta);
2219 if (mta
<= MATCHnomatch
|| mta
< ta_last
) // no match or less match
2222 templateInstanceSemantic(ti
, sc
, fargs
);
2223 if (!ti
->inst
) // if template failed to expand
2226 Dsymbol
*s
= ti
->inst
->toAlias();
2227 FuncDeclaration
*fd
;
2228 if (TemplateDeclaration
*tdx
= s
->isTemplateDeclaration())
2230 Objects dedtypesX
; // empty tiargs
2232 // Bugzilla 11553: Check for recursive instantiation of tdx.
2233 for (TemplatePrevious
*p
= tdx
->previous
; p
; p
= p
->prev
)
2235 if (arrayObjectMatch(p
->dedargs
, &dedtypesX
))
2237 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
2238 /* It must be a subscope of p->sc, other scope chains are not recursive
2241 for (Scope
*scx
= sc
; scx
; scx
= scx
->enclosing
)
2245 error(loc
, "recursive template expansion while looking for %s.%s", ti
->toChars(), tdx
->toChars());
2250 /* BUG: should also check for ref param differences
2254 TemplatePrevious pr
;
2255 pr
.prev
= tdx
->previous
;
2257 pr
.dedargs
= &dedtypesX
;
2258 tdx
->previous
= &pr
; // add this to threaded list
2260 fd
= resolveFuncCall(loc
, sc
, s
, NULL
, tthis
, fargs
, 1);
2262 tdx
->previous
= pr
.prev
; // unlink from threaded list
2264 else if (s
->isFuncDeclaration())
2266 fd
= resolveFuncCall(loc
, sc
, s
, NULL
, tthis
, fargs
, 1);
2274 if (fd
->type
->ty
!= Tfunction
)
2276 m
->lastf
= fd
; // to propagate "error match"
2278 m
->last
= MATCHnomatch
;
2282 Type
*tthis_fd
= fd
->needThis() && !fd
->isCtorDeclaration() ? tthis
: NULL
;
2284 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2285 MATCH mfa
= tf
->callMatch(tthis_fd
, fargs
);
2289 if (mta
< ta_last
) goto Ltd_best2
;
2290 if (mta
> ta_last
) goto Ltd2
;
2292 if (mfa
< m
->last
) goto Ltd_best2
;
2293 if (mfa
> m
->last
) goto Ltd2
;
2295 //printf("Lambig2\n");
2304 // td is the new best match
2308 property
= 0; // (backward compatibility)
2312 tthis_best
= tthis_fd
;
2319 //printf("td = %s\n", td->toChars());
2320 for (size_t ovi
= 0; f
; f
= f
->overnext0
, ovi
++)
2322 if (f
->type
->ty
!= Tfunction
|| f
->errors
)
2325 /* This is a 'dummy' instance to evaluate constraint properly.
2327 TemplateInstance
*ti
= new TemplateInstance(loc
, td
, tiargs
);
2328 ti
->parent
= td
->parent
; // Maybe calculating valid 'enclosing' is unnecessary.
2330 FuncDeclaration
*fd
= f
;
2331 int x
= td
->deduceFunctionTemplateMatch(ti
, sc
, fd
, tthis
, fargs
);
2332 MATCH mta
= (MATCH
)(x
>> 4);
2333 MATCH mfa
= (MATCH
)(x
& 0xF);
2334 //printf("match:t/f = %d/%d\n", mta, mfa);
2335 if (!fd
|| mfa
== MATCHnomatch
)
2338 Type
*tthis_fd
= fd
->needThis() ? tthis
: NULL
;
2340 bool isCtorCall
= tthis_fd
&& fd
->isCtorDeclaration();
2343 // Constructor call requires additional check.
2345 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2347 if (MODimplicitConv(tf
->mod
, tthis_fd
->mod
) ||
2348 (tf
->isWild() && tf
->isShared() == tthis_fd
->isShared()) ||
2349 fd
->isolateReturn())
2354 continue; // MATCHnomatch
2357 if (mta
< ta_last
) goto Ltd_best
;
2358 if (mta
> ta_last
) goto Ltd
;
2360 if (mfa
< m
->last
) goto Ltd_best
;
2361 if (mfa
> m
->last
) goto Ltd
;
2365 // Disambiguate by picking the most specialized TemplateDeclaration
2366 MATCH c1
= td
->leastAsSpecialized(sc
, td_best
, fargs
);
2367 MATCH c2
= td_best
->leastAsSpecialized(sc
, td
, fargs
);
2368 //printf("1: c1 = %d, c2 = %d\n", c1, c2);
2369 if (c1
> c2
) goto Ltd
;
2370 if (c1
< c2
) goto Ltd_best
;
2372 assert(fd
&& m
->lastf
);
2374 // Disambiguate by tf->callMatch
2375 TypeFunction
*tf1
= (TypeFunction
*)fd
->type
;
2376 assert(tf1
->ty
== Tfunction
);
2377 TypeFunction
*tf2
= (TypeFunction
*)m
->lastf
->type
;
2378 assert(tf2
->ty
== Tfunction
);
2379 MATCH c1
= tf1
->callMatch(tthis_fd
, fargs
);
2380 MATCH c2
= tf2
->callMatch(tthis_best
, fargs
);
2381 //printf("2: c1 = %d, c2 = %d\n", c1, c2);
2382 if (c1
> c2
) goto Ltd
;
2383 if (c1
< c2
) goto Ltd_best
;
2386 // Disambiguate by picking the most specialized FunctionDeclaration
2387 MATCH c1
= fd
->leastAsSpecialized(m
->lastf
);
2388 MATCH c2
= m
->lastf
->leastAsSpecialized(fd
);
2389 //printf("3: c1 = %d, c2 = %d\n", c1, c2);
2390 if (c1
> c2
) goto Ltd
;
2391 if (c1
< c2
) goto Ltd_best
;
2394 // Bugzilla 14450: Prefer exact qualified constructor for the creating object type
2395 if (isCtorCall
&& fd
->type
->mod
!= m
->lastf
->type
->mod
)
2397 if (tthis
->mod
== fd
->type
->mod
) goto Ltd
;
2398 if (tthis
->mod
== m
->lastf
->type
->mod
) goto Ltd_best
;
2405 Ltd_best
: // td_best is the best match so far
2406 //printf("Ltd_best\n");
2409 Ltd
: // td is the new best match
2414 property
= 0; // (backward compatibility)
2418 tthis_best
= tthis_fd
;
2441 p
.ta_last
= m
->last
!= MATCHnomatch
? MATCHexact
: MATCHnomatch
;
2442 p
.tthis_best
= NULL
;
2444 TemplateDeclaration
*td
= dstart
->isTemplateDeclaration();
2445 if (td
&& td
->funcroot
)
2446 dstart
= td
->funcroot
;
2448 overloadApply(dstart
, &p
, &ParamDeduce::fp
);
2450 //printf("td_best = %p, m->lastf = %p\n", p.td_best, m->lastf);
2451 if (p
.td_best
&& p
.ti_best
&& m
->count
== 1)
2453 // Matches to template function
2454 assert(p
.td_best
->onemember
&& p
.td_best
->onemember
->isFuncDeclaration());
2456 /* The best match is td_best with arguments tdargs.
2457 * Now instantiate the template.
2459 assert(p
.td_best
->_scope
);
2461 sc
= p
.td_best
->_scope
; // workaround for Type::aliasthisOf
2463 TemplateInstance
*ti
= new TemplateInstance(loc
, p
.td_best
, p
.ti_best
->tiargs
);
2464 templateInstanceSemantic(ti
, sc
, fargs
);
2466 m
->lastf
= ti
->toAlias()->isFuncDeclaration();
2474 m
->last
= MATCHnomatch
;
2478 // look forward instantiated overload function
2479 // Dsymbol::oneMembers is alredy called in TemplateInstance::semantic.
2480 // it has filled overnext0d
2481 while (p
.ov_index
--)
2483 m
->lastf
= m
->lastf
->overnext0
;
2487 p
.tthis_best
= m
->lastf
->needThis() && !m
->lastf
->isCtorDeclaration() ? tthis
: NULL
;
2489 TypeFunction
*tf
= (TypeFunction
*)m
->lastf
->type
;
2490 if (tf
->ty
== Terror
)
2492 assert(tf
->ty
== Tfunction
);
2493 if (!tf
->callMatch(p
.tthis_best
, fargs
))
2496 /* As Bugzilla 3682 shows, a template instance can be matched while instantiating
2497 * that same template. Thus, the function type can be incomplete. Complete it.
2499 * Bugzilla 9208: For auto function, completion should be deferred to the end of
2500 * its semantic3. Should not complete it in here.
2502 if (tf
->next
&& !m
->lastf
->inferRetType
)
2504 m
->lastf
->type
= typeSemantic(tf
, loc
, sc
);
2509 // Matches to non template function,
2510 // or found matches were ambiguous.
2511 assert(m
->count
>= 1);
2518 m
->last
= MATCHnomatch
;
2522 /*************************************************
2523 * Limited function template instantiation for using fd->leastAsSpecialized()
2525 FuncDeclaration
*TemplateDeclaration::doHeaderInstantiation(
2526 TemplateInstance
*ti
, Scope
*sc2
,
2527 FuncDeclaration
*fd
, Type
*tthis
, Expressions
*fargs
)
2531 // function body and contracts are not need
2532 if (fd
->isCtorDeclaration())
2533 fd
= new CtorDeclaration(fd
->loc
, fd
->endloc
, fd
->storage_class
, fd
->type
->syntaxCopy());
2535 fd
= new FuncDeclaration(fd
->loc
, fd
->endloc
, fd
->ident
, fd
->storage_class
, fd
->type
->syntaxCopy());
2538 assert(fd
->type
->ty
== Tfunction
);
2539 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2544 // Match 'tthis' to any TemplateThisParameter's
2545 bool hasttp
= false;
2546 for (size_t i
= 0; i
< parameters
->length
; i
++)
2548 TemplateParameter
*tp
= (*parameters
)[i
];
2549 TemplateThisParameter
*ttp
= tp
->isTemplateThisParameter();
2555 tf
= (TypeFunction
*)tf
->addSTC(ModToStc(tthis
->mod
));
2560 Scope
*scx
= sc2
->push();
2562 // Shouldn't run semantic on default arguments and return type.
2563 for (size_t i
= 0; i
< tf
->parameterList
.parameters
->length
; i
++)
2564 (*tf
->parameterList
.parameters
)[i
]->defaultArg
= NULL
;
2565 if (fd
->isCtorDeclaration())
2567 // For constructors, emitting return type is necessary for
2568 // isolateReturn() in functionResolve.
2569 scx
->flags
|= SCOPEctor
;
2571 Dsymbol
*parent
= toParent2();
2573 AggregateDeclaration
*ad
= parent
->isAggregateDeclaration();
2574 if (!ad
|| parent
->isUnionDeclaration())
2580 tret
= ad
->handleType();
2582 tret
= tret
->addStorageClass(fd
->storage_class
| scx
->stc
);
2583 tret
= tret
->addMod(tf
->mod
);
2586 if (ad
&& ad
->isStructDeclaration())
2588 //printf("tf = %s\n", tf->toChars());
2593 fd
->type
= fd
->type
->addSTC(scx
->stc
);
2594 fd
->type
= typeSemantic(fd
->type
, fd
->loc
, scx
);
2597 if (fd
->type
->ty
!= Tfunction
)
2600 fd
->originalType
= fd
->type
; // for mangling
2601 //printf("\t[%s] fd->type = %s, mod = %x, ", loc.toChars(), fd->type->toChars(), fd->type->mod);
2602 //printf("fd->needThis() = %d\n", fd->needThis());
2607 bool TemplateDeclaration::hasStaticCtorOrDtor()
2609 return false; // don't scan uninstantiated templates
2612 const char *TemplateDeclaration::toChars()
2615 return Dsymbol::toChars();
2620 buf
.writestring(ident
->toChars());
2622 for (size_t i
= 0; i
< parameters
->length
; i
++)
2624 TemplateParameter
*tp
= (*parameters
)[i
];
2626 buf
.writestring(", ");
2627 ::toCBuffer(tp
, &buf
, &hgs
);
2633 FuncDeclaration
*fd
= onemember
->isFuncDeclaration();
2636 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2637 buf
.writestring(parametersTypeToChars(tf
->parameterList
));
2643 buf
.writestring(" if (");
2644 ::toCBuffer(constraint
, &buf
, &hgs
);
2647 return buf
.extractChars();
2650 Prot
TemplateDeclaration::prot()
2655 /****************************************************
2656 * Given a new instance tithis of this TemplateDeclaration,
2657 * see if there already exists an instance.
2658 * If so, return that existing instance.
2661 TemplateInstance
*TemplateDeclaration::findExistingInstance(TemplateInstance
*tithis
, Expressions
*fargs
)
2663 //printf("findExistingInstance(%p)\n", tithis);
2664 tithis
->fargs
= fargs
;
2665 TemplateInstances
*tinstances
= (TemplateInstances
*)dmd_aaGetRvalue((AA
*)instances
, (void *)tithis
->toHash());
2668 for (size_t i
= 0; i
< tinstances
->length
; i
++)
2670 TemplateInstance
*ti
= (*tinstances
)[i
];
2671 if (tithis
->compare(ti
) == 0)
2678 /********************************************
2679 * Add instance ti to TemplateDeclaration's table of instances.
2680 * Return a handle we can use to later remove it if it fails instantiation.
2683 TemplateInstance
*TemplateDeclaration::addInstance(TemplateInstance
*ti
)
2685 //printf("addInstance() %p %p\n", instances, ti);
2686 TemplateInstances
**ptinstances
= (TemplateInstances
**)dmd_aaGet((AA
**)&instances
, (void *)ti
->toHash());
2688 *ptinstances
= new TemplateInstances();
2689 (*ptinstances
)->push(ti
);
2693 /*******************************************
2694 * Remove TemplateInstance from table of instances.
2696 * handle returned by addInstance()
2699 void TemplateDeclaration::removeInstance(TemplateInstance
*handle
)
2701 //printf("removeInstance()\n");
2702 TemplateInstances
*tinstances
= (TemplateInstances
*)dmd_aaGetRvalue((AA
*)instances
, (void *)handle
->toHash());
2705 for (size_t i
= 0; i
< tinstances
->length
; i
++)
2707 TemplateInstance
*ti
= (*tinstances
)[i
];
2710 tinstances
->remove(i
);
2717 /* ======================== Type ============================================ */
2720 * Given an identifier, figure out which TemplateParameter it is.
2721 * Return IDX_NOTFOUND if not found.
2724 static size_t templateIdentifierLookup(Identifier
*id
, TemplateParameters
*parameters
)
2726 for (size_t i
= 0; i
< parameters
->length
; i
++)
2728 TemplateParameter
*tp
= (*parameters
)[i
];
2729 if (tp
->ident
->equals(id
))
2732 return IDX_NOTFOUND
;
2735 size_t templateParameterLookup(Type
*tparam
, TemplateParameters
*parameters
)
2737 if (tparam
->ty
== Tident
)
2739 TypeIdentifier
*tident
= (TypeIdentifier
*)tparam
;
2740 //printf("\ttident = '%s'\n", tident->toChars());
2741 return templateIdentifierLookup(tident
->ident
, parameters
);
2743 return IDX_NOTFOUND
;
2746 unsigned char deduceWildHelper(Type
*t
, Type
**at
, Type
*tparam
)
2748 if ((tparam
->mod
& MODwild
) == 0)
2753 #define X(U,T) ((U) << 4) | (T)
2754 switch (X(tparam
->mod
, t
->mod
))
2757 case X(MODwild
, MODconst
):
2758 case X(MODwild
, MODshared
):
2759 case X(MODwild
, MODshared
| MODconst
):
2760 case X(MODwild
, MODimmutable
):
2761 case X(MODwildconst
, 0):
2762 case X(MODwildconst
, MODconst
):
2763 case X(MODwildconst
, MODshared
):
2764 case X(MODwildconst
, MODshared
| MODconst
):
2765 case X(MODwildconst
, MODimmutable
):
2766 case X(MODshared
| MODwild
, MODshared
):
2767 case X(MODshared
| MODwild
, MODshared
| MODconst
):
2768 case X(MODshared
| MODwild
, MODimmutable
):
2769 case X(MODshared
| MODwildconst
, MODshared
):
2770 case X(MODshared
| MODwildconst
, MODshared
| MODconst
):
2771 case X(MODshared
| MODwildconst
, MODimmutable
):
2773 unsigned char wm
= (t
->mod
& ~MODshared
);
2776 unsigned char m
= (t
->mod
& (MODconst
| MODimmutable
)) | (tparam
->mod
& t
->mod
& MODshared
);
2777 *at
= t
->unqualify(m
);
2781 case X(MODwild
, MODwild
):
2782 case X(MODwild
, MODwildconst
):
2783 case X(MODwild
, MODshared
| MODwild
):
2784 case X(MODwild
, MODshared
| MODwildconst
):
2785 case X(MODwildconst
, MODwild
):
2786 case X(MODwildconst
, MODwildconst
):
2787 case X(MODwildconst
, MODshared
| MODwild
):
2788 case X(MODwildconst
, MODshared
| MODwildconst
):
2789 case X(MODshared
| MODwild
, MODshared
| MODwild
):
2790 case X(MODshared
| MODwild
, MODshared
| MODwildconst
):
2791 case X(MODshared
| MODwildconst
, MODshared
| MODwild
):
2792 case X(MODshared
| MODwildconst
, MODshared
| MODwildconst
):
2794 *at
= t
->unqualify(tparam
->mod
& t
->mod
);
2804 MATCH
deduceTypeHelper(Type
*t
, Type
**at
, Type
*tparam
)
2808 #define X(U,T) ((U) << 4) | (T)
2809 switch (X(tparam
->mod
, t
->mod
))
2812 case X(0, MODconst
):
2814 case X(0, MODwildconst
):
2815 case X(0, MODshared
):
2816 case X(0, MODshared
| MODconst
):
2817 case X(0, MODshared
| MODwild
):
2818 case X(0, MODshared
| MODwildconst
):
2819 case X(0, MODimmutable
):
2821 // foo(U) const(T) => const(T)
2822 // foo(U) inout(T) => inout(T)
2823 // foo(U) inout(const(T)) => inout(const(T))
2824 // foo(U) shared(T) => shared(T)
2825 // foo(U) shared(const(T)) => shared(const(T))
2826 // foo(U) shared(inout(T)) => shared(inout(T))
2827 // foo(U) shared(inout(const(T))) => shared(inout(const(T)))
2828 // foo(U) immutable(T) => immutable(T)
2834 case X(MODconst
, MODconst
):
2835 case X(MODwild
, MODwild
):
2836 case X(MODwildconst
, MODwildconst
):
2837 case X(MODshared
, MODshared
):
2838 case X(MODshared
| MODconst
, MODshared
| MODconst
):
2839 case X(MODshared
| MODwild
, MODshared
| MODwild
):
2840 case X(MODshared
| MODwildconst
, MODshared
| MODwildconst
):
2841 case X(MODimmutable
, MODimmutable
):
2842 // foo(const(U)) const(T) => T
2843 // foo(inout(U)) inout(T) => T
2844 // foo(inout(const(U))) inout(const(T)) => T
2845 // foo(shared(U)) shared(T) => T
2846 // foo(shared(const(U))) shared(const(T)) => T
2847 // foo(shared(inout(U))) shared(inout(T)) => T
2848 // foo(shared(inout(const(U)))) shared(inout(const(T))) => T
2849 // foo(immutable(U)) immutable(T) => T
2851 *at
= t
->mutableOf()->unSharedOf();
2855 case X(MODconst
, 0):
2856 case X(MODconst
, MODwild
):
2857 case X(MODconst
, MODwildconst
):
2858 case X(MODconst
, MODshared
| MODconst
):
2859 case X(MODconst
, MODshared
| MODwild
):
2860 case X(MODconst
, MODshared
| MODwildconst
):
2861 case X(MODconst
, MODimmutable
):
2862 case X(MODwild
, MODshared
| MODwild
):
2863 case X(MODwildconst
, MODshared
| MODwildconst
):
2864 case X(MODshared
| MODconst
, MODimmutable
):
2865 // foo(const(U)) T => T
2866 // foo(const(U)) inout(T) => T
2867 // foo(const(U)) inout(const(T)) => T
2868 // foo(const(U)) shared(const(T)) => shared(T)
2869 // foo(const(U)) shared(inout(T)) => shared(T)
2870 // foo(const(U)) shared(inout(const(T))) => shared(T)
2871 // foo(const(U)) immutable(T) => T
2872 // foo(inout(U)) shared(inout(T)) => shared(T)
2873 // foo(inout(const(U))) shared(inout(const(T))) => shared(T)
2874 // foo(shared(const(U))) immutable(T) => T
2876 *at
= t
->mutableOf();
2880 case X(MODconst
, MODshared
):
2881 // foo(const(U)) shared(T) => shared(T)
2887 case X(MODshared
, MODshared
| MODconst
):
2888 case X(MODshared
, MODshared
| MODwild
):
2889 case X(MODshared
, MODshared
| MODwildconst
):
2890 case X(MODshared
| MODconst
, MODshared
):
2891 // foo(shared(U)) shared(const(T)) => const(T)
2892 // foo(shared(U)) shared(inout(T)) => inout(T)
2893 // foo(shared(U)) shared(inout(const(T))) => inout(const(T))
2894 // foo(shared(const(U))) shared(T) => T
2896 *at
= t
->unSharedOf();
2900 case X(MODwildconst
, MODimmutable
):
2901 case X(MODshared
| MODconst
, MODshared
| MODwildconst
):
2902 case X(MODshared
| MODwildconst
, MODimmutable
):
2903 case X(MODshared
| MODwildconst
, MODshared
| MODwild
):
2904 // foo(inout(const(U))) immutable(T) => T
2905 // foo(shared(const(U))) shared(inout(const(T))) => T
2906 // foo(shared(inout(const(U)))) immutable(T) => T
2907 // foo(shared(inout(const(U)))) shared(inout(T)) => T
2909 *at
= t
->unSharedOf()->mutableOf();
2913 case X(MODshared
| MODconst
, MODshared
| MODwild
):
2914 // foo(shared(const(U))) shared(inout(T)) => T
2916 *at
= t
->unSharedOf()->mutableOf();
2921 case X(MODwild
, MODconst
):
2922 case X(MODwild
, MODwildconst
):
2923 case X(MODwild
, MODimmutable
):
2924 case X(MODwild
, MODshared
):
2925 case X(MODwild
, MODshared
| MODconst
):
2926 case X(MODwild
, MODshared
| MODwildconst
):
2927 case X(MODwildconst
, 0):
2928 case X(MODwildconst
, MODconst
):
2929 case X(MODwildconst
, MODwild
):
2930 case X(MODwildconst
, MODshared
):
2931 case X(MODwildconst
, MODshared
| MODconst
):
2932 case X(MODwildconst
, MODshared
| MODwild
):
2933 case X(MODshared
, 0):
2934 case X(MODshared
, MODconst
):
2935 case X(MODshared
, MODwild
):
2936 case X(MODshared
, MODwildconst
):
2937 case X(MODshared
, MODimmutable
):
2938 case X(MODshared
| MODconst
, 0):
2939 case X(MODshared
| MODconst
, MODconst
):
2940 case X(MODshared
| MODconst
, MODwild
):
2941 case X(MODshared
| MODconst
, MODwildconst
):
2942 case X(MODshared
| MODwild
, 0):
2943 case X(MODshared
| MODwild
, MODconst
):
2944 case X(MODshared
| MODwild
, MODwild
):
2945 case X(MODshared
| MODwild
, MODwildconst
):
2946 case X(MODshared
| MODwild
, MODimmutable
):
2947 case X(MODshared
| MODwild
, MODshared
):
2948 case X(MODshared
| MODwild
, MODshared
| MODconst
):
2949 case X(MODshared
| MODwild
, MODshared
| MODwildconst
):
2950 case X(MODshared
| MODwildconst
, 0):
2951 case X(MODshared
| MODwildconst
, MODconst
):
2952 case X(MODshared
| MODwildconst
, MODwild
):
2953 case X(MODshared
| MODwildconst
, MODwildconst
):
2954 case X(MODshared
| MODwildconst
, MODshared
):
2955 case X(MODshared
| MODwildconst
, MODshared
| MODconst
):
2956 case X(MODimmutable
, 0):
2957 case X(MODimmutable
, MODconst
):
2958 case X(MODimmutable
, MODwild
):
2959 case X(MODimmutable
, MODwildconst
):
2960 case X(MODimmutable
, MODshared
):
2961 case X(MODimmutable
, MODshared
| MODconst
):
2962 case X(MODimmutable
, MODshared
| MODwild
):
2963 case X(MODimmutable
, MODshared
| MODwildconst
):
2964 // foo(inout(U)) T => nomatch
2965 // foo(inout(U)) const(T) => nomatch
2966 // foo(inout(U)) inout(const(T)) => nomatch
2967 // foo(inout(U)) immutable(T) => nomatch
2968 // foo(inout(U)) shared(T) => nomatch
2969 // foo(inout(U)) shared(const(T)) => nomatch
2970 // foo(inout(U)) shared(inout(const(T))) => nomatch
2971 // foo(inout(const(U))) T => nomatch
2972 // foo(inout(const(U))) const(T) => nomatch
2973 // foo(inout(const(U))) inout(T) => nomatch
2974 // foo(inout(const(U))) shared(T) => nomatch
2975 // foo(inout(const(U))) shared(const(T)) => nomatch
2976 // foo(inout(const(U))) shared(inout(T)) => nomatch
2977 // foo(shared(U)) T => nomatch
2978 // foo(shared(U)) const(T) => nomatch
2979 // foo(shared(U)) inout(T) => nomatch
2980 // foo(shared(U)) inout(const(T)) => nomatch
2981 // foo(shared(U)) immutable(T) => nomatch
2982 // foo(shared(const(U))) T => nomatch
2983 // foo(shared(const(U))) const(T) => nomatch
2984 // foo(shared(const(U))) inout(T) => nomatch
2985 // foo(shared(const(U))) inout(const(T)) => nomatch
2986 // foo(shared(inout(U))) T => nomatch
2987 // foo(shared(inout(U))) const(T) => nomatch
2988 // foo(shared(inout(U))) inout(T) => nomatch
2989 // foo(shared(inout(U))) inout(const(T)) => nomatch
2990 // foo(shared(inout(U))) immutable(T) => nomatch
2991 // foo(shared(inout(U))) shared(T) => nomatch
2992 // foo(shared(inout(U))) shared(const(T)) => nomatch
2993 // foo(shared(inout(U))) shared(inout(const(T))) => nomatch
2994 // foo(shared(inout(const(U)))) T => nomatch
2995 // foo(shared(inout(const(U)))) const(T) => nomatch
2996 // foo(shared(inout(const(U)))) inout(T) => nomatch
2997 // foo(shared(inout(const(U)))) inout(const(T)) => nomatch
2998 // foo(shared(inout(const(U)))) shared(T) => nomatch
2999 // foo(shared(inout(const(U)))) shared(const(T)) => nomatch
3000 // foo(immutable(U)) T => nomatch
3001 // foo(immutable(U)) const(T) => nomatch
3002 // foo(immutable(U)) inout(T) => nomatch
3003 // foo(immutable(U)) inout(const(T)) => nomatch
3004 // foo(immutable(U)) shared(T) => nomatch
3005 // foo(immutable(U)) shared(const(T)) => nomatch
3006 // foo(immutable(U)) shared(inout(T)) => nomatch
3007 // foo(immutable(U)) shared(inout(const(T))) => nomatch
3008 return MATCHnomatch
;
3012 return MATCHnomatch
; // silence compiler warning about missing return
3017 /* These form the heart of template argument deduction.
3018 * Given 'this' being the type argument to the template instance,
3019 * it is matched against the template declaration parameter specialization
3020 * 'tparam' to determine the type to be used for the parameter.
3022 * template Foo(T:T*) // template declaration
3023 * Foo!(int*) // template instantiation
3027 * parameters = [ T:T* ] // Array of TemplateParameter's
3029 * dedtypes = [ int ] // Array of Expression/Type's
3031 MATCH
deduceType(RootObject
*o
, Scope
*sc
, Type
*tparam
, TemplateParameters
*parameters
,
3032 Objects
*dedtypes
, unsigned *wm
, size_t inferStart
)
3034 class DeduceType
: public Visitor
3039 TemplateParameters
*parameters
;
3045 DeduceType(Scope
*sc
, Type
*tparam
, TemplateParameters
*parameters
, Objects
*dedtypes
, unsigned *wm
, size_t inferStart
)
3046 : sc(sc
), tparam(tparam
), parameters(parameters
), dedtypes(dedtypes
), wm(wm
), inferStart(inferStart
)
3048 result
= MATCHnomatch
;
3059 if (tparam
->ty
== Tident
)
3061 // Determine which parameter tparam is
3062 size_t i
= templateParameterLookup(tparam
, parameters
);
3063 if (i
== IDX_NOTFOUND
)
3068 /* Need a loc to go with the semantic routine.
3071 if (parameters
->length
)
3073 TemplateParameter
*tp
= (*parameters
)[0];
3077 /* BUG: what if tparam is a template instance, that
3078 * has as an argument another Tident?
3080 tparam
= typeSemantic(tparam
, loc
, sc
);
3081 assert(tparam
->ty
!= Tident
);
3082 result
= deduceType(t
, sc
, tparam
, parameters
, dedtypes
, wm
);
3086 TemplateParameter
*tp
= (*parameters
)[i
];
3088 TypeIdentifier
*tident
= (TypeIdentifier
*)tparam
;
3089 if (tident
->idents
.length
> 0)
3091 //printf("matching %s to %s\n", tparam->toChars(), t->toChars());
3092 Dsymbol
*s
= t
->toDsymbol(sc
);
3093 for (size_t j
= tident
->idents
.length
; j
-- > 0; )
3095 RootObject
*id
= tident
->idents
[j
];
3096 if (id
->dyncast() == DYNCAST_IDENTIFIER
)
3098 if (!s
|| !s
->parent
)
3100 Dsymbol
*s2
= s
->parent
->search(Loc(), (Identifier
*)id
);
3104 //printf("[%d] s = %s %s, s2 = %s %s\n", j, s->kind(), s->toChars(), s2->kind(), s2->toChars());
3107 if (Type
*tx
= s2
->getType())
3109 if (s
!= tx
->toDsymbol(sc
))
3120 //printf("[e] s = %s\n", s?s->toChars():"(null)");
3121 if (tp
->isTemplateTypeParameter())
3123 Type
*tt
= s
->getType();
3126 Type
*at
= (Type
*)(*dedtypes
)[i
];
3127 if (at
&& at
->ty
== Tnone
)
3128 at
= ((TypeDeduced
*)at
)->tded
;
3129 if (!at
|| tt
->equals(at
))
3131 (*dedtypes
)[i
] = tt
;
3135 if (tp
->isTemplateAliasParameter())
3137 Dsymbol
*s2
= (Dsymbol
*)(*dedtypes
)[i
];
3147 // Found the corresponding parameter tp
3148 if (!tp
->isTemplateTypeParameter())
3151 Type
*at
= (Type
*)(*dedtypes
)[i
];
3153 if (unsigned char wx
= wm
? deduceWildHelper(t
, &tt
, tparam
) : 0)
3158 (*dedtypes
)[i
] = tt
;
3160 result
= MATCHconst
;
3164 // type vs expressions
3165 if (at
->ty
== Tnone
)
3167 TypeDeduced
*xt
= (TypeDeduced
*)at
;
3168 result
= xt
->matchAll(tt
);
3169 if (result
> MATCHnomatch
)
3171 (*dedtypes
)[i
] = tt
;
3172 if (result
> MATCHconst
)
3173 result
= MATCHconst
; // limit level for inout matches
3182 (*dedtypes
)[i
] = tt
; // Prefer current type match
3185 if (tt
->implicitConvTo(at
->constOf()))
3187 (*dedtypes
)[i
] = at
->constOf()->mutableOf();
3191 if (at
->implicitConvTo(tt
->constOf()))
3193 (*dedtypes
)[i
] = tt
->constOf()->mutableOf();
3199 else if (MATCH m
= deduceTypeHelper(t
, &tt
, tparam
))
3204 (*dedtypes
)[i
] = tt
;
3209 // type vs expressions
3210 if (at
->ty
== Tnone
)
3212 TypeDeduced
*xt
= (TypeDeduced
*)at
;
3213 result
= xt
->matchAll(tt
);
3214 if (result
> MATCHnomatch
)
3216 (*dedtypes
)[i
] = tt
;
3227 if (tt
->ty
== Tclass
&& at
->ty
== Tclass
)
3229 result
= tt
->implicitConvTo(at
);
3232 if (tt
->ty
== Tsarray
&& at
->ty
== Tarray
&&
3233 tt
->nextOf()->implicitConvTo(at
->nextOf()) >= MATCHconst
)
3241 if (tparam
->ty
== Ttypeof
)
3243 /* Need a loc to go with the semantic routine.
3246 if (parameters
->length
)
3248 TemplateParameter
*tp
= (*parameters
)[0];
3252 tparam
= typeSemantic(tparam
, loc
, sc
);
3254 if (t
->ty
!= tparam
->ty
)
3256 if (Dsymbol
*sym
= t
->toDsymbol(sc
))
3258 if (sym
->isforwardRef() && !tparam
->deco
)
3262 MATCH m
= t
->implicitConvTo(tparam
);
3263 if (m
== MATCHnomatch
)
3265 if (t
->ty
== Tclass
)
3267 TypeClass
*tc
= (TypeClass
*)t
;
3268 if (tc
->sym
->aliasthis
&& !(tc
->att
& RECtracingDT
))
3270 tc
->att
= (AliasThisRec
)(tc
->att
| RECtracingDT
);
3271 m
= deduceType(t
->aliasthisOf(), sc
, tparam
, parameters
, dedtypes
, wm
);
3272 tc
->att
= (AliasThisRec
)(tc
->att
& ~RECtracingDT
);
3275 else if (t
->ty
== Tstruct
)
3277 TypeStruct
*ts
= (TypeStruct
*)t
;
3278 if (ts
->sym
->aliasthis
&& !(ts
->att
& RECtracingDT
))
3280 ts
->att
= (AliasThisRec
)(ts
->att
| RECtracingDT
);
3281 m
= deduceType(t
->aliasthisOf(), sc
, tparam
, parameters
, dedtypes
, wm
);
3282 ts
->att
= (AliasThisRec
)(ts
->att
& ~RECtracingDT
);
3292 if (tparam
->deco
&& !tparam
->hasWild())
3294 result
= t
->implicitConvTo(tparam
);
3298 Type
*tpn
= tparam
->nextOf();
3299 if (wm
&& t
->ty
== Taarray
&& tparam
->isWild())
3301 // Bugzilla 12403: In IFTI, stop inout matching on transitive part of AA types.
3302 tpn
= tpn
->substWildTo(MODmutable
);
3305 result
= deduceType(t
->nextOf(), sc
, tpn
, parameters
, dedtypes
, wm
);
3310 result
= MATCHexact
;
3314 result
= MATCHnomatch
;
3318 result
= MATCHconst
;
3321 void visit(TypeVector
*t
)
3323 if (tparam
->ty
== Tvector
)
3325 TypeVector
*tp
= (TypeVector
*)tparam
;
3326 result
= deduceType(t
->basetype
, sc
, tp
->basetype
, parameters
, dedtypes
, wm
);
3332 void visit(TypeDArray
*t
)
3337 void visit(TypeSArray
*t
)
3339 // Extra check that array dimensions must match
3342 if (tparam
->ty
== Tarray
)
3344 MATCH m
= deduceType(t
->next
, sc
, tparam
->nextOf(), parameters
, dedtypes
, wm
);
3345 result
= (m
>= MATCHconst
) ? MATCHconvert
: MATCHnomatch
;
3349 TemplateParameter
*tp
= NULL
;
3350 Expression
*edim
= NULL
;
3352 if (tparam
->ty
== Tsarray
)
3354 TypeSArray
*tsa
= (TypeSArray
*)tparam
;
3355 if (tsa
->dim
->op
== TOKvar
&&
3356 ((VarExp
*)tsa
->dim
)->var
->storage_class
& STCtemplateparameter
)
3358 Identifier
*id
= ((VarExp
*)tsa
->dim
)->var
->ident
;
3359 i
= templateIdentifierLookup(id
, parameters
);
3360 assert(i
!= IDX_NOTFOUND
);
3361 tp
= (*parameters
)[i
];
3366 else if (tparam
->ty
== Taarray
)
3368 TypeAArray
*taa
= (TypeAArray
*)tparam
;
3369 i
= templateParameterLookup(taa
->index
, parameters
);
3370 if (i
!= IDX_NOTFOUND
)
3371 tp
= (*parameters
)[i
];
3377 taa
->index
->resolve(Loc(), sc
, &e
, &tx
, &s
);
3378 edim
= s
? getValue(s
) : getValue(e
);
3381 if ((tp
&& tp
->matchArg(sc
, t
->dim
, i
, parameters
, dedtypes
, NULL
)) ||
3382 (edim
&& edim
->toInteger() == t
->dim
->toInteger()))
3384 result
= deduceType(t
->next
, sc
, tparam
->nextOf(), parameters
, dedtypes
, wm
);
3391 result
= MATCHnomatch
;
3394 void visit(TypeAArray
*t
)
3396 // Extra check that index type must match
3397 if (tparam
&& tparam
->ty
== Taarray
)
3399 TypeAArray
*tp
= (TypeAArray
*)tparam
;
3400 if (!deduceType(t
->index
, sc
, tp
->index
, parameters
, dedtypes
))
3402 result
= MATCHnomatch
;
3409 void visit(TypeFunction
*t
)
3411 //printf("TypeFunction::deduceType()\n");
3412 //printf("\tthis = %d, ", t->ty); t->print();
3413 //printf("\ttparam = %d, ", tparam->ty); tparam->print();
3415 // Extra check that function characteristics must match
3416 if (tparam
&& tparam
->ty
== Tfunction
)
3418 TypeFunction
*tp
= (TypeFunction
*)tparam
;
3419 if (t
->parameterList
.varargs
!= tp
->parameterList
.varargs
||
3420 t
->linkage
!= tp
->linkage
)
3422 result
= MATCHnomatch
;
3426 size_t nfargs
= t
->parameterList
.length();
3427 size_t nfparams
= tp
->parameterList
.length();
3429 // bug 2579 fix: Apply function parameter storage classes to parameter types
3430 for (size_t i
= 0; i
< nfparams
; i
++)
3432 Parameter
*fparam
= tp
->parameterList
[i
];
3433 fparam
->type
= fparam
->type
->addStorageClass(fparam
->storageClass
);
3434 fparam
->storageClass
&= ~(STC_TYPECTOR
| STCin
);
3436 //printf("\t-> this = %d, ", t->ty); t->print();
3437 //printf("\t-> tparam = %d, ", tparam->ty); tparam->print();
3439 /* See if tuple match
3441 if (nfparams
> 0 && nfargs
>= nfparams
- 1)
3443 /* See if 'A' of the template parameter matches 'A'
3444 * of the type of the last function parameter.
3446 Parameter
*fparam
= tp
->parameterList
[nfparams
- 1];
3448 assert(fparam
->type
);
3449 if (fparam
->type
->ty
!= Tident
)
3451 TypeIdentifier
*tid
= (TypeIdentifier
*)fparam
->type
;
3452 if (tid
->idents
.length
)
3455 /* Look through parameters to find tuple matching tid->ident
3460 if (tupi
== parameters
->length
)
3462 TemplateParameter
*tx
= (*parameters
)[tupi
];
3463 TemplateTupleParameter
*tup
= tx
->isTemplateTupleParameter();
3464 if (tup
&& tup
->ident
->equals(tid
->ident
))
3468 /* The types of the function arguments [nfparams - 1 .. nfargs]
3469 * now form the tuple argument.
3471 size_t tuple_dim
= nfargs
- (nfparams
- 1);
3473 /* See if existing tuple, and whether it matches or not
3475 RootObject
*o
= (*dedtypes
)[tupi
];
3478 // Existing deduced argument must be a tuple, and must match
3479 Tuple
*tup
= isTuple(o
);
3480 if (!tup
|| tup
->objects
.length
!= tuple_dim
)
3482 result
= MATCHnomatch
;
3485 for (size_t i
= 0; i
< tuple_dim
; i
++)
3487 Parameter
*arg
= t
->parameterList
[nfparams
- 1 + i
];
3488 if (!arg
->type
->equals(tup
->objects
[i
]))
3490 result
= MATCHnomatch
;
3498 Tuple
*tup
= new Tuple();
3499 tup
->objects
.setDim(tuple_dim
);
3500 for (size_t i
= 0; i
< tuple_dim
; i
++)
3502 Parameter
*arg
= t
->parameterList
[nfparams
- 1 + i
];
3503 tup
->objects
[i
] = arg
->type
;
3505 (*dedtypes
)[tupi
] = tup
;
3507 nfparams
--; // don't consider the last parameter for type deduction
3512 if (nfargs
!= nfparams
)
3514 result
= MATCHnomatch
;
3518 for (size_t i
= 0; i
< nfparams
; i
++)
3520 Parameter
*a
= t
->parameterList
[i
];
3521 Parameter
*ap
= tp
->parameterList
[i
];
3523 if (!a
->isCovariant(t
->isref
, ap
) ||
3524 !deduceType(a
->type
, sc
, ap
->type
, parameters
, dedtypes
))
3526 result
= MATCHnomatch
;
3534 void visit(TypeIdentifier
*t
)
3537 if (tparam
&& tparam
->ty
== Tident
)
3539 TypeIdentifier
*tp
= (TypeIdentifier
*)tparam
;
3541 for (size_t i
= 0; i
< t
->idents
.length
; i
++)
3543 RootObject
*id1
= t
->idents
[i
];
3544 RootObject
*id2
= tp
->idents
[i
];
3546 if (!id1
->equals(id2
))
3548 result
= MATCHnomatch
;
3556 void visit(TypeInstance
*t
)
3559 if (tparam
&& tparam
->ty
== Tinstance
&& t
->tempinst
->tempdecl
)
3561 TemplateDeclaration
*tempdecl
= t
->tempinst
->tempdecl
->isTemplateDeclaration();
3564 TypeInstance
*tp
= (TypeInstance
*)tparam
;
3566 //printf("tempinst->tempdecl = %p\n", tempdecl);
3567 //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl);
3568 if (!tp
->tempinst
->tempdecl
)
3570 //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars());
3573 * template Foo(T : sa!(T), alias sa)
3575 size_t i
= templateIdentifierLookup(tp
->tempinst
->name
, parameters
);
3576 if (i
== IDX_NOTFOUND
)
3578 /* Didn't find it as a parameter identifier. Try looking
3579 * it up and seeing if is an alias. See Bugzilla 1454
3581 TypeIdentifier
*tid
= new TypeIdentifier(tp
->loc
, tp
->tempinst
->name
);
3585 tid
->resolve(tp
->loc
, sc
, &e
, &tx
, &s
);
3588 s
= tx
->toDsymbol(sc
);
3589 if (TemplateInstance
*ti
= s
? s
->parent
->isTemplateInstance() : NULL
)
3591 // Bugzilla 14290: Try to match with ti->tempecl,
3592 // only when ti is an enclosing instance.
3593 Dsymbol
*p
= sc
->parent
;
3594 while (p
&& p
!= ti
)
3603 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
3608 for (; td
; td
= td
->overnext
)
3617 TemplateParameter
*tpx
= (*parameters
)[i
];
3618 if (!tpx
->matchArg(sc
, tempdecl
, i
, parameters
, dedtypes
, NULL
))
3621 else if (tempdecl
!= tp
->tempinst
->tempdecl
)
3626 for (size_t i
= 0; 1; i
++)
3628 //printf("\ttest: tempinst->tiargs[%d]\n", i);
3629 RootObject
*o1
= NULL
;
3630 if (i
< t
->tempinst
->tiargs
->length
)
3631 o1
= (*t
->tempinst
->tiargs
)[i
];
3632 else if (i
< t
->tempinst
->tdtypes
.length
&& i
< tp
->tempinst
->tiargs
->length
)
3634 // Pick up default arg
3635 o1
= t
->tempinst
->tdtypes
[i
];
3637 else if (i
>= tp
->tempinst
->tiargs
->length
)
3640 if (i
>= tp
->tempinst
->tiargs
->length
)
3642 size_t dim
= tempdecl
->parameters
->length
- (tempdecl
->isVariadic() ? 1 : 0);
3643 while (i
< dim
&& ((*tempdecl
->parameters
)[i
]->dependent
||
3644 (*tempdecl
->parameters
)[i
]->hasDefaultArg()))
3649 break; // match if all remained parameters are dependent
3653 RootObject
*o2
= (*tp
->tempinst
->tiargs
)[i
];
3654 Type
*t2
= isType(o2
);
3656 size_t j
= (t2
&& t2
->ty
== Tident
&& i
== tp
->tempinst
->tiargs
->length
- 1)
3657 ? templateParameterLookup(t2
, parameters
) : IDX_NOTFOUND
;
3658 if (j
!= IDX_NOTFOUND
&& j
== parameters
->length
- 1 &&
3659 (*parameters
)[j
]->isTemplateTupleParameter())
3663 * alias A!(int, float) X;
3664 * static if (is(X Y == A!(Z), Z...)) {}
3665 * deduce that Z is a tuple(int, float)
3668 /* Create tuple from remaining args
3670 Tuple
*vt
= new Tuple();
3671 size_t vtdim
= (tempdecl
->isVariadic()
3672 ? t
->tempinst
->tiargs
->length
: t
->tempinst
->tdtypes
.length
) - i
;
3673 vt
->objects
.setDim(vtdim
);
3674 for (size_t k
= 0; k
< vtdim
; k
++)
3677 if (k
< t
->tempinst
->tiargs
->length
)
3678 o
= (*t
->tempinst
->tiargs
)[i
+ k
];
3679 else // Pick up default arg
3680 o
= t
->tempinst
->tdtypes
[i
+ k
];
3684 Tuple
*v
= (Tuple
*)(*dedtypes
)[j
];
3691 (*dedtypes
)[j
] = vt
;
3697 Type
*t1
= isType(o1
);
3698 Dsymbol
*s1
= isDsymbol(o1
);
3699 Dsymbol
*s2
= isDsymbol(o2
);
3700 Expression
*e1
= s1
? getValue(s1
) : getValue(isExpression(o1
));
3701 Expression
*e2
= isExpression(o2
);
3705 if (!deduceType(t1
, sc
, t2
, parameters
, dedtypes
))
3711 e1
= e1
->ctfeInterpret();
3713 /* If it is one of the template parameters for this template,
3714 * we should not attempt to interpret it. It already has a value.
3716 if (e2
->op
== TOKvar
&&
3717 (((VarExp
*)e2
)->var
->storage_class
& STCtemplateparameter
))
3720 * (T:Number!(e2), int e2)
3722 j
= templateIdentifierLookup(((VarExp
*)e2
)->var
->ident
, parameters
);
3723 if (j
!= IDX_NOTFOUND
)
3725 // The template parameter was not from this template
3726 // (it may be from a parent template, for example)
3729 e2
= expressionSemantic(e2
, sc
); // Bugzilla 13417
3730 e2
= e2
->ctfeInterpret();
3732 //printf("e1 = %s, type = %s %d\n", e1->toChars(), e1->type->toChars(), e1->type->ty);
3733 //printf("e2 = %s, type = %s %d\n", e2->toChars(), e2->type->toChars(), e2->type->ty);
3734 if (!e1
->equals(e2
))
3736 if (!e2
->implicitConvTo(e1
->type
))
3739 e2
= e2
->implicitCastTo(sc
, e1
->type
);
3740 e2
= e2
->ctfeInterpret();
3741 if (!e1
->equals(e2
))
3745 else if (e1
&& t2
&& t2
->ty
== Tident
)
3747 j
= templateParameterLookup(t2
, parameters
);
3749 if (j
== IDX_NOTFOUND
)
3751 t2
->resolve(((TypeIdentifier
*)t2
)->loc
, sc
, &e2
, &t2
, &s2
);
3756 if (!(*parameters
)[j
]->matchArg(sc
, e1
, j
, parameters
, dedtypes
, NULL
))
3762 if (!s1
->equals(s2
))
3765 else if (s1
&& t2
&& t2
->ty
== Tident
)
3767 j
= templateParameterLookup(t2
, parameters
);
3768 if (j
== IDX_NOTFOUND
)
3770 t2
->resolve(((TypeIdentifier
*)t2
)->loc
, sc
, &e2
, &t2
, &s2
);
3775 if (!(*parameters
)[j
]->matchArg(sc
, s1
, j
, parameters
, dedtypes
, NULL
))
3786 //printf("no match\n");
3787 result
= MATCHnomatch
;
3790 void visit(TypeStruct
*t
)
3792 /* If this struct is a template struct, and we're matching
3793 * it against a template instance, convert the struct type
3794 * to a template instance, too, and try again.
3796 TemplateInstance
*ti
= t
->sym
->parent
->isTemplateInstance();
3798 if (tparam
&& tparam
->ty
== Tinstance
)
3800 if (ti
&& ti
->toAlias() == t
->sym
)
3802 TypeInstance
*tx
= new TypeInstance(Loc(), ti
);
3803 result
= deduceType(tx
, sc
, tparam
, parameters
, dedtypes
, wm
);
3807 /* Match things like:
3810 TypeInstance
*tpi
= (TypeInstance
*)tparam
;
3811 if (tpi
->idents
.length
)
3813 RootObject
*id
= tpi
->idents
[tpi
->idents
.length
- 1];
3814 if (id
->dyncast() == DYNCAST_IDENTIFIER
&& t
->sym
->ident
->equals((Identifier
*)id
))
3816 Type
*tparent
= t
->sym
->parent
->getType();
3819 /* Slice off the .foo in S!(T).foo
3821 tpi
->idents
.length
--;
3822 result
= deduceType(tparent
, sc
, tpi
, parameters
, dedtypes
, wm
);
3823 tpi
->idents
.length
++;
3831 if (tparam
&& tparam
->ty
== Tstruct
)
3833 TypeStruct
*tp
= (TypeStruct
*)tparam
;
3835 //printf("\t%d\n", (MATCH) t->implicitConvTo(tp));
3836 if (wm
&& t
->deduceWild(tparam
, false))
3838 result
= MATCHconst
;
3841 result
= t
->implicitConvTo(tp
);
3847 void visit(TypeEnum
*t
)
3850 if (tparam
&& tparam
->ty
== Tenum
)
3852 TypeEnum
*tp
= (TypeEnum
*)tparam
;
3853 if (t
->sym
== tp
->sym
)
3856 result
= MATCHnomatch
;
3859 Type
*tb
= t
->toBasetype();
3860 if (tb
->ty
== tparam
->ty
||
3861 (tb
->ty
== Tsarray
&& tparam
->ty
== Taarray
))
3863 result
= deduceType(tb
, sc
, tparam
, parameters
, dedtypes
, wm
);
3869 /* Helper for TypeClass::deduceType().
3870 * Classes can match with implicit conversion to a base class or interface.
3871 * This is complicated, because there may be more than one base class which
3872 * matches. In such cases, one or more parameters remain ambiguous.
3875 * interface I(X, Y) {}
3876 * class C : I(uint, double), I(char, double) {}
3878 * foo(T, U)( I!(T, U) x)
3880 * deduces that U is double, but T remains ambiguous (could be char or uint).
3882 * Given a baseclass b, and initial deduced types 'dedtypes', this function
3883 * tries to match tparam with b, and also tries all base interfaces of b.
3884 * If a match occurs, numBaseClassMatches is incremented, and the new deduced
3885 * types are ANDed with the current 'best' estimate for dedtypes.
3887 static void deduceBaseClassParameters(BaseClass
*b
,
3888 Scope
*sc
, Type
*tparam
, TemplateParameters
*parameters
, Objects
*dedtypes
,
3889 Objects
*best
, int &numBaseClassMatches
)
3891 TemplateInstance
*parti
= b
->sym
? b
->sym
->parent
->isTemplateInstance() : NULL
;
3894 // Make a temporary copy of dedtypes so we don't destroy it
3895 Objects
*tmpdedtypes
= new Objects();
3896 tmpdedtypes
->setDim(dedtypes
->length
);
3897 memcpy(tmpdedtypes
->tdata(), dedtypes
->tdata(), dedtypes
->length
* sizeof(void *));
3899 TypeInstance
*t
= new TypeInstance(Loc(), parti
);
3900 MATCH m
= deduceType(t
, sc
, tparam
, parameters
, tmpdedtypes
);
3901 if (m
> MATCHnomatch
)
3903 // If this is the first ever match, it becomes our best estimate
3904 if (numBaseClassMatches
==0)
3905 memcpy(best
->tdata(), tmpdedtypes
->tdata(), tmpdedtypes
->length
* sizeof(void *));
3906 else for (size_t k
= 0; k
< tmpdedtypes
->length
; ++k
)
3908 // If we've found more than one possible type for a parameter,
3909 // mark it as unknown.
3910 if ((*tmpdedtypes
)[k
] != (*best
)[k
])
3911 (*best
)[k
] = (*dedtypes
)[k
];
3913 ++numBaseClassMatches
;
3916 // Now recursively test the inherited interfaces
3917 for (size_t j
= 0; j
< b
->baseInterfaces
.length
; ++j
)
3919 BaseClass
*bi
= &b
->baseInterfaces
.ptr
[j
];
3920 deduceBaseClassParameters(bi
,
3921 sc
, tparam
, parameters
, dedtypes
,
3922 best
, numBaseClassMatches
);
3927 void visit(TypeClass
*t
)
3929 //printf("TypeClass::deduceType(this = %s)\n", t->toChars());
3931 /* If this class is a template class, and we're matching
3932 * it against a template instance, convert the class type
3933 * to a template instance, too, and try again.
3935 TemplateInstance
*ti
= t
->sym
->parent
->isTemplateInstance();
3937 if (tparam
&& tparam
->ty
== Tinstance
)
3939 if (ti
&& ti
->toAlias() == t
->sym
)
3941 TypeInstance
*tx
= new TypeInstance(Loc(), ti
);
3942 MATCH m
= deduceType(tx
, sc
, tparam
, parameters
, dedtypes
, wm
);
3943 // Even if the match fails, there is still a chance it could match
3945 if (m
!= MATCHnomatch
)
3952 /* Match things like:
3955 TypeInstance
*tpi
= (TypeInstance
*)tparam
;
3956 if (tpi
->idents
.length
)
3958 RootObject
*id
= tpi
->idents
[tpi
->idents
.length
- 1];
3959 if (id
->dyncast() == DYNCAST_IDENTIFIER
&& t
->sym
->ident
->equals((Identifier
*)id
))
3961 Type
*tparent
= t
->sym
->parent
->getType();
3964 /* Slice off the .foo in S!(T).foo
3966 tpi
->idents
.length
--;
3967 result
= deduceType(tparent
, sc
, tpi
, parameters
, dedtypes
, wm
);
3968 tpi
->idents
.length
++;
3974 // If it matches exactly or via implicit conversion, we're done
3976 if (result
!= MATCHnomatch
)
3979 /* There is still a chance to match via implicit conversion to
3980 * a base class or interface. Because there could be more than one such
3981 * match, we need to check them all.
3984 int numBaseClassMatches
= 0; // Have we found an interface match?
3986 // Our best guess at dedtypes
3987 Objects
*best
= new Objects();
3988 best
->setDim(dedtypes
->length
);
3990 ClassDeclaration
*s
= t
->sym
;
3991 while (s
&& s
->baseclasses
->length
> 0)
3993 // Test the base class
3994 deduceBaseClassParameters((*s
->baseclasses
)[0],
3995 sc
, tparam
, parameters
, dedtypes
,
3996 best
, numBaseClassMatches
);
3998 // Test the interfaces inherited by the base class
3999 for (size_t i
= 0; i
< s
->interfaces
.length
; ++i
)
4001 BaseClass
*b
= s
->interfaces
.ptr
[i
];
4002 deduceBaseClassParameters(b
, sc
, tparam
, parameters
, dedtypes
,
4003 best
, numBaseClassMatches
);
4005 s
= (*s
->baseclasses
)[0]->sym
;
4008 if (numBaseClassMatches
== 0)
4010 result
= MATCHnomatch
;
4014 // If we got at least one match, copy the known types into dedtypes
4015 memcpy(dedtypes
->tdata(), best
->tdata(), best
->length
* sizeof(void *));
4016 result
= MATCHconvert
;
4021 if (tparam
&& tparam
->ty
== Tclass
)
4023 TypeClass
*tp
= (TypeClass
*)tparam
;
4025 //printf("\t%d\n", (MATCH) t->implicitConvTo(tp));
4026 if (wm
&& t
->deduceWild(tparam
, false))
4028 result
= MATCHconst
;
4031 result
= t
->implicitConvTo(tp
);
4037 void visit(Expression
*e
)
4039 //printf("Expression::deduceType(e = %s)\n", e->toChars());
4040 size_t i
= templateParameterLookup(tparam
, parameters
);
4041 if (i
== IDX_NOTFOUND
|| ((TypeIdentifier
*)tparam
)->idents
.length
> 0)
4043 if (e
== emptyArrayElement
&& tparam
->ty
== Tarray
)
4045 Type
*tn
= ((TypeNext
*)tparam
)->next
;
4046 result
= deduceType(emptyArrayElement
, sc
, tn
, parameters
, dedtypes
, wm
);
4049 e
->type
->accept(this);
4053 TemplateTypeParameter
*tp
= (*parameters
)[i
]->isTemplateTypeParameter();
4057 if (e
== emptyArrayElement
)
4061 result
= MATCHexact
;
4064 if (tp
->defaultType
)
4066 tp
->defaultType
->accept(this);
4071 Type
*at
= (Type
*)(*dedtypes
)[i
];
4073 if (unsigned char wx
= deduceWildHelper(e
->type
, &tt
, tparam
))
4076 result
= MATCHconst
;
4078 else if (MATCH m
= deduceTypeHelper(e
->type
, &tt
, tparam
))
4085 // expression vs (none)
4088 (*dedtypes
)[i
] = new TypeDeduced(tt
, e
, tparam
);
4092 TypeDeduced
*xt
= NULL
;
4093 if (at
->ty
== Tnone
)
4095 xt
= (TypeDeduced
*)at
;
4099 // From previous matched expressions to current deduced type
4100 MATCH match1
= xt
? xt
->matchAll(tt
) : MATCHnomatch
;
4102 // From current expresssion to previous deduced type
4103 Type
*pt
= at
->addMod(tparam
->mod
);
4105 pt
= pt
->substWildTo(*wm
);
4106 MATCH match2
= e
->implicitConvTo(pt
);
4108 if (match1
> MATCHnomatch
&& match2
> MATCHnomatch
)
4110 if (at
->implicitConvTo(tt
) <= MATCHnomatch
)
4111 match1
= MATCHnomatch
; // Prefer at
4112 else if (tt
->implicitConvTo(at
) <= MATCHnomatch
)
4113 match2
= MATCHnomatch
; // Prefer tt
4114 else if (tt
->isTypeBasic() && tt
->ty
== at
->ty
&& tt
->mod
!= at
->mod
)
4116 if (!tt
->isMutable() && !at
->isMutable())
4117 tt
= tt
->mutableOf()->addMod(MODmerge(tt
->mod
, at
->mod
));
4118 else if (tt
->isMutable())
4120 if (at
->mod
== 0) // Prefer unshared
4121 match1
= MATCHnomatch
;
4123 match2
= MATCHnomatch
;
4125 else if (at
->isMutable())
4127 if (tt
->mod
== 0) // Prefer unshared
4128 match2
= MATCHnomatch
;
4130 match1
= MATCHnomatch
;
4132 //printf("tt = %s, at = %s\n", tt->toChars(), at->toChars());
4136 match1
= MATCHnomatch
;
4137 match2
= MATCHnomatch
;
4140 if (match1
> MATCHnomatch
)
4142 // Prefer current match: tt
4144 xt
->update(tt
, e
, tparam
);
4146 (*dedtypes
)[i
] = tt
;
4150 if (match2
> MATCHnomatch
)
4152 // Prefer previous match: (*dedtypes)[i]
4154 xt
->update(e
, tparam
);
4159 /* Deduce common type
4161 if (Type
*t
= rawTypeMerge(at
, tt
))
4164 xt
->update(t
, e
, tparam
);
4168 pt
= tt
->addMod(tparam
->mod
);
4170 pt
= pt
->substWildTo(*wm
);
4171 result
= e
->implicitConvTo(pt
);
4175 result
= MATCHnomatch
;
4178 MATCH
deduceEmptyArrayElement()
4180 if (!emptyArrayElement
)
4182 emptyArrayElement
= new IdentifierExp(Loc(), Id::p
); // dummy
4183 emptyArrayElement
->type
= Type::tvoid
;
4185 assert(tparam
->ty
== Tarray
);
4187 Type
*tn
= ((TypeNext
*)tparam
)->next
;
4188 return deduceType(emptyArrayElement
, sc
, tn
, parameters
, dedtypes
, wm
);
4191 void visit(NullExp
*e
)
4193 if (tparam
->ty
== Tarray
&& e
->type
->ty
== Tnull
)
4195 // tparam:T[] <- e:null (void[])
4196 result
= deduceEmptyArrayElement();
4199 visit((Expression
*)e
);
4202 void visit(StringExp
*e
)
4205 if (e
->type
->ty
== Tarray
&&
4206 (tparam
->ty
== Tsarray
||
4207 (tparam
->ty
== Taarray
&& (taai
= ((TypeAArray
*)tparam
)->index
)->ty
== Tident
&&
4208 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
4210 // Consider compile-time known boundaries
4211 e
->type
->nextOf()->sarrayOf(e
->len
)->accept(this);
4214 visit((Expression
*)e
);
4217 void visit(ArrayLiteralExp
*e
)
4219 // https://issues.dlang.org/show_bug.cgi?id=20092
4220 if (e
->elements
&& e
->elements
->length
&&
4221 e
->type
->toBasetype()->nextOf()->ty
== Tvoid
)
4223 result
= deduceEmptyArrayElement();
4226 if ((!e
->elements
|| !e
->elements
->length
) &&
4227 e
->type
->toBasetype()->nextOf()->ty
== Tvoid
&&
4228 tparam
->ty
== Tarray
)
4230 // tparam:T[] <- e:[] (void[])
4231 result
= deduceEmptyArrayElement();
4235 if (tparam
->ty
== Tarray
&& e
->elements
&& e
->elements
->length
)
4237 Type
*tn
= ((TypeDArray
*)tparam
)->next
;
4238 result
= MATCHexact
;
4241 MATCH m
= deduceType(e
->basis
, sc
, tn
, parameters
, dedtypes
, wm
);
4245 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
4247 if (result
<= MATCHnomatch
)
4249 Expression
*el
= (*e
->elements
)[i
];
4252 MATCH m
= deduceType(el
, sc
, tn
, parameters
, dedtypes
, wm
);
4260 if (e
->type
->ty
== Tarray
&&
4261 (tparam
->ty
== Tsarray
||
4262 (tparam
->ty
== Taarray
&& (taai
= ((TypeAArray
*)tparam
)->index
)->ty
== Tident
&&
4263 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
4265 // Consider compile-time known boundaries
4266 e
->type
->nextOf()->sarrayOf(e
->elements
->length
)->accept(this);
4269 visit((Expression
*)e
);
4272 void visit(AssocArrayLiteralExp
*e
)
4274 if (tparam
->ty
== Taarray
&& e
->keys
&& e
->keys
->length
)
4276 TypeAArray
*taa
= (TypeAArray
*)tparam
;
4277 result
= MATCHexact
;
4278 for (size_t i
= 0; i
< e
->keys
->length
; i
++)
4280 MATCH m1
= deduceType((*e
->keys
)[i
], sc
, taa
->index
, parameters
, dedtypes
, wm
);
4283 if (result
<= MATCHnomatch
)
4285 MATCH m2
= deduceType((*e
->values
)[i
], sc
, taa
->next
, parameters
, dedtypes
, wm
);
4288 if (result
<= MATCHnomatch
)
4293 visit((Expression
*)e
);
4296 void visit(FuncExp
*e
)
4298 //printf("e->type = %s, tparam = %s\n", e->type->toChars(), tparam->toChars());
4302 if (!to
->nextOf() || to
->nextOf()->ty
!= Tfunction
)
4304 TypeFunction
*tof
= (TypeFunction
*)to
->nextOf();
4306 // Parameter types inference from 'tof'
4307 assert(e
->td
->_scope
);
4308 TypeFunction
*tf
= (TypeFunction
*)e
->fd
->type
;
4309 //printf("\ttof = %s\n", tof->toChars());
4310 //printf("\ttf = %s\n", tf->toChars());
4311 size_t dim
= tf
->parameterList
.length();
4313 if (tof
->parameterList
.length() != dim
||
4314 tof
->parameterList
.varargs
!= tf
->parameterList
.varargs
)
4317 Objects
*tiargs
= new Objects();
4318 tiargs
->reserve(e
->td
->parameters
->length
);
4320 for (size_t i
= 0; i
< e
->td
->parameters
->length
; i
++)
4322 TemplateParameter
*tp
= (*e
->td
->parameters
)[i
];
4324 for (; u
< dim
; u
++)
4326 Parameter
*p
= tf
->parameterList
[u
];
4327 if (p
->type
->ty
== Tident
&&
4328 ((TypeIdentifier
*)p
->type
)->ident
== tp
->ident
)
4334 Parameter
*pto
= tof
->parameterList
[u
];
4337 Type
*t
= pto
->type
->syntaxCopy(); // Bugzilla 11774
4338 if (reliesOnTident(t
, parameters
, inferStart
))
4340 t
= typeSemantic(t
, e
->loc
, sc
);
4341 if (t
->ty
== Terror
)
4346 // Set target of return type inference
4347 if (!tf
->next
&& tof
->next
)
4348 e
->fd
->treq
= tparam
;
4350 TemplateInstance
*ti
= new TemplateInstance(e
->loc
, e
->td
, tiargs
);
4351 Expression
*ex
= new ScopeExp(e
->loc
, ti
);
4352 ex
= expressionSemantic(ex
, e
->td
->_scope
);
4354 // Reset inference target for the later re-semantic
4357 if (ex
->op
== TOKerror
)
4359 if (ex
->op
!= TOKfunction
)
4367 if (t
->ty
== Tdelegate
&& tparam
->ty
== Tpointer
)
4370 // Allow conversion from implicit function pointer to delegate
4371 if (e
->tok
== TOKreserved
&&
4372 t
->ty
== Tpointer
&& tparam
->ty
== Tdelegate
)
4374 TypeFunction
*tf
= (TypeFunction
*)t
->nextOf();
4375 t
= (new TypeDelegate(tf
))->merge();
4377 //printf("tparam = %s <= e->type = %s, t = %s\n", tparam->toChars(), e->type->toChars(), t->toChars());
4381 void visit(SliceExp
*e
)
4384 if (e
->type
->ty
== Tarray
&&
4385 (tparam
->ty
== Tsarray
||
4386 (tparam
->ty
== Taarray
&& (taai
= ((TypeAArray
*)tparam
)->index
)->ty
== Tident
&&
4387 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
4389 // Consider compile-time known boundaries
4390 if (Type
*tsa
= toStaticArrayType(e
))
4396 visit((Expression
*)e
);
4399 void visit(CommaExp
*e
)
4401 ((CommaExp
*)e
)->e2
->accept(this);
4405 DeduceType
v(sc
, tparam
, parameters
, dedtypes
, wm
, inferStart
);
4406 if (Type
*t
= isType(o
))
4410 assert(isExpression(o
) && wm
);
4411 ((Expression
*)o
)->accept(&v
);
4416 /*******************************
4418 * t Tested type, if NULL, returns NULL.
4419 * tparams Optional template parameters.
4421 * If one of the subtypes of this type is a TypeIdentifier,
4422 * i.e. it's an unresolved type, return that type.
4424 * Only when the TypeIdentifier is one of template parameters,
4428 bool reliesOnTident(Type
*t
, TemplateParameters
*tparams
, size_t iStart
)
4430 class ReliesOnTident
: public Visitor
4433 TemplateParameters
*tparams
;
4437 ReliesOnTident(TemplateParameters
*tparams
, size_t iStart
)
4438 : tparams(tparams
), iStart(iStart
)
4447 void visit(TypeNext
*t
)
4449 t
->next
->accept(this);
4452 void visit(TypeVector
*t
)
4454 t
->basetype
->accept(this);
4457 void visit(TypeAArray
*t
)
4459 visit((TypeNext
*)t
);
4461 t
->index
->accept(this);
4464 void visit(TypeFunction
*t
)
4466 size_t dim
= t
->parameterList
.length();
4467 for (size_t i
= 0; i
< dim
; i
++)
4469 Parameter
*fparam
= t
->parameterList
[i
];
4470 fparam
->type
->accept(this);
4475 t
->next
->accept(this);
4478 void visit(TypeIdentifier
*t
)
4486 for (size_t i
= iStart
; i
< tparams
->length
; i
++)
4488 TemplateParameter
*tp
= (*tparams
)[i
];
4489 if (tp
->ident
->equals(t
->ident
))
4497 void visit(TypeInstance
*t
)
4502 for (size_t i
= iStart
; i
< tparams
->length
; i
++)
4504 TemplateParameter
*tp
= (*tparams
)[i
];
4505 if (t
->tempinst
->name
== tp
->ident
)
4511 if (!t
->tempinst
->tiargs
)
4513 for (size_t i
= 0; i
< t
->tempinst
->tiargs
->length
; i
++)
4515 Type
*ta
= isType((*t
->tempinst
->tiargs
)[i
]);
4525 void visit(TypeTypeof
*t
)
4527 //printf("TypeTypeof::reliesOnTident('%s')\n", t->toChars());
4528 t
->exp
->accept(this);
4531 void visit(TypeTuple
*t
)
4535 for (size_t i
= 0; i
< t
->arguments
->length
; i
++)
4537 Parameter
*arg
= (*t
->arguments
)[i
];
4538 arg
->type
->accept(this);
4545 void visit(Expression
*)
4547 //printf("Expression::reliesOnTident('%s')\n", e->toChars());
4550 void visit(IdentifierExp
*e
)
4552 //printf("IdentifierExp::reliesOnTident('%s')\n", e->toChars());
4553 for (size_t i
= iStart
; i
< tparams
->length
; i
++)
4555 TemplateParameter
*tp
= (*tparams
)[i
];
4556 if (e
->ident
== tp
->ident
)
4564 void visit(TupleExp
*e
)
4566 //printf("TupleExp::reliesOnTident('%s')\n", e->toChars());
4569 for (size_t i
= 0; i
< e
->exps
->length
; i
++)
4571 Expression
*ea
= (*e
->exps
)[i
];
4579 void visit(ArrayLiteralExp
*e
)
4581 //printf("ArrayLiteralExp::reliesOnTident('%s')\n", e->toChars());
4584 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
4586 Expression
*el
= (*e
->elements
)[i
];
4594 void visit(AssocArrayLiteralExp
*e
)
4596 //printf("AssocArrayLiteralExp::reliesOnTident('%s')\n", e->toChars());
4597 for (size_t i
= 0; i
< e
->keys
->length
; i
++)
4599 Expression
*ek
= (*e
->keys
)[i
];
4604 for (size_t i
= 0; i
< e
->values
->length
; i
++)
4606 Expression
*ev
= (*e
->values
)[i
];
4613 void visit(StructLiteralExp
*e
)
4615 //printf("StructLiteralExp::reliesOnTident('%s')\n", e->toChars());
4618 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
4620 Expression
*ea
= (*e
->elements
)[i
];
4628 void visit(TypeExp
*e
)
4630 //printf("TypeExp::reliesOnTident('%s')\n", e->toChars());
4631 e
->type
->accept(this);
4634 void visit(NewExp
*e
)
4636 //printf("NewExp::reliesOnTident('%s')\n", e->toChars());
4638 e
->thisexp
->accept(this);
4639 if (!result
&& e
->newargs
)
4641 for (size_t i
= 0; i
< e
->newargs
->length
; i
++)
4643 Expression
*ea
= (*e
->newargs
)[i
];
4649 e
->newtype
->accept(this);
4650 if (!result
&& e
->arguments
)
4652 for (size_t i
= 0; i
< e
->arguments
->length
; i
++)
4654 Expression
*ea
= (*e
->arguments
)[i
];
4662 void visit(NewAnonClassExp
*)
4664 //printf("NewAnonClassExp::reliesOnTident('%s')\n", e->toChars());
4668 void visit(FuncExp
*)
4670 //printf("FuncExp::reliesOnTident('%s')\n", e->toChars());
4674 void visit(TypeidExp
*e
)
4676 //printf("TypeidExp::reliesOnTident('%s')\n", e->toChars());
4677 if (Expression
*ea
= isExpression(e
->obj
))
4679 else if (Type
*ta
= isType(e
->obj
))
4683 void visit(TraitsExp
*e
)
4685 //printf("TraitsExp::reliesOnTident('%s')\n", e->toChars());
4688 for (size_t i
= 0; i
< e
->args
->length
; i
++)
4690 RootObject
*oa
= (*e
->args
)[i
];
4691 if (Expression
*ea
= isExpression(oa
))
4693 else if (Type
*ta
= isType(oa
))
4701 void visit(IsExp
*e
)
4703 //printf("IsExp::reliesOnTident('%s')\n", e->toChars());
4704 e
->targ
->accept(this);
4707 void visit(UnaExp
*e
)
4709 //printf("UnaExp::reliesOnTident('%s')\n", e->toChars());
4710 e
->e1
->accept(this);
4713 void visit(DotTemplateInstanceExp
*e
)
4715 //printf("DotTemplateInstanceExp::reliesOnTident('%s')\n", e->toChars());
4717 if (!result
&& e
->ti
->tiargs
)
4719 for (size_t i
= 0; i
< e
->ti
->tiargs
->length
; i
++)
4721 RootObject
*oa
= (*e
->ti
->tiargs
)[i
];
4722 if (Expression
*ea
= isExpression(oa
))
4724 else if (Type
*ta
= isType(oa
))
4732 void visit(CallExp
*e
)
4734 //printf("CallExp::reliesOnTident('%s')\n", e->toChars());
4736 if (!result
&& e
->arguments
)
4738 for (size_t i
= 0; i
< e
->arguments
->length
; i
++)
4740 Expression
*ea
= (*e
->arguments
)[i
];
4748 void visit(CastExp
*e
)
4750 //printf("CastExp::reliesOnTident('%s')\n", e->toChars());
4752 // e.to can be null for cast() with no type
4753 if (!result
&& e
->to
)
4754 e
->to
->accept(this);
4757 void visit(SliceExp
*e
)
4759 //printf("SliceExp::reliesOnTident('%s')\n", e->toChars());
4761 if (!result
&& e
->lwr
)
4762 e
->lwr
->accept(this);
4763 if (!result
&& e
->upr
)
4764 e
->upr
->accept(this);
4767 void visit(IntervalExp
*e
)
4769 //printf("IntervalExp::reliesOnTident('%s')\n", e->toChars());
4770 e
->lwr
->accept(this);
4772 e
->upr
->accept(this);
4775 void visit(ArrayExp
*e
)
4777 //printf("ArrayExp::reliesOnTident('%s')\n", e->toChars());
4779 if (!result
&& e
->arguments
)
4781 for (size_t i
= 0; i
< e
->arguments
->length
; i
++)
4783 Expression
*ea
= (*e
->arguments
)[i
];
4789 void visit(BinExp
*e
)
4791 //printf("BinExp::reliesOnTident('%s')\n", e->toChars());
4792 e
->e1
->accept(this);
4794 e
->e2
->accept(this);
4797 void visit(CondExp
*e
)
4799 //printf("BinExp::reliesOnTident('%s')\n", e->toChars());
4800 e
->econd
->accept(this);
4809 ReliesOnTident
v(tparams
, iStart
);
4814 /* ======================== TemplateParameter =============================== */
4816 TemplateParameter::TemplateParameter(Loc loc
, Identifier
*ident
)
4819 this->ident
= ident
;
4820 this->dependent
= false;
4823 TemplateTypeParameter
*TemplateParameter::isTemplateTypeParameter()
4828 TemplateValueParameter
*TemplateParameter::isTemplateValueParameter()
4833 TemplateAliasParameter
*TemplateParameter::isTemplateAliasParameter()
4838 TemplateTupleParameter
*TemplateParameter::isTemplateTupleParameter()
4843 TemplateThisParameter
*TemplateParameter::isTemplateThisParameter()
4848 /*******************************************
4849 * Match to a particular TemplateParameter.
4851 * instLoc location that the template is instantiated.
4852 * tiargs[] actual arguments to template instance
4854 * parameters[] template parameters
4855 * dedtypes[] deduced arguments to template instance
4856 * *psparam set to symbol declared and initialized to dedtypes[i]
4858 MATCH
TemplateParameter::matchArg(Loc instLoc
, Scope
*sc
, Objects
*tiargs
,
4859 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
4860 Declaration
**psparam
)
4864 if (i
< tiargs
->length
)
4865 oarg
= (*tiargs
)[i
];
4868 // Get default argument instead
4869 oarg
= defaultArg(instLoc
, sc
);
4872 assert(i
< dedtypes
->length
);
4873 // It might have already been deduced
4874 oarg
= (*dedtypes
)[i
];
4879 return matchArg(sc
, oarg
, i
, parameters
, dedtypes
, psparam
);
4884 return MATCHnomatch
;
4887 /* ======================== TemplateTypeParameter =========================== */
4891 Type
*TemplateTypeParameter::tdummy
= NULL
;
4893 TemplateTypeParameter::TemplateTypeParameter(Loc loc
, Identifier
*ident
, Type
*specType
,
4895 : TemplateParameter(loc
, ident
)
4897 this->ident
= ident
;
4898 this->specType
= specType
;
4899 this->defaultType
= defaultType
;
4902 TemplateTypeParameter
*TemplateTypeParameter::isTemplateTypeParameter()
4907 TemplateParameter
*TemplateTypeParameter::syntaxCopy()
4909 return new TemplateTypeParameter(loc
, ident
,
4910 specType
? specType
->syntaxCopy() : NULL
,
4911 defaultType
? defaultType
->syntaxCopy() : NULL
);
4914 bool TemplateTypeParameter::declareParameter(Scope
*sc
)
4916 //printf("TemplateTypeParameter::declareParameter('%s')\n", ident->toChars());
4917 TypeIdentifier
*ti
= new TypeIdentifier(loc
, ident
);
4918 Declaration
*ad
= new AliasDeclaration(loc
, ident
, ti
);
4919 return sc
->insert(ad
) != NULL
;
4922 MATCH
TemplateTypeParameter::matchArg(Scope
*sc
, RootObject
*oarg
,
4923 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
4924 Declaration
**psparam
)
4926 //printf("TemplateTypeParameter::matchArg('%s')\n", ident->toChars());
4927 MATCH m
= MATCHexact
;
4928 Type
*ta
= isType(oarg
);
4931 //printf("%s %p %p %p\n", oarg->toChars(), isExpression(oarg), isDsymbol(oarg), isTuple(oarg));
4934 //printf("ta is %s\n", ta->toChars());
4938 if (!ta
|| ta
== tdummy
)
4941 //printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta->toChars(), specType->toChars());
4942 MATCH m2
= deduceType(ta
, sc
, specType
, parameters
, dedtypes
);
4943 if (m2
<= MATCHnomatch
)
4945 //printf("\tfailed deduceType\n");
4953 Type
*t
= (Type
*)(*dedtypes
)[i
];
4955 if (dependent
&& !t
->equals(ta
)) // Bugzilla 14357
4958 /* This is a self-dependent parameter. For example:
4959 * template X(T : T*) {}
4960 * template X(T : S!T, alias S) {}
4962 //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
4970 // Must match already deduced type
4971 Type
*t
= (Type
*)(*dedtypes
)[i
];
4975 //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
4981 // So that matches with specializations are better
4985 (*dedtypes
)[i
] = ta
;
4988 *psparam
= new AliasDeclaration(loc
, ident
, ta
);
4989 //printf("\tm = %d\n", m);
4990 return dependent
? MATCHexact
: m
;
4995 //printf("\tm = %d\n", MATCHnomatch);
4996 return MATCHnomatch
;
5000 void TemplateTypeParameter::print(RootObject
*oarg
, RootObject
*oded
)
5002 printf(" %s\n", ident
->toChars());
5004 Type
*t
= isType(oarg
);
5005 Type
*ta
= isType(oded
);
5010 printf("\tSpecialization: %s\n", specType
->toChars());
5012 printf("\tDefault: %s\n", defaultType
->toChars());
5013 printf("\tParameter: %s\n", t
? t
->toChars() : "NULL");
5014 printf("\tDeduced Type: %s\n", ta
->toChars());
5017 void *TemplateTypeParameter::dummyArg()
5022 // Use this for alias-parameter's too (?)
5024 tdummy
= new TypeIdentifier(loc
, ident
);
5031 RootObject
*TemplateTypeParameter::specialization()
5036 RootObject
*TemplateTypeParameter::defaultArg(Loc
, Scope
*sc
)
5038 Type
*t
= defaultType
;
5041 t
= t
->syntaxCopy();
5042 t
= typeSemantic(t
, loc
, sc
); // use the parameter loc
5047 bool TemplateTypeParameter::hasDefaultArg()
5049 return defaultType
!= NULL
;
5052 /* ======================== TemplateThisParameter =========================== */
5056 TemplateThisParameter::TemplateThisParameter(Loc loc
, Identifier
*ident
,
5059 : TemplateTypeParameter(loc
, ident
, specType
, defaultType
)
5063 TemplateThisParameter
*TemplateThisParameter::isTemplateThisParameter()
5068 TemplateParameter
*TemplateThisParameter::syntaxCopy()
5070 return new TemplateThisParameter(loc
, ident
,
5071 specType
? specType
->syntaxCopy() : NULL
,
5072 defaultType
? defaultType
->syntaxCopy() : NULL
);
5075 /* ======================== TemplateAliasParameter ========================== */
5079 Dsymbol
*TemplateAliasParameter::sdummy
= NULL
;
5081 TemplateAliasParameter::TemplateAliasParameter(Loc loc
, Identifier
*ident
,
5082 Type
*specType
, RootObject
*specAlias
, RootObject
*defaultAlias
)
5083 : TemplateParameter(loc
, ident
)
5085 this->ident
= ident
;
5086 this->specType
= specType
;
5087 this->specAlias
= specAlias
;
5088 this->defaultAlias
= defaultAlias
;
5091 TemplateAliasParameter
*TemplateAliasParameter::isTemplateAliasParameter()
5096 TemplateParameter
*TemplateAliasParameter::syntaxCopy()
5098 return new TemplateAliasParameter(loc
, ident
,
5099 specType
? specType
->syntaxCopy() : NULL
,
5100 objectSyntaxCopy(specAlias
),
5101 objectSyntaxCopy(defaultAlias
));
5104 bool TemplateAliasParameter::declareParameter(Scope
*sc
)
5106 TypeIdentifier
*ti
= new TypeIdentifier(loc
, ident
);
5107 Declaration
*ad
= new AliasDeclaration(loc
, ident
, ti
);
5108 return sc
->insert(ad
) != NULL
;
5111 MATCH
TemplateAliasParameter::matchArg(Scope
*sc
, RootObject
*oarg
,
5112 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
5113 Declaration
**psparam
)
5115 //printf("TemplateAliasParameter::matchArg('%s')\n", ident->toChars());
5116 MATCH m
= MATCHexact
;
5117 Type
*ta
= isType(oarg
);
5118 RootObject
*sa
= ta
&& !ta
->deco
? NULL
: getDsymbol(oarg
);
5119 Expression
*ea
= isExpression(oarg
);
5120 if (ea
&& (ea
->op
== TOKthis
|| ea
->op
== TOKsuper
))
5121 sa
= ((ThisExp
*)ea
)->var
;
5122 else if (ea
&& ea
->op
== TOKscope
)
5123 sa
= ((ScopeExp
*)ea
)->sds
;
5126 if (((Dsymbol
*)sa
)->isAggregateDeclaration())
5129 /* specType means the alias must be a declaration with a type
5130 * that matches specType.
5134 Declaration
*d
= ((Dsymbol
*)sa
)->isDeclaration();
5137 if (!d
->type
->equals(specType
))
5148 if (!ea
->type
->equals(specType
))
5152 else if (ta
&& ta
->ty
== Tinstance
&& !specAlias
)
5154 /* Bugzilla xxxxx: Specialized parameter should be prefeerd
5155 * match to the template type parameter.
5156 * template X(alias a) {} // a == this
5157 * template X(alias a : B!A, alias B, A...) {} // B!A => ta
5160 else if (sa
&& sa
== TemplateTypeParameter::tdummy
)
5162 /* Bugzilla 2025: Aggregate Types should preferentially
5163 * match to the template type parameter.
5164 * template X(alias a) {} // a == this
5165 * template X(T) {} // T => sa
5176 Dsymbol
*sx
= isDsymbol(sa
);
5177 if (sa
!= specAlias
&& sx
)
5179 Type
*talias
= isType(specAlias
);
5183 TemplateInstance
*ti
= sx
->isTemplateInstance();
5184 if (!ti
&& sx
->parent
)
5186 ti
= sx
->parent
->isTemplateInstance();
5187 if (ti
&& ti
->name
!= sx
->ident
)
5193 Type
*t
= new TypeInstance(Loc(), ti
);
5194 MATCH m2
= deduceType(t
, sc
, talias
, parameters
, dedtypes
);
5195 if (m2
<= MATCHnomatch
)
5199 else if ((*dedtypes
)[i
])
5201 // Must match already deduced symbol
5202 RootObject
*si
= (*dedtypes
)[i
];
5203 if (!sa
|| si
!= sa
)
5206 (*dedtypes
)[i
] = sa
;
5210 if (Dsymbol
*s
= isDsymbol(sa
))
5212 *psparam
= new AliasDeclaration(loc
, ident
, s
);
5214 else if (Type
*t
= isType(sa
))
5216 *psparam
= new AliasDeclaration(loc
, ident
, t
);
5222 // Declare manifest constant
5223 Initializer
*init
= new ExpInitializer(loc
, ea
);
5224 VarDeclaration
*v
= new VarDeclaration(loc
, NULL
, ident
, init
);
5225 v
->storage_class
= STCmanifest
;
5226 dsymbolSemantic(v
, sc
);
5230 return dependent
? MATCHexact
: m
;
5235 //printf("\tm = %d\n", MATCHnomatch);
5236 return MATCHnomatch
;
5240 void TemplateAliasParameter::print(RootObject
*, RootObject
*oded
)
5242 printf(" %s\n", ident
->toChars());
5244 Dsymbol
*sa
= isDsymbol(oded
);
5247 printf("\tParameter alias: %s\n", sa
->toChars());
5250 void *TemplateAliasParameter::dummyArg()
5252 RootObject
*s
= specAlias
;
5256 sdummy
= new Dsymbol();
5263 RootObject
*TemplateAliasParameter::specialization()
5268 RootObject
*TemplateAliasParameter::defaultArg(Loc
, Scope
*sc
)
5270 RootObject
*da
= defaultAlias
;
5271 Type
*ta
= isType(defaultAlias
);
5274 if (ta
->ty
== Tinstance
)
5276 // If the default arg is a template, instantiate for each type
5277 da
= ta
->syntaxCopy();
5281 RootObject
*o
= aliasParameterSemantic(loc
, sc
, da
, NULL
); // use the parameter loc
5285 bool TemplateAliasParameter::hasDefaultArg()
5287 return defaultAlias
!= NULL
;
5290 /* ======================== TemplateValueParameter ========================== */
5294 AA
*TemplateValueParameter::edummies
= NULL
;
5296 TemplateValueParameter::TemplateValueParameter(Loc loc
, Identifier
*ident
, Type
*valType
,
5297 Expression
*specValue
, Expression
*defaultValue
)
5298 : TemplateParameter(loc
, ident
)
5300 this->ident
= ident
;
5301 this->valType
= valType
;
5302 this->specValue
= specValue
;
5303 this->defaultValue
= defaultValue
;
5306 TemplateValueParameter
*TemplateValueParameter::isTemplateValueParameter()
5311 TemplateParameter
*TemplateValueParameter::syntaxCopy()
5313 return new TemplateValueParameter(loc
, ident
,
5314 valType
->syntaxCopy(),
5315 specValue
? specValue
->syntaxCopy() : NULL
,
5316 defaultValue
? defaultValue
->syntaxCopy() : NULL
);
5319 bool TemplateValueParameter::declareParameter(Scope
*sc
)
5321 VarDeclaration
*v
= new VarDeclaration(loc
, valType
, ident
, NULL
);
5322 v
->storage_class
= STCtemplateparameter
;
5323 return sc
->insert(v
) != NULL
;
5326 MATCH
TemplateValueParameter::matchArg(Scope
*sc
, RootObject
*oarg
,
5327 size_t i
, TemplateParameters
*, Objects
*dedtypes
, Declaration
**psparam
)
5329 //printf("TemplateValueParameter::matchArg('%s')\n", ident->toChars());
5331 MATCH m
= MATCHexact
;
5333 Expression
*ei
= isExpression(oarg
);
5338 Dsymbol
*si
= isDsymbol(oarg
);
5339 FuncDeclaration
*f
= si
? si
->isFuncDeclaration() : NULL
;
5340 if (!f
|| !f
->fbody
|| f
->needThis())
5343 ei
= new VarExp(loc
, f
);
5344 ei
= expressionSemantic(ei
, sc
);
5346 /* If a function is really property-like, and then
5347 * it's CTFEable, ei will be a literal expression.
5349 unsigned int olderrors
= global
.startGagging();
5350 ei
= resolveProperties(sc
, ei
);
5351 ei
= ei
->ctfeInterpret();
5352 if (global
.endGagging(olderrors
) || ei
->op
== TOKerror
)
5355 /* Bugzilla 14520: A property-like function can match to both
5356 * TemplateAlias and ValueParameter. But for template overloads,
5357 * it should always prefer alias parameter to be consistent
5358 * template match result.
5360 * template X(alias f) { enum X = 1; }
5361 * template X(int val) { enum X = 2; }
5362 * int f1() { return 0; } // CTFEable
5363 * int f2(); // body-less function is not CTFEable
5364 * enum x1 = X!f1; // should be 1
5365 * enum x2 = X!f2; // should be 1
5367 * e.g. The x1 value must be same even if the f1 definition will be moved
5368 * into di while stripping body code.
5373 if (ei
&& ei
->op
== TOKvar
)
5375 // Resolve const variables that we had skipped earlier
5376 ei
= ei
->ctfeInterpret();
5379 //printf("\tvalType: %s, ty = %d\n", valType->toChars(), valType->ty);
5380 vt
= typeSemantic(valType
, loc
, sc
);
5381 //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars());
5382 //printf("vt = %s\n", vt->toChars());
5386 MATCH m2
= ei
->implicitConvTo(vt
);
5387 //printf("m: %d\n", m);
5390 if (m
<= MATCHnomatch
)
5392 ei
= ei
->implicitCastTo(sc
, vt
);
5393 ei
= ei
->ctfeInterpret();
5398 if (!ei
|| (Expression
*)dmd_aaGetRvalue(edummies
, (void *)ei
->type
) == ei
)
5401 Expression
*e
= specValue
;
5403 sc
= sc
->startCTFE();
5404 e
= expressionSemantic(e
, sc
);
5405 e
= resolveProperties(sc
, e
);
5407 e
= e
->implicitCastTo(sc
, vt
);
5408 e
= e
->ctfeInterpret();
5410 ei
= ei
->syntaxCopy();
5411 sc
= sc
->startCTFE();
5412 ei
= expressionSemantic(ei
, sc
);
5414 ei
= ei
->implicitCastTo(sc
, vt
);
5415 ei
= ei
->ctfeInterpret();
5416 //printf("\tei: %s, %s\n", ei->toChars(), ei->type->toChars());
5417 //printf("\te : %s, %s\n", e->toChars(), e->type->toChars());
5425 // Must match already deduced value
5426 Expression
*e
= (Expression
*)(*dedtypes
)[i
];
5428 if (!ei
|| !ei
->equals(e
))
5432 (*dedtypes
)[i
] = ei
;
5436 Initializer
*init
= new ExpInitializer(loc
, ei
);
5437 Declaration
*sparam
= new VarDeclaration(loc
, vt
, ident
, init
);
5438 sparam
->storage_class
= STCmanifest
;
5441 return dependent
? MATCHexact
: m
;
5444 //printf("\tno match\n");
5447 return MATCHnomatch
;
5451 void TemplateValueParameter::print(RootObject
*, RootObject
*oded
)
5453 printf(" %s\n", ident
->toChars());
5455 Expression
*ea
= isExpression(oded
);
5458 printf("\tSpecialization: %s\n", specValue
->toChars());
5459 printf("\tParameter Value: %s\n", ea
? ea
->toChars() : "NULL");
5462 void *TemplateValueParameter::dummyArg()
5464 Expression
*e
= specValue
;
5467 // Create a dummy value
5468 Expression
**pe
= (Expression
**)dmd_aaGet(&edummies
, (void *)valType
);
5470 *pe
= valType
->defaultInit();
5477 RootObject
*TemplateValueParameter::specialization()
5482 RootObject
*TemplateValueParameter::defaultArg(Loc instLoc
, Scope
*sc
)
5484 Expression
*e
= defaultValue
;
5487 e
= e
->syntaxCopy();
5488 if ((e
= expressionSemantic(e
, sc
)) == NULL
)
5490 if ((e
= resolveProperties(sc
, e
)) == NULL
)
5492 e
= e
->resolveLoc(instLoc
, sc
); // use the instantiated loc
5493 e
= e
->optimize(WANTvalue
);
5498 bool TemplateValueParameter::hasDefaultArg()
5500 return defaultValue
!= NULL
;
5503 /* ======================== TemplateTupleParameter ========================== */
5505 // variadic-parameter
5507 TemplateTupleParameter::TemplateTupleParameter(Loc loc
, Identifier
*ident
)
5508 : TemplateParameter(loc
, ident
)
5510 this->ident
= ident
;
5513 TemplateTupleParameter
*TemplateTupleParameter::isTemplateTupleParameter()
5518 TemplateParameter
*TemplateTupleParameter::syntaxCopy()
5520 return new TemplateTupleParameter(loc
, ident
);
5523 bool TemplateTupleParameter::declareParameter(Scope
*sc
)
5525 TypeIdentifier
*ti
= new TypeIdentifier(loc
, ident
);
5526 Declaration
*ad
= new AliasDeclaration(loc
, ident
, ti
);
5527 return sc
->insert(ad
) != NULL
;
5530 MATCH
TemplateTupleParameter::matchArg(Loc
, Scope
*sc
, Objects
*tiargs
,
5531 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
5532 Declaration
**psparam
)
5534 /* The rest of the actual arguments (tiargs[]) form the match
5535 * for the variadic parameter.
5537 assert(i
+ 1 == dedtypes
->length
); // must be the last one
5540 if (Tuple
*u
= isTuple((*dedtypes
)[i
]))
5542 // It has already been deduced
5545 else if (i
+ 1 == tiargs
->length
&& isTuple((*tiargs
)[i
]))
5546 ovar
= isTuple((*tiargs
)[i
]);
5550 //printf("ovar = %p\n", ovar);
5551 if (i
< tiargs
->length
)
5553 //printf("i = %d, tiargs->length = %d\n", i, tiargs->length);
5554 ovar
->objects
.setDim(tiargs
->length
- i
);
5555 for (size_t j
= 0; j
< ovar
->objects
.length
; j
++)
5556 ovar
->objects
[j
] = (*tiargs
)[i
+ j
];
5559 return matchArg(sc
, ovar
, i
, parameters
, dedtypes
, psparam
);
5562 MATCH
TemplateTupleParameter::matchArg(Scope
*, RootObject
*oarg
,
5563 size_t i
, TemplateParameters
*, Objects
*dedtypes
, Declaration
**psparam
)
5565 //printf("TemplateTupleParameter::matchArg('%s')\n", ident->toChars());
5566 Tuple
*ovar
= isTuple(oarg
);
5568 return MATCHnomatch
;
5571 Tuple
*tup
= isTuple((*dedtypes
)[i
]);
5573 return MATCHnomatch
;
5574 if (!match(tup
, ovar
))
5575 return MATCHnomatch
;
5577 (*dedtypes
)[i
] = ovar
;
5580 *psparam
= new TupleDeclaration(loc
, ident
, &ovar
->objects
);
5581 return dependent
? MATCHexact
: MATCHconvert
;
5585 void TemplateTupleParameter::print(RootObject
*, RootObject
*oded
)
5587 printf(" %s... [", ident
->toChars());
5588 Tuple
*v
= isTuple(oded
);
5591 //printf("|%d| ", v->objects.length);
5592 for (size_t i
= 0; i
< v
->objects
.length
; i
++)
5597 RootObject
*o
= v
->objects
[i
];
5599 Dsymbol
*sa
= isDsymbol(o
);
5601 printf("alias: %s", sa
->toChars());
5603 Type
*ta
= isType(o
);
5605 printf("type: %s", ta
->toChars());
5607 Expression
*ea
= isExpression(o
);
5609 printf("exp: %s", ea
->toChars());
5611 assert(!isTuple(o
)); // no nested Tuple arguments
5617 void *TemplateTupleParameter::dummyArg()
5623 RootObject
*TemplateTupleParameter::specialization()
5628 RootObject
*TemplateTupleParameter::defaultArg(Loc
, Scope
*)
5633 bool TemplateTupleParameter::hasDefaultArg()
5638 /* ======================== TemplateInstance ================================ */
5640 TemplateInstance::TemplateInstance(Loc loc
, Identifier
*ident
)
5641 : ScopeDsymbol(NULL
)
5645 this->tiargs
= NULL
;
5646 this->tempdecl
= NULL
;
5651 this->deferred
= NULL
;
5652 this->memberOf
= NULL
;
5653 this->argsym
= NULL
;
5654 this->aliasdecl
= NULL
;
5655 this->semantictiargsdone
= false;
5658 this->havetempdecl
= false;
5659 this->enclosing
= NULL
;
5660 this->gagged
= false;
5666 * This constructor is only called when we figured out which function
5667 * template to instantiate.
5670 TemplateInstance::TemplateInstance(Loc loc
, TemplateDeclaration
*td
, Objects
*tiargs
)
5671 : ScopeDsymbol(NULL
)
5674 this->name
= td
->ident
;
5675 this->tiargs
= tiargs
;
5676 this->tempdecl
= td
;
5681 this->deferred
= NULL
;
5682 this->memberOf
= NULL
;
5683 this->argsym
= NULL
;
5684 this->aliasdecl
= NULL
;
5685 this->semantictiargsdone
= true;
5688 this->havetempdecl
= true;
5689 this->enclosing
= NULL
;
5690 this->gagged
= false;
5694 assert(tempdecl
->_scope
);
5698 Objects
*TemplateInstance::arraySyntaxCopy(Objects
*objs
)
5704 a
->setDim(objs
->length
);
5705 for (size_t i
= 0; i
< objs
->length
; i
++)
5706 (*a
)[i
] = objectSyntaxCopy((*objs
)[i
]);
5711 Dsymbol
*TemplateInstance::syntaxCopy(Dsymbol
*s
)
5713 TemplateInstance
*ti
=
5714 s
? (TemplateInstance
*)s
5715 : new TemplateInstance(loc
, name
);
5716 ti
->tiargs
= arraySyntaxCopy(tiargs
);
5717 TemplateDeclaration
*td
;
5718 if (inst
&& tempdecl
&& (td
= tempdecl
->isTemplateDeclaration()) != NULL
)
5719 td
->ScopeDsymbol::syntaxCopy(ti
);
5721 ScopeDsymbol::syntaxCopy(ti
);
5725 void TemplateInstance::expandMembers(Scope
*sc2
)
5727 for (size_t i
= 0; i
< members
->length
; i
++)
5729 Dsymbol
*s
= (*members
)[i
];
5733 for (size_t i
= 0; i
< members
->length
; i
++)
5735 Dsymbol
*s
= (*members
)[i
];
5739 for (size_t i
= 0; i
< members
->length
; i
++)
5741 Dsymbol
*s
= (*members
)[i
];
5742 //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars());
5743 //printf("test: enclosing = %d, sc2->parent = %s\n", enclosing, sc2->parent->toChars());
5745 // s->parent = sc->parent;
5746 //printf("test3: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars());
5747 dsymbolSemantic(s
, sc2
);
5748 //printf("test4: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars());
5749 Module::runDeferredSemantic();
5753 void TemplateInstance::tryExpandMembers(Scope
*sc2
)
5756 // extracted to a function to allow windows SEH to work without destructors in the same function
5757 //printf("%d\n", nest);
5758 if (++nest
> global
.recursionLimit
)
5760 global
.gag
= 0; // ensure error message gets printed
5761 error("recursive expansion exceeded allowed nesting limit");
5770 void TemplateInstance::trySemantic3(Scope
*sc2
)
5772 // extracted to a function to allow windows SEH to work without destructors in the same function
5774 //printf("%d\n", nest);
5775 if (++nest
> global
.recursionLimit
)
5777 global
.gag
= 0; // ensure error message gets printed
5778 error("recursive expansion exceeded allowed nesting limit");
5781 semantic3(this, sc2
);
5786 /**********************************************
5787 * Find template declaration corresponding to template instance.
5790 * false if finding fails.
5792 * This function is reentrant against error occurrence. If returns false,
5793 * any members of this object won't be modified, and repetition call will
5794 * reproduce same error.
5797 bool TemplateInstance::findTempDecl(Scope
*sc
, WithScopeSymbol
**pwithsym
)
5805 //printf("TemplateInstance::findTempDecl() %s\n", toChars());
5810 * figure out which TemplateDeclaration foo refers to.
5812 Identifier
*id
= name
;
5814 Dsymbol
*s
= sc
->search(loc
, id
, &scopesym
);
5817 s
= sc
->search_correct(id
);
5819 error("template `%s` is not defined, did you mean %s?", id
->toChars(), s
->toChars());
5821 error("template `%s` is not defined", id
->toChars());
5826 *pwithsym
= scopesym
->isWithScopeSymbol();
5828 /* We might have found an alias within a template when
5829 * we really want the template.
5831 TemplateInstance
*ti
;
5833 (ti
= s
->parent
->isTemplateInstance()) != NULL
)
5835 if (ti
->tempdecl
&& ti
->tempdecl
->ident
== id
)
5837 /* This is so that one can refer to the enclosing
5838 * template, even if it has the same name as a member
5839 * of the template, if it has a !(arguments)
5841 TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration();
5843 if (td
->overroot
) // if not start of overloaded list of TemplateDeclaration's
5844 td
= td
->overroot
; // then get the start
5849 if (!updateTempDecl(sc
, s
))
5858 static int fp(void *param
, Dsymbol
*s
)
5860 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
5864 TemplateInstance
*ti
= (TemplateInstance
*)param
;
5865 if (td
->semanticRun
== PASSinit
)
5869 // Try to fix forward reference. Ungag errors while doing so.
5870 Ungag ungag
= td
->ungagSpeculative();
5871 dsymbolSemantic(td
, td
->_scope
);
5873 if (td
->semanticRun
== PASSinit
)
5875 ti
->error("%s forward references template declaration %s", ti
->toChars(), td
->toChars());
5882 // Look for forward references
5883 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
5884 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
5885 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
5887 if (overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, (void *)this, &ParamFwdTi::fp
))
5893 /**********************************************
5894 * Confirm s is a valid template, then store it.
5897 * s candidate symbol of template. It may be:
5898 * TemplateDeclaration
5899 * FuncDeclaration with findTemplateDeclRoot() != NULL
5900 * OverloadSet which contains candidates
5902 * true if updating succeeds.
5905 bool TemplateInstance::updateTempDecl(Scope
*sc
, Dsymbol
*s
)
5909 Identifier
*id
= name
;
5912 /* If an OverloadSet, look for a unique member that is a template declaration
5914 OverloadSet
*os
= s
->isOverloadSet();
5918 for (size_t i
= 0; i
< os
->a
.length
; i
++)
5920 Dsymbol
*s2
= os
->a
[i
];
5921 if (FuncDeclaration
*f
= s2
->isFuncDeclaration())
5922 s2
= f
->findTemplateDeclRoot();
5924 s2
= s2
->isTemplateDeclaration();
5937 error("template `%s` is not defined", id
->toChars());
5942 OverDeclaration
*od
= s
->isOverDeclaration();
5945 tempdecl
= od
; // TODO: more strict check
5949 /* It should be a TemplateDeclaration, not some other symbol
5951 if (FuncDeclaration
*f
= s
->isFuncDeclaration())
5952 tempdecl
= f
->findTemplateDeclRoot();
5954 tempdecl
= s
->isTemplateDeclaration();
5957 if (!s
->parent
&& global
.errors
)
5959 if (!s
->parent
&& s
->getType())
5961 Dsymbol
*s2
= s
->getType()->toDsymbol(sc
);
5964 error("%s is not a template declaration, it is a %s", id
->toChars(), s
->kind());
5969 //assert(s->parent);
5970 TemplateInstance
*ti
= s
->parent
? s
->parent
->isTemplateInstance() : NULL
;
5972 (ti
->name
== s
->ident
||
5973 ti
->toAlias()->ident
== s
->ident
)
5977 /* This is so that one can refer to the enclosing
5978 * template, even if it has the same name as a member
5979 * of the template, if it has a !(arguments)
5981 TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration();
5983 if (td
->overroot
) // if not start of overloaded list of TemplateDeclaration's
5984 td
= td
->overroot
; // then get the start
5989 error("%s is not a template declaration, it is a %s", id
->toChars(), s
->kind());
5994 return (tempdecl
!= NULL
);
5997 /**********************************
5998 * Run semantic on the elements of tiargs.
6002 * false if one or more arguments have errors.
6004 * This function is reentrant against error occurrence. If returns false,
6005 * all elements of tiargs won't be modified.
6008 bool TemplateInstance::semanticTiargs(Scope
*sc
)
6010 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars());
6011 if (semantictiargsdone
)
6013 if (semanticTiargs(loc
, sc
, tiargs
, 0))
6015 // cache the result iff semantic analysis succeeded entirely
6016 semantictiargsdone
= 1;
6022 /**********************************
6023 * Run semantic of tiargs as arguments of template.
6027 * tiargs array of template arguments
6028 * flags 1: replace const variables with their initializers
6029 * 2: don't devolve Parameter to Type
6031 * false if one or more arguments have errors.
6034 bool TemplateInstance::semanticTiargs(Loc loc
, Scope
*sc
, Objects
*tiargs
, int flags
)
6036 // Run semantic on each argument, place results in tiargs[]
6037 //printf("+TemplateInstance::semanticTiargs()\n");
6041 for (size_t j
= 0; j
< tiargs
->length
; j
++)
6043 RootObject
*o
= (*tiargs
)[j
];
6044 Type
*ta
= isType(o
);
6045 Expression
*ea
= isExpression(o
);
6046 Dsymbol
*sa
= isDsymbol(o
);
6048 //printf("1: (*tiargs)[%d] = %p, s=%p, v=%p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
6051 //printf("type %s\n", ta->toChars());
6052 // It might really be an Expression or an Alias
6053 ta
->resolve(loc
, sc
, &ea
, &ta
, &sa
, (flags
& 1) != 0);
6058 assert(global
.errors
);
6063 if (ta
->ty
== Ttuple
)
6066 TypeTuple
*tt
= (TypeTuple
*)ta
;
6067 size_t dim
= tt
->arguments
->length
;
6071 tiargs
->reserve(dim
);
6072 for (size_t i
= 0; i
< dim
; i
++)
6074 Parameter
*arg
= (*tt
->arguments
)[i
];
6075 if (flags
& 2 && (arg
->ident
|| arg
->userAttribDecl
))
6076 tiargs
->insert(j
+ i
, arg
);
6078 tiargs
->insert(j
+ i
, arg
->type
);
6084 if (ta
->ty
== Terror
)
6089 (*tiargs
)[j
] = ta
->merge2();
6094 //printf("+[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
6095 if (flags
& 1) // only used by __traits
6097 ea
= expressionSemantic(ea
, sc
);
6099 // must not interpret the args, excepting template parameters
6100 if (ea
->op
!= TOKvar
||
6101 (((VarExp
*)ea
)->var
->storage_class
& STCtemplateparameter
))
6103 ea
= ea
->optimize(WANTvalue
);
6108 sc
= sc
->startCTFE();
6109 ea
= expressionSemantic(ea
, sc
);
6112 if (ea
->op
== TOKvar
)
6114 /* This test is to skip substituting a const var with
6115 * its initializer. The problem is the initializer won't
6116 * match with an 'alias' parameter. Instead, do the
6117 * const substitution in TemplateValueParameter::matchArg().
6120 else if (definitelyValueParameter(ea
))
6122 if (ea
->checkValue()) // check void expression
6123 ea
= new ErrorExp();
6124 unsigned int olderrs
= global
.errors
;
6125 ea
= ea
->ctfeInterpret();
6126 if (global
.errors
!= olderrs
)
6127 ea
= new ErrorExp();
6130 //printf("-[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
6131 if (ea
->op
== TOKtuple
)
6134 TupleExp
*te
= (TupleExp
*)ea
;
6135 size_t dim
= te
->exps
->length
;
6139 tiargs
->reserve(dim
);
6140 for (size_t i
= 0; i
< dim
; i
++)
6141 tiargs
->insert(j
+ i
, (*te
->exps
)[i
]);
6146 if (ea
->op
== TOKerror
)
6153 if (ea
->op
== TOKtype
)
6158 if (ea
->op
== TOKscope
)
6160 sa
= ((ScopeExp
*)ea
)->sds
;
6163 if (ea
->op
== TOKfunction
)
6165 FuncExp
*fe
= (FuncExp
*)ea
;
6166 /* A function literal, that is passed to template and
6167 * already semanticed as function pointer, never requires
6168 * outer frame. So convert it to global function is valid.
6170 if (fe
->fd
->tok
== TOKreserved
&& fe
->type
->ty
== Tpointer
)
6172 // change to non-nested
6173 fe
->fd
->tok
= TOKfunction
;
6174 fe
->fd
->vthis
= NULL
;
6178 /* If template argument is a template lambda,
6179 * get template declaration itself. */
6184 if (ea
->op
== TOKdotvar
&& !(flags
& 1))
6186 // translate expression to dsymbol.
6187 sa
= ((DotVarExp
*)ea
)->var
;
6190 if (ea
->op
== TOKtemplate
)
6192 sa
= ((TemplateExp
*)ea
)->td
;
6195 if (ea
->op
== TOKdottd
&& !(flags
& 1))
6197 // translate expression to dsymbol.
6198 sa
= ((DotTemplateExp
*)ea
)->td
;
6205 //printf("dsym %s %s\n", sa->kind(), sa->toChars());
6212 TupleDeclaration
*d
= sa
->toAlias()->isTupleDeclaration();
6217 tiargs
->insert(j
, d
->objects
);
6221 if (FuncAliasDeclaration
*fa
= sa
->isFuncAliasDeclaration())
6223 FuncDeclaration
*f
= fa
->toAliasFunc();
6224 if (!fa
->hasOverloads
&& f
->isUnique())
6226 // Strip FuncAlias only when the aliased function
6227 // does not have any overloads.
6233 TemplateDeclaration
*td
= sa
->isTemplateDeclaration();
6234 if (td
&& td
->semanticRun
== PASSinit
&& td
->literal
)
6236 dsymbolSemantic(td
, sc
);
6238 FuncDeclaration
*fd
= sa
->isFuncDeclaration();
6240 fd
->functionSemantic();
6242 else if (isParameter(o
))
6249 //printf("1: (*tiargs)[%d] = %p\n", j, (*tiargs)[j]);
6254 bool TemplateInstance::findBestMatch(Scope
*sc
, Expressions
*fargs
)
6258 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
6260 assert(tempdecl
->_scope
);
6262 tdtypes
.setDim(tempdecl
->parameters
->length
);
6263 if (!tempdecl
->matchWithInstance(sc
, this, &tdtypes
, fargs
, 2))
6265 error("incompatible arguments for template instantiation");
6268 // TODO: Normalizing tiargs for bugzilla 7469 is necessary?
6272 unsigned errs
= global
.errors
;
6278 TemplateInstance
*ti
;
6281 TemplateDeclaration
*td_best
;
6282 TemplateDeclaration
*td_ambig
;
6285 static int fp(void *param
, Dsymbol
*s
)
6287 return ((ParamBest
*)param
)->fp(s
);
6291 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
6295 if (td
== td_best
) // skip duplicates
6298 //printf("td = %s\n", td->toPrettyChars());
6300 // If more arguments than parameters,
6301 // then this is no match.
6302 if (td
->parameters
->length
< ti
->tiargs
->length
)
6304 if (!td
->isVariadic())
6308 dedtypes
.setDim(td
->parameters
->length
);
6310 assert(td
->semanticRun
!= PASSinit
);
6311 MATCH m
= td
->matchWithInstance(sc
, ti
, &dedtypes
, ti
->fargs
, 0);
6312 //printf("matchWithInstance = %d\n", m);
6313 if (m
<= MATCHnomatch
) // no match at all
6316 if (m
< m_best
) goto Ltd_best
;
6317 if (m
> m_best
) goto Ltd
;
6320 // Disambiguate by picking the most specialized TemplateDeclaration
6321 MATCH c1
= td
->leastAsSpecialized(sc
, td_best
, ti
->fargs
);
6322 MATCH c2
= td_best
->leastAsSpecialized(sc
, td
, ti
->fargs
);
6323 //printf("c1 = %d, c2 = %d\n", c1, c2);
6324 if (c1
> c2
) goto Ltd
;
6325 if (c1
< c2
) goto Ltd_best
;
6331 Ltd_best
: // td_best is the best match so far
6335 Ltd
: // td is the new best match
6339 ti
->tdtypes
.setDim(dedtypes
.length
);
6340 memcpy(ti
->tdtypes
.tdata(), dedtypes
.tdata(), ti
->tdtypes
.length
* sizeof(void *));
6349 /* Since there can be multiple TemplateDeclaration's with the same
6350 * name, look for the best match.
6352 TemplateDeclaration
*td_last
= NULL
;
6354 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
6355 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
6356 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
6361 p
.m_best
= MATCHnomatch
;
6362 overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, &p
, &ParamBest::fp
);
6366 ::error(loc
, "%s %s.%s matches more than one template declaration:\n%s: %s\nand\n%s: %s",
6367 p
.td_best
->kind(), p
.td_best
->parent
->toPrettyChars(), p
.td_best
->ident
->toChars(),
6368 p
.td_best
->loc
.toChars() , p
.td_best
->toChars(),
6369 p
.td_ambig
->loc
.toChars(), p
.td_ambig
->toChars());
6375 td_last
= p
.td_best
;
6376 else if (td_last
!= p
.td_best
)
6378 ScopeDsymbol::multiplyDefined(loc
, td_last
, p
.td_best
);
6386 /* Bugzilla 7469: Normalize tiargs by using corresponding deduced
6387 * template value parameters and tuples for the correct mangling.
6389 * By doing this before hasNestedArgs, CTFEable local variable will be
6390 * accepted as a value parameter. For example:
6393 * struct S(int n) {} // non-global template
6394 * const int num = 1; // CTFEable local variable
6395 * S!num s; // S!1 is instantiated, not S!num
6398 size_t dim
= td_last
->parameters
->length
- (td_last
->isVariadic() ? 1 : 0);
6399 for (size_t i
= 0; i
< dim
; i
++)
6401 if (tiargs
->length
<= i
)
6402 tiargs
->push(tdtypes
[i
]);
6403 assert(i
< tiargs
->length
);
6405 TemplateValueParameter
*tvp
= (*td_last
->parameters
)[i
]->isTemplateValueParameter();
6409 // tdtypes[i] is already normalized to the required type in matchArg
6411 (*tiargs
)[i
] = tdtypes
[i
];
6413 if (td_last
->isVariadic() && tiargs
->length
== dim
&& tdtypes
[dim
])
6415 Tuple
*va
= isTuple(tdtypes
[dim
]);
6417 for (size_t i
= 0; i
< va
->objects
.length
; i
++)
6418 tiargs
->push(va
->objects
[i
]);
6421 else if (errors
&& inst
)
6423 // instantiation was failed with error reporting
6424 assert(global
.errors
);
6429 TemplateDeclaration
*tdecl
= tempdecl
->isTemplateDeclaration();
6431 if (errs
!= global
.errors
)
6432 errorSupplemental(loc
, "while looking for match for %s", toChars());
6433 else if (tdecl
&& !tdecl
->overnext
)
6435 // Only one template, so we can give better error message
6436 error("does not match template declaration %s", tdecl
->toChars());
6439 ::error(loc
, "%s %s.%s does not match any template declaration",
6440 tempdecl
->kind(), tempdecl
->parent
->toPrettyChars(), tempdecl
->ident
->toChars());
6444 /* The best match is td_last
6448 return (errs
== global
.errors
);
6451 /*****************************************************
6452 * Determine if template instance is really a template function,
6453 * and that template function needs to infer types from the function
6456 * Like findBestMatch, iterate possible template candidates,
6457 * but just looks only the necessity of type inference.
6460 bool TemplateInstance::needsTypeInference(Scope
*sc
, int flag
)
6462 //printf("TemplateInstance::needsTypeInference() %s\n", toChars());
6463 if (semanticRun
!= PASSinit
)
6466 struct ParamNeedsInf
6470 TemplateInstance
*ti
;
6476 static int fp(void *param
, Dsymbol
*s
)
6478 return ((ParamNeedsInf
*)param
)->fp(s
);
6482 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
6488 /* If any of the overloaded template declarations need inference,
6491 FuncDeclaration
*fd
;
6494 if (TemplateDeclaration
*td2
= td
->onemember
->isTemplateDeclaration())
6496 if (!td2
->onemember
|| !td2
->onemember
->isFuncDeclaration())
6498 if (ti
->tiargs
->length
>= td
->parameters
->length
- (td
->isVariadic() ? 1 : 0))
6502 if ((fd
= td
->onemember
->isFuncDeclaration()) == NULL
||
6503 fd
->type
->ty
!= Tfunction
)
6508 for (size_t i
= 0; i
< td
->parameters
->length
; i
++)
6510 if ((*td
->parameters
)[i
]->isTemplateThisParameter())
6514 /* Determine if the instance arguments, tiargs, are all that is necessary
6515 * to instantiate the template.
6517 //printf("tp = %p, td->parameters->length = %d, tiargs->length = %d\n", tp, td->parameters->length, ti->tiargs->length);
6518 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
6519 if (size_t dim
= tf
->parameterList
.length())
6521 TemplateParameter
*tp
= td
->isVariadic();
6522 if (tp
&& td
->parameters
->length
> 1)
6525 if (!tp
&& ti
->tiargs
->length
< td
->parameters
->length
)
6527 // Can remain tiargs be filled by default arguments?
6528 for (size_t i
= ti
->tiargs
->length
; i
< td
->parameters
->length
; i
++)
6530 if (!(*td
->parameters
)[i
]->hasDefaultArg())
6535 for (size_t i
= 0; i
< dim
; i
++)
6537 // 'auto ref' needs inference.
6538 if (tf
->parameterList
[i
]->storageClass
& STCauto
)
6545 /* Calculate the need for overload resolution.
6546 * When only one template can match with tiargs, inference is not necessary.
6548 dedtypes
.setDim(td
->parameters
->length
);
6550 if (td
->semanticRun
== PASSinit
)
6554 // Try to fix forward reference. Ungag errors while doing so.
6555 Ungag ungag
= td
->ungagSpeculative();
6556 dsymbolSemantic(td
, td
->_scope
);
6558 if (td
->semanticRun
== PASSinit
)
6560 ti
->error("%s forward references template declaration %s", ti
->toChars(), td
->toChars());
6564 assert(td
->semanticRun
!= PASSinit
);
6565 MATCH m
= td
->matchWithInstance(sc
, ti
, &dedtypes
, NULL
, 0);
6566 if (m
<= MATCHnomatch
)
6570 /* If there is more than one function template which matches, we may
6571 * need type inference (see Bugzilla 4430)
6587 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
6588 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
6589 unsigned olderrs
= global
.errors
;
6590 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
6592 if (overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, &p
, &ParamNeedsInf::fp
))
6595 if (olderrs
!= global
.errors
)
6599 errorSupplemental(loc
, "while looking for match for %s", toChars());
6600 semanticRun
= PASSsemanticdone
;
6605 //printf("false\n");
6610 /*****************************************
6611 * Determines if a TemplateInstance will need a nested
6612 * generation of the TemplateDeclaration.
6613 * Sets enclosing property if so, and returns != 0;
6616 bool TemplateInstance::hasNestedArgs(Objects
*args
, bool isstatic
)
6619 //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());
6621 /* A nested instance happens when an argument references a local
6622 * symbol that is on the stack.
6624 for (size_t i
= 0; i
< args
->length
; i
++)
6626 RootObject
*o
= (*args
)[i
];
6627 Expression
*ea
= isExpression(o
);
6628 Dsymbol
*sa
= isDsymbol(o
);
6629 Tuple
*va
= isTuple(o
);
6632 if (ea
->op
== TOKvar
)
6634 sa
= ((VarExp
*)ea
)->var
;
6637 if (ea
->op
== TOKthis
)
6639 sa
= ((ThisExp
*)ea
)->var
;
6642 if (ea
->op
== TOKfunction
)
6644 if (((FuncExp
*)ea
)->td
)
6645 sa
= ((FuncExp
*)ea
)->td
;
6647 sa
= ((FuncExp
*)ea
)->fd
;
6650 // Emulate Expression::toMangleBuffer call that had exist in TemplateInstance::genIdent.
6651 if (ea
->op
!= TOKint64
&&
6652 ea
->op
!= TOKfloat64
&&
6653 ea
->op
!= TOKcomplex80
&&
6654 ea
->op
!= TOKnull
&&
6655 ea
->op
!= TOKstring
&&
6656 ea
->op
!= TOKarrayliteral
&&
6657 ea
->op
!= TOKassocarrayliteral
&&
6658 ea
->op
!= TOKstructliteral
)
6660 ea
->error("expression %s is not a valid template value argument", ea
->toChars());
6668 TemplateDeclaration
*td
= sa
->isTemplateDeclaration();
6671 TemplateInstance
*ti
= sa
->toParent()->isTemplateInstance();
6672 if (ti
&& ti
->enclosing
)
6675 TemplateInstance
*ti
= sa
->isTemplateInstance();
6676 Declaration
*d
= sa
->isDeclaration();
6677 if ((td
&& td
->literal
) ||
6678 (ti
&& ti
->enclosing
) ||
6679 (d
&& !d
->isDataseg() &&
6680 !(d
->storage_class
& STCmanifest
) &&
6681 (!d
->isFuncDeclaration() || d
->isFuncDeclaration()->isNested()) &&
6685 // if module level template
6688 Dsymbol
*dparent
= sa
->toParent2();
6690 enclosing
= dparent
;
6691 else if (enclosing
!= dparent
)
6693 /* Select the more deeply nested of the two.
6694 * Error if one is not nested inside the other.
6696 for (Dsymbol
*p
= enclosing
; p
; p
= p
->parent
)
6699 goto L1
; // enclosing is most nested
6701 for (Dsymbol
*p
= dparent
; p
; p
= p
->parent
)
6705 enclosing
= dparent
;
6706 goto L1
; // dparent is most nested
6709 error("%s is nested in both %s and %s",
6710 toChars(), enclosing
->toChars(), dparent
->toChars());
6714 //printf("\tnested inside %s\n", enclosing->toChars());
6719 error("cannot use local `%s` as parameter to non-global template %s", sa
->toChars(), tempdecl
->toChars());
6726 nested
|= (int)hasNestedArgs(&va
->objects
, isstatic
);
6729 //printf("-TemplateInstance::hasNestedArgs('%s') = %d\n", tempdecl->ident->toChars(), nested);
6733 /*****************************************
6734 * Append 'this' to the specific module members[]
6736 Dsymbols
*TemplateInstance::appendToModuleMember()
6738 Module
*mi
= minst
; // instantiated -> inserted module
6740 if (global
.params
.useUnitTests
||
6741 global
.params
.debuglevel
)
6743 // Turn all non-root instances to speculative
6744 if (mi
&& !mi
->isRoot())
6748 //printf("%s->appendToModuleMember() enclosing = %s mi = %s\n",
6750 // enclosing ? enclosing->toPrettyChars() : NULL,
6751 // mi ? mi->toPrettyChars() : NULL);
6752 if (!mi
|| mi
->isRoot())
6754 /* If the instantiated module is speculative or root, insert to the
6755 * member of a root module. Then:
6756 * - semantic3 pass will get called on the instance members.
6757 * - codegen pass will get a selection chance to do/skip it.
6762 static Dsymbol
*getStrictEnclosing(TemplateInstance
*ti
)
6767 return ti
->enclosing
;
6768 ti
= ti
->tempdecl
->isInstantiated();
6774 Dsymbol
*enc
= N::getStrictEnclosing(this);
6776 // insert target is made stable by using the module
6777 // where tempdecl is declared.
6778 mi
= (enc
? enc
: tempdecl
)->getModule();
6780 mi
= mi
->importedFrom
;
6781 assert(mi
->isRoot());
6785 /* If the instantiated module is non-root, insert to the member of the
6786 * non-root module. Then:
6787 * - semantic3 pass won't be called on the instance.
6788 * - codegen pass won't reach to the instance.
6791 //printf("\t--> mi = %s\n", mi->toPrettyChars());
6793 if (memberOf
== mi
) // already a member
6798 Dsymbols
*a
= mi
->members
;
6801 if (mi
->semanticRun
>= PASSsemantic2done
&& mi
->isRoot())
6802 Module::addDeferredSemantic2(this);
6803 if (mi
->semanticRun
>= PASSsemantic3done
&& mi
->isRoot())
6804 Module::addDeferredSemantic3(this);
6808 /****************************************
6809 * This instance needs an identifier for name mangling purposes.
6810 * Create one by taking the template declaration name and adding
6811 * the type signature for it.
6814 Identifier
*TemplateInstance::genIdent(Objects
*args
)
6816 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
6817 assert(args
== tiargs
);
6819 mangleToBuffer(this, &buf
);
6820 //printf("\tgenIdent = %s\n", id);
6821 return Identifier::idPool(buf
.peekChars());
6824 /*************************************
6825 * Lazily generate identifier for template instance.
6826 * This is because 75% of the ident's are never needed.
6829 Identifier
*TemplateInstance::getIdent()
6831 if (!ident
&& inst
&& !errors
)
6832 ident
= genIdent(tiargs
); // need an identifier for name mangling purposes.
6836 /****************************************************
6837 * Declare parameters of template instance, initialize them with the
6838 * template instance arguments.
6841 void TemplateInstance::declareParameters(Scope
*sc
)
6843 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
6846 //printf("TemplateInstance::declareParameters()\n");
6847 for (size_t i
= 0; i
< tdtypes
.length
; i
++)
6849 TemplateParameter
*tp
= (*tempdecl
->parameters
)[i
];
6850 //RootObject *o = (*tiargs)[i];
6851 RootObject
*o
= tdtypes
[i
]; // initializer for tp
6853 //printf("\ttdtypes[%d] = %p\n", i, o);
6854 tempdecl
->declareParameter(sc
, tp
, o
);
6858 /**************************************
6859 * Given an error instantiating the TemplateInstance,
6860 * give the nested TemplateInstance instantiations that got
6861 * us here. Those are a list threaded into the nested scopes.
6863 void TemplateInstance::printInstantiationTrace()
6868 const unsigned max_shown
= 6;
6869 const char format
[] = "instantiated from here: %s";
6871 // determine instantiation depth and number of recursive instantiations
6872 unsigned n_instantiations
= 1;
6873 unsigned n_totalrecursions
= 0;
6874 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
6877 // If two instantiations use the same declaration, they are recursive.
6878 // (this works even if they are instantiated from different places in the
6880 // In principle, we could also check for multiple-template recursion, but it's
6881 // probably not worthwhile.
6882 if (cur
->tinst
&& cur
->tempdecl
&& cur
->tinst
->tempdecl
6883 && cur
->tempdecl
->loc
.equals(cur
->tinst
->tempdecl
->loc
))
6884 ++n_totalrecursions
;
6887 // show full trace only if it's short or verbose is on
6888 if (n_instantiations
<= max_shown
|| global
.params
.verbose
)
6890 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
6893 errorSupplemental(cur
->loc
, format
, cur
->toChars());
6896 else if (n_instantiations
- n_totalrecursions
<= max_shown
)
6898 // By collapsing recursive instantiations into a single line,
6899 // we can stay under the limit.
6900 int recursionDepth
=0;
6901 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
6904 if (cur
->tinst
&& cur
->tempdecl
&& cur
->tinst
->tempdecl
6905 && cur
->tempdecl
->loc
.equals(cur
->tinst
->tempdecl
->loc
))
6912 errorSupplemental(cur
->loc
, "%d recursive instantiations from here: %s", recursionDepth
+2, cur
->toChars());
6914 errorSupplemental(cur
->loc
, format
, cur
->toChars());
6921 // Even after collapsing the recursions, the depth is too deep.
6922 // Just display the first few and last few instantiations.
6924 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
6928 if (i
== max_shown
/ 2)
6929 errorSupplemental(cur
->loc
, "... (%d instantiations, -v to show) ...", n_instantiations
- max_shown
);
6931 if (i
< max_shown
/ 2 ||
6932 i
>= n_instantiations
- max_shown
+ max_shown
/ 2)
6933 errorSupplemental(cur
->loc
, format
, cur
->toChars());
6939 Dsymbol
*TemplateInstance::toAlias()
6943 // Maybe we can resolve it
6946 dsymbolSemantic(this, _scope
);
6950 error("cannot resolve forward reference");
6957 return inst
->toAlias();
6961 return aliasdecl
->toAlias();
6967 const char *TemplateInstance::kind() const
6969 return "template instance";
6972 bool TemplateInstance::oneMember(Dsymbol
**ps
, Identifier
*)
6978 const char *TemplateInstance::toChars()
6981 toCBufferInstance(this, &buf
);
6982 return buf
.extractChars();
6985 const char *TemplateInstance::toPrettyCharsHelper()
6988 toCBufferInstance(this, &buf
, true);
6989 return buf
.extractChars();
6992 /*************************************
6993 * Compare proposed template instantiation with existing template instantiation.
6994 * Note that this is not commutative because of the auto ref check.
6996 * this = proposed template instantiation
6997 * o = existing template instantiation
6999 * 0 for match, 1 for no match
7001 int TemplateInstance::compare(RootObject
*o
)
7003 TemplateInstance
*ti
= (TemplateInstance
*)o
;
7005 //printf("this = %p, ti = %p\n", this, ti);
7006 assert(tdtypes
.length
== ti
->tdtypes
.length
);
7008 // Nesting must match
7009 if (enclosing
!= ti
->enclosing
)
7011 //printf("test2 enclosing %s ti->enclosing %s\n", enclosing ? enclosing->toChars() : "", ti->enclosing ? ti->enclosing->toChars() : "");
7014 //printf("parent = %s, ti->parent = %s\n", parent->toPrettyChars(), ti->parent->toPrettyChars());
7016 if (!arrayObjectMatch(&tdtypes
, &ti
->tdtypes
))
7019 /* Template functions may have different instantiations based on
7020 * "auto ref" parameters.
7022 if (FuncDeclaration
*fd
= ti
->toAlias()->isFuncDeclaration())
7026 ParameterList fparameters
= fd
->getParameterList();
7027 size_t nfparams
= fparameters
.length(); // Num function parameters
7028 for (size_t j
= 0; j
< nfparams
; j
++)
7030 Parameter
*fparam
= fparameters
[j
];
7031 if (fparam
->storageClass
& STCautoref
) // if "auto ref"
7035 if (fargs
->length
<= j
)
7037 Expression
*farg
= (*fargs
)[j
];
7038 if (farg
->isLvalue())
7040 if (!(fparam
->storageClass
& STCref
))
7041 goto Lnotequals
; // auto ref's don't match
7045 if (fparam
->storageClass
& STCref
)
7046 goto Lnotequals
; // auto ref's don't match
7058 hash_t
TemplateInstance::toHash()
7062 hash
= (size_t)(void *)enclosing
;
7063 hash
+= arrayObjectHash(&tdtypes
);
7069 /**************************************
7070 * IsExpression can evaluate the specified type speculatively, and even if
7071 * it instantiates any symbols, they are normally unnecessary for the
7073 * However, if those symbols leak to the actual code, compiler should remark
7074 * them as non-speculative to generate their code and link to the final executable.
7076 void unSpeculative(Scope
*sc
, RootObject
*o
)
7081 if (Tuple
*tup
= isTuple(o
))
7083 for (size_t i
= 0; i
< tup
->objects
.length
; i
++)
7085 unSpeculative(sc
, tup
->objects
[i
]);
7090 Dsymbol
*s
= getDsymbol(o
);
7094 if (Declaration
*d
= s
->isDeclaration())
7096 if (VarDeclaration
*vd
= d
->isVarDeclaration())
7098 else if (AliasDeclaration
*ad
= d
->isAliasDeclaration())
7112 if (TemplateInstance
*ti
= s
->isTemplateInstance())
7114 // If the instance is already non-speculative,
7115 // or it is leaked to the speculative scope.
7116 if (ti
->minst
!= NULL
|| sc
->minst
== NULL
)
7119 // Remark as non-speculative instance.
7120 ti
->minst
= sc
->minst
;
7122 ti
->tinst
= sc
->tinst
;
7124 unSpeculative(sc
, ti
->tempdecl
);
7127 if (TemplateInstance
*ti
= s
->isInstantiated())
7128 unSpeculative(sc
, ti
);
7131 /***********************************************
7132 * Returns true if this is not instantiated in non-root module, and
7133 * is a part of non-speculative instantiatiation.
7135 * Note: minst does not stabilize until semantic analysis is completed,
7136 * so don't call this function during semantic analysis to return precise result.
7138 bool TemplateInstance::needsCodegen()
7140 // Now -allInst is just for the backward compatibility.
7141 if (global
.params
.allInst
)
7143 //printf("%s minst = %s, enclosing (%s)->isNonRoot = %d\n",
7144 // toPrettyChars(), minst ? minst->toChars() : NULL,
7145 // enclosing ? enclosing->toPrettyChars() : NULL, enclosing && enclosing->inNonRoot());
7148 // Bugzilla 14588: If the captured context is not a function
7149 // (e.g. class), the instance layout determination is guaranteed,
7150 // because the semantic/semantic2 pass will be executed
7151 // even for non-root instances.
7152 if (!enclosing
->isFuncDeclaration())
7155 // Bugzilla 14834: If the captured context is a function,
7156 // this excessive instantiation may cause ODR violation, because
7157 // -allInst and others doesn't guarantee the semantic3 execution
7158 // for that function.
7160 // If the enclosing is also an instantiated function,
7161 // we have to rely on the ancestor's needsCodegen() result.
7162 if (TemplateInstance
*ti
= enclosing
->isInstantiated())
7163 return ti
->needsCodegen();
7165 // Bugzilla 13415: If and only if the enclosing scope needs codegen,
7166 // this nested templates would also need code generation.
7167 return !enclosing
->inNonRoot();
7174 // If this is a speculative instantiation,
7175 // 1. do codegen if ancestors really needs codegen.
7176 // 2. become non-speculative if siblings are not speculative
7178 TemplateInstance
*tnext
= this->tnext
;
7179 TemplateInstance
*tinst
= this->tinst
;
7180 // At first, disconnect chain first to prevent infinite recursion.
7184 // Determine necessity of tinst before tnext.
7185 if (tinst
&& tinst
->needsCodegen())
7187 minst
= tinst
->minst
; // cache result
7189 assert(minst
->isRoot() || minst
->rootImports());
7192 if (tnext
&& (tnext
->needsCodegen() || tnext
->minst
))
7194 minst
= tnext
->minst
; // cache result
7196 return minst
->isRoot() || minst
->rootImports();
7199 // Elide codegen because this is really speculative.
7203 /* Even when this is reached to the codegen pass,
7204 * a non-root nested template should not generate code,
7205 * due to avoid ODR violation.
7207 if (enclosing
&& enclosing
->inNonRoot())
7211 bool r
= tinst
->needsCodegen();
7212 minst
= tinst
->minst
; // cache result
7217 bool r
= tnext
->needsCodegen();
7218 minst
= tnext
->minst
; // cache result
7224 /* The issue is that if the importee is compiled with a different -debug
7225 * setting than the importer, the importer may believe it exists
7226 * in the compiled importee when it does not, when the instantiation
7227 * is behind a conditional debug declaration.
7229 // workaround for Bugzilla 11239
7230 if (global
.params
.useUnitTests
||
7231 global
.params
.debuglevel
)
7233 // Prefer instantiations from root modules, to maximize link-ability.
7234 if (minst
->isRoot())
7237 TemplateInstance
*tnext
= this->tnext
;
7238 TemplateInstance
*tinst
= this->tinst
;
7242 if (tinst
&& tinst
->needsCodegen())
7244 minst
= tinst
->minst
; // cache result
7246 assert(minst
->isRoot() || minst
->rootImports());
7249 if (tnext
&& tnext
->needsCodegen())
7251 minst
= tnext
->minst
; // cache result
7253 assert(minst
->isRoot() || minst
->rootImports());
7257 // Bugzilla 2500 case
7258 if (minst
->rootImports())
7261 // Elide codegen because this is not included in root instances.
7266 // Prefer instantiations from non-root module, to minimize object code size.
7268 /* If a TemplateInstance is ever instantiated by non-root modules,
7269 * we do not have to generate code for it,
7270 * because it will be generated when the non-root module is compiled.
7272 * But, if the non-root 'minst' imports any root modules, it might still need codegen.
7274 * The problem is if A imports B, and B imports A, and both A
7275 * and B instantiate the same template, does the compilation of A
7276 * or the compilation of B do the actual instantiation?
7278 * See Bugzilla 2500.
7280 if (!minst
->isRoot() && !minst
->rootImports())
7283 TemplateInstance
*tnext
= this->tnext
;
7286 if (tnext
&& !tnext
->needsCodegen() && tnext
->minst
)
7288 minst
= tnext
->minst
; // cache result
7289 assert(!minst
->isRoot());
7293 // Do codegen because this is not included in non-root instances.
7298 /* ======================== TemplateMixin ================================ */
7300 TemplateMixin::TemplateMixin(Loc loc
, Identifier
*ident
, TypeQualified
*tqual
, Objects
*tiargs
)
7301 : TemplateInstance(loc
, tqual
->idents
.length
? (Identifier
*)tqual
->idents
[tqual
->idents
.length
- 1]
7302 : ((TypeIdentifier
*)tqual
)->ident
)
7304 //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : "");
7305 this->ident
= ident
;
7306 this->tqual
= tqual
;
7307 this->tiargs
= tiargs
? tiargs
: new Objects();
7310 Dsymbol
*TemplateMixin::syntaxCopy(Dsymbol
*)
7312 TemplateMixin
*tm
= new TemplateMixin(loc
, ident
,
7313 (TypeQualified
*)tqual
->syntaxCopy(), tiargs
);
7314 return TemplateInstance::syntaxCopy(tm
);
7317 bool TemplateMixin::findTempDecl(Scope
*sc
)
7319 // Follow qualifications to find the TemplateDeclaration
7325 tqual
->resolve(loc
, sc
, &e
, &t
, &s
);
7328 error("is not defined");
7332 tempdecl
= s
->isTemplateDeclaration();
7333 OverloadSet
*os
= s
->isOverloadSet();
7335 /* If an OverloadSet, look for a unique member that is a template declaration
7340 for (size_t i
= 0; i
< os
->a
.length
; i
++)
7342 Dsymbol
*s2
= os
->a
[i
]->isTemplateDeclaration();
7356 error("%s isn't a template", s
->toChars());
7362 struct ParamFwdResTm
7364 static int fp(void *param
, Dsymbol
*s
)
7366 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
7370 TemplateMixin
*tm
= (TemplateMixin
*)param
;
7371 if (td
->semanticRun
== PASSinit
)
7374 dsymbolSemantic(td
, td
->_scope
);
7377 tm
->semanticRun
= PASSinit
;
7384 // Look for forward references
7385 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
7386 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
7387 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
7389 if (overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, (void *)this, &ParamFwdResTm::fp
))
7395 const char *TemplateMixin::kind() const
7400 bool TemplateMixin::oneMember(Dsymbol
**ps
, Identifier
*ident
)
7402 return Dsymbol::oneMember(ps
, ident
);
7405 int TemplateMixin::apply(Dsymbol_apply_ft_t fp
, void *param
)
7407 if (_scope
) // if fwd reference
7408 dsymbolSemantic(this, NULL
); // try to resolve it
7411 for (size_t i
= 0; i
< members
->length
; i
++)
7413 Dsymbol
*s
= (*members
)[i
];
7416 if (s
->apply(fp
, param
))
7424 bool TemplateMixin::hasPointers()
7426 //printf("TemplateMixin::hasPointers() %s\n", toChars());
7430 for (size_t i
= 0; i
< members
->length
; i
++)
7432 Dsymbol
*s
= (*members
)[i
];
7433 //printf(" s = %s %s\n", s->kind(), s->toChars());
7434 if (s
->hasPointers())
7443 void TemplateMixin::setFieldOffset(AggregateDeclaration
*ad
, unsigned *poffset
, bool isunion
)
7445 //printf("TemplateMixin::setFieldOffset() %s\n", toChars());
7446 if (_scope
) // if fwd reference
7447 dsymbolSemantic(this, NULL
); // try to resolve it
7450 for (size_t i
= 0; i
< members
->length
; i
++)
7452 Dsymbol
*s
= (*members
)[i
];
7453 //printf("\t%s\n", s->toChars());
7454 s
->setFieldOffset(ad
, poffset
, isunion
);
7459 const char *TemplateMixin::toChars()
7462 toCBufferInstance(this, &buf
);
7463 return buf
.extractChars();