2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2020 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"
38 #define IDX_NOTFOUND (0x12345678) // index is not found
40 Type
*rawTypeMerge(Type
*t1
, Type
*t2
);
41 bool MODimplicitConv(MOD modfrom
, MOD modto
);
42 MATCH
MODmethodConv(MOD modfrom
, MOD modto
);
43 MOD
MODmerge(MOD mod1
, MOD mod2
);
45 static size_t templateParameterLookup(Type
*tparam
, TemplateParameters
*parameters
);
46 static int arrayObjectMatch(Objects
*oa1
, Objects
*oa2
);
47 static unsigned char deduceWildHelper(Type
*t
, Type
**at
, Type
*tparam
);
48 static MATCH
deduceTypeHelper(Type
*t
, Type
**at
, Type
*tparam
);
49 static bool reliesOnTident(Type
*t
, TemplateParameters
*tparams
= NULL
, size_t iStart
= 0);
50 Expression
*semantic(Expression
*e
, Scope
*sc
);
51 bool evalStaticCondition(Scope
*sc
, Expression
*exp
, Expression
*e
, bool &errors
);
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 void TemplateDeclaration::semantic(Scope
*sc
)
572 if (semanticRun
!= PASSinit
)
573 return; // semantic() already run
575 // Remember templates defined in module object that we need to know about
576 if (sc
->_module
&& sc
->_module
->ident
== Id::object
)
578 if (ident
== Id::RTInfo
)
582 /* Remember Scope for later instantiations, but make
583 * a copy since attributes can change.
587 this->_scope
= sc
->copy();
588 this->_scope
->setNoFree();
591 semanticRun
= PASSsemantic
;
594 protection
= sc
->protection
;
595 isstatic
= toParent()->isModule() || (_scope
->stc
& STCstatic
);
599 if (AggregateDeclaration
*ad
= parent
->pastMixin()->isAggregateDeclaration())
603 // Set up scope for parameters
604 ScopeDsymbol
*paramsym
= new ScopeDsymbol();
605 paramsym
->parent
= parent
;
606 Scope
*paramscope
= sc
->push(paramsym
);
609 if (global
.params
.doDocComments
)
611 origParameters
= new TemplateParameters();
612 origParameters
->setDim(parameters
->length
);
613 for (size_t i
= 0; i
< parameters
->length
; i
++)
615 TemplateParameter
*tp
= (*parameters
)[i
];
616 (*origParameters
)[i
] = tp
->syntaxCopy();
620 for (size_t i
= 0; i
< parameters
->length
; i
++)
622 TemplateParameter
*tp
= (*parameters
)[i
];
624 if (!tp
->declareParameter(paramscope
))
626 error(tp
->loc
, "parameter '%s' multiply defined", tp
->ident
->toChars());
629 if (!tp
->semantic(paramscope
, parameters
))
633 if (i
+ 1 != parameters
->length
&& tp
->isTemplateTupleParameter())
635 error("template tuple parameter must be last one");
640 /* Calculate TemplateParameter::dependent
642 TemplateParameters tparams
;
644 for (size_t i
= 0; i
< parameters
->length
; i
++)
646 TemplateParameter
*tp
= (*parameters
)[i
];
649 for (size_t j
= 0; j
< parameters
->length
; j
++)
651 // Skip cases like: X(T : T)
655 if (TemplateTypeParameter
*ttp
= (*parameters
)[j
]->isTemplateTypeParameter())
657 if (reliesOnTident(ttp
->specType
, &tparams
))
658 tp
->dependent
= true;
660 else if (TemplateAliasParameter
*tap
= (*parameters
)[j
]->isTemplateAliasParameter())
662 if (reliesOnTident(tap
->specType
, &tparams
) ||
663 reliesOnTident(isType(tap
->specAlias
), &tparams
))
665 tp
->dependent
= true;
678 if (Dsymbol::oneMembers(members
, &s
, ident
) && s
)
685 /* BUG: should check:
686 * o no virtual functions or non-static data members of classes
688 semanticRun
= PASSsemanticdone
;
691 const char *TemplateDeclaration::kind() const
693 return (onemember
&& onemember
->isAggregateDeclaration())
698 /**********************************
699 * Overload existing TemplateDeclaration 'this' with the new one 's'.
700 * Return true if successful; i.e. no conflict.
703 bool TemplateDeclaration::overloadInsert(Dsymbol
*s
)
705 FuncDeclaration
*fd
= s
->isFuncDeclaration();
709 return funcroot
->overloadInsert(fd
);
711 return funcroot
->overloadInsert(this);
714 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
718 TemplateDeclaration
*pthis
= this;
719 TemplateDeclaration
**ptd
;
720 for (ptd
= &pthis
; *ptd
; ptd
= &(*ptd
)->overnext
)
729 /****************************
730 * Check to see if constraint is satisfied.
732 bool TemplateDeclaration::evaluateConstraint(
733 TemplateInstance
*ti
, Scope
*sc
, Scope
*paramscope
,
734 Objects
*dedargs
, FuncDeclaration
*fd
)
736 /* Detect recursive attempts to instantiate this template declaration,
738 * void foo(T)(T x) if (is(typeof(foo(x)))) { }
739 * static assert(!is(typeof(foo(7))));
740 * Recursive attempts are regarded as a constraint failure.
742 /* There's a chicken-and-egg problem here. We don't know yet if this template
743 * instantiation will be a local one (enclosing is set), and we won't know until
744 * after selecting the correct template. Thus, function we're nesting inside
745 * is not on the sc scope chain, and this can cause errors in FuncDeclaration::getLevel().
746 * Workaround the problem by setting a flag to relax the checking on frame errors.
749 for (TemplatePrevious
*p
= previous
; p
; p
= p
->prev
)
751 if (arrayObjectMatch(p
->dedargs
, dedargs
))
753 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
754 /* It must be a subscope of p->sc, other scope chains are not recursive
757 for (Scope
*scx
= sc
; scx
; scx
= scx
->enclosing
)
763 /* BUG: should also check for ref param differences
770 pr
.dedargs
= dedargs
;
771 previous
= &pr
; // add this to threaded list
773 Scope
*scx
= paramscope
->push(ti
);
781 /* Declare all the function parameters as variables and add them to the scope
782 * Making parameters is similar to FuncDeclaration::semantic3
784 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
785 assert(tf
->ty
== Tfunction
);
789 Parameters
*fparameters
= tf
->parameterList
.parameters
;
790 VarArg fvarargs
= tf
->parameterList
.varargs
;
792 size_t nfparams
= Parameter::dim(fparameters
);
793 for (size_t i
= 0; i
< nfparams
; i
++)
795 Parameter
*fparam
= Parameter::getNth(fparameters
, i
);
796 fparam
->storageClass
&= (STCin
| STCout
| STCref
| STClazy
| STCfinal
| STC_TYPECTOR
| STCnodtor
);
797 fparam
->storageClass
|= STCparameter
;
798 if (fvarargs
== VARARGtypesafe
&& i
+ 1 == nfparams
)
799 fparam
->storageClass
|= STCvariadic
;
801 for (size_t i
= 0; i
< fparameters
->length
; i
++)
803 Parameter
*fparam
= (*fparameters
)[i
];
805 continue; // don't add it, if it has no name
806 VarDeclaration
*v
= new VarDeclaration(loc
, fparam
->type
, fparam
->ident
, NULL
);
807 v
->storage_class
= fparam
->storageClass
;
810 ti
->symtab
= new DsymbolTable();
812 error("parameter %s.%s is already defined", toChars(), v
->toChars());
817 fd
->storage_class
|= STCstatic
;
819 fd
->vthis
= fd
->declareThis(scx
, fd
->isThis());
822 Expression
*e
= constraint
->syntaxCopy();
824 assert(ti
->inst
== NULL
);
825 ti
->inst
= ti
; // temporary instantiation to enable genIdent()
827 scx
->flags
|= SCOPEconstraint
;
829 bool result
= evalStaticCondition(scx
, constraint
, e
, errors
);
833 previous
= pr
.prev
; // unlink from threaded list
839 /***************************************
840 * Given that ti is an instance of this TemplateDeclaration,
841 * deduce the types of the parameters to this, and store
842 * those deduced types in dedtypes[].
844 * flag 1: don't do semantic() because of dummy types
845 * 2: don't change types in matchArg()
847 * dedtypes deduced arguments
848 * Return match level.
851 MATCH
TemplateDeclaration::matchWithInstance(Scope
*sc
, TemplateInstance
*ti
,
852 Objects
*dedtypes
, Expressions
*fargs
, int flag
)
855 size_t dedtypes_dim
= dedtypes
->length
;
862 size_t parameters_dim
= parameters
->length
;
863 int variadic
= isVariadic() != NULL
;
865 // If more arguments than parameters, no match
866 if (ti
->tiargs
->length
> parameters_dim
&& !variadic
)
871 assert(dedtypes_dim
== parameters_dim
);
872 assert(dedtypes_dim
>= ti
->tiargs
->length
|| variadic
);
876 // Set up scope for template parameters
877 ScopeDsymbol
*paramsym
= new ScopeDsymbol();
878 paramsym
->parent
= _scope
->parent
;
879 Scope
*paramscope
= _scope
->push(paramsym
);
880 paramscope
->tinst
= ti
;
881 paramscope
->minst
= sc
->minst
;
882 paramscope
->callsc
= sc
;
885 // Attempt type deduction
887 for (size_t i
= 0; i
< dedtypes_dim
; i
++)
890 TemplateParameter
*tp
= (*parameters
)[i
];
893 //printf("\targument [%d]\n", i);
894 m2
= tp
->matchArg(ti
->loc
, paramscope
, ti
->tiargs
, i
, parameters
, dedtypes
, &sparam
);
895 //printf("\tm2 = %d\n", m2);
897 if (m2
== MATCHnomatch
)
906 sparam
->semantic(paramscope
);
907 if (!paramscope
->insert(sparam
)) // TODO: This check can make more early
908 goto Lnomatch
; // in TemplateDeclaration::semantic, and
909 // then we don't need to make sparam if flags == 0
914 /* Any parameter left without a type gets the type of
915 * its corresponding arg
917 for (size_t i
= 0; i
< dedtypes_dim
; i
++)
921 assert(i
< ti
->tiargs
->length
);
922 (*dedtypes
)[i
] = (Type
*)(*ti
->tiargs
)[i
];
927 if (m
> MATCHnomatch
&& constraint
&& !flag
)
929 if (ti
->hasNestedArgs(ti
->tiargs
, this->isstatic
)) // TODO: should gag error
930 ti
->parent
= ti
->enclosing
;
932 ti
->parent
= this->parent
;
934 // Similar to doHeaderInstantiation
935 FuncDeclaration
*fd
= onemember
? onemember
->isFuncDeclaration() : NULL
;
938 assert(fd
->type
->ty
== Tfunction
);
939 TypeFunction
*tf
= (TypeFunction
*)fd
->type
->syntaxCopy();
941 fd
= new FuncDeclaration(fd
->loc
, fd
->endloc
, fd
->ident
, fd
->storage_class
, tf
);
943 fd
->inferRetType
= true;
945 // Shouldn't run semantic on default arguments and return type.
946 for (size_t i
= 0; i
< tf
->parameterList
.parameters
->length
; i
++)
947 (*tf
->parameterList
.parameters
)[i
]->defaultArg
= NULL
;
950 // Resolve parameter types and 'auto ref's.
952 unsigned olderrors
= global
.startGagging();
953 fd
->type
= tf
->semantic(loc
, paramscope
);
954 if (global
.endGagging(olderrors
))
956 assert(fd
->type
->ty
!= Tfunction
);
959 assert(fd
->type
->ty
== Tfunction
);
960 fd
->originalType
= fd
->type
; // for mangling
963 // TODO: dedtypes => ti->tiargs ?
964 if (!evaluateConstraint(ti
, sc
, paramscope
, dedtypes
, fd
))
978 /********************************************
979 * Determine partial specialization order of 'this' vs td2.
981 * match this is at least as specialized as td2
982 * 0 td2 is more specialized than this
985 MATCH
TemplateDeclaration::leastAsSpecialized(Scope
*sc
, TemplateDeclaration
*td2
, Expressions
*fargs
)
987 /* This works by taking the template parameters to this template
988 * declaration and feeding them to td2 as if it were a template
990 * If it works, then this template is at least as specialized
994 TemplateInstance
ti(Loc(), ident
); // create dummy template instance
995 // Set type arguments to dummy template instance to be types
996 // generated from the parameters to this template declaration
997 ti
.tiargs
= new Objects();
998 ti
.tiargs
->reserve(parameters
->length
);
999 for (size_t i
= 0; i
< parameters
->length
; i
++)
1001 TemplateParameter
*tp
= (*parameters
)[i
];
1004 RootObject
*p
= (RootObject
*)tp
->dummyArg();
1011 // Temporary Array to hold deduced types
1013 dedtypes
.setDim(td2
->parameters
->length
);
1015 // Attempt a type deduction
1016 MATCH m
= td2
->matchWithInstance(sc
, &ti
, &dedtypes
, fargs
, 1);
1017 if (m
> MATCHnomatch
)
1019 /* A non-variadic template is more specialized than a
1022 TemplateTupleParameter
*tp
= isVariadic();
1023 if (tp
&& !tp
->dependent
&& !td2
->isVariadic())
1029 return MATCHnomatch
;
1032 static Expression
*emptyArrayElement
= NULL
;
1034 class TypeDeduced
: public Type
1038 Expressions argexps
; // corresponding expressions
1039 Types tparams
; // tparams[i]->mod
1041 TypeDeduced(Type
*tt
, Expression
*e
, Type
*tparam
)
1046 tparams
.push(tparam
);
1049 virtual ~TypeDeduced()
1053 void update(Expression
*e
, Type
*tparam
)
1056 tparams
.push(tparam
);
1058 void update(Type
*tt
, Expression
*e
, Type
*tparam
)
1062 tparams
.push(tparam
);
1064 MATCH
matchAll(Type
*tt
)
1066 MATCH match
= MATCHexact
;
1067 for (size_t j
= 0; j
< argexps
.length
; j
++)
1069 Expression
*e
= argexps
[j
];
1071 if (e
== emptyArrayElement
)
1074 Type
*t
= tt
->addMod(tparams
[j
]->mod
)->substWildTo(MODconst
);
1076 MATCH m
= e
->implicitConvTo(t
);
1079 if (match
<= MATCHnomatch
)
1086 /*************************************************
1087 * Match function arguments against a specific template function.
1090 * sc instantiation scope
1092 * tthis 'this' argument if !NULL
1093 * fargs arguments to function
1095 * fd Partially instantiated function declaration
1096 * ti->tdtypes Expression/Type deduced template arguments
1099 * bit 0-3 Match template parameters by inferred template arguments
1100 * bit 4-7 Match template parameters by initial template arguments
1103 MATCH
TemplateDeclaration::deduceFunctionTemplateMatch(
1104 TemplateInstance
*ti
, Scope
*sc
,
1105 FuncDeclaration
*&fd
, Type
*tthis
, Expressions
*fargs
)
1109 size_t ntargs
; // array size of tiargs
1110 size_t fptupindex
= IDX_NOTFOUND
;
1111 MATCH match
= MATCHexact
;
1112 MATCH matchTiargs
= MATCHexact
;
1113 ParameterList fparameters
; // function parameter list
1114 unsigned wildmatch
= 0;
1115 size_t inferStart
= 0;
1117 Loc instLoc
= ti
->loc
;
1118 Objects
*tiargs
= ti
->tiargs
;
1119 Objects
*dedargs
= new Objects();
1120 Objects
* dedtypes
= &ti
->tdtypes
; // for T:T*, the dedargs is the T*, dedtypes is the T
1124 dedargs
->setDim(parameters
->length
);
1127 dedtypes
->setDim(parameters
->length
);
1130 if (errors
|| fd
->errors
)
1131 return MATCHnomatch
;
1133 // Set up scope for parameters
1134 ScopeDsymbol
*paramsym
= new ScopeDsymbol();
1135 paramsym
->parent
= _scope
->parent
; // should use hasnestedArgs and enclosing?
1136 Scope
*paramscope
= _scope
->push(paramsym
);
1137 paramscope
->tinst
= ti
;
1138 paramscope
->minst
= sc
->minst
;
1139 paramscope
->callsc
= sc
;
1140 paramscope
->stc
= 0;
1142 TemplateTupleParameter
*tp
= isVariadic();
1143 Tuple
*declaredTuple
= NULL
;
1148 // Set initial template arguments
1149 ntargs
= tiargs
->length
;
1150 size_t n
= parameters
->length
;
1158 /* The extra initial template arguments
1159 * now form the tuple argument.
1161 Tuple
*t
= new Tuple();
1162 assert(parameters
->length
);
1163 (*dedargs
)[parameters
->length
- 1] = t
;
1165 t
->objects
.setDim(ntargs
- n
);
1166 for (size_t i
= 0; i
< t
->objects
.length
; i
++)
1168 t
->objects
[i
] = (*tiargs
)[n
+ i
];
1170 declareParameter(paramscope
, tp
, t
);
1176 memcpy(dedargs
->tdata(), tiargs
->tdata(), n
* sizeof(*dedargs
->tdata()));
1178 for (size_t i
= 0; i
< n
; i
++)
1180 assert(i
< parameters
->length
);
1181 Declaration
*sparam
= NULL
;
1182 MATCH m
= (*parameters
)[i
]->matchArg(instLoc
, paramscope
, dedargs
, i
, parameters
, dedtypes
, &sparam
);
1183 //printf("\tdeduceType m = %d\n", m);
1184 if (m
<= MATCHnomatch
)
1186 if (m
< matchTiargs
)
1189 sparam
->semantic(paramscope
);
1190 if (!paramscope
->insert(sparam
))
1193 if (n
< parameters
->length
&& !declaredTuple
)
1198 inferStart
= parameters
->length
;
1199 //printf("tiargs matchTiargs = %d\n", matchTiargs);
1202 fparameters
= fd
->getParameterList();
1203 nfparams
= fparameters
.length(); // number of function parameters
1204 nfargs
= fargs
? fargs
->length
: 0; // number of function arguments
1206 /* Check for match of function arguments with variadic template
1207 * parameter, such as:
1209 * void foo(T, A...)(T t, A a);
1210 * void main() { foo(1,2,3); }
1212 if (tp
) // if variadic
1214 // TemplateTupleParameter always makes most lesser matching.
1215 matchTiargs
= MATCHconvert
;
1217 if (nfparams
== 0 && nfargs
!= 0) // if no function parameters
1221 Tuple
*t
= new Tuple();
1222 //printf("t = %p\n", t);
1223 (*dedargs
)[parameters
->length
- 1] = t
;
1224 declareParameter(paramscope
, tp
, t
);
1230 /* Figure out which of the function parameters matches
1231 * the tuple template parameter. Do this by matching
1233 * Set the index of this function parameter to fptupindex.
1235 for (fptupindex
= 0; fptupindex
< nfparams
; fptupindex
++)
1237 Parameter
*fparam
= (*fparameters
.parameters
)[fptupindex
];
1238 if (fparam
->type
->ty
!= Tident
)
1240 TypeIdentifier
*tid
= (TypeIdentifier
*)fparam
->type
;
1241 if (!tp
->ident
->equals(tid
->ident
) || tid
->idents
.length
)
1244 if (fparameters
.varargs
!= VARARGnone
) // variadic function doesn't
1245 goto Lnomatch
; // go with variadic template
1249 fptupindex
= IDX_NOTFOUND
;
1255 if (toParent()->isModule() || (_scope
->stc
& STCstatic
))
1259 bool hasttp
= false;
1261 // Match 'tthis' to any TemplateThisParameter's
1262 for (size_t i
= 0; i
< parameters
->length
; i
++)
1264 TemplateThisParameter
*ttp
= (*parameters
)[i
]->isTemplateThisParameter();
1269 Type
*t
= new TypeIdentifier(Loc(), ttp
->ident
);
1270 MATCH m
= deduceType(tthis
, paramscope
, t
, parameters
, dedtypes
);
1271 if (m
<= MATCHnomatch
)
1274 match
= m
; // pick worst match
1278 // Match attributes of tthis against attributes of fd
1279 if (fd
->type
&& !fd
->isCtorDeclaration())
1281 StorageClass stc
= _scope
->stc
| fd
->storage_class2
;
1282 // Propagate parent storage class (see bug 5504)
1283 Dsymbol
*p
= parent
;
1284 while (p
->isTemplateDeclaration() || p
->isTemplateInstance())
1286 AggregateDeclaration
*ad
= p
->isAggregateDeclaration();
1288 stc
|= ad
->storage_class
;
1290 unsigned char mod
= fd
->type
->mod
;
1291 if (stc
& STCimmutable
)
1295 if (stc
& (STCshared
| STCsynchronized
))
1303 unsigned char thismod
= tthis
->mod
;
1305 mod
= MODmerge(thismod
, mod
);
1306 MATCH m
= MODmethodConv(thismod
, mod
);
1307 if (m
<= MATCHnomatch
)
1314 // Loop through the function parameters
1316 //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple->objects.length : 0);
1317 //printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple->toChars() : NULL);
1319 size_t nfargs2
= nfargs
; // nfargs + supplied defaultArgs
1320 for (size_t parami
= 0; parami
< nfparams
; parami
++)
1322 Parameter
*fparam
= fparameters
[parami
];
1324 // Apply function parameter storage classes to parameter types
1325 Type
*prmtype
= fparam
->type
->addStorageClass(fparam
->storageClass
);
1329 /* See function parameters which wound up
1330 * as part of a template tuple parameter.
1332 if (fptupindex
!= IDX_NOTFOUND
&& parami
== fptupindex
)
1334 assert(prmtype
->ty
== Tident
);
1335 TypeIdentifier
*tid
= (TypeIdentifier
*)prmtype
;
1338 /* The types of the function arguments
1339 * now form the tuple argument.
1341 declaredTuple
= new Tuple();
1342 (*dedargs
)[parameters
->length
- 1] = declaredTuple
;
1344 /* Count function parameters following a tuple parameter.
1345 * void foo(U, T...)(int y, T, U, int) {} // rem == 2 (U, int)
1348 for (size_t j
= parami
+ 1; j
< nfparams
; j
++)
1350 Parameter
*p
= fparameters
[j
];
1351 if (!reliesOnTident(p
->type
, parameters
, inferStart
))
1353 Type
*pt
= p
->type
->syntaxCopy()->semantic(fd
->loc
, paramscope
);
1354 rem
+= pt
->ty
== Ttuple
? ((TypeTuple
*)pt
)->arguments
->length
: 1;
1362 if (nfargs2
- argi
< rem
)
1364 declaredTuple
->objects
.setDim(nfargs2
- argi
- rem
);
1365 for (size_t i
= 0; i
< declaredTuple
->objects
.length
; i
++)
1367 farg
= (*fargs
)[argi
+ i
];
1369 // Check invalid arguments to detect errors early.
1370 if (farg
->op
== TOKerror
|| farg
->type
->ty
== Terror
)
1373 if (!(fparam
->storageClass
& STClazy
) && farg
->type
->ty
== Tvoid
)
1378 if (unsigned char wm
= deduceWildHelper(farg
->type
, &tt
, tid
))
1385 m
= deduceTypeHelper(farg
->type
, &tt
, tid
);
1387 if (m
<= MATCHnomatch
)
1392 /* Remove top const for dynamic array types and pointer types
1394 if ((tt
->ty
== Tarray
|| tt
->ty
== Tpointer
) &&
1396 (!(fparam
->storageClass
& STCref
) ||
1397 ((fparam
->storageClass
& STCauto
) && !farg
->isLvalue())))
1399 tt
= tt
->mutableOf();
1401 declaredTuple
->objects
[i
] = tt
;
1403 declareParameter(paramscope
, tp
, declaredTuple
);
1407 // Bugzilla 6810: If declared tuple is not a type tuple,
1408 // it cannot be function parameter types.
1409 for (size_t i
= 0; i
< declaredTuple
->objects
.length
; i
++)
1411 if (!isType(declaredTuple
->objects
[i
]))
1415 assert(declaredTuple
);
1416 argi
+= declaredTuple
->objects
.length
;
1420 // If parameter type doesn't depend on inferred template parameters,
1421 // semantic it to get actual type.
1422 if (!reliesOnTident(prmtype
, parameters
, inferStart
))
1424 // should copy prmtype to avoid affecting semantic result
1425 prmtype
= prmtype
->syntaxCopy()->semantic(fd
->loc
, paramscope
);
1427 if (prmtype
->ty
== Ttuple
)
1429 TypeTuple
*tt
= (TypeTuple
*)prmtype
;
1430 size_t tt_dim
= tt
->arguments
->length
;
1431 for (size_t j
= 0; j
< tt_dim
; j
++, ++argi
)
1433 Parameter
*p
= (*tt
->arguments
)[j
];
1434 if (j
== tt_dim
- 1 && fparameters
.varargs
== VARARGtypesafe
&&
1435 parami
+ 1 == nfparams
&& argi
< nfargs
)
1446 farg
= (*fargs
)[argi
];
1447 if (!farg
->implicitConvTo(p
->type
))
1454 if (argi
>= nfargs
) // if not enough arguments
1456 if (!fparam
->defaultArg
)
1459 /* Bugzilla 2803: Before the starting of type deduction from the function
1460 * default arguments, set the already deduced parameters into paramscope.
1461 * It's necessary to avoid breaking existing acceptable code. Cases:
1463 * 1. Already deduced template parameters can appear in fparam->defaultArg:
1464 * auto foo(A, B)(A a, B b = A.stringof);
1466 * // at fparam == 'B b = A.string', A is equivalent with the deduced type 'int'
1468 * 2. If prmtype depends on default-specified template parameter, the
1469 * default type should be preferred.
1470 * auto foo(N = size_t, R)(R r, N start = 0)
1472 * // at fparam `N start = 0`, N should be 'size_t' before
1473 * // the deduction result from fparam->defaultArg.
1477 for (size_t i
= 0; i
< dedtypes
->length
; i
++)
1479 Type
*at
= isType((*dedtypes
)[i
]);
1480 if (at
&& at
->ty
== Tnone
)
1482 TypeDeduced
*xt
= (TypeDeduced
*)at
;
1483 (*dedtypes
)[i
] = xt
->tded
; // 'unbox'
1487 for (size_t i
= ntargs
; i
< dedargs
->length
; i
++)
1489 TemplateParameter
*tparam
= (*parameters
)[i
];
1491 RootObject
*oarg
= (*dedargs
)[i
];
1492 RootObject
*oded
= (*dedtypes
)[i
];
1497 if (tparam
->specialization() || !tparam
->isTemplateTypeParameter())
1499 /* The specialization can work as long as afterwards
1502 (*dedargs
)[i
] = oded
;
1503 MATCH m2
= tparam
->matchArg(instLoc
, paramscope
, dedargs
, i
, parameters
, dedtypes
, NULL
);
1504 //printf("m2 = %d\n", m2);
1505 if (m2
<= MATCHnomatch
)
1507 if (m2
< matchTiargs
)
1508 matchTiargs
= m2
; // pick worst match
1509 if (!(*dedtypes
)[i
]->equals(oded
))
1510 error("specialization not allowed for deduced parameter %s", tparam
->ident
->toChars());
1514 if (MATCHconvert
< matchTiargs
)
1515 matchTiargs
= MATCHconvert
;
1517 (*dedargs
)[i
] = declareParameter(paramscope
, tparam
, oded
);
1521 oded
= tparam
->defaultArg(instLoc
, paramscope
);
1523 (*dedargs
)[i
] = declareParameter(paramscope
, tparam
, oded
);
1530 /* If prmtype does not depend on any template parameters:
1532 * auto foo(T)(T v, double x = 0);
1534 * // at fparam == 'double x = 0'
1536 * or, if all template parameters in the prmtype are already deduced:
1538 * auto foo(R)(R range, ElementType!R sum = 0);
1540 * // at fparam == 'ElementType!R sum = 0'
1542 * Deducing prmtype from fparam->defaultArg is not necessary.
1544 if (prmtype
->deco
||
1545 prmtype
->syntaxCopy()->trySemantic(loc
, paramscope
))
1551 // Deduce prmtype from the defaultArg.
1552 farg
= fparam
->defaultArg
->syntaxCopy();
1553 farg
= ::semantic(farg
, paramscope
);
1554 farg
= resolveProperties(paramscope
, farg
);
1558 farg
= (*fargs
)[argi
];
1561 // Check invalid arguments to detect errors early.
1562 if (farg
->op
== TOKerror
|| farg
->type
->ty
== Terror
)
1567 Type
*argtype
= farg
->type
;
1569 if (!(fparam
->storageClass
& STClazy
) && argtype
->ty
== Tvoid
&& farg
->op
!= TOKfunction
)
1572 // Bugzilla 12876: optimize arugument to allow CT-known length matching
1573 farg
= farg
->optimize(WANTvalue
, (fparam
->storageClass
& (STCref
| STCout
)) != 0);
1574 //printf("farg = %s %s\n", farg->type->toChars(), farg->toChars());
1576 RootObject
*oarg
= farg
;
1577 if ((fparam
->storageClass
& STCref
) &&
1578 (!(fparam
->storageClass
& STCauto
) || farg
->isLvalue()))
1580 /* Allow expressions that have CT-known boundaries and type [] to match with [dim]
1583 if (argtype
->ty
== Tarray
&&
1584 (prmtype
->ty
== Tsarray
||
1585 (prmtype
->ty
== Taarray
&& (taai
= ((TypeAArray
*)prmtype
)->index
)->ty
== Tident
&&
1586 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
1588 if (farg
->op
== TOKstring
)
1590 StringExp
*se
= (StringExp
*)farg
;
1591 argtype
= se
->type
->nextOf()->sarrayOf(se
->len
);
1593 else if (farg
->op
== TOKarrayliteral
)
1595 ArrayLiteralExp
*ae
= (ArrayLiteralExp
*)farg
;
1596 argtype
= ae
->type
->nextOf()->sarrayOf(ae
->elements
->length
);
1598 else if (farg
->op
== TOKslice
)
1600 SliceExp
*se
= (SliceExp
*)farg
;
1601 if (Type
*tsa
= toStaticArrayType(se
))
1608 else if ((fparam
->storageClass
& STCout
) == 0 &&
1609 (argtype
->ty
== Tarray
|| argtype
->ty
== Tpointer
) &&
1610 templateParameterLookup(prmtype
, parameters
) != IDX_NOTFOUND
&&
1611 ((TypeIdentifier
*)prmtype
)->idents
.length
== 0)
1613 /* The farg passing to the prmtype always make a copy. Therefore,
1614 * we can shrink the set of the deduced type arguments for prmtype
1615 * by adjusting top-qualifier of the argtype.
1617 * prmtype argtype ta
1618 * T <- const(E)[] const(E)[]
1619 * T <- const(E[]) const(E)[]
1620 * qualifier(T) <- const(E)[] const(E[])
1621 * qualifier(T) <- const(E[]) const(E[])
1623 Type
*ta
= argtype
->castMod(prmtype
->mod
? argtype
->nextOf()->mod
: 0);
1626 Expression
*ea
= farg
->copy();
1632 if (fparameters
.varargs
== VARARGtypesafe
&& parami
+ 1 == nfparams
&& argi
+ 1 < nfargs
)
1636 MATCH m
= deduceType(oarg
, paramscope
, prmtype
, parameters
, dedtypes
, &wm
, inferStart
);
1637 //printf("\tL%d deduceType m = %d, wm = x%x, wildmatch = x%x\n", __LINE__, m, wm, wildmatch);
1640 /* If no match, see if the argument can be matched by using
1641 * implicit conversions.
1643 if (m
== MATCHnomatch
&& prmtype
->deco
)
1644 m
= farg
->implicitConvTo(prmtype
);
1646 if (m
== MATCHnomatch
)
1648 AggregateDeclaration
*ad
= isAggregate(farg
->type
);
1649 if (ad
&& ad
->aliasthis
&& argtype
!= att
)
1651 if (!att
&& argtype
->checkAliasThisRec()) // Bugzilla 12537
1654 /* If a semantic error occurs while doing alias this,
1655 * eg purity(bug 7295), just regard it as not a match.
1657 if (Expression
*e
= resolveAliasThis(sc
, farg
, true))
1665 if (m
> MATCHnomatch
&& (fparam
->storageClass
& (STCref
| STCauto
)) == STCref
)
1667 if (!farg
->isLvalue())
1669 if ((farg
->op
== TOKstring
|| farg
->op
== TOKslice
) &&
1670 (prmtype
->ty
== Tsarray
|| prmtype
->ty
== Taarray
))
1672 // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
1678 if (m
> MATCHnomatch
&& (fparam
->storageClass
& STCout
))
1680 if (!farg
->isLvalue())
1682 if (!farg
->type
->isMutable()) // Bugzilla 11916
1685 if (m
== MATCHnomatch
&& (fparam
->storageClass
& STClazy
) && prmtype
->ty
== Tvoid
&&
1686 farg
->type
->ty
!= Tvoid
)
1689 if (m
!= MATCHnomatch
)
1692 match
= m
; // pick worst match
1699 /* The following code for variadic arguments closely
1700 * matches TypeFunction::callMatch()
1702 if (!(fparameters
.varargs
== VARARGtypesafe
&& parami
+ 1 == nfparams
))
1705 /* Check for match with function parameter T...
1707 Type
*tb
= prmtype
->toBasetype();
1710 // 6764 fix - TypeAArray may be TypeSArray have not yet run semantic().
1713 // Perhaps we can do better with this, see TypeFunction::callMatch()
1714 if (tb
->ty
== Tsarray
)
1716 TypeSArray
*tsa
= (TypeSArray
*)tb
;
1717 dinteger_t sz
= tsa
->dim
->toInteger();
1718 if (sz
!= nfargs
- argi
)
1721 else if (tb
->ty
== Taarray
)
1723 TypeAArray
*taa
= (TypeAArray
*)tb
;
1724 Expression
*dim
= new IntegerExp(instLoc
, nfargs
- argi
, Type::tsize_t
);
1726 size_t i
= templateParameterLookup(taa
->index
, parameters
);
1727 if (i
== IDX_NOTFOUND
)
1734 unsigned errors
= global
.startGagging();
1735 /* ref: https://issues.dlang.org/show_bug.cgi?id=11118
1736 * The parameter isn't part of the template
1737 * ones, let's try to find it in the
1738 * instantiation scope 'sc' and the one
1739 * belonging to the template itself. */
1741 taa
->index
->resolve(instLoc
, sco
, &e
, &t
, &s
);
1745 taa
->index
->resolve(instLoc
, sco
, &e
, &t
, &s
);
1747 global
.endGagging(errors
);
1754 e
= e
->ctfeInterpret();
1755 e
= e
->implicitCastTo(sco
, Type::tsize_t
);
1756 e
= e
->optimize(WANTvalue
);
1757 if (!dim
->equals(e
))
1762 // This code matches code in TypeInstance::deduceType()
1763 TemplateParameter
*tprm
= (*parameters
)[i
];
1764 TemplateValueParameter
*tvp
= tprm
->isTemplateValueParameter();
1767 Expression
*e
= (Expression
*)(*dedtypes
)[i
];
1770 if (!dim
->equals(e
))
1775 Type
*vt
= tvp
->valType
->semantic(Loc(), sc
);
1776 MATCH m
= (MATCH
)dim
->implicitConvTo(vt
);
1777 if (m
<= MATCHnomatch
)
1779 (*dedtypes
)[i
] = dim
;
1786 TypeArray
*ta
= (TypeArray
*)tb
;
1787 Type
*tret
= fparam
->isLazyArray();
1788 for (; argi
< nfargs
; argi
++)
1790 Expression
*arg
= (*fargs
)[argi
];
1794 /* If lazy array of delegates,
1795 * convert arg(s) to delegate(s)
1799 if (ta
->next
->equals(arg
->type
))
1805 m
= arg
->implicitConvTo(tret
);
1806 if (m
== MATCHnomatch
)
1808 if (tret
->toBasetype()->ty
== Tvoid
)
1816 m
= deduceType(arg
, paramscope
, ta
->next
, parameters
, dedtypes
, &wm
, inferStart
);
1819 if (m
== MATCHnomatch
)
1835 //printf("-> argi = %d, nfargs = %d, nfargs2 = %d\n", argi, nfargs, nfargs2);
1836 if (argi
!= nfargs2
&& fparameters
.varargs
== VARARGnone
)
1842 for (size_t i
= 0; i
< dedtypes
->length
; i
++)
1844 Type
*at
= isType((*dedtypes
)[i
]);
1847 if (at
->ty
== Tnone
)
1849 TypeDeduced
*xt
= (TypeDeduced
*)at
;
1850 at
= xt
->tded
; // 'unbox'
1853 (*dedtypes
)[i
] = at
->merge2();
1856 for (size_t i
= ntargs
; i
< dedargs
->length
; i
++)
1858 TemplateParameter
*tparam
= (*parameters
)[i
];
1859 //printf("tparam[%d] = %s\n", i, tparam->ident->toChars());
1860 /* For T:T*, the dedargs is the T*, dedtypes is the T
1861 * But for function templates, we really need them to match
1863 RootObject
*oarg
= (*dedargs
)[i
];
1864 RootObject
*oded
= (*dedtypes
)[i
];
1865 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
1866 //if (oarg) printf("oarg: %s\n", oarg->toChars());
1867 //if (oded) printf("oded: %s\n", oded->toChars());
1872 if (tparam
->specialization() || !tparam
->isTemplateTypeParameter())
1874 /* The specialization can work as long as afterwards
1877 (*dedargs
)[i
] = oded
;
1878 MATCH m2
= tparam
->matchArg(instLoc
, paramscope
, dedargs
, i
, parameters
, dedtypes
, NULL
);
1879 //printf("m2 = %d\n", m2);
1880 if (m2
<= MATCHnomatch
)
1882 if (m2
< matchTiargs
)
1883 matchTiargs
= m2
; // pick worst match
1884 if (!(*dedtypes
)[i
]->equals(oded
))
1885 error("specialization not allowed for deduced parameter %s", tparam
->ident
->toChars());
1889 if (MATCHconvert
< matchTiargs
)
1890 matchTiargs
= MATCHconvert
;
1895 oded
= tparam
->defaultArg(instLoc
, paramscope
);
1898 // if tuple parameter and
1899 // tuple parameter was not in function parameter list and
1900 // we're one or more arguments short (i.e. no tuple argument)
1902 fptupindex
== IDX_NOTFOUND
&&
1903 ntargs
<= dedargs
->length
- 1)
1905 // make tuple argument an empty tuple
1906 oded
= (RootObject
*)new Tuple();
1915 /* At the template parameter T, the picked default template argument
1916 * X!int should be matched to T in order to deduce dependent
1917 * template parameter A.
1918 * auto foo(T : X!A = X!int, A...)() { ... }
1919 * foo(); // T <-- X!int, A <-- (int)
1921 if (tparam
->specialization())
1923 (*dedargs
)[i
] = oded
;
1924 MATCH m2
= tparam
->matchArg(instLoc
, paramscope
, dedargs
, i
, parameters
, dedtypes
, NULL
);
1925 //printf("m2 = %d\n", m2);
1926 if (m2
<= MATCHnomatch
)
1928 if (m2
< matchTiargs
)
1929 matchTiargs
= m2
; // pick worst match
1930 if (!(*dedtypes
)[i
]->equals(oded
))
1931 error("specialization not allowed for deduced parameter %s", tparam
->ident
->toChars());
1934 oded
= declareParameter(paramscope
, tparam
, oded
);
1935 (*dedargs
)[i
] = oded
;
1939 /* Bugzilla 7469: As same as the code for 7469 in findBestMatch,
1940 * expand a Tuple in dedargs to normalize template arguments.
1942 if (size_t d
= dedargs
->length
)
1944 if (Tuple
*va
= isTuple((*dedargs
)[d
- 1]))
1946 if (va
->objects
.length
)
1948 dedargs
->setDim(d
- 1);
1949 dedargs
->insert(d
- 1, &va
->objects
);
1953 ti
->tiargs
= dedargs
; // update to the normalized template arguments.
1955 // Partially instantiate function for constraint and fd->leastAsSpecialized()
1958 Scope
*sc2
= _scope
;
1959 sc2
= sc2
->push(paramsym
);
1960 sc2
= sc2
->push(ti
);
1963 sc2
->minst
= sc
->minst
;
1965 fd
= doHeaderInstantiation(ti
, sc2
, fd
, tthis
, fargs
);
1976 if (!evaluateConstraint(ti
, sc
, paramscope
, dedargs
, fd
))
1981 //printf("\tmatch %d\n", match);
1982 return (MATCH
)(match
| (matchTiargs
<<4));
1986 //printf("\tnomatch\n");
1987 return MATCHnomatch
;
1989 Lerror
: // todo: for the future improvement
1991 //printf("\terror\n");
1992 return MATCHnomatch
;
1995 /**************************************************
1996 * Declare template parameter tp with value o, and install it in the scope sc.
1999 RootObject
*TemplateDeclaration::declareParameter(Scope
*sc
, TemplateParameter
*tp
, RootObject
*o
)
2001 //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o);
2003 Type
*ta
= isType(o
);
2004 Expression
*ea
= isExpression(o
);
2005 Dsymbol
*sa
= isDsymbol(o
);
2006 Tuple
*va
= isTuple(o
);
2009 VarDeclaration
*v
= NULL
;
2011 if (ea
&& ea
->op
== TOKtype
)
2013 else if (ea
&& ea
->op
== TOKscope
)
2014 sa
= ((ScopeExp
*)ea
)->sds
;
2015 else if (ea
&& (ea
->op
== TOKthis
|| ea
->op
== TOKsuper
))
2016 sa
= ((ThisExp
*)ea
)->var
;
2017 else if (ea
&& ea
->op
== TOKfunction
)
2019 if (((FuncExp
*)ea
)->td
)
2020 sa
= ((FuncExp
*)ea
)->td
;
2022 sa
= ((FuncExp
*)ea
)->fd
;
2027 //printf("type %s\n", ta->toChars());
2028 d
= new AliasDeclaration(Loc(), tp
->ident
, ta
);
2032 //printf("Alias %s %s;\n", sa->ident->toChars(), tp->ident->toChars());
2033 d
= new AliasDeclaration(Loc(), tp
->ident
, sa
);
2037 // tdtypes.data[i] always matches ea here
2038 Initializer
*init
= new ExpInitializer(loc
, ea
);
2039 TemplateValueParameter
*tvp
= tp
->isTemplateValueParameter();
2041 Type
*t
= tvp
? tvp
->valType
: NULL
;
2043 v
= new VarDeclaration(loc
, t
, tp
->ident
, init
);
2044 v
->storage_class
= STCmanifest
| STCtemplateparameter
;
2049 //printf("\ttuple\n");
2050 d
= new TupleDeclaration(loc
, tp
->ident
, &va
->objects
);
2057 d
->storage_class
|= STCtemplateparameter
;
2061 // consistent with Type::checkDeprecated()
2062 while (t
->ty
!= Tenum
)
2064 if (!t
->nextOf()) break;
2065 t
= ((TypeNext
*)t
)->next
;
2067 if (Dsymbol
*s
= t
->toDsymbol(sc
))
2069 if (s
->isDeprecated())
2070 d
->storage_class
|= STCdeprecated
;
2075 if (sa
->isDeprecated())
2076 d
->storage_class
|= STCdeprecated
;
2080 error("declaration %s is already defined", tp
->ident
->toChars());
2083 /* So the caller's o gets updated with the result of semantic() being run on o
2086 o
= initializerToExpression(v
->_init
);
2090 /**************************************
2091 * Determine if TemplateDeclaration is variadic.
2094 TemplateTupleParameter
*isVariadic(TemplateParameters
*parameters
)
2096 size_t dim
= parameters
->length
;
2097 TemplateTupleParameter
*tp
= NULL
;
2100 tp
= ((*parameters
)[dim
- 1])->isTemplateTupleParameter();
2104 TemplateTupleParameter
*TemplateDeclaration::isVariadic()
2106 return ::isVariadic(parameters
);
2109 /***********************************
2110 * We can overload templates.
2113 bool TemplateDeclaration::isOverloadable()
2118 /*************************************************
2119 * Given function arguments, figure out which template function
2120 * to expand, and return matching result.
2123 * dstart the root of overloaded function templates
2124 * loc instantiation location
2125 * sc instantiation scope
2126 * tiargs initial list of template arguments
2127 * tthis if !NULL, the 'this' pointer argument
2128 * fargs arguments to function
2131 void functionResolve(Match
*m
, Dsymbol
*dstart
, Loc loc
, Scope
*sc
,
2132 Objects
*tiargs
, Type
*tthis
, Expressions
*fargs
)
2144 int property
; // 0: unintialized
2145 // 1: seen @property
2148 TemplateDeclaration
*td_best
;
2149 TemplateInstance
*ti_best
;
2153 static int fp(void *param
, Dsymbol
*s
)
2157 if (FuncDeclaration
*fd
= s
->isFuncDeclaration())
2158 return ((ParamDeduce
*)param
)->applyFunction(fd
);
2159 if (TemplateDeclaration
*td
= s
->isTemplateDeclaration())
2160 return ((ParamDeduce
*)param
)->applyTemplate(td
);
2164 int applyFunction(FuncDeclaration
*fd
)
2169 // explicitly specified tiargs never match to non template function
2170 if (tiargs
&& tiargs
->length
> 0)
2173 // constructors need a valid scope in order to detect semantic errors
2174 if (!fd
->isCtorDeclaration() &&
2175 fd
->semanticRun
< PASSsemanticdone
)
2177 Ungag ungag
= fd
->ungagSpeculative();
2180 if (fd
->semanticRun
< PASSsemanticdone
)
2182 ::error(loc
, "forward reference to template %s", fd
->toChars());
2185 //printf("fd = %s %s, fargs = %s\n", fd->toChars(), fd->type->toChars(), fargs->toChars());
2187 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2189 int prop
= (tf
->isproperty
) ? 1 : 2;
2192 else if (property
!= prop
)
2193 error(fd
->loc
, "cannot overload both property and non-property functions");
2195 /* For constructors, qualifier check will be opposite direction.
2196 * Qualified constructor always makes qualified object, then will be checked
2197 * that it is implicitly convertible to tthis.
2199 Type
*tthis_fd
= fd
->needThis() ? tthis
: NULL
;
2200 bool isCtorCall
= tthis_fd
&& fd
->isCtorDeclaration();
2203 //printf("%s tf->mod = x%x tthis_fd->mod = x%x %d\n", tf->toChars(),
2204 // tf->mod, tthis_fd->mod, fd->isolateReturn());
2205 if (MODimplicitConv(tf
->mod
, tthis_fd
->mod
) ||
2206 (tf
->isWild() && tf
->isShared() == tthis_fd
->isShared()) ||
2207 fd
->isolateReturn())
2209 /* && tf->isShared() == tthis_fd->isShared()*/
2210 // Uniquely constructed object can ignore shared qualifier.
2211 // TODO: Is this appropriate?
2215 return 0; // MATCHnomatch
2217 MATCH mfa
= tf
->callMatch(tthis_fd
, fargs
);
2218 //printf("test1: mfa = %d\n", mfa);
2219 if (mfa
> MATCHnomatch
)
2221 if (mfa
> m
->last
) goto LfIsBetter
;
2222 if (mfa
< m
->last
) goto LlastIsBetter
;
2224 /* See if one of the matches overrides the other.
2227 if (m
->lastf
->overrides(fd
)) goto LlastIsBetter
;
2228 if (fd
->overrides(m
->lastf
)) goto LfIsBetter
;
2230 /* Try to disambiguate using template-style partial ordering rules.
2231 * In essence, if f() and g() are ambiguous, if f() can call g(),
2232 * but g() cannot call f(), then pick f().
2233 * This is because f() is "more specialized."
2236 MATCH c1
= fd
->leastAsSpecialized(m
->lastf
);
2237 MATCH c2
= m
->lastf
->leastAsSpecialized(fd
);
2238 //printf("c1 = %d, c2 = %d\n", c1, c2);
2239 if (c1
> c2
) goto LfIsBetter
;
2240 if (c1
< c2
) goto LlastIsBetter
;
2243 /* The 'overrides' check above does covariant checking only
2244 * for virtual member functions. It should do it for all functions,
2245 * but in order to not risk breaking code we put it after
2246 * the 'leastAsSpecialized' check.
2247 * In the future try moving it before.
2248 * I.e. a not-the-same-but-covariant match is preferred,
2249 * as it is more restrictive.
2251 if (!m
->lastf
->type
->equals(fd
->type
))
2253 //printf("cov: %d %d\n", m->lastf->type->covariant(fd->type), fd->type->covariant(m->lastf->type));
2254 if (m
->lastf
->type
->covariant(fd
->type
) == 1) goto LlastIsBetter
;
2255 if (fd
->type
->covariant(m
->lastf
->type
) == 1) goto LfIsBetter
;
2258 /* If the two functions are the same function, like:
2260 * int foo(int x) { ... }
2261 * then pick the one with the body.
2263 if (tf
->equals(m
->lastf
->type
) &&
2264 fd
->storage_class
== m
->lastf
->storage_class
&&
2265 fd
->parent
== m
->lastf
->parent
&&
2266 fd
->protection
== m
->lastf
->protection
&&
2267 fd
->linkage
== m
->lastf
->linkage
)
2269 if ( fd
->fbody
&& !m
->lastf
->fbody
) goto LfIsBetter
;
2270 if (!fd
->fbody
&& m
->lastf
->fbody
) goto LlastIsBetter
;
2273 // Bugzilla 14450: Prefer exact qualified constructor for the creating object type
2274 if (isCtorCall
&& tf
->mod
!= m
->lastf
->type
->mod
)
2276 if (tthis
->mod
== tf
->mod
) goto LfIsBetter
;
2277 if (tthis
->mod
== m
->lastf
->type
->mod
) goto LlastIsBetter
;
2290 ta_last
= MATCHexact
;
2293 tthis_best
= tthis_fd
;
2301 int applyTemplate(TemplateDeclaration
*td
)
2303 //printf("applyTemplate()\n");
2309 sc
= td
->_scope
; // workaround for Type::aliasthisOf
2311 if (td
->semanticRun
== PASSinit
&& td
->_scope
)
2313 // Try to fix forward reference. Ungag errors while doing so.
2314 Ungag ungag
= td
->ungagSpeculative();
2315 td
->semantic(td
->_scope
);
2317 if (td
->semanticRun
== PASSinit
)
2319 ::error(loc
, "forward reference to template %s", td
->toChars());
2323 m
->last
= MATCHnomatch
;
2326 //printf("td = %s\n", td->toChars());
2329 f
= td
->onemember
? td
->onemember
->isFuncDeclaration() : NULL
;
2333 tiargs
= new Objects();
2334 TemplateInstance
*ti
= new TemplateInstance(loc
, td
, tiargs
);
2336 dedtypes
.setDim(td
->parameters
->length
);
2337 assert(td
->semanticRun
!= PASSinit
);
2338 MATCH mta
= td
->matchWithInstance(sc
, ti
, &dedtypes
, fargs
, 0);
2339 //printf("matchWithInstance = %d\n", mta);
2340 if (mta
<= MATCHnomatch
|| mta
< ta_last
) // no match or less match
2343 ti
->semantic(sc
, fargs
);
2344 if (!ti
->inst
) // if template failed to expand
2347 Dsymbol
*s
= ti
->inst
->toAlias();
2348 FuncDeclaration
*fd
;
2349 if (TemplateDeclaration
*tdx
= s
->isTemplateDeclaration())
2351 Objects dedtypesX
; // empty tiargs
2353 // Bugzilla 11553: Check for recursive instantiation of tdx.
2354 for (TemplatePrevious
*p
= tdx
->previous
; p
; p
= p
->prev
)
2356 if (arrayObjectMatch(p
->dedargs
, &dedtypesX
))
2358 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
2359 /* It must be a subscope of p->sc, other scope chains are not recursive
2362 for (Scope
*scx
= sc
; scx
; scx
= scx
->enclosing
)
2366 error(loc
, "recursive template expansion while looking for %s.%s", ti
->toChars(), tdx
->toChars());
2371 /* BUG: should also check for ref param differences
2375 TemplatePrevious pr
;
2376 pr
.prev
= tdx
->previous
;
2378 pr
.dedargs
= &dedtypesX
;
2379 tdx
->previous
= &pr
; // add this to threaded list
2381 fd
= resolveFuncCall(loc
, sc
, s
, NULL
, tthis
, fargs
, 1);
2383 tdx
->previous
= pr
.prev
; // unlink from threaded list
2385 else if (s
->isFuncDeclaration())
2387 fd
= resolveFuncCall(loc
, sc
, s
, NULL
, tthis
, fargs
, 1);
2395 if (fd
->type
->ty
!= Tfunction
)
2397 m
->lastf
= fd
; // to propagate "error match"
2399 m
->last
= MATCHnomatch
;
2403 Type
*tthis_fd
= fd
->needThis() && !fd
->isCtorDeclaration() ? tthis
: NULL
;
2405 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2406 MATCH mfa
= tf
->callMatch(tthis_fd
, fargs
);
2410 if (mta
< ta_last
) goto Ltd_best2
;
2411 if (mta
> ta_last
) goto Ltd2
;
2413 if (mfa
< m
->last
) goto Ltd_best2
;
2414 if (mfa
> m
->last
) goto Ltd2
;
2416 //printf("Lambig2\n");
2425 // td is the new best match
2429 property
= 0; // (backward compatibility)
2433 tthis_best
= tthis_fd
;
2440 //printf("td = %s\n", td->toChars());
2441 for (size_t ovi
= 0; f
; f
= f
->overnext0
, ovi
++)
2443 if (f
->type
->ty
!= Tfunction
|| f
->errors
)
2446 /* This is a 'dummy' instance to evaluate constraint properly.
2448 TemplateInstance
*ti
= new TemplateInstance(loc
, td
, tiargs
);
2449 ti
->parent
= td
->parent
; // Maybe calculating valid 'enclosing' is unnecessary.
2451 FuncDeclaration
*fd
= f
;
2452 int x
= td
->deduceFunctionTemplateMatch(ti
, sc
, fd
, tthis
, fargs
);
2453 MATCH mta
= (MATCH
)(x
>> 4);
2454 MATCH mfa
= (MATCH
)(x
& 0xF);
2455 //printf("match:t/f = %d/%d\n", mta, mfa);
2456 if (!fd
|| mfa
== MATCHnomatch
)
2459 Type
*tthis_fd
= fd
->needThis() ? tthis
: NULL
;
2461 bool isCtorCall
= tthis_fd
&& fd
->isCtorDeclaration();
2464 // Constructor call requires additional check.
2466 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2468 if (MODimplicitConv(tf
->mod
, tthis_fd
->mod
) ||
2469 (tf
->isWild() && tf
->isShared() == tthis_fd
->isShared()) ||
2470 fd
->isolateReturn())
2475 continue; // MATCHnomatch
2478 if (mta
< ta_last
) goto Ltd_best
;
2479 if (mta
> ta_last
) goto Ltd
;
2481 if (mfa
< m
->last
) goto Ltd_best
;
2482 if (mfa
> m
->last
) goto Ltd
;
2486 // Disambiguate by picking the most specialized TemplateDeclaration
2487 MATCH c1
= td
->leastAsSpecialized(sc
, td_best
, fargs
);
2488 MATCH c2
= td_best
->leastAsSpecialized(sc
, td
, fargs
);
2489 //printf("1: c1 = %d, c2 = %d\n", c1, c2);
2490 if (c1
> c2
) goto Ltd
;
2491 if (c1
< c2
) goto Ltd_best
;
2493 assert(fd
&& m
->lastf
);
2495 // Disambiguate by tf->callMatch
2496 TypeFunction
*tf1
= (TypeFunction
*)fd
->type
;
2497 assert(tf1
->ty
== Tfunction
);
2498 TypeFunction
*tf2
= (TypeFunction
*)m
->lastf
->type
;
2499 assert(tf2
->ty
== Tfunction
);
2500 MATCH c1
= tf1
->callMatch(tthis_fd
, fargs
);
2501 MATCH c2
= tf2
->callMatch(tthis_best
, fargs
);
2502 //printf("2: c1 = %d, c2 = %d\n", c1, c2);
2503 if (c1
> c2
) goto Ltd
;
2504 if (c1
< c2
) goto Ltd_best
;
2507 // Disambiguate by picking the most specialized FunctionDeclaration
2508 MATCH c1
= fd
->leastAsSpecialized(m
->lastf
);
2509 MATCH c2
= m
->lastf
->leastAsSpecialized(fd
);
2510 //printf("3: c1 = %d, c2 = %d\n", c1, c2);
2511 if (c1
> c2
) goto Ltd
;
2512 if (c1
< c2
) goto Ltd_best
;
2515 // Bugzilla 14450: Prefer exact qualified constructor for the creating object type
2516 if (isCtorCall
&& fd
->type
->mod
!= m
->lastf
->type
->mod
)
2518 if (tthis
->mod
== fd
->type
->mod
) goto Ltd
;
2519 if (tthis
->mod
== m
->lastf
->type
->mod
) goto Ltd_best
;
2526 Ltd_best
: // td_best is the best match so far
2527 //printf("Ltd_best\n");
2530 Ltd
: // td is the new best match
2535 property
= 0; // (backward compatibility)
2539 tthis_best
= tthis_fd
;
2562 p
.ta_last
= m
->last
!= MATCHnomatch
? MATCHexact
: MATCHnomatch
;
2563 p
.tthis_best
= NULL
;
2565 TemplateDeclaration
*td
= dstart
->isTemplateDeclaration();
2566 if (td
&& td
->funcroot
)
2567 dstart
= td
->funcroot
;
2569 overloadApply(dstart
, &p
, &ParamDeduce::fp
);
2571 //printf("td_best = %p, m->lastf = %p\n", p.td_best, m->lastf);
2572 if (p
.td_best
&& p
.ti_best
&& m
->count
== 1)
2574 // Matches to template function
2575 assert(p
.td_best
->onemember
&& p
.td_best
->onemember
->isFuncDeclaration());
2577 /* The best match is td_best with arguments tdargs.
2578 * Now instantiate the template.
2580 assert(p
.td_best
->_scope
);
2582 sc
= p
.td_best
->_scope
; // workaround for Type::aliasthisOf
2584 TemplateInstance
*ti
= new TemplateInstance(loc
, p
.td_best
, p
.ti_best
->tiargs
);
2585 ti
->semantic(sc
, fargs
);
2587 m
->lastf
= ti
->toAlias()->isFuncDeclaration();
2595 m
->last
= MATCHnomatch
;
2599 // look forward instantiated overload function
2600 // Dsymbol::oneMembers is alredy called in TemplateInstance::semantic.
2601 // it has filled overnext0d
2602 while (p
.ov_index
--)
2604 m
->lastf
= m
->lastf
->overnext0
;
2608 p
.tthis_best
= m
->lastf
->needThis() && !m
->lastf
->isCtorDeclaration() ? tthis
: NULL
;
2610 TypeFunction
*tf
= (TypeFunction
*)m
->lastf
->type
;
2611 if (tf
->ty
== Terror
)
2613 assert(tf
->ty
== Tfunction
);
2614 if (!tf
->callMatch(p
.tthis_best
, fargs
))
2617 /* As Bugzilla 3682 shows, a template instance can be matched while instantiating
2618 * that same template. Thus, the function type can be incomplete. Complete it.
2620 * Bugzilla 9208: For auto function, completion should be deferred to the end of
2621 * its semantic3. Should not complete it in here.
2623 if (tf
->next
&& !m
->lastf
->inferRetType
)
2625 m
->lastf
->type
= tf
->semantic(loc
, sc
);
2630 // Matches to non template function,
2631 // or found matches were ambiguous.
2632 assert(m
->count
>= 1);
2639 m
->last
= MATCHnomatch
;
2643 /*************************************************
2644 * Limited function template instantiation for using fd->leastAsSpecialized()
2646 FuncDeclaration
*TemplateDeclaration::doHeaderInstantiation(
2647 TemplateInstance
*ti
, Scope
*sc2
,
2648 FuncDeclaration
*fd
, Type
*tthis
, Expressions
*fargs
)
2652 // function body and contracts are not need
2653 if (fd
->isCtorDeclaration())
2654 fd
= new CtorDeclaration(fd
->loc
, fd
->endloc
, fd
->storage_class
, fd
->type
->syntaxCopy());
2656 fd
= new FuncDeclaration(fd
->loc
, fd
->endloc
, fd
->ident
, fd
->storage_class
, fd
->type
->syntaxCopy());
2659 assert(fd
->type
->ty
== Tfunction
);
2660 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2665 // Match 'tthis' to any TemplateThisParameter's
2666 bool hasttp
= false;
2667 for (size_t i
= 0; i
< parameters
->length
; i
++)
2669 TemplateParameter
*tp
= (*parameters
)[i
];
2670 TemplateThisParameter
*ttp
= tp
->isTemplateThisParameter();
2676 tf
= (TypeFunction
*)tf
->addSTC(ModToStc(tthis
->mod
));
2681 Scope
*scx
= sc2
->push();
2683 // Shouldn't run semantic on default arguments and return type.
2684 for (size_t i
= 0; i
< tf
->parameterList
.parameters
->length
; i
++)
2685 (*tf
->parameterList
.parameters
)[i
]->defaultArg
= NULL
;
2686 if (fd
->isCtorDeclaration())
2688 // For constructors, emitting return type is necessary for
2689 // isolateReturn() in functionResolve.
2690 scx
->flags
|= SCOPEctor
;
2692 Dsymbol
*parent
= toParent2();
2694 AggregateDeclaration
*ad
= parent
->isAggregateDeclaration();
2695 if (!ad
|| parent
->isUnionDeclaration())
2701 tret
= ad
->handleType();
2703 tret
= tret
->addStorageClass(fd
->storage_class
| scx
->stc
);
2704 tret
= tret
->addMod(tf
->mod
);
2707 if (ad
&& ad
->isStructDeclaration())
2709 //printf("tf = %s\n", tf->toChars());
2714 fd
->type
= fd
->type
->addSTC(scx
->stc
);
2715 fd
->type
= fd
->type
->semantic(fd
->loc
, scx
);
2718 if (fd
->type
->ty
!= Tfunction
)
2721 fd
->originalType
= fd
->type
; // for mangling
2722 //printf("\t[%s] fd->type = %s, mod = %x, ", loc.toChars(), fd->type->toChars(), fd->type->mod);
2723 //printf("fd->needThis() = %d\n", fd->needThis());
2728 bool TemplateDeclaration::hasStaticCtorOrDtor()
2730 return false; // don't scan uninstantiated templates
2733 const char *TemplateDeclaration::toChars()
2736 return Dsymbol::toChars();
2741 buf
.writestring(ident
->toChars());
2743 for (size_t i
= 0; i
< parameters
->length
; i
++)
2745 TemplateParameter
*tp
= (*parameters
)[i
];
2747 buf
.writestring(", ");
2748 ::toCBuffer(tp
, &buf
, &hgs
);
2754 FuncDeclaration
*fd
= onemember
->isFuncDeclaration();
2757 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
2758 buf
.writestring(parametersTypeToChars(tf
->parameterList
));
2764 buf
.writestring(" if (");
2765 ::toCBuffer(constraint
, &buf
, &hgs
);
2768 return buf
.extractChars();
2771 Prot
TemplateDeclaration::prot()
2776 /****************************************************
2777 * Given a new instance tithis of this TemplateDeclaration,
2778 * see if there already exists an instance.
2779 * If so, return that existing instance.
2782 TemplateInstance
*TemplateDeclaration::findExistingInstance(TemplateInstance
*tithis
, Expressions
*fargs
)
2784 //printf("findExistingInstance(%p)\n", tithis);
2785 tithis
->fargs
= fargs
;
2786 TemplateInstances
*tinstances
= (TemplateInstances
*)dmd_aaGetRvalue((AA
*)instances
, (void *)tithis
->toHash());
2789 for (size_t i
= 0; i
< tinstances
->length
; i
++)
2791 TemplateInstance
*ti
= (*tinstances
)[i
];
2792 if (tithis
->compare(ti
) == 0)
2799 /********************************************
2800 * Add instance ti to TemplateDeclaration's table of instances.
2801 * Return a handle we can use to later remove it if it fails instantiation.
2804 TemplateInstance
*TemplateDeclaration::addInstance(TemplateInstance
*ti
)
2806 //printf("addInstance() %p %p\n", instances, ti);
2807 TemplateInstances
**ptinstances
= (TemplateInstances
**)dmd_aaGet((AA
**)&instances
, (void *)ti
->toHash());
2809 *ptinstances
= new TemplateInstances();
2810 (*ptinstances
)->push(ti
);
2814 /*******************************************
2815 * Remove TemplateInstance from table of instances.
2817 * handle returned by addInstance()
2820 void TemplateDeclaration::removeInstance(TemplateInstance
*handle
)
2822 //printf("removeInstance()\n");
2823 TemplateInstances
*tinstances
= (TemplateInstances
*)dmd_aaGetRvalue((AA
*)instances
, (void *)handle
->toHash());
2826 for (size_t i
= 0; i
< tinstances
->length
; i
++)
2828 TemplateInstance
*ti
= (*tinstances
)[i
];
2831 tinstances
->remove(i
);
2838 /* ======================== Type ============================================ */
2841 * Given an identifier, figure out which TemplateParameter it is.
2842 * Return IDX_NOTFOUND if not found.
2845 static size_t templateIdentifierLookup(Identifier
*id
, TemplateParameters
*parameters
)
2847 for (size_t i
= 0; i
< parameters
->length
; i
++)
2849 TemplateParameter
*tp
= (*parameters
)[i
];
2850 if (tp
->ident
->equals(id
))
2853 return IDX_NOTFOUND
;
2856 size_t templateParameterLookup(Type
*tparam
, TemplateParameters
*parameters
)
2858 if (tparam
->ty
== Tident
)
2860 TypeIdentifier
*tident
= (TypeIdentifier
*)tparam
;
2861 //printf("\ttident = '%s'\n", tident->toChars());
2862 return templateIdentifierLookup(tident
->ident
, parameters
);
2864 return IDX_NOTFOUND
;
2867 unsigned char deduceWildHelper(Type
*t
, Type
**at
, Type
*tparam
)
2869 if ((tparam
->mod
& MODwild
) == 0)
2874 #define X(U,T) ((U) << 4) | (T)
2875 switch (X(tparam
->mod
, t
->mod
))
2878 case X(MODwild
, MODconst
):
2879 case X(MODwild
, MODshared
):
2880 case X(MODwild
, MODshared
| MODconst
):
2881 case X(MODwild
, MODimmutable
):
2882 case X(MODwildconst
, 0):
2883 case X(MODwildconst
, MODconst
):
2884 case X(MODwildconst
, MODshared
):
2885 case X(MODwildconst
, MODshared
| MODconst
):
2886 case X(MODwildconst
, MODimmutable
):
2887 case X(MODshared
| MODwild
, MODshared
):
2888 case X(MODshared
| MODwild
, MODshared
| MODconst
):
2889 case X(MODshared
| MODwild
, MODimmutable
):
2890 case X(MODshared
| MODwildconst
, MODshared
):
2891 case X(MODshared
| MODwildconst
, MODshared
| MODconst
):
2892 case X(MODshared
| MODwildconst
, MODimmutable
):
2894 unsigned char wm
= (t
->mod
& ~MODshared
);
2897 unsigned char m
= (t
->mod
& (MODconst
| MODimmutable
)) | (tparam
->mod
& t
->mod
& MODshared
);
2898 *at
= t
->unqualify(m
);
2902 case X(MODwild
, MODwild
):
2903 case X(MODwild
, MODwildconst
):
2904 case X(MODwild
, MODshared
| MODwild
):
2905 case X(MODwild
, MODshared
| MODwildconst
):
2906 case X(MODwildconst
, MODwild
):
2907 case X(MODwildconst
, MODwildconst
):
2908 case X(MODwildconst
, MODshared
| MODwild
):
2909 case X(MODwildconst
, MODshared
| MODwildconst
):
2910 case X(MODshared
| MODwild
, MODshared
| MODwild
):
2911 case X(MODshared
| MODwild
, MODshared
| MODwildconst
):
2912 case X(MODshared
| MODwildconst
, MODshared
| MODwild
):
2913 case X(MODshared
| MODwildconst
, MODshared
| MODwildconst
):
2915 *at
= t
->unqualify(tparam
->mod
& t
->mod
);
2925 MATCH
deduceTypeHelper(Type
*t
, Type
**at
, Type
*tparam
)
2929 #define X(U,T) ((U) << 4) | (T)
2930 switch (X(tparam
->mod
, t
->mod
))
2933 case X(0, MODconst
):
2935 case X(0, MODwildconst
):
2936 case X(0, MODshared
):
2937 case X(0, MODshared
| MODconst
):
2938 case X(0, MODshared
| MODwild
):
2939 case X(0, MODshared
| MODwildconst
):
2940 case X(0, MODimmutable
):
2942 // foo(U) const(T) => const(T)
2943 // foo(U) inout(T) => inout(T)
2944 // foo(U) inout(const(T)) => inout(const(T))
2945 // foo(U) shared(T) => shared(T)
2946 // foo(U) shared(const(T)) => shared(const(T))
2947 // foo(U) shared(inout(T)) => shared(inout(T))
2948 // foo(U) shared(inout(const(T))) => shared(inout(const(T)))
2949 // foo(U) immutable(T) => immutable(T)
2955 case X(MODconst
, MODconst
):
2956 case X(MODwild
, MODwild
):
2957 case X(MODwildconst
, MODwildconst
):
2958 case X(MODshared
, MODshared
):
2959 case X(MODshared
| MODconst
, MODshared
| MODconst
):
2960 case X(MODshared
| MODwild
, MODshared
| MODwild
):
2961 case X(MODshared
| MODwildconst
, MODshared
| MODwildconst
):
2962 case X(MODimmutable
, MODimmutable
):
2963 // foo(const(U)) const(T) => T
2964 // foo(inout(U)) inout(T) => T
2965 // foo(inout(const(U))) inout(const(T)) => T
2966 // foo(shared(U)) shared(T) => T
2967 // foo(shared(const(U))) shared(const(T)) => T
2968 // foo(shared(inout(U))) shared(inout(T)) => T
2969 // foo(shared(inout(const(U)))) shared(inout(const(T))) => T
2970 // foo(immutable(U)) immutable(T) => T
2972 *at
= t
->mutableOf()->unSharedOf();
2976 case X(MODconst
, 0):
2977 case X(MODconst
, MODwild
):
2978 case X(MODconst
, MODwildconst
):
2979 case X(MODconst
, MODshared
| MODconst
):
2980 case X(MODconst
, MODshared
| MODwild
):
2981 case X(MODconst
, MODshared
| MODwildconst
):
2982 case X(MODconst
, MODimmutable
):
2983 case X(MODwild
, MODshared
| MODwild
):
2984 case X(MODwildconst
, MODshared
| MODwildconst
):
2985 case X(MODshared
| MODconst
, MODimmutable
):
2986 // foo(const(U)) T => T
2987 // foo(const(U)) inout(T) => T
2988 // foo(const(U)) inout(const(T)) => T
2989 // foo(const(U)) shared(const(T)) => shared(T)
2990 // foo(const(U)) shared(inout(T)) => shared(T)
2991 // foo(const(U)) shared(inout(const(T))) => shared(T)
2992 // foo(const(U)) immutable(T) => T
2993 // foo(inout(U)) shared(inout(T)) => shared(T)
2994 // foo(inout(const(U))) shared(inout(const(T))) => shared(T)
2995 // foo(shared(const(U))) immutable(T) => T
2997 *at
= t
->mutableOf();
3001 case X(MODconst
, MODshared
):
3002 // foo(const(U)) shared(T) => shared(T)
3008 case X(MODshared
, MODshared
| MODconst
):
3009 case X(MODshared
, MODshared
| MODwild
):
3010 case X(MODshared
, MODshared
| MODwildconst
):
3011 case X(MODshared
| MODconst
, MODshared
):
3012 // foo(shared(U)) shared(const(T)) => const(T)
3013 // foo(shared(U)) shared(inout(T)) => inout(T)
3014 // foo(shared(U)) shared(inout(const(T))) => inout(const(T))
3015 // foo(shared(const(U))) shared(T) => T
3017 *at
= t
->unSharedOf();
3021 case X(MODwildconst
, MODimmutable
):
3022 case X(MODshared
| MODconst
, MODshared
| MODwildconst
):
3023 case X(MODshared
| MODwildconst
, MODimmutable
):
3024 case X(MODshared
| MODwildconst
, MODshared
| MODwild
):
3025 // foo(inout(const(U))) immutable(T) => T
3026 // foo(shared(const(U))) shared(inout(const(T))) => T
3027 // foo(shared(inout(const(U)))) immutable(T) => T
3028 // foo(shared(inout(const(U)))) shared(inout(T)) => T
3030 *at
= t
->unSharedOf()->mutableOf();
3034 case X(MODshared
| MODconst
, MODshared
| MODwild
):
3035 // foo(shared(const(U))) shared(inout(T)) => T
3037 *at
= t
->unSharedOf()->mutableOf();
3042 case X(MODwild
, MODconst
):
3043 case X(MODwild
, MODwildconst
):
3044 case X(MODwild
, MODimmutable
):
3045 case X(MODwild
, MODshared
):
3046 case X(MODwild
, MODshared
| MODconst
):
3047 case X(MODwild
, MODshared
| MODwildconst
):
3048 case X(MODwildconst
, 0):
3049 case X(MODwildconst
, MODconst
):
3050 case X(MODwildconst
, MODwild
):
3051 case X(MODwildconst
, MODshared
):
3052 case X(MODwildconst
, MODshared
| MODconst
):
3053 case X(MODwildconst
, MODshared
| MODwild
):
3054 case X(MODshared
, 0):
3055 case X(MODshared
, MODconst
):
3056 case X(MODshared
, MODwild
):
3057 case X(MODshared
, MODwildconst
):
3058 case X(MODshared
, MODimmutable
):
3059 case X(MODshared
| MODconst
, 0):
3060 case X(MODshared
| MODconst
, MODconst
):
3061 case X(MODshared
| MODconst
, MODwild
):
3062 case X(MODshared
| MODconst
, MODwildconst
):
3063 case X(MODshared
| MODwild
, 0):
3064 case X(MODshared
| MODwild
, MODconst
):
3065 case X(MODshared
| MODwild
, MODwild
):
3066 case X(MODshared
| MODwild
, MODwildconst
):
3067 case X(MODshared
| MODwild
, MODimmutable
):
3068 case X(MODshared
| MODwild
, MODshared
):
3069 case X(MODshared
| MODwild
, MODshared
| MODconst
):
3070 case X(MODshared
| MODwild
, MODshared
| MODwildconst
):
3071 case X(MODshared
| MODwildconst
, 0):
3072 case X(MODshared
| MODwildconst
, MODconst
):
3073 case X(MODshared
| MODwildconst
, MODwild
):
3074 case X(MODshared
| MODwildconst
, MODwildconst
):
3075 case X(MODshared
| MODwildconst
, MODshared
):
3076 case X(MODshared
| MODwildconst
, MODshared
| MODconst
):
3077 case X(MODimmutable
, 0):
3078 case X(MODimmutable
, MODconst
):
3079 case X(MODimmutable
, MODwild
):
3080 case X(MODimmutable
, MODwildconst
):
3081 case X(MODimmutable
, MODshared
):
3082 case X(MODimmutable
, MODshared
| MODconst
):
3083 case X(MODimmutable
, MODshared
| MODwild
):
3084 case X(MODimmutable
, MODshared
| MODwildconst
):
3085 // foo(inout(U)) T => nomatch
3086 // foo(inout(U)) const(T) => nomatch
3087 // foo(inout(U)) inout(const(T)) => nomatch
3088 // foo(inout(U)) immutable(T) => nomatch
3089 // foo(inout(U)) shared(T) => nomatch
3090 // foo(inout(U)) shared(const(T)) => nomatch
3091 // foo(inout(U)) shared(inout(const(T))) => nomatch
3092 // foo(inout(const(U))) T => nomatch
3093 // foo(inout(const(U))) const(T) => nomatch
3094 // foo(inout(const(U))) inout(T) => nomatch
3095 // foo(inout(const(U))) shared(T) => nomatch
3096 // foo(inout(const(U))) shared(const(T)) => nomatch
3097 // foo(inout(const(U))) shared(inout(T)) => nomatch
3098 // foo(shared(U)) T => nomatch
3099 // foo(shared(U)) const(T) => nomatch
3100 // foo(shared(U)) inout(T) => nomatch
3101 // foo(shared(U)) inout(const(T)) => nomatch
3102 // foo(shared(U)) immutable(T) => nomatch
3103 // foo(shared(const(U))) T => nomatch
3104 // foo(shared(const(U))) const(T) => nomatch
3105 // foo(shared(const(U))) inout(T) => nomatch
3106 // foo(shared(const(U))) inout(const(T)) => nomatch
3107 // foo(shared(inout(U))) T => nomatch
3108 // foo(shared(inout(U))) const(T) => nomatch
3109 // foo(shared(inout(U))) inout(T) => nomatch
3110 // foo(shared(inout(U))) inout(const(T)) => nomatch
3111 // foo(shared(inout(U))) immutable(T) => nomatch
3112 // foo(shared(inout(U))) shared(T) => nomatch
3113 // foo(shared(inout(U))) shared(const(T)) => nomatch
3114 // foo(shared(inout(U))) shared(inout(const(T))) => nomatch
3115 // foo(shared(inout(const(U)))) T => nomatch
3116 // foo(shared(inout(const(U)))) const(T) => nomatch
3117 // foo(shared(inout(const(U)))) inout(T) => nomatch
3118 // foo(shared(inout(const(U)))) inout(const(T)) => nomatch
3119 // foo(shared(inout(const(U)))) shared(T) => nomatch
3120 // foo(shared(inout(const(U)))) shared(const(T)) => nomatch
3121 // foo(immutable(U)) T => nomatch
3122 // foo(immutable(U)) const(T) => nomatch
3123 // foo(immutable(U)) inout(T) => nomatch
3124 // foo(immutable(U)) inout(const(T)) => nomatch
3125 // foo(immutable(U)) shared(T) => nomatch
3126 // foo(immutable(U)) shared(const(T)) => nomatch
3127 // foo(immutable(U)) shared(inout(T)) => nomatch
3128 // foo(immutable(U)) shared(inout(const(T))) => nomatch
3129 return MATCHnomatch
;
3133 return MATCHnomatch
; // silence compiler warning about missing return
3138 /* These form the heart of template argument deduction.
3139 * Given 'this' being the type argument to the template instance,
3140 * it is matched against the template declaration parameter specialization
3141 * 'tparam' to determine the type to be used for the parameter.
3143 * template Foo(T:T*) // template declaration
3144 * Foo!(int*) // template instantiation
3148 * parameters = [ T:T* ] // Array of TemplateParameter's
3150 * dedtypes = [ int ] // Array of Expression/Type's
3152 MATCH
deduceType(RootObject
*o
, Scope
*sc
, Type
*tparam
, TemplateParameters
*parameters
,
3153 Objects
*dedtypes
, unsigned *wm
, size_t inferStart
)
3155 class DeduceType
: public Visitor
3160 TemplateParameters
*parameters
;
3166 DeduceType(Scope
*sc
, Type
*tparam
, TemplateParameters
*parameters
, Objects
*dedtypes
, unsigned *wm
, size_t inferStart
)
3167 : sc(sc
), tparam(tparam
), parameters(parameters
), dedtypes(dedtypes
), wm(wm
), inferStart(inferStart
)
3169 result
= MATCHnomatch
;
3180 if (tparam
->ty
== Tident
)
3182 // Determine which parameter tparam is
3183 size_t i
= templateParameterLookup(tparam
, parameters
);
3184 if (i
== IDX_NOTFOUND
)
3189 /* Need a loc to go with the semantic routine.
3192 if (parameters
->length
)
3194 TemplateParameter
*tp
= (*parameters
)[0];
3198 /* BUG: what if tparam is a template instance, that
3199 * has as an argument another Tident?
3201 tparam
= tparam
->semantic(loc
, sc
);
3202 assert(tparam
->ty
!= Tident
);
3203 result
= deduceType(t
, sc
, tparam
, parameters
, dedtypes
, wm
);
3207 TemplateParameter
*tp
= (*parameters
)[i
];
3209 TypeIdentifier
*tident
= (TypeIdentifier
*)tparam
;
3210 if (tident
->idents
.length
> 0)
3212 //printf("matching %s to %s\n", tparam->toChars(), t->toChars());
3213 Dsymbol
*s
= t
->toDsymbol(sc
);
3214 for (size_t j
= tident
->idents
.length
; j
-- > 0; )
3216 RootObject
*id
= tident
->idents
[j
];
3217 if (id
->dyncast() == DYNCAST_IDENTIFIER
)
3219 if (!s
|| !s
->parent
)
3221 Dsymbol
*s2
= s
->parent
->search(Loc(), (Identifier
*)id
);
3225 //printf("[%d] s = %s %s, s2 = %s %s\n", j, s->kind(), s->toChars(), s2->kind(), s2->toChars());
3228 if (Type
*tx
= s2
->getType())
3230 if (s
!= tx
->toDsymbol(sc
))
3241 //printf("[e] s = %s\n", s?s->toChars():"(null)");
3242 if (tp
->isTemplateTypeParameter())
3244 Type
*tt
= s
->getType();
3247 Type
*at
= (Type
*)(*dedtypes
)[i
];
3248 if (at
&& at
->ty
== Tnone
)
3249 at
= ((TypeDeduced
*)at
)->tded
;
3250 if (!at
|| tt
->equals(at
))
3252 (*dedtypes
)[i
] = tt
;
3256 if (tp
->isTemplateAliasParameter())
3258 Dsymbol
*s2
= (Dsymbol
*)(*dedtypes
)[i
];
3268 // Found the corresponding parameter tp
3269 if (!tp
->isTemplateTypeParameter())
3272 Type
*at
= (Type
*)(*dedtypes
)[i
];
3274 if (unsigned char wx
= wm
? deduceWildHelper(t
, &tt
, tparam
) : 0)
3279 (*dedtypes
)[i
] = tt
;
3281 result
= MATCHconst
;
3285 // type vs expressions
3286 if (at
->ty
== Tnone
)
3288 TypeDeduced
*xt
= (TypeDeduced
*)at
;
3289 result
= xt
->matchAll(tt
);
3290 if (result
> MATCHnomatch
)
3292 (*dedtypes
)[i
] = tt
;
3293 if (result
> MATCHconst
)
3294 result
= MATCHconst
; // limit level for inout matches
3303 (*dedtypes
)[i
] = tt
; // Prefer current type match
3306 if (tt
->implicitConvTo(at
->constOf()))
3308 (*dedtypes
)[i
] = at
->constOf()->mutableOf();
3312 if (at
->implicitConvTo(tt
->constOf()))
3314 (*dedtypes
)[i
] = tt
->constOf()->mutableOf();
3320 else if (MATCH m
= deduceTypeHelper(t
, &tt
, tparam
))
3325 (*dedtypes
)[i
] = tt
;
3330 // type vs expressions
3331 if (at
->ty
== Tnone
)
3333 TypeDeduced
*xt
= (TypeDeduced
*)at
;
3334 result
= xt
->matchAll(tt
);
3335 if (result
> MATCHnomatch
)
3337 (*dedtypes
)[i
] = tt
;
3348 if (tt
->ty
== Tclass
&& at
->ty
== Tclass
)
3350 result
= tt
->implicitConvTo(at
);
3353 if (tt
->ty
== Tsarray
&& at
->ty
== Tarray
&&
3354 tt
->nextOf()->implicitConvTo(at
->nextOf()) >= MATCHconst
)
3362 if (tparam
->ty
== Ttypeof
)
3364 /* Need a loc to go with the semantic routine.
3367 if (parameters
->length
)
3369 TemplateParameter
*tp
= (*parameters
)[0];
3373 tparam
= tparam
->semantic(loc
, sc
);
3375 if (t
->ty
!= tparam
->ty
)
3377 if (Dsymbol
*sym
= t
->toDsymbol(sc
))
3379 if (sym
->isforwardRef() && !tparam
->deco
)
3383 MATCH m
= t
->implicitConvTo(tparam
);
3384 if (m
== MATCHnomatch
)
3386 if (t
->ty
== Tclass
)
3388 TypeClass
*tc
= (TypeClass
*)t
;
3389 if (tc
->sym
->aliasthis
&& !(tc
->att
& RECtracingDT
))
3391 tc
->att
= (AliasThisRec
)(tc
->att
| RECtracingDT
);
3392 m
= deduceType(t
->aliasthisOf(), sc
, tparam
, parameters
, dedtypes
, wm
);
3393 tc
->att
= (AliasThisRec
)(tc
->att
& ~RECtracingDT
);
3396 else if (t
->ty
== Tstruct
)
3398 TypeStruct
*ts
= (TypeStruct
*)t
;
3399 if (ts
->sym
->aliasthis
&& !(ts
->att
& RECtracingDT
))
3401 ts
->att
= (AliasThisRec
)(ts
->att
| RECtracingDT
);
3402 m
= deduceType(t
->aliasthisOf(), sc
, tparam
, parameters
, dedtypes
, wm
);
3403 ts
->att
= (AliasThisRec
)(ts
->att
& ~RECtracingDT
);
3413 if (tparam
->deco
&& !tparam
->hasWild())
3415 result
= t
->implicitConvTo(tparam
);
3419 Type
*tpn
= tparam
->nextOf();
3420 if (wm
&& t
->ty
== Taarray
&& tparam
->isWild())
3422 // Bugzilla 12403: In IFTI, stop inout matching on transitive part of AA types.
3423 tpn
= tpn
->substWildTo(MODmutable
);
3426 result
= deduceType(t
->nextOf(), sc
, tpn
, parameters
, dedtypes
, wm
);
3431 result
= MATCHexact
;
3435 result
= MATCHnomatch
;
3439 result
= MATCHconst
;
3442 void visit(TypeVector
*t
)
3444 if (tparam
->ty
== Tvector
)
3446 TypeVector
*tp
= (TypeVector
*)tparam
;
3447 result
= deduceType(t
->basetype
, sc
, tp
->basetype
, parameters
, dedtypes
, wm
);
3453 void visit(TypeDArray
*t
)
3458 void visit(TypeSArray
*t
)
3460 // Extra check that array dimensions must match
3463 if (tparam
->ty
== Tarray
)
3465 MATCH m
= deduceType(t
->next
, sc
, tparam
->nextOf(), parameters
, dedtypes
, wm
);
3466 result
= (m
>= MATCHconst
) ? MATCHconvert
: MATCHnomatch
;
3470 TemplateParameter
*tp
= NULL
;
3471 Expression
*edim
= NULL
;
3473 if (tparam
->ty
== Tsarray
)
3475 TypeSArray
*tsa
= (TypeSArray
*)tparam
;
3476 if (tsa
->dim
->op
== TOKvar
&&
3477 ((VarExp
*)tsa
->dim
)->var
->storage_class
& STCtemplateparameter
)
3479 Identifier
*id
= ((VarExp
*)tsa
->dim
)->var
->ident
;
3480 i
= templateIdentifierLookup(id
, parameters
);
3481 assert(i
!= IDX_NOTFOUND
);
3482 tp
= (*parameters
)[i
];
3487 else if (tparam
->ty
== Taarray
)
3489 TypeAArray
*taa
= (TypeAArray
*)tparam
;
3490 i
= templateParameterLookup(taa
->index
, parameters
);
3491 if (i
!= IDX_NOTFOUND
)
3492 tp
= (*parameters
)[i
];
3498 taa
->index
->resolve(Loc(), sc
, &e
, &tx
, &s
);
3499 edim
= s
? getValue(s
) : getValue(e
);
3502 if ((tp
&& tp
->matchArg(sc
, t
->dim
, i
, parameters
, dedtypes
, NULL
)) ||
3503 (edim
&& edim
->toInteger() == t
->dim
->toInteger()))
3505 result
= deduceType(t
->next
, sc
, tparam
->nextOf(), parameters
, dedtypes
, wm
);
3512 result
= MATCHnomatch
;
3515 void visit(TypeAArray
*t
)
3517 // Extra check that index type must match
3518 if (tparam
&& tparam
->ty
== Taarray
)
3520 TypeAArray
*tp
= (TypeAArray
*)tparam
;
3521 if (!deduceType(t
->index
, sc
, tp
->index
, parameters
, dedtypes
))
3523 result
= MATCHnomatch
;
3530 void visit(TypeFunction
*t
)
3532 //printf("TypeFunction::deduceType()\n");
3533 //printf("\tthis = %d, ", t->ty); t->print();
3534 //printf("\ttparam = %d, ", tparam->ty); tparam->print();
3536 // Extra check that function characteristics must match
3537 if (tparam
&& tparam
->ty
== Tfunction
)
3539 TypeFunction
*tp
= (TypeFunction
*)tparam
;
3540 if (t
->parameterList
.varargs
!= tp
->parameterList
.varargs
||
3541 t
->linkage
!= tp
->linkage
)
3543 result
= MATCHnomatch
;
3547 size_t nfargs
= t
->parameterList
.length();
3548 size_t nfparams
= tp
->parameterList
.length();
3550 // bug 2579 fix: Apply function parameter storage classes to parameter types
3551 for (size_t i
= 0; i
< nfparams
; i
++)
3553 Parameter
*fparam
= tp
->parameterList
[i
];
3554 fparam
->type
= fparam
->type
->addStorageClass(fparam
->storageClass
);
3555 fparam
->storageClass
&= ~(STC_TYPECTOR
| STCin
);
3557 //printf("\t-> this = %d, ", t->ty); t->print();
3558 //printf("\t-> tparam = %d, ", tparam->ty); tparam->print();
3560 /* See if tuple match
3562 if (nfparams
> 0 && nfargs
>= nfparams
- 1)
3564 /* See if 'A' of the template parameter matches 'A'
3565 * of the type of the last function parameter.
3567 Parameter
*fparam
= tp
->parameterList
[nfparams
- 1];
3569 assert(fparam
->type
);
3570 if (fparam
->type
->ty
!= Tident
)
3572 TypeIdentifier
*tid
= (TypeIdentifier
*)fparam
->type
;
3573 if (tid
->idents
.length
)
3576 /* Look through parameters to find tuple matching tid->ident
3581 if (tupi
== parameters
->length
)
3583 TemplateParameter
*tx
= (*parameters
)[tupi
];
3584 TemplateTupleParameter
*tup
= tx
->isTemplateTupleParameter();
3585 if (tup
&& tup
->ident
->equals(tid
->ident
))
3589 /* The types of the function arguments [nfparams - 1 .. nfargs]
3590 * now form the tuple argument.
3592 size_t tuple_dim
= nfargs
- (nfparams
- 1);
3594 /* See if existing tuple, and whether it matches or not
3596 RootObject
*o
= (*dedtypes
)[tupi
];
3599 // Existing deduced argument must be a tuple, and must match
3600 Tuple
*tup
= isTuple(o
);
3601 if (!tup
|| tup
->objects
.length
!= tuple_dim
)
3603 result
= MATCHnomatch
;
3606 for (size_t i
= 0; i
< tuple_dim
; i
++)
3608 Parameter
*arg
= t
->parameterList
[nfparams
- 1 + i
];
3609 if (!arg
->type
->equals(tup
->objects
[i
]))
3611 result
= MATCHnomatch
;
3619 Tuple
*tup
= new Tuple();
3620 tup
->objects
.setDim(tuple_dim
);
3621 for (size_t i
= 0; i
< tuple_dim
; i
++)
3623 Parameter
*arg
= t
->parameterList
[nfparams
- 1 + i
];
3624 tup
->objects
[i
] = arg
->type
;
3626 (*dedtypes
)[tupi
] = tup
;
3628 nfparams
--; // don't consider the last parameter for type deduction
3633 if (nfargs
!= nfparams
)
3635 result
= MATCHnomatch
;
3639 for (size_t i
= 0; i
< nfparams
; i
++)
3641 Parameter
*a
= t
->parameterList
[i
];
3642 Parameter
*ap
= tp
->parameterList
[i
];
3644 if (!a
->isCovariant(t
->isref
, ap
) ||
3645 !deduceType(a
->type
, sc
, ap
->type
, parameters
, dedtypes
))
3647 result
= MATCHnomatch
;
3655 void visit(TypeIdentifier
*t
)
3658 if (tparam
&& tparam
->ty
== Tident
)
3660 TypeIdentifier
*tp
= (TypeIdentifier
*)tparam
;
3662 for (size_t i
= 0; i
< t
->idents
.length
; i
++)
3664 RootObject
*id1
= t
->idents
[i
];
3665 RootObject
*id2
= tp
->idents
[i
];
3667 if (!id1
->equals(id2
))
3669 result
= MATCHnomatch
;
3677 void visit(TypeInstance
*t
)
3680 if (tparam
&& tparam
->ty
== Tinstance
&& t
->tempinst
->tempdecl
)
3682 TemplateDeclaration
*tempdecl
= t
->tempinst
->tempdecl
->isTemplateDeclaration();
3685 TypeInstance
*tp
= (TypeInstance
*)tparam
;
3687 //printf("tempinst->tempdecl = %p\n", tempdecl);
3688 //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl);
3689 if (!tp
->tempinst
->tempdecl
)
3691 //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars());
3694 * template Foo(T : sa!(T), alias sa)
3696 size_t i
= templateIdentifierLookup(tp
->tempinst
->name
, parameters
);
3697 if (i
== IDX_NOTFOUND
)
3699 /* Didn't find it as a parameter identifier. Try looking
3700 * it up and seeing if is an alias. See Bugzilla 1454
3702 TypeIdentifier
*tid
= new TypeIdentifier(tp
->loc
, tp
->tempinst
->name
);
3706 tid
->resolve(tp
->loc
, sc
, &e
, &tx
, &s
);
3709 s
= tx
->toDsymbol(sc
);
3710 if (TemplateInstance
*ti
= s
? s
->parent
->isTemplateInstance() : NULL
)
3712 // Bugzilla 14290: Try to match with ti->tempecl,
3713 // only when ti is an enclosing instance.
3714 Dsymbol
*p
= sc
->parent
;
3715 while (p
&& p
!= ti
)
3724 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
3729 for (; td
; td
= td
->overnext
)
3738 TemplateParameter
*tpx
= (*parameters
)[i
];
3739 if (!tpx
->matchArg(sc
, tempdecl
, i
, parameters
, dedtypes
, NULL
))
3742 else if (tempdecl
!= tp
->tempinst
->tempdecl
)
3747 for (size_t i
= 0; 1; i
++)
3749 //printf("\ttest: tempinst->tiargs[%d]\n", i);
3750 RootObject
*o1
= NULL
;
3751 if (i
< t
->tempinst
->tiargs
->length
)
3752 o1
= (*t
->tempinst
->tiargs
)[i
];
3753 else if (i
< t
->tempinst
->tdtypes
.length
&& i
< tp
->tempinst
->tiargs
->length
)
3755 // Pick up default arg
3756 o1
= t
->tempinst
->tdtypes
[i
];
3758 else if (i
>= tp
->tempinst
->tiargs
->length
)
3761 if (i
>= tp
->tempinst
->tiargs
->length
)
3763 size_t dim
= tempdecl
->parameters
->length
- (tempdecl
->isVariadic() ? 1 : 0);
3764 while (i
< dim
&& ((*tempdecl
->parameters
)[i
]->dependent
||
3765 (*tempdecl
->parameters
)[i
]->hasDefaultArg()))
3770 break; // match if all remained parameters are dependent
3774 RootObject
*o2
= (*tp
->tempinst
->tiargs
)[i
];
3775 Type
*t2
= isType(o2
);
3777 size_t j
= (t2
&& t2
->ty
== Tident
&& i
== tp
->tempinst
->tiargs
->length
- 1)
3778 ? templateParameterLookup(t2
, parameters
) : IDX_NOTFOUND
;
3779 if (j
!= IDX_NOTFOUND
&& j
== parameters
->length
- 1 &&
3780 (*parameters
)[j
]->isTemplateTupleParameter())
3784 * alias A!(int, float) X;
3785 * static if (is(X Y == A!(Z), Z...)) {}
3786 * deduce that Z is a tuple(int, float)
3789 /* Create tuple from remaining args
3791 Tuple
*vt
= new Tuple();
3792 size_t vtdim
= (tempdecl
->isVariadic()
3793 ? t
->tempinst
->tiargs
->length
: t
->tempinst
->tdtypes
.length
) - i
;
3794 vt
->objects
.setDim(vtdim
);
3795 for (size_t k
= 0; k
< vtdim
; k
++)
3798 if (k
< t
->tempinst
->tiargs
->length
)
3799 o
= (*t
->tempinst
->tiargs
)[i
+ k
];
3800 else // Pick up default arg
3801 o
= t
->tempinst
->tdtypes
[i
+ k
];
3805 Tuple
*v
= (Tuple
*)(*dedtypes
)[j
];
3812 (*dedtypes
)[j
] = vt
;
3818 Type
*t1
= isType(o1
);
3819 Dsymbol
*s1
= isDsymbol(o1
);
3820 Dsymbol
*s2
= isDsymbol(o2
);
3821 Expression
*e1
= s1
? getValue(s1
) : getValue(isExpression(o1
));
3822 Expression
*e2
= isExpression(o2
);
3826 if (!deduceType(t1
, sc
, t2
, parameters
, dedtypes
))
3832 e1
= e1
->ctfeInterpret();
3834 /* If it is one of the template parameters for this template,
3835 * we should not attempt to interpret it. It already has a value.
3837 if (e2
->op
== TOKvar
&&
3838 (((VarExp
*)e2
)->var
->storage_class
& STCtemplateparameter
))
3841 * (T:Number!(e2), int e2)
3843 j
= templateIdentifierLookup(((VarExp
*)e2
)->var
->ident
, parameters
);
3844 if (j
!= IDX_NOTFOUND
)
3846 // The template parameter was not from this template
3847 // (it may be from a parent template, for example)
3850 e2
= ::semantic(e2
, sc
); // Bugzilla 13417
3851 e2
= e2
->ctfeInterpret();
3853 //printf("e1 = %s, type = %s %d\n", e1->toChars(), e1->type->toChars(), e1->type->ty);
3854 //printf("e2 = %s, type = %s %d\n", e2->toChars(), e2->type->toChars(), e2->type->ty);
3855 if (!e1
->equals(e2
))
3857 if (!e2
->implicitConvTo(e1
->type
))
3860 e2
= e2
->implicitCastTo(sc
, e1
->type
);
3861 e2
= e2
->ctfeInterpret();
3862 if (!e1
->equals(e2
))
3866 else if (e1
&& t2
&& t2
->ty
== Tident
)
3868 j
= templateParameterLookup(t2
, parameters
);
3870 if (j
== IDX_NOTFOUND
)
3872 t2
->resolve(((TypeIdentifier
*)t2
)->loc
, sc
, &e2
, &t2
, &s2
);
3877 if (!(*parameters
)[j
]->matchArg(sc
, e1
, j
, parameters
, dedtypes
, NULL
))
3883 if (!s1
->equals(s2
))
3886 else if (s1
&& t2
&& t2
->ty
== Tident
)
3888 j
= templateParameterLookup(t2
, parameters
);
3889 if (j
== IDX_NOTFOUND
)
3891 t2
->resolve(((TypeIdentifier
*)t2
)->loc
, sc
, &e2
, &t2
, &s2
);
3896 if (!(*parameters
)[j
]->matchArg(sc
, s1
, j
, parameters
, dedtypes
, NULL
))
3907 //printf("no match\n");
3908 result
= MATCHnomatch
;
3911 void visit(TypeStruct
*t
)
3913 /* If this struct is a template struct, and we're matching
3914 * it against a template instance, convert the struct type
3915 * to a template instance, too, and try again.
3917 TemplateInstance
*ti
= t
->sym
->parent
->isTemplateInstance();
3919 if (tparam
&& tparam
->ty
== Tinstance
)
3921 if (ti
&& ti
->toAlias() == t
->sym
)
3923 TypeInstance
*tx
= new TypeInstance(Loc(), ti
);
3924 result
= deduceType(tx
, sc
, tparam
, parameters
, dedtypes
, wm
);
3928 /* Match things like:
3931 TypeInstance
*tpi
= (TypeInstance
*)tparam
;
3932 if (tpi
->idents
.length
)
3934 RootObject
*id
= tpi
->idents
[tpi
->idents
.length
- 1];
3935 if (id
->dyncast() == DYNCAST_IDENTIFIER
&& t
->sym
->ident
->equals((Identifier
*)id
))
3937 Type
*tparent
= t
->sym
->parent
->getType();
3940 /* Slice off the .foo in S!(T).foo
3942 tpi
->idents
.length
--;
3943 result
= deduceType(tparent
, sc
, tpi
, parameters
, dedtypes
, wm
);
3944 tpi
->idents
.length
++;
3952 if (tparam
&& tparam
->ty
== Tstruct
)
3954 TypeStruct
*tp
= (TypeStruct
*)tparam
;
3956 //printf("\t%d\n", (MATCH) t->implicitConvTo(tp));
3957 if (wm
&& t
->deduceWild(tparam
, false))
3959 result
= MATCHconst
;
3962 result
= t
->implicitConvTo(tp
);
3968 void visit(TypeEnum
*t
)
3971 if (tparam
&& tparam
->ty
== Tenum
)
3973 TypeEnum
*tp
= (TypeEnum
*)tparam
;
3974 if (t
->sym
== tp
->sym
)
3977 result
= MATCHnomatch
;
3980 Type
*tb
= t
->toBasetype();
3981 if (tb
->ty
== tparam
->ty
||
3982 (tb
->ty
== Tsarray
&& tparam
->ty
== Taarray
))
3984 result
= deduceType(tb
, sc
, tparam
, parameters
, dedtypes
, wm
);
3990 /* Helper for TypeClass::deduceType().
3991 * Classes can match with implicit conversion to a base class or interface.
3992 * This is complicated, because there may be more than one base class which
3993 * matches. In such cases, one or more parameters remain ambiguous.
3996 * interface I(X, Y) {}
3997 * class C : I(uint, double), I(char, double) {}
3999 * foo(T, U)( I!(T, U) x)
4001 * deduces that U is double, but T remains ambiguous (could be char or uint).
4003 * Given a baseclass b, and initial deduced types 'dedtypes', this function
4004 * tries to match tparam with b, and also tries all base interfaces of b.
4005 * If a match occurs, numBaseClassMatches is incremented, and the new deduced
4006 * types are ANDed with the current 'best' estimate for dedtypes.
4008 static void deduceBaseClassParameters(BaseClass
*b
,
4009 Scope
*sc
, Type
*tparam
, TemplateParameters
*parameters
, Objects
*dedtypes
,
4010 Objects
*best
, int &numBaseClassMatches
)
4012 TemplateInstance
*parti
= b
->sym
? b
->sym
->parent
->isTemplateInstance() : NULL
;
4015 // Make a temporary copy of dedtypes so we don't destroy it
4016 Objects
*tmpdedtypes
= new Objects();
4017 tmpdedtypes
->setDim(dedtypes
->length
);
4018 memcpy(tmpdedtypes
->tdata(), dedtypes
->tdata(), dedtypes
->length
* sizeof(void *));
4020 TypeInstance
*t
= new TypeInstance(Loc(), parti
);
4021 MATCH m
= deduceType(t
, sc
, tparam
, parameters
, tmpdedtypes
);
4022 if (m
> MATCHnomatch
)
4024 // If this is the first ever match, it becomes our best estimate
4025 if (numBaseClassMatches
==0)
4026 memcpy(best
->tdata(), tmpdedtypes
->tdata(), tmpdedtypes
->length
* sizeof(void *));
4027 else for (size_t k
= 0; k
< tmpdedtypes
->length
; ++k
)
4029 // If we've found more than one possible type for a parameter,
4030 // mark it as unknown.
4031 if ((*tmpdedtypes
)[k
] != (*best
)[k
])
4032 (*best
)[k
] = (*dedtypes
)[k
];
4034 ++numBaseClassMatches
;
4037 // Now recursively test the inherited interfaces
4038 for (size_t j
= 0; j
< b
->baseInterfaces
.length
; ++j
)
4040 BaseClass
*bi
= &b
->baseInterfaces
.ptr
[j
];
4041 deduceBaseClassParameters(bi
,
4042 sc
, tparam
, parameters
, dedtypes
,
4043 best
, numBaseClassMatches
);
4048 void visit(TypeClass
*t
)
4050 //printf("TypeClass::deduceType(this = %s)\n", t->toChars());
4052 /* If this class is a template class, and we're matching
4053 * it against a template instance, convert the class type
4054 * to a template instance, too, and try again.
4056 TemplateInstance
*ti
= t
->sym
->parent
->isTemplateInstance();
4058 if (tparam
&& tparam
->ty
== Tinstance
)
4060 if (ti
&& ti
->toAlias() == t
->sym
)
4062 TypeInstance
*tx
= new TypeInstance(Loc(), ti
);
4063 MATCH m
= deduceType(tx
, sc
, tparam
, parameters
, dedtypes
, wm
);
4064 // Even if the match fails, there is still a chance it could match
4066 if (m
!= MATCHnomatch
)
4073 /* Match things like:
4076 TypeInstance
*tpi
= (TypeInstance
*)tparam
;
4077 if (tpi
->idents
.length
)
4079 RootObject
*id
= tpi
->idents
[tpi
->idents
.length
- 1];
4080 if (id
->dyncast() == DYNCAST_IDENTIFIER
&& t
->sym
->ident
->equals((Identifier
*)id
))
4082 Type
*tparent
= t
->sym
->parent
->getType();
4085 /* Slice off the .foo in S!(T).foo
4087 tpi
->idents
.length
--;
4088 result
= deduceType(tparent
, sc
, tpi
, parameters
, dedtypes
, wm
);
4089 tpi
->idents
.length
++;
4095 // If it matches exactly or via implicit conversion, we're done
4097 if (result
!= MATCHnomatch
)
4100 /* There is still a chance to match via implicit conversion to
4101 * a base class or interface. Because there could be more than one such
4102 * match, we need to check them all.
4105 int numBaseClassMatches
= 0; // Have we found an interface match?
4107 // Our best guess at dedtypes
4108 Objects
*best
= new Objects();
4109 best
->setDim(dedtypes
->length
);
4111 ClassDeclaration
*s
= t
->sym
;
4112 while (s
&& s
->baseclasses
->length
> 0)
4114 // Test the base class
4115 deduceBaseClassParameters((*s
->baseclasses
)[0],
4116 sc
, tparam
, parameters
, dedtypes
,
4117 best
, numBaseClassMatches
);
4119 // Test the interfaces inherited by the base class
4120 for (size_t i
= 0; i
< s
->interfaces
.length
; ++i
)
4122 BaseClass
*b
= s
->interfaces
.ptr
[i
];
4123 deduceBaseClassParameters(b
, sc
, tparam
, parameters
, dedtypes
,
4124 best
, numBaseClassMatches
);
4126 s
= (*s
->baseclasses
)[0]->sym
;
4129 if (numBaseClassMatches
== 0)
4131 result
= MATCHnomatch
;
4135 // If we got at least one match, copy the known types into dedtypes
4136 memcpy(dedtypes
->tdata(), best
->tdata(), best
->length
* sizeof(void *));
4137 result
= MATCHconvert
;
4142 if (tparam
&& tparam
->ty
== Tclass
)
4144 TypeClass
*tp
= (TypeClass
*)tparam
;
4146 //printf("\t%d\n", (MATCH) t->implicitConvTo(tp));
4147 if (wm
&& t
->deduceWild(tparam
, false))
4149 result
= MATCHconst
;
4152 result
= t
->implicitConvTo(tp
);
4158 void visit(Expression
*e
)
4160 //printf("Expression::deduceType(e = %s)\n", e->toChars());
4161 size_t i
= templateParameterLookup(tparam
, parameters
);
4162 if (i
== IDX_NOTFOUND
|| ((TypeIdentifier
*)tparam
)->idents
.length
> 0)
4164 if (e
== emptyArrayElement
&& tparam
->ty
== Tarray
)
4166 Type
*tn
= ((TypeNext
*)tparam
)->next
;
4167 result
= deduceType(emptyArrayElement
, sc
, tn
, parameters
, dedtypes
, wm
);
4170 e
->type
->accept(this);
4174 TemplateTypeParameter
*tp
= (*parameters
)[i
]->isTemplateTypeParameter();
4178 if (e
== emptyArrayElement
)
4182 result
= MATCHexact
;
4185 if (tp
->defaultType
)
4187 tp
->defaultType
->accept(this);
4192 Type
*at
= (Type
*)(*dedtypes
)[i
];
4194 if (unsigned char wx
= deduceWildHelper(e
->type
, &tt
, tparam
))
4197 result
= MATCHconst
;
4199 else if (MATCH m
= deduceTypeHelper(e
->type
, &tt
, tparam
))
4206 // expression vs (none)
4209 (*dedtypes
)[i
] = new TypeDeduced(tt
, e
, tparam
);
4213 TypeDeduced
*xt
= NULL
;
4214 if (at
->ty
== Tnone
)
4216 xt
= (TypeDeduced
*)at
;
4220 // From previous matched expressions to current deduced type
4221 MATCH match1
= xt
? xt
->matchAll(tt
) : MATCHnomatch
;
4223 // From current expresssion to previous deduced type
4224 Type
*pt
= at
->addMod(tparam
->mod
);
4226 pt
= pt
->substWildTo(*wm
);
4227 MATCH match2
= e
->implicitConvTo(pt
);
4229 if (match1
> MATCHnomatch
&& match2
> MATCHnomatch
)
4231 if (at
->implicitConvTo(tt
) <= MATCHnomatch
)
4232 match1
= MATCHnomatch
; // Prefer at
4233 else if (tt
->implicitConvTo(at
) <= MATCHnomatch
)
4234 match2
= MATCHnomatch
; // Prefer tt
4235 else if (tt
->isTypeBasic() && tt
->ty
== at
->ty
&& tt
->mod
!= at
->mod
)
4237 if (!tt
->isMutable() && !at
->isMutable())
4238 tt
= tt
->mutableOf()->addMod(MODmerge(tt
->mod
, at
->mod
));
4239 else if (tt
->isMutable())
4241 if (at
->mod
== 0) // Prefer unshared
4242 match1
= MATCHnomatch
;
4244 match2
= MATCHnomatch
;
4246 else if (at
->isMutable())
4248 if (tt
->mod
== 0) // Prefer unshared
4249 match2
= MATCHnomatch
;
4251 match1
= MATCHnomatch
;
4253 //printf("tt = %s, at = %s\n", tt->toChars(), at->toChars());
4257 match1
= MATCHnomatch
;
4258 match2
= MATCHnomatch
;
4261 if (match1
> MATCHnomatch
)
4263 // Prefer current match: tt
4265 xt
->update(tt
, e
, tparam
);
4267 (*dedtypes
)[i
] = tt
;
4271 if (match2
> MATCHnomatch
)
4273 // Prefer previous match: (*dedtypes)[i]
4275 xt
->update(e
, tparam
);
4280 /* Deduce common type
4282 if (Type
*t
= rawTypeMerge(at
, tt
))
4285 xt
->update(t
, e
, tparam
);
4289 pt
= tt
->addMod(tparam
->mod
);
4291 pt
= pt
->substWildTo(*wm
);
4292 result
= e
->implicitConvTo(pt
);
4296 result
= MATCHnomatch
;
4299 MATCH
deduceEmptyArrayElement()
4301 if (!emptyArrayElement
)
4303 emptyArrayElement
= new IdentifierExp(Loc(), Id::p
); // dummy
4304 emptyArrayElement
->type
= Type::tvoid
;
4306 assert(tparam
->ty
== Tarray
);
4308 Type
*tn
= ((TypeNext
*)tparam
)->next
;
4309 return deduceType(emptyArrayElement
, sc
, tn
, parameters
, dedtypes
, wm
);
4312 void visit(NullExp
*e
)
4314 if (tparam
->ty
== Tarray
&& e
->type
->ty
== Tnull
)
4316 // tparam:T[] <- e:null (void[])
4317 result
= deduceEmptyArrayElement();
4320 visit((Expression
*)e
);
4323 void visit(StringExp
*e
)
4326 if (e
->type
->ty
== Tarray
&&
4327 (tparam
->ty
== Tsarray
||
4328 (tparam
->ty
== Taarray
&& (taai
= ((TypeAArray
*)tparam
)->index
)->ty
== Tident
&&
4329 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
4331 // Consider compile-time known boundaries
4332 e
->type
->nextOf()->sarrayOf(e
->len
)->accept(this);
4335 visit((Expression
*)e
);
4338 void visit(ArrayLiteralExp
*e
)
4340 // https://issues.dlang.org/show_bug.cgi?id=20092
4341 if (e
->elements
&& e
->elements
->length
&&
4342 e
->type
->toBasetype()->nextOf()->ty
== Tvoid
)
4344 result
= deduceEmptyArrayElement();
4347 if ((!e
->elements
|| !e
->elements
->length
) &&
4348 e
->type
->toBasetype()->nextOf()->ty
== Tvoid
&&
4349 tparam
->ty
== Tarray
)
4351 // tparam:T[] <- e:[] (void[])
4352 result
= deduceEmptyArrayElement();
4356 if (tparam
->ty
== Tarray
&& e
->elements
&& e
->elements
->length
)
4358 Type
*tn
= ((TypeDArray
*)tparam
)->next
;
4359 result
= MATCHexact
;
4362 MATCH m
= deduceType(e
->basis
, sc
, tn
, parameters
, dedtypes
, wm
);
4366 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
4368 if (result
<= MATCHnomatch
)
4370 Expression
*el
= (*e
->elements
)[i
];
4373 MATCH m
= deduceType(el
, sc
, tn
, parameters
, dedtypes
, wm
);
4381 if (e
->type
->ty
== Tarray
&&
4382 (tparam
->ty
== Tsarray
||
4383 (tparam
->ty
== Taarray
&& (taai
= ((TypeAArray
*)tparam
)->index
)->ty
== Tident
&&
4384 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
4386 // Consider compile-time known boundaries
4387 e
->type
->nextOf()->sarrayOf(e
->elements
->length
)->accept(this);
4390 visit((Expression
*)e
);
4393 void visit(AssocArrayLiteralExp
*e
)
4395 if (tparam
->ty
== Taarray
&& e
->keys
&& e
->keys
->length
)
4397 TypeAArray
*taa
= (TypeAArray
*)tparam
;
4398 result
= MATCHexact
;
4399 for (size_t i
= 0; i
< e
->keys
->length
; i
++)
4401 MATCH m1
= deduceType((*e
->keys
)[i
], sc
, taa
->index
, parameters
, dedtypes
, wm
);
4404 if (result
<= MATCHnomatch
)
4406 MATCH m2
= deduceType((*e
->values
)[i
], sc
, taa
->next
, parameters
, dedtypes
, wm
);
4409 if (result
<= MATCHnomatch
)
4414 visit((Expression
*)e
);
4417 void visit(FuncExp
*e
)
4419 //printf("e->type = %s, tparam = %s\n", e->type->toChars(), tparam->toChars());
4423 if (!to
->nextOf() || to
->nextOf()->ty
!= Tfunction
)
4425 TypeFunction
*tof
= (TypeFunction
*)to
->nextOf();
4427 // Parameter types inference from 'tof'
4428 assert(e
->td
->_scope
);
4429 TypeFunction
*tf
= (TypeFunction
*)e
->fd
->type
;
4430 //printf("\ttof = %s\n", tof->toChars());
4431 //printf("\ttf = %s\n", tf->toChars());
4432 size_t dim
= tf
->parameterList
.length();
4434 if (tof
->parameterList
.length() != dim
||
4435 tof
->parameterList
.varargs
!= tf
->parameterList
.varargs
)
4438 Objects
*tiargs
= new Objects();
4439 tiargs
->reserve(e
->td
->parameters
->length
);
4441 for (size_t i
= 0; i
< e
->td
->parameters
->length
; i
++)
4443 TemplateParameter
*tp
= (*e
->td
->parameters
)[i
];
4445 for (; u
< dim
; u
++)
4447 Parameter
*p
= tf
->parameterList
[u
];
4448 if (p
->type
->ty
== Tident
&&
4449 ((TypeIdentifier
*)p
->type
)->ident
== tp
->ident
)
4455 Parameter
*pto
= tof
->parameterList
[u
];
4458 Type
*t
= pto
->type
->syntaxCopy(); // Bugzilla 11774
4459 if (reliesOnTident(t
, parameters
, inferStart
))
4461 t
= t
->semantic(e
->loc
, sc
);
4462 if (t
->ty
== Terror
)
4467 // Set target of return type inference
4468 if (!tf
->next
&& tof
->next
)
4469 e
->fd
->treq
= tparam
;
4471 TemplateInstance
*ti
= new TemplateInstance(e
->loc
, e
->td
, tiargs
);
4472 Expression
*ex
= new ScopeExp(e
->loc
, ti
);
4473 ex
= ::semantic(ex
, e
->td
->_scope
);
4475 // Reset inference target for the later re-semantic
4478 if (ex
->op
== TOKerror
)
4480 if (ex
->op
!= TOKfunction
)
4488 if (t
->ty
== Tdelegate
&& tparam
->ty
== Tpointer
)
4491 // Allow conversion from implicit function pointer to delegate
4492 if (e
->tok
== TOKreserved
&&
4493 t
->ty
== Tpointer
&& tparam
->ty
== Tdelegate
)
4495 TypeFunction
*tf
= (TypeFunction
*)t
->nextOf();
4496 t
= (new TypeDelegate(tf
))->merge();
4498 //printf("tparam = %s <= e->type = %s, t = %s\n", tparam->toChars(), e->type->toChars(), t->toChars());
4502 void visit(SliceExp
*e
)
4505 if (e
->type
->ty
== Tarray
&&
4506 (tparam
->ty
== Tsarray
||
4507 (tparam
->ty
== Taarray
&& (taai
= ((TypeAArray
*)tparam
)->index
)->ty
== Tident
&&
4508 ((TypeIdentifier
*)taai
)->idents
.length
== 0)))
4510 // Consider compile-time known boundaries
4511 if (Type
*tsa
= toStaticArrayType(e
))
4517 visit((Expression
*)e
);
4520 void visit(CommaExp
*e
)
4522 ((CommaExp
*)e
)->e2
->accept(this);
4526 DeduceType
v(sc
, tparam
, parameters
, dedtypes
, wm
, inferStart
);
4527 if (Type
*t
= isType(o
))
4531 assert(isExpression(o
) && wm
);
4532 ((Expression
*)o
)->accept(&v
);
4537 /*******************************
4539 * t Tested type, if NULL, returns NULL.
4540 * tparams Optional template parameters.
4542 * If one of the subtypes of this type is a TypeIdentifier,
4543 * i.e. it's an unresolved type, return that type.
4545 * Only when the TypeIdentifier is one of template parameters,
4549 bool reliesOnTident(Type
*t
, TemplateParameters
*tparams
, size_t iStart
)
4551 class ReliesOnTident
: public Visitor
4554 TemplateParameters
*tparams
;
4558 ReliesOnTident(TemplateParameters
*tparams
, size_t iStart
)
4559 : tparams(tparams
), iStart(iStart
)
4568 void visit(TypeNext
*t
)
4570 t
->next
->accept(this);
4573 void visit(TypeVector
*t
)
4575 t
->basetype
->accept(this);
4578 void visit(TypeAArray
*t
)
4580 visit((TypeNext
*)t
);
4582 t
->index
->accept(this);
4585 void visit(TypeFunction
*t
)
4587 size_t dim
= t
->parameterList
.length();
4588 for (size_t i
= 0; i
< dim
; i
++)
4590 Parameter
*fparam
= t
->parameterList
[i
];
4591 fparam
->type
->accept(this);
4596 t
->next
->accept(this);
4599 void visit(TypeIdentifier
*t
)
4607 for (size_t i
= iStart
; i
< tparams
->length
; i
++)
4609 TemplateParameter
*tp
= (*tparams
)[i
];
4610 if (tp
->ident
->equals(t
->ident
))
4618 void visit(TypeInstance
*t
)
4623 for (size_t i
= iStart
; i
< tparams
->length
; i
++)
4625 TemplateParameter
*tp
= (*tparams
)[i
];
4626 if (t
->tempinst
->name
== tp
->ident
)
4632 if (!t
->tempinst
->tiargs
)
4634 for (size_t i
= 0; i
< t
->tempinst
->tiargs
->length
; i
++)
4636 Type
*ta
= isType((*t
->tempinst
->tiargs
)[i
]);
4646 void visit(TypeTypeof
*t
)
4648 //printf("TypeTypeof::reliesOnTident('%s')\n", t->toChars());
4649 t
->exp
->accept(this);
4652 void visit(TypeTuple
*t
)
4656 for (size_t i
= 0; i
< t
->arguments
->length
; i
++)
4658 Parameter
*arg
= (*t
->arguments
)[i
];
4659 arg
->type
->accept(this);
4666 void visit(Expression
*)
4668 //printf("Expression::reliesOnTident('%s')\n", e->toChars());
4671 void visit(IdentifierExp
*e
)
4673 //printf("IdentifierExp::reliesOnTident('%s')\n", e->toChars());
4674 for (size_t i
= iStart
; i
< tparams
->length
; i
++)
4676 TemplateParameter
*tp
= (*tparams
)[i
];
4677 if (e
->ident
== tp
->ident
)
4685 void visit(TupleExp
*e
)
4687 //printf("TupleExp::reliesOnTident('%s')\n", e->toChars());
4690 for (size_t i
= 0; i
< e
->exps
->length
; i
++)
4692 Expression
*ea
= (*e
->exps
)[i
];
4700 void visit(ArrayLiteralExp
*e
)
4702 //printf("ArrayLiteralExp::reliesOnTident('%s')\n", e->toChars());
4705 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
4707 Expression
*el
= (*e
->elements
)[i
];
4715 void visit(AssocArrayLiteralExp
*e
)
4717 //printf("AssocArrayLiteralExp::reliesOnTident('%s')\n", e->toChars());
4718 for (size_t i
= 0; i
< e
->keys
->length
; i
++)
4720 Expression
*ek
= (*e
->keys
)[i
];
4725 for (size_t i
= 0; i
< e
->values
->length
; i
++)
4727 Expression
*ev
= (*e
->values
)[i
];
4734 void visit(StructLiteralExp
*e
)
4736 //printf("StructLiteralExp::reliesOnTident('%s')\n", e->toChars());
4739 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
4741 Expression
*ea
= (*e
->elements
)[i
];
4749 void visit(TypeExp
*e
)
4751 //printf("TypeExp::reliesOnTident('%s')\n", e->toChars());
4752 e
->type
->accept(this);
4755 void visit(NewExp
*e
)
4757 //printf("NewExp::reliesOnTident('%s')\n", e->toChars());
4759 e
->thisexp
->accept(this);
4760 if (!result
&& e
->newargs
)
4762 for (size_t i
= 0; i
< e
->newargs
->length
; i
++)
4764 Expression
*ea
= (*e
->newargs
)[i
];
4770 e
->newtype
->accept(this);
4771 if (!result
&& e
->arguments
)
4773 for (size_t i
= 0; i
< e
->arguments
->length
; i
++)
4775 Expression
*ea
= (*e
->arguments
)[i
];
4783 void visit(NewAnonClassExp
*)
4785 //printf("NewAnonClassExp::reliesOnTident('%s')\n", e->toChars());
4789 void visit(FuncExp
*)
4791 //printf("FuncExp::reliesOnTident('%s')\n", e->toChars());
4795 void visit(TypeidExp
*e
)
4797 //printf("TypeidExp::reliesOnTident('%s')\n", e->toChars());
4798 if (Expression
*ea
= isExpression(e
->obj
))
4800 else if (Type
*ta
= isType(e
->obj
))
4804 void visit(TraitsExp
*e
)
4806 //printf("TraitsExp::reliesOnTident('%s')\n", e->toChars());
4809 for (size_t i
= 0; i
< e
->args
->length
; i
++)
4811 RootObject
*oa
= (*e
->args
)[i
];
4812 if (Expression
*ea
= isExpression(oa
))
4814 else if (Type
*ta
= isType(oa
))
4822 void visit(IsExp
*e
)
4824 //printf("IsExp::reliesOnTident('%s')\n", e->toChars());
4825 e
->targ
->accept(this);
4828 void visit(UnaExp
*e
)
4830 //printf("UnaExp::reliesOnTident('%s')\n", e->toChars());
4831 e
->e1
->accept(this);
4834 void visit(DotTemplateInstanceExp
*e
)
4836 //printf("DotTemplateInstanceExp::reliesOnTident('%s')\n", e->toChars());
4838 if (!result
&& e
->ti
->tiargs
)
4840 for (size_t i
= 0; i
< e
->ti
->tiargs
->length
; i
++)
4842 RootObject
*oa
= (*e
->ti
->tiargs
)[i
];
4843 if (Expression
*ea
= isExpression(oa
))
4845 else if (Type
*ta
= isType(oa
))
4853 void visit(CallExp
*e
)
4855 //printf("CallExp::reliesOnTident('%s')\n", e->toChars());
4857 if (!result
&& e
->arguments
)
4859 for (size_t i
= 0; i
< e
->arguments
->length
; i
++)
4861 Expression
*ea
= (*e
->arguments
)[i
];
4869 void visit(CastExp
*e
)
4871 //printf("CastExp::reliesOnTident('%s')\n", e->toChars());
4873 // e.to can be null for cast() with no type
4874 if (!result
&& e
->to
)
4875 e
->to
->accept(this);
4878 void visit(SliceExp
*e
)
4880 //printf("SliceExp::reliesOnTident('%s')\n", e->toChars());
4882 if (!result
&& e
->lwr
)
4883 e
->lwr
->accept(this);
4884 if (!result
&& e
->upr
)
4885 e
->upr
->accept(this);
4888 void visit(IntervalExp
*e
)
4890 //printf("IntervalExp::reliesOnTident('%s')\n", e->toChars());
4891 e
->lwr
->accept(this);
4893 e
->upr
->accept(this);
4896 void visit(ArrayExp
*e
)
4898 //printf("ArrayExp::reliesOnTident('%s')\n", e->toChars());
4900 if (!result
&& e
->arguments
)
4902 for (size_t i
= 0; i
< e
->arguments
->length
; i
++)
4904 Expression
*ea
= (*e
->arguments
)[i
];
4910 void visit(BinExp
*e
)
4912 //printf("BinExp::reliesOnTident('%s')\n", e->toChars());
4913 e
->e1
->accept(this);
4915 e
->e2
->accept(this);
4918 void visit(CondExp
*e
)
4920 //printf("BinExp::reliesOnTident('%s')\n", e->toChars());
4921 e
->econd
->accept(this);
4930 ReliesOnTident
v(tparams
, iStart
);
4935 /* ======================== TemplateParameter =============================== */
4937 TemplateParameter::TemplateParameter(Loc loc
, Identifier
*ident
)
4940 this->ident
= ident
;
4941 this->dependent
= false;
4944 TemplateTypeParameter
*TemplateParameter::isTemplateTypeParameter()
4949 TemplateValueParameter
*TemplateParameter::isTemplateValueParameter()
4954 TemplateAliasParameter
*TemplateParameter::isTemplateAliasParameter()
4959 TemplateTupleParameter
*TemplateParameter::isTemplateTupleParameter()
4964 TemplateThisParameter
*TemplateParameter::isTemplateThisParameter()
4969 /*******************************************
4970 * Match to a particular TemplateParameter.
4972 * instLoc location that the template is instantiated.
4973 * tiargs[] actual arguments to template instance
4975 * parameters[] template parameters
4976 * dedtypes[] deduced arguments to template instance
4977 * *psparam set to symbol declared and initialized to dedtypes[i]
4979 MATCH
TemplateParameter::matchArg(Loc instLoc
, Scope
*sc
, Objects
*tiargs
,
4980 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
4981 Declaration
**psparam
)
4985 if (i
< tiargs
->length
)
4986 oarg
= (*tiargs
)[i
];
4989 // Get default argument instead
4990 oarg
= defaultArg(instLoc
, sc
);
4993 assert(i
< dedtypes
->length
);
4994 // It might have already been deduced
4995 oarg
= (*dedtypes
)[i
];
5000 return matchArg(sc
, oarg
, i
, parameters
, dedtypes
, psparam
);
5005 return MATCHnomatch
;
5008 /* ======================== TemplateTypeParameter =========================== */
5012 Type
*TemplateTypeParameter::tdummy
= NULL
;
5014 TemplateTypeParameter::TemplateTypeParameter(Loc loc
, Identifier
*ident
, Type
*specType
,
5016 : TemplateParameter(loc
, ident
)
5018 this->ident
= ident
;
5019 this->specType
= specType
;
5020 this->defaultType
= defaultType
;
5023 TemplateTypeParameter
*TemplateTypeParameter::isTemplateTypeParameter()
5028 TemplateParameter
*TemplateTypeParameter::syntaxCopy()
5030 return new TemplateTypeParameter(loc
, ident
,
5031 specType
? specType
->syntaxCopy() : NULL
,
5032 defaultType
? defaultType
->syntaxCopy() : NULL
);
5035 bool TemplateTypeParameter::declareParameter(Scope
*sc
)
5037 //printf("TemplateTypeParameter::declareParameter('%s')\n", ident->toChars());
5038 TypeIdentifier
*ti
= new TypeIdentifier(loc
, ident
);
5039 Declaration
*ad
= new AliasDeclaration(loc
, ident
, ti
);
5040 return sc
->insert(ad
) != NULL
;
5043 bool TemplateTypeParameter::semantic(Scope
*sc
, TemplateParameters
*parameters
)
5045 //printf("TemplateTypeParameter::semantic('%s')\n", ident->toChars());
5046 if (specType
&& !reliesOnTident(specType
, parameters
))
5048 specType
= specType
->semantic(loc
, sc
);
5050 return !(specType
&& isError(specType
));
5053 MATCH
TemplateTypeParameter::matchArg(Scope
*sc
, RootObject
*oarg
,
5054 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
5055 Declaration
**psparam
)
5057 //printf("TemplateTypeParameter::matchArg('%s')\n", ident->toChars());
5058 MATCH m
= MATCHexact
;
5059 Type
*ta
= isType(oarg
);
5062 //printf("%s %p %p %p\n", oarg->toChars(), isExpression(oarg), isDsymbol(oarg), isTuple(oarg));
5065 //printf("ta is %s\n", ta->toChars());
5069 if (!ta
|| ta
== tdummy
)
5072 //printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta->toChars(), specType->toChars());
5073 MATCH m2
= deduceType(ta
, sc
, specType
, parameters
, dedtypes
);
5074 if (m2
<= MATCHnomatch
)
5076 //printf("\tfailed deduceType\n");
5084 Type
*t
= (Type
*)(*dedtypes
)[i
];
5086 if (dependent
&& !t
->equals(ta
)) // Bugzilla 14357
5089 /* This is a self-dependent parameter. For example:
5090 * template X(T : T*) {}
5091 * template X(T : S!T, alias S) {}
5093 //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
5101 // Must match already deduced type
5102 Type
*t
= (Type
*)(*dedtypes
)[i
];
5106 //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
5112 // So that matches with specializations are better
5116 (*dedtypes
)[i
] = ta
;
5119 *psparam
= new AliasDeclaration(loc
, ident
, ta
);
5120 //printf("\tm = %d\n", m);
5121 return dependent
? MATCHexact
: m
;
5126 //printf("\tm = %d\n", MATCHnomatch);
5127 return MATCHnomatch
;
5131 void TemplateTypeParameter::print(RootObject
*oarg
, RootObject
*oded
)
5133 printf(" %s\n", ident
->toChars());
5135 Type
*t
= isType(oarg
);
5136 Type
*ta
= isType(oded
);
5141 printf("\tSpecialization: %s\n", specType
->toChars());
5143 printf("\tDefault: %s\n", defaultType
->toChars());
5144 printf("\tParameter: %s\n", t
? t
->toChars() : "NULL");
5145 printf("\tDeduced Type: %s\n", ta
->toChars());
5148 void *TemplateTypeParameter::dummyArg()
5153 // Use this for alias-parameter's too (?)
5155 tdummy
= new TypeIdentifier(loc
, ident
);
5162 RootObject
*TemplateTypeParameter::specialization()
5167 RootObject
*TemplateTypeParameter::defaultArg(Loc
, Scope
*sc
)
5169 Type
*t
= defaultType
;
5172 t
= t
->syntaxCopy();
5173 t
= t
->semantic(loc
, sc
); // use the parameter loc
5178 bool TemplateTypeParameter::hasDefaultArg()
5180 return defaultType
!= NULL
;
5183 /* ======================== TemplateThisParameter =========================== */
5187 TemplateThisParameter::TemplateThisParameter(Loc loc
, Identifier
*ident
,
5190 : TemplateTypeParameter(loc
, ident
, specType
, defaultType
)
5194 TemplateThisParameter
*TemplateThisParameter::isTemplateThisParameter()
5199 TemplateParameter
*TemplateThisParameter::syntaxCopy()
5201 return new TemplateThisParameter(loc
, ident
,
5202 specType
? specType
->syntaxCopy() : NULL
,
5203 defaultType
? defaultType
->syntaxCopy() : NULL
);
5206 /* ======================== TemplateAliasParameter ========================== */
5210 Dsymbol
*TemplateAliasParameter::sdummy
= NULL
;
5212 TemplateAliasParameter::TemplateAliasParameter(Loc loc
, Identifier
*ident
,
5213 Type
*specType
, RootObject
*specAlias
, RootObject
*defaultAlias
)
5214 : TemplateParameter(loc
, ident
)
5216 this->ident
= ident
;
5217 this->specType
= specType
;
5218 this->specAlias
= specAlias
;
5219 this->defaultAlias
= defaultAlias
;
5222 TemplateAliasParameter
*TemplateAliasParameter::isTemplateAliasParameter()
5227 TemplateParameter
*TemplateAliasParameter::syntaxCopy()
5229 return new TemplateAliasParameter(loc
, ident
,
5230 specType
? specType
->syntaxCopy() : NULL
,
5231 objectSyntaxCopy(specAlias
),
5232 objectSyntaxCopy(defaultAlias
));
5235 bool TemplateAliasParameter::declareParameter(Scope
*sc
)
5237 TypeIdentifier
*ti
= new TypeIdentifier(loc
, ident
);
5238 Declaration
*ad
= new AliasDeclaration(loc
, ident
, ti
);
5239 return sc
->insert(ad
) != NULL
;
5242 static RootObject
*aliasParameterSemantic(Loc loc
, Scope
*sc
, RootObject
*o
, TemplateParameters
*parameters
)
5246 Expression
*ea
= isExpression(o
);
5247 Type
*ta
= isType(o
);
5248 if (ta
&& (!parameters
|| !reliesOnTident(ta
, parameters
)))
5250 Dsymbol
*s
= ta
->toDsymbol(sc
);
5254 o
= ta
->semantic(loc
, sc
);
5258 sc
= sc
->startCTFE();
5259 ea
= ::semantic(ea
, sc
);
5261 o
= ea
->ctfeInterpret();
5267 bool TemplateAliasParameter::semantic(Scope
*sc
, TemplateParameters
*parameters
)
5269 if (specType
&& !reliesOnTident(specType
, parameters
))
5271 specType
= specType
->semantic(loc
, sc
);
5273 specAlias
= aliasParameterSemantic(loc
, sc
, specAlias
, parameters
);
5274 return !(specType
&& isError(specType
)) &&
5275 !(specAlias
&& isError(specAlias
));
5278 MATCH
TemplateAliasParameter::matchArg(Scope
*sc
, RootObject
*oarg
,
5279 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
5280 Declaration
**psparam
)
5282 //printf("TemplateAliasParameter::matchArg('%s')\n", ident->toChars());
5283 MATCH m
= MATCHexact
;
5284 Type
*ta
= isType(oarg
);
5285 RootObject
*sa
= ta
&& !ta
->deco
? NULL
: getDsymbol(oarg
);
5286 Expression
*ea
= isExpression(oarg
);
5287 if (ea
&& (ea
->op
== TOKthis
|| ea
->op
== TOKsuper
))
5288 sa
= ((ThisExp
*)ea
)->var
;
5289 else if (ea
&& ea
->op
== TOKscope
)
5290 sa
= ((ScopeExp
*)ea
)->sds
;
5293 if (((Dsymbol
*)sa
)->isAggregateDeclaration())
5296 /* specType means the alias must be a declaration with a type
5297 * that matches specType.
5301 Declaration
*d
= ((Dsymbol
*)sa
)->isDeclaration();
5304 if (!d
->type
->equals(specType
))
5315 if (!ea
->type
->equals(specType
))
5319 else if (ta
&& ta
->ty
== Tinstance
&& !specAlias
)
5321 /* Bugzilla xxxxx: Specialized parameter should be prefeerd
5322 * match to the template type parameter.
5323 * template X(alias a) {} // a == this
5324 * template X(alias a : B!A, alias B, A...) {} // B!A => ta
5327 else if (sa
&& sa
== TemplateTypeParameter::tdummy
)
5329 /* Bugzilla 2025: Aggregate Types should preferentially
5330 * match to the template type parameter.
5331 * template X(alias a) {} // a == this
5332 * template X(T) {} // T => sa
5343 Dsymbol
*sx
= isDsymbol(sa
);
5344 if (sa
!= specAlias
&& sx
)
5346 Type
*talias
= isType(specAlias
);
5350 TemplateInstance
*ti
= sx
->isTemplateInstance();
5351 if (!ti
&& sx
->parent
)
5353 ti
= sx
->parent
->isTemplateInstance();
5354 if (ti
&& ti
->name
!= sx
->ident
)
5360 Type
*t
= new TypeInstance(Loc(), ti
);
5361 MATCH m2
= deduceType(t
, sc
, talias
, parameters
, dedtypes
);
5362 if (m2
<= MATCHnomatch
)
5366 else if ((*dedtypes
)[i
])
5368 // Must match already deduced symbol
5369 RootObject
*si
= (*dedtypes
)[i
];
5370 if (!sa
|| si
!= sa
)
5373 (*dedtypes
)[i
] = sa
;
5377 if (Dsymbol
*s
= isDsymbol(sa
))
5379 *psparam
= new AliasDeclaration(loc
, ident
, s
);
5381 else if (Type
*t
= isType(sa
))
5383 *psparam
= new AliasDeclaration(loc
, ident
, t
);
5389 // Declare manifest constant
5390 Initializer
*init
= new ExpInitializer(loc
, ea
);
5391 VarDeclaration
*v
= new VarDeclaration(loc
, NULL
, ident
, init
);
5392 v
->storage_class
= STCmanifest
;
5397 return dependent
? MATCHexact
: m
;
5402 //printf("\tm = %d\n", MATCHnomatch);
5403 return MATCHnomatch
;
5407 void TemplateAliasParameter::print(RootObject
*, RootObject
*oded
)
5409 printf(" %s\n", ident
->toChars());
5411 Dsymbol
*sa
= isDsymbol(oded
);
5414 printf("\tParameter alias: %s\n", sa
->toChars());
5417 void *TemplateAliasParameter::dummyArg()
5419 RootObject
*s
= specAlias
;
5423 sdummy
= new Dsymbol();
5430 RootObject
*TemplateAliasParameter::specialization()
5435 RootObject
*TemplateAliasParameter::defaultArg(Loc
, Scope
*sc
)
5437 RootObject
*da
= defaultAlias
;
5438 Type
*ta
= isType(defaultAlias
);
5441 if (ta
->ty
== Tinstance
)
5443 // If the default arg is a template, instantiate for each type
5444 da
= ta
->syntaxCopy();
5448 RootObject
*o
= aliasParameterSemantic(loc
, sc
, da
, NULL
); // use the parameter loc
5452 bool TemplateAliasParameter::hasDefaultArg()
5454 return defaultAlias
!= NULL
;
5457 /* ======================== TemplateValueParameter ========================== */
5461 AA
*TemplateValueParameter::edummies
= NULL
;
5463 TemplateValueParameter::TemplateValueParameter(Loc loc
, Identifier
*ident
, Type
*valType
,
5464 Expression
*specValue
, Expression
*defaultValue
)
5465 : TemplateParameter(loc
, ident
)
5467 this->ident
= ident
;
5468 this->valType
= valType
;
5469 this->specValue
= specValue
;
5470 this->defaultValue
= defaultValue
;
5473 TemplateValueParameter
*TemplateValueParameter::isTemplateValueParameter()
5478 TemplateParameter
*TemplateValueParameter::syntaxCopy()
5480 return new TemplateValueParameter(loc
, ident
,
5481 valType
->syntaxCopy(),
5482 specValue
? specValue
->syntaxCopy() : NULL
,
5483 defaultValue
? defaultValue
->syntaxCopy() : NULL
);
5486 bool TemplateValueParameter::declareParameter(Scope
*sc
)
5488 VarDeclaration
*v
= new VarDeclaration(loc
, valType
, ident
, NULL
);
5489 v
->storage_class
= STCtemplateparameter
;
5490 return sc
->insert(v
) != NULL
;
5493 bool TemplateValueParameter::semantic(Scope
*sc
, TemplateParameters
*)
5495 valType
= valType
->semantic(loc
, sc
);
5497 return !isError(valType
);
5500 MATCH
TemplateValueParameter::matchArg(Scope
*sc
, RootObject
*oarg
,
5501 size_t i
, TemplateParameters
*, Objects
*dedtypes
, Declaration
**psparam
)
5503 //printf("TemplateValueParameter::matchArg('%s')\n", ident->toChars());
5505 MATCH m
= MATCHexact
;
5507 Expression
*ei
= isExpression(oarg
);
5512 Dsymbol
*si
= isDsymbol(oarg
);
5513 FuncDeclaration
*f
= si
? si
->isFuncDeclaration() : NULL
;
5514 if (!f
|| !f
->fbody
|| f
->needThis())
5517 ei
= new VarExp(loc
, f
);
5518 ei
= ::semantic(ei
, sc
);
5520 /* If a function is really property-like, and then
5521 * it's CTFEable, ei will be a literal expression.
5523 unsigned int olderrors
= global
.startGagging();
5524 ei
= resolveProperties(sc
, ei
);
5525 ei
= ei
->ctfeInterpret();
5526 if (global
.endGagging(olderrors
) || ei
->op
== TOKerror
)
5529 /* Bugzilla 14520: A property-like function can match to both
5530 * TemplateAlias and ValueParameter. But for template overloads,
5531 * it should always prefer alias parameter to be consistent
5532 * template match result.
5534 * template X(alias f) { enum X = 1; }
5535 * template X(int val) { enum X = 2; }
5536 * int f1() { return 0; } // CTFEable
5537 * int f2(); // body-less function is not CTFEable
5538 * enum x1 = X!f1; // should be 1
5539 * enum x2 = X!f2; // should be 1
5541 * e.g. The x1 value must be same even if the f1 definition will be moved
5542 * into di while stripping body code.
5547 if (ei
&& ei
->op
== TOKvar
)
5549 // Resolve const variables that we had skipped earlier
5550 ei
= ei
->ctfeInterpret();
5553 //printf("\tvalType: %s, ty = %d\n", valType->toChars(), valType->ty);
5554 vt
= valType
->semantic(loc
, sc
);
5555 //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars());
5556 //printf("vt = %s\n", vt->toChars());
5560 MATCH m2
= ei
->implicitConvTo(vt
);
5561 //printf("m: %d\n", m);
5564 if (m
<= MATCHnomatch
)
5566 ei
= ei
->implicitCastTo(sc
, vt
);
5567 ei
= ei
->ctfeInterpret();
5572 if (!ei
|| (Expression
*)dmd_aaGetRvalue(edummies
, (void *)ei
->type
) == ei
)
5575 Expression
*e
= specValue
;
5577 sc
= sc
->startCTFE();
5578 e
= ::semantic(e
, sc
);
5579 e
= resolveProperties(sc
, e
);
5581 e
= e
->implicitCastTo(sc
, vt
);
5582 e
= e
->ctfeInterpret();
5584 ei
= ei
->syntaxCopy();
5585 sc
= sc
->startCTFE();
5586 ei
= ::semantic(ei
, sc
);
5588 ei
= ei
->implicitCastTo(sc
, vt
);
5589 ei
= ei
->ctfeInterpret();
5590 //printf("\tei: %s, %s\n", ei->toChars(), ei->type->toChars());
5591 //printf("\te : %s, %s\n", e->toChars(), e->type->toChars());
5599 // Must match already deduced value
5600 Expression
*e
= (Expression
*)(*dedtypes
)[i
];
5602 if (!ei
|| !ei
->equals(e
))
5606 (*dedtypes
)[i
] = ei
;
5610 Initializer
*init
= new ExpInitializer(loc
, ei
);
5611 Declaration
*sparam
= new VarDeclaration(loc
, vt
, ident
, init
);
5612 sparam
->storage_class
= STCmanifest
;
5615 return dependent
? MATCHexact
: m
;
5618 //printf("\tno match\n");
5621 return MATCHnomatch
;
5625 void TemplateValueParameter::print(RootObject
*, RootObject
*oded
)
5627 printf(" %s\n", ident
->toChars());
5629 Expression
*ea
= isExpression(oded
);
5632 printf("\tSpecialization: %s\n", specValue
->toChars());
5633 printf("\tParameter Value: %s\n", ea
? ea
->toChars() : "NULL");
5636 void *TemplateValueParameter::dummyArg()
5638 Expression
*e
= specValue
;
5641 // Create a dummy value
5642 Expression
**pe
= (Expression
**)dmd_aaGet(&edummies
, (void *)valType
);
5644 *pe
= valType
->defaultInit();
5651 RootObject
*TemplateValueParameter::specialization()
5656 RootObject
*TemplateValueParameter::defaultArg(Loc instLoc
, Scope
*sc
)
5658 Expression
*e
= defaultValue
;
5661 e
= e
->syntaxCopy();
5662 if ((e
= ::semantic(e
, sc
)) == NULL
)
5664 if ((e
= resolveProperties(sc
, e
)) == NULL
)
5666 e
= e
->resolveLoc(instLoc
, sc
); // use the instantiated loc
5667 e
= e
->optimize(WANTvalue
);
5672 bool TemplateValueParameter::hasDefaultArg()
5674 return defaultValue
!= NULL
;
5677 /* ======================== TemplateTupleParameter ========================== */
5679 // variadic-parameter
5681 TemplateTupleParameter::TemplateTupleParameter(Loc loc
, Identifier
*ident
)
5682 : TemplateParameter(loc
, ident
)
5684 this->ident
= ident
;
5687 TemplateTupleParameter
*TemplateTupleParameter::isTemplateTupleParameter()
5692 TemplateParameter
*TemplateTupleParameter::syntaxCopy()
5694 return new TemplateTupleParameter(loc
, ident
);
5697 bool TemplateTupleParameter::declareParameter(Scope
*sc
)
5699 TypeIdentifier
*ti
= new TypeIdentifier(loc
, ident
);
5700 Declaration
*ad
= new AliasDeclaration(loc
, ident
, ti
);
5701 return sc
->insert(ad
) != NULL
;
5704 bool TemplateTupleParameter::semantic(Scope
*, TemplateParameters
*)
5709 MATCH
TemplateTupleParameter::matchArg(Loc
, Scope
*sc
, Objects
*tiargs
,
5710 size_t i
, TemplateParameters
*parameters
, Objects
*dedtypes
,
5711 Declaration
**psparam
)
5713 /* The rest of the actual arguments (tiargs[]) form the match
5714 * for the variadic parameter.
5716 assert(i
+ 1 == dedtypes
->length
); // must be the last one
5719 if (Tuple
*u
= isTuple((*dedtypes
)[i
]))
5721 // It has already been deduced
5724 else if (i
+ 1 == tiargs
->length
&& isTuple((*tiargs
)[i
]))
5725 ovar
= isTuple((*tiargs
)[i
]);
5729 //printf("ovar = %p\n", ovar);
5730 if (i
< tiargs
->length
)
5732 //printf("i = %d, tiargs->length = %d\n", i, tiargs->length);
5733 ovar
->objects
.setDim(tiargs
->length
- i
);
5734 for (size_t j
= 0; j
< ovar
->objects
.length
; j
++)
5735 ovar
->objects
[j
] = (*tiargs
)[i
+ j
];
5738 return matchArg(sc
, ovar
, i
, parameters
, dedtypes
, psparam
);
5741 MATCH
TemplateTupleParameter::matchArg(Scope
*, RootObject
*oarg
,
5742 size_t i
, TemplateParameters
*, Objects
*dedtypes
, Declaration
**psparam
)
5744 //printf("TemplateTupleParameter::matchArg('%s')\n", ident->toChars());
5745 Tuple
*ovar
= isTuple(oarg
);
5747 return MATCHnomatch
;
5750 Tuple
*tup
= isTuple((*dedtypes
)[i
]);
5752 return MATCHnomatch
;
5753 if (!match(tup
, ovar
))
5754 return MATCHnomatch
;
5756 (*dedtypes
)[i
] = ovar
;
5759 *psparam
= new TupleDeclaration(loc
, ident
, &ovar
->objects
);
5760 return dependent
? MATCHexact
: MATCHconvert
;
5764 void TemplateTupleParameter::print(RootObject
*, RootObject
*oded
)
5766 printf(" %s... [", ident
->toChars());
5767 Tuple
*v
= isTuple(oded
);
5770 //printf("|%d| ", v->objects.length);
5771 for (size_t i
= 0; i
< v
->objects
.length
; i
++)
5776 RootObject
*o
= v
->objects
[i
];
5778 Dsymbol
*sa
= isDsymbol(o
);
5780 printf("alias: %s", sa
->toChars());
5782 Type
*ta
= isType(o
);
5784 printf("type: %s", ta
->toChars());
5786 Expression
*ea
= isExpression(o
);
5788 printf("exp: %s", ea
->toChars());
5790 assert(!isTuple(o
)); // no nested Tuple arguments
5796 void *TemplateTupleParameter::dummyArg()
5802 RootObject
*TemplateTupleParameter::specialization()
5807 RootObject
*TemplateTupleParameter::defaultArg(Loc
, Scope
*)
5812 bool TemplateTupleParameter::hasDefaultArg()
5817 /* ======================== TemplateInstance ================================ */
5819 TemplateInstance::TemplateInstance(Loc loc
, Identifier
*ident
)
5820 : ScopeDsymbol(NULL
)
5824 this->tiargs
= NULL
;
5825 this->tempdecl
= NULL
;
5830 this->deferred
= NULL
;
5831 this->memberOf
= NULL
;
5832 this->argsym
= NULL
;
5833 this->aliasdecl
= NULL
;
5834 this->semantictiargsdone
= false;
5837 this->havetempdecl
= false;
5838 this->enclosing
= NULL
;
5839 this->gagged
= false;
5845 * This constructor is only called when we figured out which function
5846 * template to instantiate.
5849 TemplateInstance::TemplateInstance(Loc loc
, TemplateDeclaration
*td
, Objects
*tiargs
)
5850 : ScopeDsymbol(NULL
)
5853 this->name
= td
->ident
;
5854 this->tiargs
= tiargs
;
5855 this->tempdecl
= td
;
5860 this->deferred
= NULL
;
5861 this->memberOf
= NULL
;
5862 this->argsym
= NULL
;
5863 this->aliasdecl
= NULL
;
5864 this->semantictiargsdone
= true;
5867 this->havetempdecl
= true;
5868 this->enclosing
= NULL
;
5869 this->gagged
= false;
5873 assert(tempdecl
->_scope
);
5877 Objects
*TemplateInstance::arraySyntaxCopy(Objects
*objs
)
5883 a
->setDim(objs
->length
);
5884 for (size_t i
= 0; i
< objs
->length
; i
++)
5885 (*a
)[i
] = objectSyntaxCopy((*objs
)[i
]);
5890 Dsymbol
*TemplateInstance::syntaxCopy(Dsymbol
*s
)
5892 TemplateInstance
*ti
=
5893 s
? (TemplateInstance
*)s
5894 : new TemplateInstance(loc
, name
);
5895 ti
->tiargs
= arraySyntaxCopy(tiargs
);
5896 TemplateDeclaration
*td
;
5897 if (inst
&& tempdecl
&& (td
= tempdecl
->isTemplateDeclaration()) != NULL
)
5898 td
->ScopeDsymbol::syntaxCopy(ti
);
5900 ScopeDsymbol::syntaxCopy(ti
);
5904 void TemplateInstance::semantic(Scope
*sc
)
5909 void TemplateInstance::expandMembers(Scope
*sc2
)
5911 for (size_t i
= 0; i
< members
->length
; i
++)
5913 Dsymbol
*s
= (*members
)[i
];
5917 for (size_t i
= 0; i
< members
->length
; i
++)
5919 Dsymbol
*s
= (*members
)[i
];
5923 for (size_t i
= 0; i
< members
->length
; i
++)
5925 Dsymbol
*s
= (*members
)[i
];
5926 //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars());
5927 //printf("test: enclosing = %d, sc2->parent = %s\n", enclosing, sc2->parent->toChars());
5929 // s->parent = sc->parent;
5930 //printf("test3: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars());
5932 //printf("test4: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars());
5933 Module::runDeferredSemantic();
5937 void TemplateInstance::tryExpandMembers(Scope
*sc2
)
5940 // extracted to a function to allow windows SEH to work without destructors in the same function
5941 //printf("%d\n", nest);
5942 if (++nest
> global
.recursionLimit
)
5944 global
.gag
= 0; // ensure error message gets printed
5945 error("recursive expansion exceeded allowed nesting limit");
5954 void TemplateInstance::trySemantic3(Scope
*sc2
)
5956 // extracted to a function to allow windows SEH to work without destructors in the same function
5958 //printf("%d\n", nest);
5959 if (++nest
> global
.recursionLimit
)
5961 global
.gag
= 0; // ensure error message gets printed
5962 error("recursive expansion exceeded allowed nesting limit");
5970 void TemplateInstance::semantic(Scope
*sc
, Expressions
*fargs
)
5972 //printf("[%s] TemplateInstance::semantic('%s', this=%p, gag = %d, sc = %p)\n", loc.toChars(), toChars(), this, global.gag, sc);
5973 if (inst
) // if semantic() was already run
5977 if (semanticRun
!= PASSinit
)
5979 Ungag
ungag(global
.gag
);
5982 error(loc
, "recursive template expansion");
5984 semanticRun
= PASSinit
;
5991 // Get the enclosing template instance from the scope tinst
5994 // Get the instantiating module from the scope minst
5996 // Bugzilla 10920: If the enclosing function is non-root symbol,
5997 // this instance should be speculative.
5998 if (!tinst
&& sc
->func
&& sc
->func
->inNonRoot())
6003 gagged
= (global
.gag
> 0);
6005 semanticRun
= PASSsemantic
;
6007 /* Find template declaration first,
6008 * then run semantic on each argument (place results in tiargs[]),
6009 * last find most specialized template from overload list/set.
6011 if (!findTempDecl(sc
, NULL
) ||
6012 !semanticTiargs(sc
) ||
6013 !findBestMatch(sc
, fargs
))
6018 // Bugzilla 13220: Rollback status for later semantic re-running.
6019 semanticRun
= PASSinit
;
6026 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
6029 // If tempdecl is a mixin, disallow it
6030 if (tempdecl
->ismixin
)
6032 error("mixin templates are not regular templates");
6036 hasNestedArgs(tiargs
, tempdecl
->isstatic
);
6040 /* See if there is an existing TemplateInstantiation that already
6041 * implements the typeargs. If so, just refer to that one instead.
6043 inst
= tempdecl
->findExistingInstance(this, fargs
);
6044 TemplateInstance
*errinst
= NULL
;
6047 // So, we need to implement 'this' instance.
6049 else if (inst
->gagged
&& !gagged
&& inst
->errors
)
6051 // If the first instantiation had failed, re-run semantic,
6052 // so that error messages are shown.
6058 parent
= inst
->parent
;
6059 errors
= inst
->errors
;
6061 // If both this and the previous instantiation were gagged,
6062 // use the number of errors that happened last time.
6063 global
.errors
+= errors
;
6064 global
.gaggedErrors
+= errors
;
6066 // If the first instantiation was gagged, but this is not:
6069 // It had succeeded, mark it is a non-gagged instantiation,
6071 inst
->gagged
= gagged
;
6074 this->tnext
= inst
->tnext
;
6077 /* A module can have explicit template instance and its alias
6078 * in module scope (e,g, `alias Base64 = Base64Impl!('+', '/');`).
6079 * If the first instantiation 'inst' had happened in non-root module,
6080 * compiler can assume that its instantiated code would be included
6081 * in the separately compiled obj/lib file (e.g. phobos.lib).
6083 * However, if 'this' second instantiation happened in root module,
6084 * compiler might need to invoke its codegen (Bugzilla 2500 & 2644).
6085 * But whole import graph is not determined until all semantic pass finished,
6086 * so 'inst' should conservatively finish the semantic3 pass for the codegen.
6088 if (minst
&& minst
->isRoot() && !(inst
->minst
&& inst
->minst
->isRoot()))
6090 /* Swap the position of 'inst' and 'this' in the instantiation graph.
6091 * Then, the primary instance `inst` will be changed to a root instance.
6094 * non-root -> A!() -> B!()[inst] -> C!()
6096 * root -> D!() -> B!()[this]
6099 * non-root -> A!() -> B!()[this]
6101 * root -> D!() -> B!()[inst] -> C!()
6104 TemplateInstance
*ti
= tinst
;
6105 minst
= inst
->minst
;
6106 tinst
= inst
->tinst
;
6110 if (minst
) // if inst was not speculative
6112 /* Add 'inst' once again to the root module members[], then the
6113 * instance members will get codegen chances.
6115 inst
->appendToModuleMember();
6121 unsigned errorsave
= global
.errors
;
6124 parent
= enclosing
? enclosing
: tempdecl
->parent
;
6125 //printf("parent = '%s'\n", parent->kind());
6127 TemplateInstance
*tempdecl_instance_idx
= tempdecl
->addInstance(this);
6131 // Store the place we added it to in target_symbol_list(_idx) so we can
6132 // remove it later if we encounter an error.
6133 Dsymbols
*target_symbol_list
= appendToModuleMember();
6134 size_t target_symbol_list_idx
= target_symbol_list
? target_symbol_list
->length
- 1 : 0;
6136 // Copy the syntax trees from the TemplateDeclaration
6137 members
= Dsymbol::arraySyntaxCopy(tempdecl
->members
);
6139 // resolve TemplateThisParameter
6140 for (size_t i
= 0; i
< tempdecl
->parameters
->length
; i
++)
6142 if ((*tempdecl
->parameters
)[i
]->isTemplateThisParameter() == NULL
)
6144 Type
*t
= isType((*tiargs
)[i
]);
6146 if (StorageClass stc
= ModToStc(t
->mod
))
6148 //printf("t = %s, stc = x%llx\n", t->toChars(), stc);
6149 Dsymbols
*s
= new Dsymbols();
6150 s
->push(new StorageClassDeclaration(stc
, members
));
6156 // Create our own scope for the template parameters
6157 Scope
*scope
= tempdecl
->_scope
;
6158 if (tempdecl
->semanticRun
== PASSinit
)
6160 error("template instantiation %s forward references template declaration %s", toChars(), tempdecl
->toChars());
6164 argsym
= new ScopeDsymbol();
6165 argsym
->parent
= scope
->parent
;
6166 scope
= scope
->push(argsym
);
6167 scope
->tinst
= this;
6168 scope
->minst
= minst
;
6171 // Declare each template parameter as an alias for the argument type
6172 Scope
*paramscope
= scope
->push();
6173 paramscope
->stc
= 0;
6174 paramscope
->protection
= Prot(Prot::public_
); // Bugzilla 14169: template parameters should be public
6175 declareParameters(paramscope
);
6178 // Add members of template instance to template instance symbol table
6179 // parent = scope->scopesym;
6180 symtab
= new DsymbolTable();
6181 for (size_t i
= 0; i
< members
->length
; i
++)
6183 Dsymbol
*s
= (*members
)[i
];
6184 s
->addMember(scope
, this);
6187 /* See if there is only one member of template instance, and that
6188 * member has the same name as the template instance.
6189 * If so, this template instance becomes an alias for that member.
6191 //printf("members->length = %d\n", members->length);
6192 if (members
->length
)
6195 if (Dsymbol::oneMembers(members
, &s
, tempdecl
->ident
) && s
)
6197 //printf("tempdecl->ident = %s, s = '%s'\n", tempdecl->ident->toChars(), s->kind(), s->toPrettyChars());
6198 //printf("setting aliasdecl\n");
6203 /* If function template declaration
6205 if (fargs
&& aliasdecl
)
6207 FuncDeclaration
*fd
= aliasdecl
->isFuncDeclaration();
6210 /* Transmit fargs to type so that TypeFunction::semantic() can
6211 * resolve any "auto ref" storage classes.
6213 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
6214 if (tf
&& tf
->ty
== Tfunction
)
6219 // Do semantic() analysis on template instance members
6221 sc2
= scope
->push(this);
6222 //printf("enclosing = %d, sc->parent = %s\n", enclosing, sc->parent->toChars());
6227 tryExpandMembers(sc2
);
6229 semanticRun
= PASSsemanticdone
;
6231 /* ConditionalDeclaration may introduce eponymous declaration,
6232 * so we should find it once again after semantic.
6234 if (members
->length
)
6237 if (Dsymbol::oneMembers(members
, &s
, tempdecl
->ident
) && s
)
6239 if (!aliasdecl
|| aliasdecl
!= s
)
6241 //printf("tempdecl->ident = %s, s = '%s'\n", tempdecl->ident->toChars(), s->kind(), s->toPrettyChars());
6242 //printf("setting aliasdecl 2\n");
6248 if (global
.errors
!= errorsave
)
6249 goto Laftersemantic
;
6251 /* If any of the instantiation members didn't get semantic() run
6252 * on them due to forward references, we cannot run semantic2()
6253 * or semantic3() yet.
6256 bool found_deferred_ad
= false;
6257 for (size_t i
= 0; i
< Module::deferred
.length
; i
++)
6259 Dsymbol
*sd
= Module::deferred
[i
];
6260 AggregateDeclaration
*ad
= sd
->isAggregateDeclaration();
6261 if (ad
&& ad
->parent
&& ad
->parent
->isTemplateInstance())
6263 //printf("deferred template aggregate: %s %s\n",
6264 // sd->parent->toChars(), sd->toChars());
6265 found_deferred_ad
= true;
6266 if (ad
->parent
== this)
6268 ad
->deferred
= this;
6273 if (found_deferred_ad
|| Module::deferred
.length
)
6274 goto Laftersemantic
;
6277 /* The problem is when to parse the initializer for a variable.
6278 * Perhaps VarDeclaration::semantic() should do it like it does
6279 * for initializers inside a function.
6281 //if (sc->parent->isFuncDeclaration())
6283 /* BUG 782: this has problems if the classes this depends on
6284 * are forward referenced. Find a way to defer semantic()
6289 if (global
.errors
!= errorsave
)
6290 goto Laftersemantic
;
6292 if ((sc
->func
|| (sc
->flags
& SCOPEfullinst
)) && !tinst
)
6294 /* If a template is instantiated inside function, the whole instantiation
6295 * should be done at that position. But, immediate running semantic3 of
6296 * dependent templates may cause unresolved forward reference (Bugzilla 9050).
6297 * To avoid the issue, don't run semantic3 until semantic and semantic2 done.
6299 TemplateInstances deferred
;
6300 this->deferred
= &deferred
;
6302 //printf("Run semantic3 on %s\n", toChars());
6305 for (size_t i
= 0; i
< deferred
.length
; i
++)
6307 //printf("+ run deferred semantic3 on %s\n", deferred[i]->toChars());
6308 deferred
[i
]->semantic3(NULL
);
6311 this->deferred
= NULL
;
6315 bool doSemantic3
= false;
6316 if (sc
->func
&& aliasdecl
&& aliasdecl
->toAlias()->isFuncDeclaration())
6318 /* Template function instantiation should run semantic3 immediately
6319 * for attribute inference.
6325 /* A lambda function in template arguments might capture the
6326 * instantiated scope context. For the correct context inference,
6327 * all instantiated functions should run the semantic3 immediately.
6328 * See also compilable/test14973.d
6330 for (size_t i
= 0; i
< tdtypes
.length
; i
++)
6332 RootObject
*oarg
= tdtypes
[i
];
6333 Dsymbol
*s
= getDsymbol(oarg
);
6337 if (TemplateDeclaration
*td
= s
->isTemplateDeclaration())
6341 assert(td
->members
&& td
->members
->length
== 1);
6342 s
= (*td
->members
)[0];
6344 if (FuncLiteralDeclaration
*fld
= s
->isFuncLiteralDeclaration())
6346 if (fld
->tok
== TOKreserved
)
6353 //printf("[%s] %s doSemantic3 = %d\n", loc.toChars(), toChars(), doSemantic3);
6358 TemplateInstance
*ti
= tinst
;
6360 while (ti
&& !ti
->deferred
&& ti
->tinst
)
6363 if (++nest
> global
.recursionLimit
)
6365 global
.gag
= 0; // ensure error message gets printed
6366 error("recursive expansion");
6370 if (ti
&& ti
->deferred
)
6372 //printf("deferred semantic3 of %p %s, ti = %s, ti->deferred = %p\n", this, toChars(), ti->toChars());
6373 for (size_t i
= 0; ; i
++)
6375 if (i
== ti
->deferred
->length
)
6377 ti
->deferred
->push(this);
6380 if ((*ti
->deferred
)[i
] == this)
6388 /* Bugzilla 13816: AliasDeclaration tries to resolve forward reference
6389 * twice (See inuse check in AliasDeclaration::toAlias()). It's
6390 * necessary to resolve mutual references of instantiated symbols, but
6391 * it will left a true recursive alias in tuple declaration - an
6392 * AliasDeclaration A refers TupleDeclaration B, and B contains A
6393 * in its elements. To correctly make it an error, we strictly need to
6394 * resolve the alias of eponymous member.
6396 aliasdecl
= aliasdecl
->toAlias2();
6404 // Give additional context info if error occurred during instantiation
6405 if (global
.errors
!= errorsave
)
6409 if (!tempdecl
->literal
)
6410 error(loc
, "error instantiating");
6412 tinst
->printInstantiationTrace();
6417 // Errors are gagged, so remove the template instance from the
6418 // instance/symbol lists we added it to and reset our state to
6419 // finish clean and so we can try to instantiate it again later
6420 // (see bugzilla 4302 and 6602).
6421 tempdecl
->removeInstance(tempdecl_instance_idx
);
6422 if (target_symbol_list
)
6424 // Because we added 'this' in the last position above, we
6425 // should be able to remove it without messing other indices up.
6426 assert((*target_symbol_list
)[target_symbol_list_idx
] == this);
6427 target_symbol_list
->remove(target_symbol_list_idx
);
6428 memberOf
= NULL
; // no longer a member
6430 semanticRun
= PASSinit
;
6437 /* Bugzilla 14541: If the previous gagged instance had failed by
6438 * circular references, currrent "error reproduction instantiation"
6439 * might succeed, because of the difference of instantiated context.
6440 * On such case, the cached error instance needs to be overridden by the
6441 * succeeded instance.
6443 //printf("replaceInstance()\n");
6444 TemplateInstances
*tinstances
= (TemplateInstances
*)dmd_aaGetRvalue((AA
*)tempdecl
->instances
, (void *)hash
);
6446 for (size_t i
= 0; i
< tinstances
->length
; i
++)
6448 TemplateInstance
*ti
= (*tinstances
)[i
];
6451 (*tinstances
)[i
] = this; // override
6459 /**********************************************
6460 * Find template declaration corresponding to template instance.
6463 * false if finding fails.
6465 * This function is reentrant against error occurrence. If returns false,
6466 * any members of this object won't be modified, and repetition call will
6467 * reproduce same error.
6470 bool TemplateInstance::findTempDecl(Scope
*sc
, WithScopeSymbol
**pwithsym
)
6478 //printf("TemplateInstance::findTempDecl() %s\n", toChars());
6483 * figure out which TemplateDeclaration foo refers to.
6485 Identifier
*id
= name
;
6487 Dsymbol
*s
= sc
->search(loc
, id
, &scopesym
);
6490 s
= sc
->search_correct(id
);
6492 error("template '%s' is not defined, did you mean %s?", id
->toChars(), s
->toChars());
6494 error("template '%s' is not defined", id
->toChars());
6499 *pwithsym
= scopesym
->isWithScopeSymbol();
6501 /* We might have found an alias within a template when
6502 * we really want the template.
6504 TemplateInstance
*ti
;
6506 (ti
= s
->parent
->isTemplateInstance()) != NULL
)
6508 if (ti
->tempdecl
&& ti
->tempdecl
->ident
== id
)
6510 /* This is so that one can refer to the enclosing
6511 * template, even if it has the same name as a member
6512 * of the template, if it has a !(arguments)
6514 TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration();
6516 if (td
->overroot
) // if not start of overloaded list of TemplateDeclaration's
6517 td
= td
->overroot
; // then get the start
6522 if (!updateTempDecl(sc
, s
))
6531 static int fp(void *param
, Dsymbol
*s
)
6533 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
6537 TemplateInstance
*ti
= (TemplateInstance
*)param
;
6538 if (td
->semanticRun
== PASSinit
)
6542 // Try to fix forward reference. Ungag errors while doing so.
6543 Ungag ungag
= td
->ungagSpeculative();
6544 td
->semantic(td
->_scope
);
6546 if (td
->semanticRun
== PASSinit
)
6548 ti
->error("%s forward references template declaration %s", ti
->toChars(), td
->toChars());
6555 // Look for forward references
6556 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
6557 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
6558 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
6560 if (overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, (void *)this, &ParamFwdTi::fp
))
6566 /**********************************************
6567 * Confirm s is a valid template, then store it.
6570 * s candidate symbol of template. It may be:
6571 * TemplateDeclaration
6572 * FuncDeclaration with findTemplateDeclRoot() != NULL
6573 * OverloadSet which contains candidates
6575 * true if updating succeeds.
6578 bool TemplateInstance::updateTempDecl(Scope
*sc
, Dsymbol
*s
)
6582 Identifier
*id
= name
;
6585 /* If an OverloadSet, look for a unique member that is a template declaration
6587 OverloadSet
*os
= s
->isOverloadSet();
6591 for (size_t i
= 0; i
< os
->a
.length
; i
++)
6593 Dsymbol
*s2
= os
->a
[i
];
6594 if (FuncDeclaration
*f
= s2
->isFuncDeclaration())
6595 s2
= f
->findTemplateDeclRoot();
6597 s2
= s2
->isTemplateDeclaration();
6610 error("template '%s' is not defined", id
->toChars());
6615 OverDeclaration
*od
= s
->isOverDeclaration();
6618 tempdecl
= od
; // TODO: more strict check
6622 /* It should be a TemplateDeclaration, not some other symbol
6624 if (FuncDeclaration
*f
= s
->isFuncDeclaration())
6625 tempdecl
= f
->findTemplateDeclRoot();
6627 tempdecl
= s
->isTemplateDeclaration();
6630 if (!s
->parent
&& global
.errors
)
6632 if (!s
->parent
&& s
->getType())
6634 Dsymbol
*s2
= s
->getType()->toDsymbol(sc
);
6637 error("%s is not a template declaration, it is a %s", id
->toChars(), s
->kind());
6642 //assert(s->parent);
6643 TemplateInstance
*ti
= s
->parent
? s
->parent
->isTemplateInstance() : NULL
;
6645 (ti
->name
== s
->ident
||
6646 ti
->toAlias()->ident
== s
->ident
)
6650 /* This is so that one can refer to the enclosing
6651 * template, even if it has the same name as a member
6652 * of the template, if it has a !(arguments)
6654 TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration();
6656 if (td
->overroot
) // if not start of overloaded list of TemplateDeclaration's
6657 td
= td
->overroot
; // then get the start
6662 error("%s is not a template declaration, it is a %s", id
->toChars(), s
->kind());
6667 return (tempdecl
!= NULL
);
6670 /**********************************
6671 * Run semantic on the elements of tiargs.
6675 * false if one or more arguments have errors.
6677 * This function is reentrant against error occurrence. If returns false,
6678 * all elements of tiargs won't be modified.
6681 bool TemplateInstance::semanticTiargs(Scope
*sc
)
6683 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars());
6684 if (semantictiargsdone
)
6686 if (semanticTiargs(loc
, sc
, tiargs
, 0))
6688 // cache the result iff semantic analysis succeeded entirely
6689 semantictiargsdone
= 1;
6695 /**********************************
6696 * Run semantic of tiargs as arguments of template.
6700 * tiargs array of template arguments
6701 * flags 1: replace const variables with their initializers
6702 * 2: don't devolve Parameter to Type
6704 * false if one or more arguments have errors.
6707 bool TemplateInstance::semanticTiargs(Loc loc
, Scope
*sc
, Objects
*tiargs
, int flags
)
6709 // Run semantic on each argument, place results in tiargs[]
6710 //printf("+TemplateInstance::semanticTiargs()\n");
6714 for (size_t j
= 0; j
< tiargs
->length
; j
++)
6716 RootObject
*o
= (*tiargs
)[j
];
6717 Type
*ta
= isType(o
);
6718 Expression
*ea
= isExpression(o
);
6719 Dsymbol
*sa
= isDsymbol(o
);
6721 //printf("1: (*tiargs)[%d] = %p, s=%p, v=%p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
6724 //printf("type %s\n", ta->toChars());
6725 // It might really be an Expression or an Alias
6726 ta
->resolve(loc
, sc
, &ea
, &ta
, &sa
);
6731 assert(global
.errors
);
6736 if (ta
->ty
== Ttuple
)
6739 TypeTuple
*tt
= (TypeTuple
*)ta
;
6740 size_t dim
= tt
->arguments
->length
;
6744 tiargs
->reserve(dim
);
6745 for (size_t i
= 0; i
< dim
; i
++)
6747 Parameter
*arg
= (*tt
->arguments
)[i
];
6748 if (flags
& 2 && arg
->ident
)
6749 tiargs
->insert(j
+ i
, arg
);
6751 tiargs
->insert(j
+ i
, arg
->type
);
6757 if (ta
->ty
== Terror
)
6762 (*tiargs
)[j
] = ta
->merge2();
6767 //printf("+[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
6768 if (flags
& 1) // only used by __traits
6770 ea
= ::semantic(ea
, sc
);
6772 // must not interpret the args, excepting template parameters
6773 if (ea
->op
!= TOKvar
||
6774 (((VarExp
*)ea
)->var
->storage_class
& STCtemplateparameter
))
6776 ea
= ea
->optimize(WANTvalue
);
6781 sc
= sc
->startCTFE();
6782 ea
= ::semantic(ea
, sc
);
6785 if (ea
->op
== TOKvar
)
6787 /* This test is to skip substituting a const var with
6788 * its initializer. The problem is the initializer won't
6789 * match with an 'alias' parameter. Instead, do the
6790 * const substitution in TemplateValueParameter::matchArg().
6793 else if (definitelyValueParameter(ea
))
6795 if (ea
->checkValue()) // check void expression
6796 ea
= new ErrorExp();
6797 unsigned int olderrs
= global
.errors
;
6798 ea
= ea
->ctfeInterpret();
6799 if (global
.errors
!= olderrs
)
6800 ea
= new ErrorExp();
6803 //printf("-[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
6804 if (ea
->op
== TOKtuple
)
6807 TupleExp
*te
= (TupleExp
*)ea
;
6808 size_t dim
= te
->exps
->length
;
6812 tiargs
->reserve(dim
);
6813 for (size_t i
= 0; i
< dim
; i
++)
6814 tiargs
->insert(j
+ i
, (*te
->exps
)[i
]);
6819 if (ea
->op
== TOKerror
)
6826 if (ea
->op
== TOKtype
)
6831 if (ea
->op
== TOKscope
)
6833 sa
= ((ScopeExp
*)ea
)->sds
;
6836 if (ea
->op
== TOKfunction
)
6838 FuncExp
*fe
= (FuncExp
*)ea
;
6839 /* A function literal, that is passed to template and
6840 * already semanticed as function pointer, never requires
6841 * outer frame. So convert it to global function is valid.
6843 if (fe
->fd
->tok
== TOKreserved
&& fe
->type
->ty
== Tpointer
)
6845 // change to non-nested
6846 fe
->fd
->tok
= TOKfunction
;
6847 fe
->fd
->vthis
= NULL
;
6851 /* If template argument is a template lambda,
6852 * get template declaration itself. */
6857 if (ea
->op
== TOKdotvar
)
6859 // translate expression to dsymbol.
6860 sa
= ((DotVarExp
*)ea
)->var
;
6863 if (ea
->op
== TOKtemplate
)
6865 sa
= ((TemplateExp
*)ea
)->td
;
6868 if (ea
->op
== TOKdottd
)
6870 // translate expression to dsymbol.
6871 sa
= ((DotTemplateExp
*)ea
)->td
;
6878 //printf("dsym %s %s\n", sa->kind(), sa->toChars());
6885 TupleDeclaration
*d
= sa
->toAlias()->isTupleDeclaration();
6890 tiargs
->insert(j
, d
->objects
);
6894 if (FuncAliasDeclaration
*fa
= sa
->isFuncAliasDeclaration())
6896 FuncDeclaration
*f
= fa
->toAliasFunc();
6897 if (!fa
->hasOverloads
&& f
->isUnique())
6899 // Strip FuncAlias only when the aliased function
6900 // does not have any overloads.
6906 TemplateDeclaration
*td
= sa
->isTemplateDeclaration();
6907 if (td
&& td
->semanticRun
== PASSinit
&& td
->literal
)
6911 FuncDeclaration
*fd
= sa
->isFuncDeclaration();
6913 fd
->functionSemantic();
6915 else if (isParameter(o
))
6922 //printf("1: (*tiargs)[%d] = %p\n", j, (*tiargs)[j]);
6927 bool TemplateInstance::findBestMatch(Scope
*sc
, Expressions
*fargs
)
6931 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
6933 assert(tempdecl
->_scope
);
6935 tdtypes
.setDim(tempdecl
->parameters
->length
);
6936 if (!tempdecl
->matchWithInstance(sc
, this, &tdtypes
, fargs
, 2))
6938 error("incompatible arguments for template instantiation");
6941 // TODO: Normalizing tiargs for bugzilla 7469 is necessary?
6945 unsigned errs
= global
.errors
;
6951 TemplateInstance
*ti
;
6954 TemplateDeclaration
*td_best
;
6955 TemplateDeclaration
*td_ambig
;
6958 static int fp(void *param
, Dsymbol
*s
)
6960 return ((ParamBest
*)param
)->fp(s
);
6964 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
6968 if (td
== td_best
) // skip duplicates
6971 //printf("td = %s\n", td->toPrettyChars());
6973 // If more arguments than parameters,
6974 // then this is no match.
6975 if (td
->parameters
->length
< ti
->tiargs
->length
)
6977 if (!td
->isVariadic())
6981 dedtypes
.setDim(td
->parameters
->length
);
6983 assert(td
->semanticRun
!= PASSinit
);
6984 MATCH m
= td
->matchWithInstance(sc
, ti
, &dedtypes
, ti
->fargs
, 0);
6985 //printf("matchWithInstance = %d\n", m);
6986 if (m
<= MATCHnomatch
) // no match at all
6989 if (m
< m_best
) goto Ltd_best
;
6990 if (m
> m_best
) goto Ltd
;
6993 // Disambiguate by picking the most specialized TemplateDeclaration
6994 MATCH c1
= td
->leastAsSpecialized(sc
, td_best
, ti
->fargs
);
6995 MATCH c2
= td_best
->leastAsSpecialized(sc
, td
, ti
->fargs
);
6996 //printf("c1 = %d, c2 = %d\n", c1, c2);
6997 if (c1
> c2
) goto Ltd
;
6998 if (c1
< c2
) goto Ltd_best
;
7004 Ltd_best
: // td_best is the best match so far
7008 Ltd
: // td is the new best match
7012 ti
->tdtypes
.setDim(dedtypes
.length
);
7013 memcpy(ti
->tdtypes
.tdata(), dedtypes
.tdata(), ti
->tdtypes
.length
* sizeof(void *));
7022 /* Since there can be multiple TemplateDeclaration's with the same
7023 * name, look for the best match.
7025 TemplateDeclaration
*td_last
= NULL
;
7027 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
7028 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
7029 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
7034 p
.m_best
= MATCHnomatch
;
7035 overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, &p
, &ParamBest::fp
);
7039 ::error(loc
, "%s %s.%s matches more than one template declaration:\n%s: %s\nand\n%s: %s",
7040 p
.td_best
->kind(), p
.td_best
->parent
->toPrettyChars(), p
.td_best
->ident
->toChars(),
7041 p
.td_best
->loc
.toChars() , p
.td_best
->toChars(),
7042 p
.td_ambig
->loc
.toChars(), p
.td_ambig
->toChars());
7048 td_last
= p
.td_best
;
7049 else if (td_last
!= p
.td_best
)
7051 ScopeDsymbol::multiplyDefined(loc
, td_last
, p
.td_best
);
7059 /* Bugzilla 7469: Normalize tiargs by using corresponding deduced
7060 * template value parameters and tuples for the correct mangling.
7062 * By doing this before hasNestedArgs, CTFEable local variable will be
7063 * accepted as a value parameter. For example:
7066 * struct S(int n) {} // non-global template
7067 * const int num = 1; // CTFEable local variable
7068 * S!num s; // S!1 is instantiated, not S!num
7071 size_t dim
= td_last
->parameters
->length
- (td_last
->isVariadic() ? 1 : 0);
7072 for (size_t i
= 0; i
< dim
; i
++)
7074 if (tiargs
->length
<= i
)
7075 tiargs
->push(tdtypes
[i
]);
7076 assert(i
< tiargs
->length
);
7078 TemplateValueParameter
*tvp
= (*td_last
->parameters
)[i
]->isTemplateValueParameter();
7082 // tdtypes[i] is already normalized to the required type in matchArg
7084 (*tiargs
)[i
] = tdtypes
[i
];
7086 if (td_last
->isVariadic() && tiargs
->length
== dim
&& tdtypes
[dim
])
7088 Tuple
*va
= isTuple(tdtypes
[dim
]);
7090 for (size_t i
= 0; i
< va
->objects
.length
; i
++)
7091 tiargs
->push(va
->objects
[i
]);
7094 else if (errors
&& inst
)
7096 // instantiation was failed with error reporting
7097 assert(global
.errors
);
7102 TemplateDeclaration
*tdecl
= tempdecl
->isTemplateDeclaration();
7104 if (errs
!= global
.errors
)
7105 errorSupplemental(loc
, "while looking for match for %s", toChars());
7106 else if (tdecl
&& !tdecl
->overnext
)
7108 // Only one template, so we can give better error message
7109 error("does not match template declaration %s", tdecl
->toChars());
7112 ::error(loc
, "%s %s.%s does not match any template declaration",
7113 tempdecl
->kind(), tempdecl
->parent
->toPrettyChars(), tempdecl
->ident
->toChars());
7117 /* The best match is td_last
7121 return (errs
== global
.errors
);
7124 /*****************************************************
7125 * Determine if template instance is really a template function,
7126 * and that template function needs to infer types from the function
7129 * Like findBestMatch, iterate possible template candidates,
7130 * but just looks only the necessity of type inference.
7133 bool TemplateInstance::needsTypeInference(Scope
*sc
, int flag
)
7135 //printf("TemplateInstance::needsTypeInference() %s\n", toChars());
7136 if (semanticRun
!= PASSinit
)
7139 struct ParamNeedsInf
7143 TemplateInstance
*ti
;
7149 static int fp(void *param
, Dsymbol
*s
)
7151 return ((ParamNeedsInf
*)param
)->fp(s
);
7155 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
7161 /* If any of the overloaded template declarations need inference,
7164 FuncDeclaration
*fd
;
7167 if (TemplateDeclaration
*td2
= td
->onemember
->isTemplateDeclaration())
7169 if (!td2
->onemember
|| !td2
->onemember
->isFuncDeclaration())
7171 if (ti
->tiargs
->length
>= td
->parameters
->length
- (td
->isVariadic() ? 1 : 0))
7175 if ((fd
= td
->onemember
->isFuncDeclaration()) == NULL
||
7176 fd
->type
->ty
!= Tfunction
)
7181 for (size_t i
= 0; i
< td
->parameters
->length
; i
++)
7183 if ((*td
->parameters
)[i
]->isTemplateThisParameter())
7187 /* Determine if the instance arguments, tiargs, are all that is necessary
7188 * to instantiate the template.
7190 //printf("tp = %p, td->parameters->length = %d, tiargs->length = %d\n", tp, td->parameters->length, ti->tiargs->length);
7191 TypeFunction
*tf
= (TypeFunction
*)fd
->type
;
7192 if (size_t dim
= tf
->parameterList
.length())
7194 TemplateParameter
*tp
= td
->isVariadic();
7195 if (tp
&& td
->parameters
->length
> 1)
7198 if (!tp
&& ti
->tiargs
->length
< td
->parameters
->length
)
7200 // Can remain tiargs be filled by default arguments?
7201 for (size_t i
= ti
->tiargs
->length
; i
< td
->parameters
->length
; i
++)
7203 if (!(*td
->parameters
)[i
]->hasDefaultArg())
7208 for (size_t i
= 0; i
< dim
; i
++)
7210 // 'auto ref' needs inference.
7211 if (tf
->parameterList
[i
]->storageClass
& STCauto
)
7218 /* Calculate the need for overload resolution.
7219 * When only one template can match with tiargs, inference is not necessary.
7221 dedtypes
.setDim(td
->parameters
->length
);
7223 if (td
->semanticRun
== PASSinit
)
7227 // Try to fix forward reference. Ungag errors while doing so.
7228 Ungag ungag
= td
->ungagSpeculative();
7229 td
->semantic(td
->_scope
);
7231 if (td
->semanticRun
== PASSinit
)
7233 ti
->error("%s forward references template declaration %s", ti
->toChars(), td
->toChars());
7237 assert(td
->semanticRun
!= PASSinit
);
7238 MATCH m
= td
->matchWithInstance(sc
, ti
, &dedtypes
, NULL
, 0);
7239 if (m
<= MATCHnomatch
)
7243 /* If there is more than one function template which matches, we may
7244 * need type inference (see Bugzilla 4430)
7260 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
7261 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
7262 unsigned olderrs
= global
.errors
;
7263 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
7265 if (overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, &p
, &ParamNeedsInf::fp
))
7268 if (olderrs
!= global
.errors
)
7272 errorSupplemental(loc
, "while looking for match for %s", toChars());
7273 semanticRun
= PASSsemanticdone
;
7278 //printf("false\n");
7283 /*****************************************
7284 * Determines if a TemplateInstance will need a nested
7285 * generation of the TemplateDeclaration.
7286 * Sets enclosing property if so, and returns != 0;
7289 bool TemplateInstance::hasNestedArgs(Objects
*args
, bool isstatic
)
7292 //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());
7294 /* A nested instance happens when an argument references a local
7295 * symbol that is on the stack.
7297 for (size_t i
= 0; i
< args
->length
; i
++)
7299 RootObject
*o
= (*args
)[i
];
7300 Expression
*ea
= isExpression(o
);
7301 Dsymbol
*sa
= isDsymbol(o
);
7302 Tuple
*va
= isTuple(o
);
7305 if (ea
->op
== TOKvar
)
7307 sa
= ((VarExp
*)ea
)->var
;
7310 if (ea
->op
== TOKthis
)
7312 sa
= ((ThisExp
*)ea
)->var
;
7315 if (ea
->op
== TOKfunction
)
7317 if (((FuncExp
*)ea
)->td
)
7318 sa
= ((FuncExp
*)ea
)->td
;
7320 sa
= ((FuncExp
*)ea
)->fd
;
7323 // Emulate Expression::toMangleBuffer call that had exist in TemplateInstance::genIdent.
7324 if (ea
->op
!= TOKint64
&&
7325 ea
->op
!= TOKfloat64
&&
7326 ea
->op
!= TOKcomplex80
&&
7327 ea
->op
!= TOKnull
&&
7328 ea
->op
!= TOKstring
&&
7329 ea
->op
!= TOKarrayliteral
&&
7330 ea
->op
!= TOKassocarrayliteral
&&
7331 ea
->op
!= TOKstructliteral
)
7333 ea
->error("expression %s is not a valid template value argument", ea
->toChars());
7341 TemplateDeclaration
*td
= sa
->isTemplateDeclaration();
7344 TemplateInstance
*ti
= sa
->toParent()->isTemplateInstance();
7345 if (ti
&& ti
->enclosing
)
7348 TemplateInstance
*ti
= sa
->isTemplateInstance();
7349 Declaration
*d
= sa
->isDeclaration();
7350 if ((td
&& td
->literal
) ||
7351 (ti
&& ti
->enclosing
) ||
7352 (d
&& !d
->isDataseg() &&
7353 !(d
->storage_class
& STCmanifest
) &&
7354 (!d
->isFuncDeclaration() || d
->isFuncDeclaration()->isNested()) &&
7358 // if module level template
7361 Dsymbol
*dparent
= sa
->toParent2();
7363 enclosing
= dparent
;
7364 else if (enclosing
!= dparent
)
7366 /* Select the more deeply nested of the two.
7367 * Error if one is not nested inside the other.
7369 for (Dsymbol
*p
= enclosing
; p
; p
= p
->parent
)
7372 goto L1
; // enclosing is most nested
7374 for (Dsymbol
*p
= dparent
; p
; p
= p
->parent
)
7378 enclosing
= dparent
;
7379 goto L1
; // dparent is most nested
7382 error("%s is nested in both %s and %s",
7383 toChars(), enclosing
->toChars(), dparent
->toChars());
7387 //printf("\tnested inside %s\n", enclosing->toChars());
7392 error("cannot use local '%s' as parameter to non-global template %s", sa
->toChars(), tempdecl
->toChars());
7399 nested
|= (int)hasNestedArgs(&va
->objects
, isstatic
);
7402 //printf("-TemplateInstance::hasNestedArgs('%s') = %d\n", tempdecl->ident->toChars(), nested);
7406 /*****************************************
7407 * Append 'this' to the specific module members[]
7409 Dsymbols
*TemplateInstance::appendToModuleMember()
7411 Module
*mi
= minst
; // instantiated -> inserted module
7413 if (global
.params
.useUnitTests
||
7414 global
.params
.debuglevel
)
7416 // Turn all non-root instances to speculative
7417 if (mi
&& !mi
->isRoot())
7421 //printf("%s->appendToModuleMember() enclosing = %s mi = %s\n",
7423 // enclosing ? enclosing->toPrettyChars() : NULL,
7424 // mi ? mi->toPrettyChars() : NULL);
7425 if (!mi
|| mi
->isRoot())
7427 /* If the instantiated module is speculative or root, insert to the
7428 * member of a root module. Then:
7429 * - semantic3 pass will get called on the instance members.
7430 * - codegen pass will get a selection chance to do/skip it.
7435 static Dsymbol
*getStrictEnclosing(TemplateInstance
*ti
)
7440 return ti
->enclosing
;
7441 ti
= ti
->tempdecl
->isInstantiated();
7447 Dsymbol
*enc
= N::getStrictEnclosing(this);
7449 // insert target is made stable by using the module
7450 // where tempdecl is declared.
7451 mi
= (enc
? enc
: tempdecl
)->getModule();
7453 mi
= mi
->importedFrom
;
7454 assert(mi
->isRoot());
7458 /* If the instantiated module is non-root, insert to the member of the
7459 * non-root module. Then:
7460 * - semantic3 pass won't be called on the instance.
7461 * - codegen pass won't reach to the instance.
7464 //printf("\t--> mi = %s\n", mi->toPrettyChars());
7466 if (memberOf
== mi
) // already a member
7471 Dsymbols
*a
= mi
->members
;
7474 if (mi
->semanticRun
>= PASSsemantic2done
&& mi
->isRoot())
7475 Module::addDeferredSemantic2(this);
7476 if (mi
->semanticRun
>= PASSsemantic3done
&& mi
->isRoot())
7477 Module::addDeferredSemantic3(this);
7481 /****************************************
7482 * This instance needs an identifier for name mangling purposes.
7483 * Create one by taking the template declaration name and adding
7484 * the type signature for it.
7487 Identifier
*TemplateInstance::genIdent(Objects
*args
)
7489 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
7492 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
7494 const char *id
= tempdecl
->ident
->toChars();
7497 // Use "__U" for the symbols declared inside template constraint.
7498 buf
.printf("__U%llu%s", (ulonglong
)strlen(id
), id
);
7501 buf
.printf("__T%llu%s", (ulonglong
)strlen(id
), id
);
7502 size_t nparams
= tempdecl
->parameters
->length
- (tempdecl
->isVariadic() ? 1 : 0);
7503 for (size_t i
= 0; i
< args
->length
; i
++)
7505 RootObject
*o
= (*args
)[i
];
7506 Type
*ta
= isType(o
);
7507 Expression
*ea
= isExpression(o
);
7508 Dsymbol
*sa
= isDsymbol(o
);
7509 Tuple
*va
= isTuple(o
);
7510 //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va);
7511 if (i
< nparams
&& (*tempdecl
->parameters
)[i
]->specialization())
7512 buf
.writeByte('H'); // Bugzilla 6574
7517 buf
.writestring(ta
->deco
);
7520 assert(global
.errors
);
7525 // Don't interpret it yet, it might actually be an alias template parameter.
7526 // Only constfold manifest constants, not const/immutable lvalues, see https://issues.dlang.org/show_bug.cgi?id=17339.
7527 const bool keepLvalue
= true;
7528 ea
= ea
->optimize(WANTvalue
, keepLvalue
);
7529 if (ea
->op
== TOKvar
)
7531 sa
= ((VarExp
*)ea
)->var
;
7535 if (ea
->op
== TOKthis
)
7537 sa
= ((ThisExp
*)ea
)->var
;
7541 if (ea
->op
== TOKfunction
)
7543 if (((FuncExp
*)ea
)->td
)
7544 sa
= ((FuncExp
*)ea
)->td
;
7546 sa
= ((FuncExp
*)ea
)->fd
;
7551 if (ea
->op
== TOKtuple
)
7553 ea
->error("tuple is not a valid template value argument");
7556 // Now that we know it is not an alias, we MUST obtain a value
7557 unsigned olderr
= global
.errors
;
7558 ea
= ea
->ctfeInterpret();
7559 if (ea
->op
== TOKerror
|| olderr
!= global
.errors
)
7562 /* Use deco that matches what it would be for a function parameter
7564 buf
.writestring(ea
->type
->deco
);
7565 mangleToBuffer(ea
, &buf
);
7572 Declaration
*d
= sa
->isDeclaration();
7573 if (d
&& (!d
->type
|| !d
->type
->deco
))
7575 error("forward reference of %s %s", d
->kind(), d
->toChars());
7580 mangleToBuffer(sa
, &bufsa
);
7581 const char *s
= bufsa
.extractChars();
7583 /* Bugzilla 3043: if the first character of s is a digit this
7584 * causes ambiguity issues because the digits of the two numbers are adjacent.
7585 * Current demanglers resolve this by trying various places to separate the
7586 * numbers until one gets a successful demangle.
7587 * Unfortunately, fixing this ambiguity will break existing binary
7588 * compatibility and the demanglers, so we'll leave it as is.
7590 buf
.printf("%u%s", (unsigned)strlen(s
), s
);
7594 assert(i
+ 1 == args
->length
); // must be last one
7595 args
= &va
->objects
;
7602 id
= buf
.peekChars();
7603 //printf("\tgenIdent = %s\n", id);
7604 return Identifier::idPool(id
);
7607 /*************************************
7608 * Lazily generate identifier for template instance.
7609 * This is because 75% of the ident's are never needed.
7612 Identifier
*TemplateInstance::getIdent()
7614 if (!ident
&& inst
&& !errors
)
7615 ident
= genIdent(tiargs
); // need an identifier for name mangling purposes.
7619 /****************************************************
7620 * Declare parameters of template instance, initialize them with the
7621 * template instance arguments.
7624 void TemplateInstance::declareParameters(Scope
*sc
)
7626 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
7629 //printf("TemplateInstance::declareParameters()\n");
7630 for (size_t i
= 0; i
< tdtypes
.length
; i
++)
7632 TemplateParameter
*tp
= (*tempdecl
->parameters
)[i
];
7633 //RootObject *o = (*tiargs)[i];
7634 RootObject
*o
= tdtypes
[i
]; // initializer for tp
7636 //printf("\ttdtypes[%d] = %p\n", i, o);
7637 tempdecl
->declareParameter(sc
, tp
, o
);
7641 void TemplateInstance::semantic2(Scope
*sc
)
7643 if (semanticRun
>= PASSsemantic2
)
7645 semanticRun
= PASSsemantic2
;
7646 if (!errors
&& members
)
7648 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
7651 sc
= tempdecl
->_scope
;
7653 sc
= sc
->push(argsym
);
7654 sc
= sc
->push(this);
7658 int needGagging
= (gagged
&& !global
.gag
);
7659 unsigned int olderrors
= global
.errors
;
7660 int oldGaggedErrors
= -1; // dead-store to prevent spurious warning
7662 oldGaggedErrors
= global
.startGagging();
7664 for (size_t i
= 0; i
< members
->length
; i
++)
7666 Dsymbol
*s
= (*members
)[i
];
7668 if (gagged
&& global
.errors
!= olderrors
)
7672 if (global
.errors
!= olderrors
)
7676 if (!tempdecl
->literal
)
7677 error(loc
, "error instantiating");
7679 tinst
->printInstantiationTrace();
7684 global
.endGagging(oldGaggedErrors
);
7691 void TemplateInstance::semantic3(Scope
*sc
)
7693 //if (toChars()[0] == 'D') *(char*)0=0;
7694 if (semanticRun
>= PASSsemantic3
)
7696 semanticRun
= PASSsemantic3
;
7697 if (!errors
&& members
)
7699 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
7702 sc
= tempdecl
->_scope
;
7703 sc
= sc
->push(argsym
);
7704 sc
= sc
->push(this);
7708 int needGagging
= (gagged
&& !global
.gag
);
7709 unsigned int olderrors
= global
.errors
;
7710 int oldGaggedErrors
= -1; // dead-store to prevent spurious warning
7711 /* If this is a gagged instantiation, gag errors.
7712 * Future optimisation: If the results are actually needed, errors
7713 * would already be gagged, so we don't really need to run semantic
7717 oldGaggedErrors
= global
.startGagging();
7719 for (size_t i
= 0; i
< members
->length
; i
++)
7721 Dsymbol
*s
= (*members
)[i
];
7723 if (gagged
&& global
.errors
!= olderrors
)
7727 if (global
.errors
!= olderrors
)
7731 if (!tempdecl
->literal
)
7732 error(loc
, "error instantiating");
7734 tinst
->printInstantiationTrace();
7739 global
.endGagging(oldGaggedErrors
);
7746 /**************************************
7747 * Given an error instantiating the TemplateInstance,
7748 * give the nested TemplateInstance instantiations that got
7749 * us here. Those are a list threaded into the nested scopes.
7751 void TemplateInstance::printInstantiationTrace()
7756 const unsigned max_shown
= 6;
7757 const char format
[] = "instantiated from here: %s";
7759 // determine instantiation depth and number of recursive instantiations
7760 unsigned n_instantiations
= 1;
7761 unsigned n_totalrecursions
= 0;
7762 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
7765 // If two instantiations use the same declaration, they are recursive.
7766 // (this works even if they are instantiated from different places in the
7768 // In principle, we could also check for multiple-template recursion, but it's
7769 // probably not worthwhile.
7770 if (cur
->tinst
&& cur
->tempdecl
&& cur
->tinst
->tempdecl
7771 && cur
->tempdecl
->loc
.equals(cur
->tinst
->tempdecl
->loc
))
7772 ++n_totalrecursions
;
7775 // show full trace only if it's short or verbose is on
7776 if (n_instantiations
<= max_shown
|| global
.params
.verbose
)
7778 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
7781 errorSupplemental(cur
->loc
, format
, cur
->toChars());
7784 else if (n_instantiations
- n_totalrecursions
<= max_shown
)
7786 // By collapsing recursive instantiations into a single line,
7787 // we can stay under the limit.
7788 int recursionDepth
=0;
7789 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
7792 if (cur
->tinst
&& cur
->tempdecl
&& cur
->tinst
->tempdecl
7793 && cur
->tempdecl
->loc
.equals(cur
->tinst
->tempdecl
->loc
))
7800 errorSupplemental(cur
->loc
, "%d recursive instantiations from here: %s", recursionDepth
+2, cur
->toChars());
7802 errorSupplemental(cur
->loc
, format
, cur
->toChars());
7809 // Even after collapsing the recursions, the depth is too deep.
7810 // Just display the first few and last few instantiations.
7812 for (TemplateInstance
*cur
= this; cur
; cur
= cur
->tinst
)
7816 if (i
== max_shown
/ 2)
7817 errorSupplemental(cur
->loc
, "... (%d instantiations, -v to show) ...", n_instantiations
- max_shown
);
7819 if (i
< max_shown
/ 2 ||
7820 i
>= n_instantiations
- max_shown
+ max_shown
/ 2)
7821 errorSupplemental(cur
->loc
, format
, cur
->toChars());
7827 Dsymbol
*TemplateInstance::toAlias()
7831 // Maybe we can resolve it
7838 error("cannot resolve forward reference");
7845 return inst
->toAlias();
7849 return aliasdecl
->toAlias();
7855 const char *TemplateInstance::kind() const
7857 return "template instance";
7860 bool TemplateInstance::oneMember(Dsymbol
**ps
, Identifier
*)
7866 const char *TemplateInstance::toChars()
7869 toCBufferInstance(this, &buf
);
7870 return buf
.extractChars();
7873 const char *TemplateInstance::toPrettyCharsHelper()
7876 toCBufferInstance(this, &buf
, true);
7877 return buf
.extractChars();
7880 /*************************************
7881 * Compare proposed template instantiation with existing template instantiation.
7882 * Note that this is not commutative because of the auto ref check.
7884 * this = proposed template instantiation
7885 * o = existing template instantiation
7887 * 0 for match, 1 for no match
7889 int TemplateInstance::compare(RootObject
*o
)
7891 TemplateInstance
*ti
= (TemplateInstance
*)o
;
7893 //printf("this = %p, ti = %p\n", this, ti);
7894 assert(tdtypes
.length
== ti
->tdtypes
.length
);
7896 // Nesting must match
7897 if (enclosing
!= ti
->enclosing
)
7899 //printf("test2 enclosing %s ti->enclosing %s\n", enclosing ? enclosing->toChars() : "", ti->enclosing ? ti->enclosing->toChars() : "");
7902 //printf("parent = %s, ti->parent = %s\n", parent->toPrettyChars(), ti->parent->toPrettyChars());
7904 if (!arrayObjectMatch(&tdtypes
, &ti
->tdtypes
))
7907 /* Template functions may have different instantiations based on
7908 * "auto ref" parameters.
7910 if (FuncDeclaration
*fd
= ti
->toAlias()->isFuncDeclaration())
7914 ParameterList fparameters
= fd
->getParameterList();
7915 size_t nfparams
= fparameters
.length(); // Num function parameters
7916 for (size_t j
= 0; j
< nfparams
; j
++)
7918 Parameter
*fparam
= fparameters
[j
];
7919 if (fparam
->storageClass
& STCautoref
) // if "auto ref"
7923 if (fargs
->length
<= j
)
7925 Expression
*farg
= (*fargs
)[j
];
7926 if (farg
->isLvalue())
7928 if (!(fparam
->storageClass
& STCref
))
7929 goto Lnotequals
; // auto ref's don't match
7933 if (fparam
->storageClass
& STCref
)
7934 goto Lnotequals
; // auto ref's don't match
7946 hash_t
TemplateInstance::toHash()
7950 hash
= (size_t)(void *)enclosing
;
7951 hash
+= arrayObjectHash(&tdtypes
);
7957 /**************************************
7958 * IsExpression can evaluate the specified type speculatively, and even if
7959 * it instantiates any symbols, they are normally unnecessary for the
7961 * However, if those symbols leak to the actual code, compiler should remark
7962 * them as non-speculative to generate their code and link to the final executable.
7964 void unSpeculative(Scope
*sc
, RootObject
*o
)
7969 if (Tuple
*tup
= isTuple(o
))
7971 for (size_t i
= 0; i
< tup
->objects
.length
; i
++)
7973 unSpeculative(sc
, tup
->objects
[i
]);
7978 Dsymbol
*s
= getDsymbol(o
);
7982 if (Declaration
*d
= s
->isDeclaration())
7984 if (VarDeclaration
*vd
= d
->isVarDeclaration())
7986 else if (AliasDeclaration
*ad
= d
->isAliasDeclaration())
8000 if (TemplateInstance
*ti
= s
->isTemplateInstance())
8002 // If the instance is already non-speculative,
8003 // or it is leaked to the speculative scope.
8004 if (ti
->minst
!= NULL
|| sc
->minst
== NULL
)
8007 // Remark as non-speculative instance.
8008 ti
->minst
= sc
->minst
;
8010 ti
->tinst
= sc
->tinst
;
8012 unSpeculative(sc
, ti
->tempdecl
);
8015 if (TemplateInstance
*ti
= s
->isInstantiated())
8016 unSpeculative(sc
, ti
);
8019 /***********************************************
8020 * Returns true if this is not instantiated in non-root module, and
8021 * is a part of non-speculative instantiatiation.
8023 * Note: minst does not stabilize until semantic analysis is completed,
8024 * so don't call this function during semantic analysis to return precise result.
8026 bool TemplateInstance::needsCodegen()
8028 // Now -allInst is just for the backward compatibility.
8029 if (global
.params
.allInst
)
8031 //printf("%s minst = %s, enclosing (%s)->isNonRoot = %d\n",
8032 // toPrettyChars(), minst ? minst->toChars() : NULL,
8033 // enclosing ? enclosing->toPrettyChars() : NULL, enclosing && enclosing->inNonRoot());
8036 // Bugzilla 14588: If the captured context is not a function
8037 // (e.g. class), the instance layout determination is guaranteed,
8038 // because the semantic/semantic2 pass will be executed
8039 // even for non-root instances.
8040 if (!enclosing
->isFuncDeclaration())
8043 // Bugzilla 14834: If the captured context is a function,
8044 // this excessive instantiation may cause ODR violation, because
8045 // -allInst and others doesn't guarantee the semantic3 execution
8046 // for that function.
8048 // If the enclosing is also an instantiated function,
8049 // we have to rely on the ancestor's needsCodegen() result.
8050 if (TemplateInstance
*ti
= enclosing
->isInstantiated())
8051 return ti
->needsCodegen();
8053 // Bugzilla 13415: If and only if the enclosing scope needs codegen,
8054 // this nested templates would also need code generation.
8055 return !enclosing
->inNonRoot();
8062 // If this is a speculative instantiation,
8063 // 1. do codegen if ancestors really needs codegen.
8064 // 2. become non-speculative if siblings are not speculative
8066 TemplateInstance
*tnext
= this->tnext
;
8067 TemplateInstance
*tinst
= this->tinst
;
8068 // At first, disconnect chain first to prevent infinite recursion.
8072 // Determine necessity of tinst before tnext.
8073 if (tinst
&& tinst
->needsCodegen())
8075 minst
= tinst
->minst
; // cache result
8077 assert(minst
->isRoot() || minst
->rootImports());
8080 if (tnext
&& (tnext
->needsCodegen() || tnext
->minst
))
8082 minst
= tnext
->minst
; // cache result
8084 return minst
->isRoot() || minst
->rootImports();
8087 // Elide codegen because this is really speculative.
8091 /* Even when this is reached to the codegen pass,
8092 * a non-root nested template should not generate code,
8093 * due to avoid ODR violation.
8095 if (enclosing
&& enclosing
->inNonRoot())
8099 bool r
= tinst
->needsCodegen();
8100 minst
= tinst
->minst
; // cache result
8105 bool r
= tnext
->needsCodegen();
8106 minst
= tnext
->minst
; // cache result
8112 /* The issue is that if the importee is compiled with a different -debug
8113 * setting than the importer, the importer may believe it exists
8114 * in the compiled importee when it does not, when the instantiation
8115 * is behind a conditional debug declaration.
8117 // workaround for Bugzilla 11239
8118 if (global
.params
.useUnitTests
||
8119 global
.params
.debuglevel
)
8121 // Prefer instantiations from root modules, to maximize link-ability.
8122 if (minst
->isRoot())
8125 TemplateInstance
*tnext
= this->tnext
;
8126 TemplateInstance
*tinst
= this->tinst
;
8130 if (tinst
&& tinst
->needsCodegen())
8132 minst
= tinst
->minst
; // cache result
8134 assert(minst
->isRoot() || minst
->rootImports());
8137 if (tnext
&& tnext
->needsCodegen())
8139 minst
= tnext
->minst
; // cache result
8141 assert(minst
->isRoot() || minst
->rootImports());
8145 // Bugzilla 2500 case
8146 if (minst
->rootImports())
8149 // Elide codegen because this is not included in root instances.
8154 // Prefer instantiations from non-root module, to minimize object code size.
8156 /* If a TemplateInstance is ever instantiated by non-root modules,
8157 * we do not have to generate code for it,
8158 * because it will be generated when the non-root module is compiled.
8160 * But, if the non-root 'minst' imports any root modules, it might still need codegen.
8162 * The problem is if A imports B, and B imports A, and both A
8163 * and B instantiate the same template, does the compilation of A
8164 * or the compilation of B do the actual instantiation?
8166 * See Bugzilla 2500.
8168 if (!minst
->isRoot() && !minst
->rootImports())
8171 TemplateInstance
*tnext
= this->tnext
;
8174 if (tnext
&& !tnext
->needsCodegen() && tnext
->minst
)
8176 minst
= tnext
->minst
; // cache result
8177 assert(!minst
->isRoot());
8181 // Do codegen because this is not included in non-root instances.
8186 /* ======================== TemplateMixin ================================ */
8188 TemplateMixin::TemplateMixin(Loc loc
, Identifier
*ident
, TypeQualified
*tqual
, Objects
*tiargs
)
8189 : TemplateInstance(loc
, tqual
->idents
.length
? (Identifier
*)tqual
->idents
[tqual
->idents
.length
- 1]
8190 : ((TypeIdentifier
*)tqual
)->ident
)
8192 //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : "");
8193 this->ident
= ident
;
8194 this->tqual
= tqual
;
8195 this->tiargs
= tiargs
? tiargs
: new Objects();
8198 Dsymbol
*TemplateMixin::syntaxCopy(Dsymbol
*)
8200 TemplateMixin
*tm
= new TemplateMixin(loc
, ident
,
8201 (TypeQualified
*)tqual
->syntaxCopy(), tiargs
);
8202 return TemplateInstance::syntaxCopy(tm
);
8205 bool TemplateMixin::findTempDecl(Scope
*sc
)
8207 // Follow qualifications to find the TemplateDeclaration
8213 tqual
->resolve(loc
, sc
, &e
, &t
, &s
);
8216 error("is not defined");
8220 tempdecl
= s
->isTemplateDeclaration();
8221 OverloadSet
*os
= s
->isOverloadSet();
8223 /* If an OverloadSet, look for a unique member that is a template declaration
8228 for (size_t i
= 0; i
< os
->a
.length
; i
++)
8230 Dsymbol
*s2
= os
->a
[i
]->isTemplateDeclaration();
8244 error("%s isn't a template", s
->toChars());
8250 struct ParamFwdResTm
8252 static int fp(void *param
, Dsymbol
*s
)
8254 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
8258 TemplateMixin
*tm
= (TemplateMixin
*)param
;
8259 if (td
->semanticRun
== PASSinit
)
8262 td
->semantic(td
->_scope
);
8265 tm
->semanticRun
= PASSinit
;
8272 // Look for forward references
8273 OverloadSet
*tovers
= tempdecl
->isOverloadSet();
8274 size_t overs_dim
= tovers
? tovers
->a
.length
: 1;
8275 for (size_t oi
= 0; oi
< overs_dim
; oi
++)
8277 if (overloadApply(tovers
? tovers
->a
[oi
] : tempdecl
, (void *)this, &ParamFwdResTm::fp
))
8283 void TemplateMixin::semantic(Scope
*sc
)
8285 if (semanticRun
!= PASSinit
)
8287 // When a class/struct contains mixin members, and is done over
8288 // because of forward references, never reach here so semanticRun
8289 // has been reset to PASSinit.
8292 semanticRun
= PASSsemantic
;
8298 scx
= _scope
; // save so we don't make redundant copies
8302 /* Run semantic on each argument, place results in tiargs[],
8303 * then find best match template with tiargs
8305 if (!findTempDecl(sc
) ||
8306 !semanticTiargs(sc
) ||
8307 !findBestMatch(sc
, NULL
))
8309 if (semanticRun
== PASSinit
) // forward reference had occured
8311 //printf("forward reference - deferring\n");
8312 _scope
= scx
? scx
: sc
->copy();
8313 _scope
->setNoFree();
8314 _scope
->_module
->addDeferredSemantic(this);
8320 return; // error recovery
8322 TemplateDeclaration
*tempdecl
= this->tempdecl
->isTemplateDeclaration();
8327 /* Assign scope local unique identifier, as same as lambdas.
8329 const char *s
= "__mixin";
8331 DsymbolTable
*symtab
;
8332 if (FuncDeclaration
*func
= sc
->parent
->isFuncDeclaration())
8334 symtab
= func
->localsymtab
;
8337 // Inside template constraint, symtab is not set yet.
8343 symtab
= sc
->parent
->isScopeDsymbol()->symtab
;
8346 int num
= (int)dmd_aaLen(symtab
->tab
) + 1;
8347 ident
= Identifier::generateId(s
, num
);
8348 symtab
->insert(this);
8353 parent
= sc
->parent
;
8355 /* Detect recursive mixin instantiations.
8357 for (Dsymbol
*s
= parent
; s
; s
= s
->parent
)
8359 //printf("\ts = '%s'\n", s->toChars());
8360 TemplateMixin
*tm
= s
->isTemplateMixin();
8361 if (!tm
|| tempdecl
!= tm
->tempdecl
)
8364 /* Different argument list lengths happen with variadic args
8366 if (tiargs
->length
!= tm
->tiargs
->length
)
8369 for (size_t i
= 0; i
< tiargs
->length
; i
++)
8371 RootObject
*o
= (*tiargs
)[i
];
8372 Type
*ta
= isType(o
);
8373 Expression
*ea
= isExpression(o
);
8374 Dsymbol
*sa
= isDsymbol(o
);
8375 RootObject
*tmo
= (*tm
->tiargs
)[i
];
8378 Type
*tmta
= isType(tmo
);
8381 if (!ta
->equals(tmta
))
8386 Expression
*tme
= isExpression(tmo
);
8387 if (!tme
|| !ea
->equals(tme
))
8392 Dsymbol
*tmsa
= isDsymbol(tmo
);
8399 error("recursive mixin instantiation");
8406 // Copy the syntax trees from the TemplateDeclaration
8407 members
= Dsymbol::arraySyntaxCopy(tempdecl
->members
);
8411 symtab
= new DsymbolTable();
8413 for (Scope
*sce
= sc
; 1; sce
= sce
->enclosing
)
8415 ScopeDsymbol
*sds
= (ScopeDsymbol
*)sce
->scopesym
;
8418 sds
->importScope(this, Prot(Prot::public_
));
8423 Scope
*scy
= sc
->push(this);
8426 argsym
= new ScopeDsymbol();
8427 argsym
->parent
= scy
->parent
;
8428 Scope
*argscope
= scy
->push(argsym
);
8430 unsigned errorsave
= global
.errors
;
8432 // Declare each template parameter as an alias for the argument type
8433 declareParameters(argscope
);
8435 // Add members to enclosing scope, as well as this scope
8436 for (size_t i
= 0; i
< members
->length
; i
++)
8438 Dsymbol
*s
= (*members
)[i
];
8439 s
->addMember(argscope
, this);
8440 //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym);
8441 //printf("s->parent = %s\n", s->parent->toChars());
8444 // Do semantic() analysis on template instance members
8445 Scope
*sc2
= argscope
->push(this);
8446 //size_t deferred_dim = Module::deferred.length;
8449 //printf("%d\n", nest);
8450 if (++nest
> global
.recursionLimit
)
8452 global
.gag
= 0; // ensure error message gets printed
8453 error("recursive expansion");
8457 for (size_t i
= 0; i
< members
->length
; i
++)
8459 Dsymbol
*s
= (*members
)[i
];
8463 for (size_t i
= 0; i
< members
->length
; i
++)
8465 Dsymbol
*s
= (*members
)[i
];
8469 for (size_t i
= 0; i
< members
->length
; i
++)
8471 Dsymbol
*s
= (*members
)[i
];
8477 /* In DeclDefs scope, TemplateMixin does not have to handle deferred symbols.
8478 * Because the members would already call Module::addDeferredSemantic() for themselves.
8479 * See Struct, Class, Interface, and EnumDeclaration::semantic().
8481 //if (!sc->func && Module::deferred.length > deferred_dim) {}
8483 AggregateDeclaration
*ad
= toParent()->isAggregateDeclaration();
8484 if (sc
->func
&& !ad
)
8490 // Give additional context info if error occurred during instantiation
8491 if (global
.errors
!= errorsave
)
8493 error("error instantiating");
8502 void TemplateMixin::semantic2(Scope
*sc
)
8504 if (semanticRun
>= PASSsemantic2
)
8506 semanticRun
= PASSsemantic2
;
8510 sc
= sc
->push(argsym
);
8511 sc
= sc
->push(this);
8512 for (size_t i
= 0; i
< members
->length
; i
++)
8514 Dsymbol
*s
= (*members
)[i
];
8522 void TemplateMixin::semantic3(Scope
*sc
)
8524 if (semanticRun
>= PASSsemantic3
)
8526 semanticRun
= PASSsemantic3
;
8529 sc
= sc
->push(argsym
);
8530 sc
= sc
->push(this);
8531 for (size_t i
= 0; i
< members
->length
; i
++)
8533 Dsymbol
*s
= (*members
)[i
];
8541 const char *TemplateMixin::kind() const
8546 bool TemplateMixin::oneMember(Dsymbol
**ps
, Identifier
*ident
)
8548 return Dsymbol::oneMember(ps
, ident
);
8551 int TemplateMixin::apply(Dsymbol_apply_ft_t fp
, void *param
)
8553 if (_scope
) // if fwd reference
8554 semantic(NULL
); // try to resolve it
8557 for (size_t i
= 0; i
< members
->length
; i
++)
8559 Dsymbol
*s
= (*members
)[i
];
8562 if (s
->apply(fp
, param
))
8570 bool TemplateMixin::hasPointers()
8572 //printf("TemplateMixin::hasPointers() %s\n", toChars());
8576 for (size_t i
= 0; i
< members
->length
; i
++)
8578 Dsymbol
*s
= (*members
)[i
];
8579 //printf(" s = %s %s\n", s->kind(), s->toChars());
8580 if (s
->hasPointers())
8589 void TemplateMixin::setFieldOffset(AggregateDeclaration
*ad
, unsigned *poffset
, bool isunion
)
8591 //printf("TemplateMixin::setFieldOffset() %s\n", toChars());
8592 if (_scope
) // if fwd reference
8593 semantic(NULL
); // try to resolve it
8596 for (size_t i
= 0; i
< members
->length
; i
++)
8598 Dsymbol
*s
= (*members
)[i
];
8599 //printf("\t%s\n", s->toChars());
8600 s
->setFieldOffset(ad
, poffset
, isunion
);
8605 const char *TemplateMixin::toChars()
8608 toCBufferInstance(this, &buf
);
8609 return buf
.extractChars();