
/* Compiler implementation of the D programming language
 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
 * written by Walter Bright
 * http://www.digitalmars.com
 * Distributed under the Boost Software License, Version 1.0.
 * http://www.boost.org/LICENSE_1_0.txt
 * https://github.com/D-Programming-Language/dmd/blob/master/src/template.c
 */

// Handle template implementation

#include "root/dsystem.h"
#include "root/root.h"
#include "root/aav.h"
#include "root/rmem.h"
#include "root/stringtable.h"
#include "root/hash.h"

#include "mangle.h"
#include "mtype.h"
#include "template.h"
#include "init.h"
#include "expression.h"
#include "scope.h"
#include "module.h"
#include "aggregate.h"
#include "declaration.h"
#include "dsymbol.h"
#include "mars.h"
#include "dsymbol.h"
#include "identifier.h"
#include "hdrgen.h"
#include "id.h"
#include "attrib.h"
#include "tokens.h"

#define IDX_NOTFOUND (0x12345678)               // index is not found

Type *rawTypeMerge(Type *t1, Type *t2);
bool MODimplicitConv(MOD modfrom, MOD modto);
MATCH MODmethodConv(MOD modfrom, MOD modto);
MOD MODmerge(MOD mod1, MOD mod2);

static size_t templateParameterLookup(Type *tparam, TemplateParameters *parameters);
static int arrayObjectMatch(Objects *oa1, Objects *oa2);
static unsigned char deduceWildHelper(Type *t, Type **at, Type *tparam);
static MATCH deduceTypeHelper(Type *t, Type **at, Type *tparam);
static bool reliesOnTident(Type *t, TemplateParameters *tparams = NULL, size_t iStart = 0);
Expression *semantic(Expression *e, Scope *sc);
bool evalStaticCondition(Scope *sc, Expression *exp, Expression *e, bool &errors);

/********************************************
 * These functions substitute for dynamic_cast. dynamic_cast does not work
 * on earlier versions of gcc.
 */

Expression *isExpression(RootObject *o)
{
    //return dynamic_cast<Expression *>(o);
    if (!o || o->dyncast() != DYNCAST_EXPRESSION)
        return NULL;
    return (Expression *)o;
}

Dsymbol *isDsymbol(RootObject *o)
{
    //return dynamic_cast<Dsymbol *>(o);
    if (!o || o->dyncast() != DYNCAST_DSYMBOL)
        return NULL;
    return (Dsymbol *)o;
}

Type *isType(RootObject *o)
{
    //return dynamic_cast<Type *>(o);
    if (!o || o->dyncast() != DYNCAST_TYPE)
        return NULL;
    return (Type *)o;
}

Tuple *isTuple(RootObject *o)
{
    //return dynamic_cast<Tuple *>(o);
    if (!o || o->dyncast() != DYNCAST_TUPLE)
        return NULL;
    return (Tuple *)o;
}

Parameter *isParameter(RootObject *o)
{
    //return dynamic_cast<Parameter *>(o);
    if (!o || o->dyncast() != DYNCAST_PARAMETER)
        return NULL;
    return (Parameter *)o;
}

/**************************************
 * Is this Object an error?
 */
bool isError(RootObject *o)
{
    Type *t = isType(o);
    if (t)
        return (t->ty == Terror);
    Expression *e = isExpression(o);
    if (e)
        return (e->op == TOKerror || !e->type || e->type->ty == Terror);
    Tuple *v = isTuple(o);
    if (v)
        return arrayObjectIsError(&v->objects);
    Dsymbol *s = isDsymbol(o);
    assert(s);
    if (s->errors)
        return true;
    return s->parent ? isError(s->parent) : false;
}

/**************************************
 * Are any of the Objects an error?
 */
bool arrayObjectIsError(Objects *args)
{
    for (size_t i = 0; i < args->dim; i++)
    {
        RootObject *o = (*args)[i];
        if (isError(o))
            return true;
    }
    return false;
}

/***********************
 * Try to get arg as a type.
 */

Type *getType(RootObject *o)
{
    Type *t = isType(o);
    if (!t)
    {
        Expression *e = isExpression(o);
        if (e)
            t = e->type;
    }
    return t;
}

Dsymbol *getDsymbol(RootObject *oarg)
{
    //printf("getDsymbol()\n");
    //printf("e %p s %p t %p v %p\n", isExpression(oarg), isDsymbol(oarg), isType(oarg), isTuple(oarg));

    Dsymbol *sa;
    Expression *ea = isExpression(oarg);
    if (ea)
    {
        // Try to convert Expression to symbol
        if (ea->op == TOKvar)
            sa = ((VarExp *)ea)->var;
        else if (ea->op == TOKfunction)
        {
            if (((FuncExp *)ea)->td)
                sa = ((FuncExp *)ea)->td;
            else
                sa = ((FuncExp *)ea)->fd;
        }
        else if (ea->op == TOKtemplate)
            sa = ((TemplateExp *)ea)->td;
        else
            sa = NULL;
    }
    else
    {
        // Try to convert Type to symbol
        Type *ta = isType(oarg);
        if (ta)
            sa = ta->toDsymbol(NULL);
        else
            sa = isDsymbol(oarg);       // if already a symbol
    }
    return sa;
}

/***********************
 * Try to get value from manifest constant
 */

static Expression *getValue(Expression *e)
{
    if (e && e->op == TOKvar)
    {
        VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration();
        if (v && v->storage_class & STCmanifest)
        {
            e = v->getConstInitializer();
        }
    }
    return e;
}

static Expression *getValue(Dsymbol *&s)
{
    Expression *e = NULL;
    if (s)
    {
        VarDeclaration *v = s->isVarDeclaration();
        if (v && v->storage_class & STCmanifest)
        {
            e = v->getConstInitializer();
        }
    }
    return e;
}

/**********************************
 * Return true if e could be valid only as a template value parameter.
 * Return false if it might be an alias or tuple.
 * (Note that even in this case, it could still turn out to be a value).
 */
bool definitelyValueParameter(Expression *e)
{
    // None of these can be value parameters
    if (e->op == TOKtuple || e->op == TOKscope  ||
        e->op == TOKtype || e->op == TOKdottype ||
        e->op == TOKtemplate ||  e->op == TOKdottd ||
        e->op == TOKfunction || e->op == TOKerror ||
        e->op == TOKthis || e->op == TOKsuper)
        return false;

    if (e->op != TOKdotvar)
        return true;

    /* Template instantiations involving a DotVar expression are difficult.
     * In most cases, they should be treated as a value parameter, and interpreted.
     * But they might also just be a fully qualified name, which should be treated
     * as an alias.
     */

    // x.y.f cannot be a value
    FuncDeclaration *f = ((DotVarExp *)e)->var->isFuncDeclaration();
    if (f)
        return false;

    while (e->op == TOKdotvar)
    {
        e = ((DotVarExp *)e)->e1;
    }
    // this.x.y and super.x.y couldn't possibly be valid values.
    if (e->op == TOKthis || e->op == TOKsuper)
        return false;

    // e.type.x could be an alias
    if (e->op == TOKdottype)
        return false;

    // var.x.y is the only other possible form of alias
    if (e->op != TOKvar)
        return true;

    VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration();

    // func.x.y is not an alias
    if (!v)
        return true;

    // TODO: Should we force CTFE if it is a global constant?

    return false;
}

static Expression *getExpression(RootObject *o)
{
    Dsymbol *s = isDsymbol(o);
    return s ? getValue(s) : getValue(isExpression(o));
}

/******************************
 * If o1 matches o2, return true.
 * Else, return false.
 */

static bool match(RootObject *o1, RootObject *o2)
{
    //printf("match() o1 = %p %s (%d), o2 = %p %s (%d)\n",
    //       o1, o1->toChars(), o1->dyncast(), o2, o2->toChars(), o2->dyncast());

    /* A proper implementation of the various equals() overrides
     * should make it possible to just do o1->equals(o2), but
     * we'll do that another day.
     */

    /* Manifest constants should be compared by their values,
     * at least in template arguments.
     */

    if (Type *t1 = isType(o1))
    {
        Type *t2 = isType(o2);
        if (!t2)
            goto Lnomatch;

        //printf("\tt1 = %s\n", t1->toChars());
        //printf("\tt2 = %s\n", t2->toChars());
        if (!t1->equals(t2))
            goto Lnomatch;

        goto Lmatch;
    }
    if (Expression *e1 = getExpression(o1))
    {
        Expression *e2 = getExpression(o2);
        if (!e2)
            goto Lnomatch;

        //printf("\te1 = %s %s %s\n", e1->type->toChars(), Token::toChars(e1->op), e1->toChars());
        //printf("\te2 = %s %s %s\n", e2->type->toChars(), Token::toChars(e2->op), e2->toChars());

        // two expressions can be equal although they do not have the same
        // type; that happens when they have the same value. So check type
        // as well as expression equality to ensure templates are properly
        // matched.
        if (!e1->type->equals(e2->type) || !e1->equals(e2))
            goto Lnomatch;

        goto Lmatch;
    }
    if (Dsymbol *s1 = isDsymbol(o1))
    {
        Dsymbol *s2 = isDsymbol(o2);
        if (!s2)
            goto Lnomatch;

        //printf("\ts1 = %s\n", s1->toChars());
        //printf("\ts2 = %s\n", s2->toChars());
        if (!s1->equals(s2))
            goto Lnomatch;
        if (s1->parent != s2->parent && !s1->isFuncDeclaration() && !s2->isFuncDeclaration())
            goto Lnomatch;

        goto Lmatch;
    }
    if (Tuple *u1 = isTuple(o1))
    {
        Tuple *u2 = isTuple(o2);
        if (!u2)
            goto Lnomatch;

        //printf("\tu1 = %s\n", u1->toChars());
        //printf("\tu2 = %s\n", u2->toChars());
        if (!arrayObjectMatch(&u1->objects, &u2->objects))
            goto Lnomatch;

        goto Lmatch;
    }
Lmatch:
    //printf("\t-> match\n");
    return true;

Lnomatch:
    //printf("\t-> nomatch\n");
    return false;
}


/************************************
 * Match an array of them.
 */
int arrayObjectMatch(Objects *oa1, Objects *oa2)
{
    if (oa1 == oa2)
        return 1;
    if (oa1->dim != oa2->dim)
        return 0;
    for (size_t j = 0; j < oa1->dim; j++)
    {
        RootObject *o1 = (*oa1)[j];
        RootObject *o2 = (*oa2)[j];
        if (!match(o1, o2))
        {
            return 0;
        }
    }
    return 1;
}


/************************************
 * Computes hash of expression.
 * Handles all Expression classes and MUST match their equals method,
 * i.e. e1->equals(e2) implies expressionHash(e1) == expressionHash(e2).
 */
static hash_t expressionHash(Expression *e)
{
    switch (e->op)
    {
    case TOKint64:
        return (size_t) ((IntegerExp *)e)->getInteger();

    case TOKfloat64:
        return CTFloat::hash(((RealExp *)e)->value);

    case TOKcomplex80:
    {
        ComplexExp *ce = (ComplexExp *)e;
        return mixHash(CTFloat::hash(ce->toReal()), CTFloat::hash(ce->toImaginary()));
    }

    case TOKidentifier:
        return (size_t)(void *) ((IdentifierExp *)e)->ident;

    case TOKnull:
        return (size_t)(void *) ((NullExp *)e)->type;

    case TOKstring:
    {
        StringExp *se = (StringExp *)e;
        return calcHash((const char *)se->string, se->len * se->sz);
    }

    case TOKtuple:
    {
        TupleExp *te = (TupleExp *)e;
        size_t hash = 0;
        hash += te->e0 ? expressionHash(te->e0) : 0;
        for (size_t i = 0; i < te->exps->dim; i++)
        {
            Expression *elem = (*te->exps)[i];
            hash = mixHash(hash, expressionHash(elem));
        }
        return hash;
    }

    case TOKarrayliteral:
    {
        ArrayLiteralExp *ae = (ArrayLiteralExp *)e;
        size_t hash = 0;
        for (size_t i = 0; i < ae->elements->dim; i++)
            hash = mixHash(hash, expressionHash(ae->getElement(i)));
        return hash;
    }

    case TOKassocarrayliteral:
    {
        AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e;
        size_t hash = 0;
        for (size_t i = 0; i < ae->keys->dim; i++)
            // reduction needs associative op as keys are unsorted (use XOR)
            hash ^= mixHash(expressionHash((*ae->keys)[i]), expressionHash((*ae->values)[i]));
        return hash;
    }

    case TOKstructliteral:
    {
        StructLiteralExp *se = (StructLiteralExp *)e;
        size_t hash = 0;
        for (size_t i = 0; i < se->elements->dim; i++)
        {
            Expression *elem = (*se->elements)[i];
            hash = mixHash(hash, elem ? expressionHash(elem) : 0);
        }
        return hash;
    }

    case TOKvar:
        return (size_t)(void *) ((VarExp *)e)->var;

    case TOKfunction:
        return (size_t)(void *) ((FuncExp *)e)->fd;

    default:
        // no custom equals for this expression
        // equals based on identity
        return (size_t)(void *) e;
    }
}


/************************************
 * Return hash of Objects.
 */
static hash_t arrayObjectHash(Objects *oa1)
{
    hash_t hash = 0;
    for (size_t j = 0; j < oa1->dim; j++)
    {
        /* Must follow the logic of match()
         */
        RootObject *o1 = (*oa1)[j];
        if (Type *t1 = isType(o1))
            hash = mixHash(hash, (size_t)t1->deco);
        else if (Expression *e1 = getExpression(o1))
            hash = mixHash(hash, expressionHash(e1));
        else if (Dsymbol *s1 = isDsymbol(o1))
        {
            FuncAliasDeclaration *fa1 = s1->isFuncAliasDeclaration();
            if (fa1)
                s1 = fa1->toAliasFunc();
            hash = mixHash(hash, mixHash((size_t)(void *)s1->getIdent(), (size_t)(void *)s1->parent));
        }
        else if (Tuple *u1 = isTuple(o1))
            hash = mixHash(hash, arrayObjectHash(&u1->objects));
    }
    return hash;
}

RootObject *objectSyntaxCopy(RootObject *o)
{
    if (!o)
        return NULL;
    if (Type *t = isType(o))
        return t->syntaxCopy();
    if (Expression *e = isExpression(o))
        return e->syntaxCopy();
    return o;
}


/* ======================== TemplateDeclaration ============================= */

TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id,
        TemplateParameters *parameters, Expression *constraint, Dsymbols *decldefs, bool ismixin, bool literal)
    : ScopeDsymbol(id)
{
    this->loc = loc;
    this->parameters = parameters;
    this->origParameters = parameters;
    this->constraint = constraint;
    this->members = decldefs;
    this->overnext = NULL;
    this->overroot = NULL;
    this->funcroot = NULL;
    this->onemember = NULL;
    this->literal = literal;
    this->ismixin = ismixin;
    this->isstatic = true;
    this->previous = NULL;
    this->protection = Prot(PROTundefined);
    this->instances = NULL;

    // Compute in advance for Ddoc's use
    // Bugzilla 11153: ident could be NULL if parsing fails.
    if (members && ident)
    {
        Dsymbol *s;
        if (Dsymbol::oneMembers(members, &s, ident) && s)
        {
            onemember = s;
            s->parent = this;
        }
    }
}

Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *)
{
    //printf("TemplateDeclaration::syntaxCopy()\n");
    TemplateParameters *p = NULL;
    if (parameters)
    {
        p = new TemplateParameters();
        p->setDim(parameters->dim);
        for (size_t i = 0; i < p->dim; i++)
            (*p)[i] = (*parameters)[i]->syntaxCopy();
    }
    return new TemplateDeclaration(loc, ident, p,
        constraint ? constraint->syntaxCopy() : NULL,
        Dsymbol::arraySyntaxCopy(members), ismixin, literal);
}

void TemplateDeclaration::semantic(Scope *sc)
{
    if (semanticRun != PASSinit)
        return;         // semantic() already run

    // Remember templates defined in module object that we need to know about
    if (sc->_module && sc->_module->ident == Id::object)
    {
        if (ident == Id::RTInfo)
            Type::rtinfo = this;
    }

    /* Remember Scope for later instantiations, but make
     * a copy since attributes can change.
     */
    if (!this->_scope)
    {
        this->_scope = sc->copy();
        this->_scope->setNoFree();
    }

    semanticRun = PASSsemantic;

    parent = sc->parent;
    protection = sc->protection;
    isstatic = toParent()->isModule() || (_scope->stc & STCstatic);

    if (!isstatic)
    {
        if (AggregateDeclaration *ad = parent->pastMixin()->isAggregateDeclaration())
            ad->makeNested();
    }

    // Set up scope for parameters
    ScopeDsymbol *paramsym = new ScopeDsymbol();
    paramsym->parent = parent;
    Scope *paramscope = sc->push(paramsym);
    paramscope->stc = 0;

    if (global.params.doDocComments)
    {
        origParameters = new TemplateParameters();
        origParameters->setDim(parameters->dim);
        for (size_t i = 0; i < parameters->dim; i++)
        {
            TemplateParameter *tp = (*parameters)[i];
            (*origParameters)[i] = tp->syntaxCopy();
        }
    }

    for (size_t i = 0; i < parameters->dim; i++)
    {
        TemplateParameter *tp = (*parameters)[i];

        if (!tp->declareParameter(paramscope))
        {
            error(tp->loc, "parameter '%s' multiply defined", tp->ident->toChars());
            errors = true;
        }
        if (!tp->semantic(paramscope, parameters))
        {
            errors = true;
        }
        if (i + 1 != parameters->dim && tp->isTemplateTupleParameter())
        {
            error("template tuple parameter must be last one");
            errors = true;
        }
    }

    /* Calculate TemplateParameter::dependent
     */
    TemplateParameters tparams;
    tparams.setDim(1);
    for (size_t i = 0; i < parameters->dim; i++)
    {
        TemplateParameter *tp = (*parameters)[i];
        tparams[0] = tp;

        for (size_t j = 0; j < parameters->dim; j++)
        {
            // Skip cases like: X(T : T)
            if (i == j)
                continue;

            if (TemplateTypeParameter *ttp = (*parameters)[j]->isTemplateTypeParameter())
            {
                if (reliesOnTident(ttp->specType, &tparams))
                    tp->dependent = true;
            }
            else if (TemplateAliasParameter *tap = (*parameters)[j]->isTemplateAliasParameter())
            {
                if (reliesOnTident(tap->specType, &tparams) ||
                    reliesOnTident(isType(tap->specAlias), &tparams))
                {
                    tp->dependent = true;
                }
            }
        }
    }

    paramscope->pop();

    // Compute again
    onemember = NULL;
    if (members)
    {
        Dsymbol *s;
        if (Dsymbol::oneMembers(members, &s, ident) && s)
        {
            onemember = s;
            s->parent = this;
        }
    }

    /* BUG: should check:
     *  o no virtual functions or non-static data members of classes
     */
}

const char *TemplateDeclaration::kind() const
{
    return (onemember && onemember->isAggregateDeclaration())
                ? onemember->kind()
                : "template";
}

/**********************************
 * Overload existing TemplateDeclaration 'this' with the new one 's'.
 * Return true if successful; i.e. no conflict.
 */

bool TemplateDeclaration::overloadInsert(Dsymbol *s)
{
    FuncDeclaration *fd = s->isFuncDeclaration();
    if (fd)
    {
        if (funcroot)
            return funcroot->overloadInsert(fd);
        funcroot = fd;
        return funcroot->overloadInsert(this);
    }

    TemplateDeclaration *td = s->isTemplateDeclaration();
    if (!td)
        return false;

    TemplateDeclaration *pthis = this;
    TemplateDeclaration **ptd;
    for (ptd = &pthis; *ptd; ptd = &(*ptd)->overnext)
    {
    }

    td->overroot = this;
    *ptd = td;
    return true;
}

/****************************
 * Check to see if constraint is satisfied.
 */
bool TemplateDeclaration::evaluateConstraint(
        TemplateInstance *ti, Scope *sc, Scope *paramscope,
        Objects *dedargs, FuncDeclaration *fd)
{
    /* Detect recursive attempts to instantiate this template declaration,
     * Bugzilla 4072
     *  void foo(T)(T x) if (is(typeof(foo(x)))) { }
     *  static assert(!is(typeof(foo(7))));
     * Recursive attempts are regarded as a constraint failure.
     */
    /* There's a chicken-and-egg problem here. We don't know yet if this template
     * instantiation will be a local one (enclosing is set), and we won't know until
     * after selecting the correct template. Thus, function we're nesting inside
     * is not on the sc scope chain, and this can cause errors in FuncDeclaration::getLevel().
     * Workaround the problem by setting a flag to relax the checking on frame errors.
     */

    for (TemplatePrevious *p = previous; p; p = p->prev)
    {
        if (arrayObjectMatch(p->dedargs, dedargs))
        {
            //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
            /* It must be a subscope of p->sc, other scope chains are not recursive
             * instantiations.
             */
            for (Scope *scx = sc; scx; scx = scx->enclosing)
            {
                if (scx == p->sc)
                    return false;
            }
        }
        /* BUG: should also check for ref param differences
         */
    }

    TemplatePrevious pr;
    pr.prev    = previous;
    pr.sc      = paramscope;
    pr.dedargs = dedargs;
    previous = &pr;                 // add this to threaded list

    Scope *scx = paramscope->push(ti);
    scx->parent = ti;
    scx->tinst = NULL;
    scx->minst = NULL;

    assert(!ti->symtab);
    if (fd)
    {
        /* Declare all the function parameters as variables and add them to the scope
         * Making parameters is similar to FuncDeclaration::semantic3
         */
        TypeFunction *tf = (TypeFunction *)fd->type;
        assert(tf->ty == Tfunction);

        scx->parent = fd;

        Parameters *fparameters = tf->parameters;
        int fvarargs = tf->varargs;

        size_t nfparams = Parameter::dim(fparameters);
        for (size_t i = 0; i < nfparams; i++)
        {
            Parameter *fparam = Parameter::getNth(fparameters, i);
            fparam->storageClass &= (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
            fparam->storageClass |= STCparameter;
            if (fvarargs == 2 && i + 1 == nfparams)
                fparam->storageClass |= STCvariadic;
        }
        for (size_t i = 0; i < fparameters->dim; i++)
        {
            Parameter *fparam = (*fparameters)[i];
            if (!fparam->ident)
                continue;                       // don't add it, if it has no name
            VarDeclaration *v = new VarDeclaration(loc, fparam->type, fparam->ident, NULL);
            v->storage_class = fparam->storageClass;
            v->semantic(scx);
            if (!ti->symtab)
                ti->symtab = new DsymbolTable();
            if (!scx->insert(v))
                error("parameter %s.%s is already defined", toChars(), v->toChars());
            else
                v->parent = fd;
        }
        if (isstatic)
            fd->storage_class |= STCstatic;

        fd->vthis = fd->declareThis(scx, fd->isThis());
    }

    Expression *e = constraint->syntaxCopy();

    assert(ti->inst == NULL);
    ti->inst = ti;  // temporary instantiation to enable genIdent()

    scx->flags |= SCOPEconstraint;
    bool errors = false;
    bool result = evalStaticCondition(scx, constraint, e, errors);
    ti->inst = NULL;
    ti->symtab = NULL;
    scx = scx->pop();
    previous = pr.prev;             // unlink from threaded list
    if (errors)
        return false;
    return result;
}

/***************************************
 * Given that ti is an instance of this TemplateDeclaration,
 * deduce the types of the parameters to this, and store
 * those deduced types in dedtypes[].
 * Input:
 *      flag    1: don't do semantic() because of dummy types
 *              2: don't change types in matchArg()
 * Output:
 *      dedtypes        deduced arguments
 * Return match level.
 */

MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,
        Objects *dedtypes, Expressions *fargs, int flag)
{
    MATCH m;
    size_t dedtypes_dim = dedtypes->dim;

    dedtypes->zero();

    if (errors)
        return MATCHnomatch;

    size_t parameters_dim = parameters->dim;
    int variadic = isVariadic() != NULL;

    // If more arguments than parameters, no match
    if (ti->tiargs->dim > parameters_dim && !variadic)
    {
        return MATCHnomatch;
    }

    assert(dedtypes_dim == parameters_dim);
    assert(dedtypes_dim >= ti->tiargs->dim || variadic);

    assert(_scope);

    // Set up scope for template parameters
    ScopeDsymbol *paramsym = new ScopeDsymbol();
    paramsym->parent = _scope->parent;
    Scope *paramscope = _scope->push(paramsym);
    paramscope->tinst = ti;
    paramscope->minst = sc->minst;
    paramscope->callsc = sc;
    paramscope->stc = 0;

    // Attempt type deduction
    m = MATCHexact;
    for (size_t i = 0; i < dedtypes_dim; i++)
    {
        MATCH m2;
        TemplateParameter *tp = (*parameters)[i];
        Declaration *sparam;

        //printf("\targument [%d]\n", i);
        m2 = tp->matchArg(ti->loc, paramscope, ti->tiargs, i, parameters, dedtypes, &sparam);
        //printf("\tm2 = %d\n", m2);

        if (m2 == MATCHnomatch)
        {
            goto Lnomatch;
        }

        if (m2 < m)
            m = m2;

        if (!flag)
            sparam->semantic(paramscope);
        if (!paramscope->insert(sparam))    // TODO: This check can make more early
            goto Lnomatch;                  // in TemplateDeclaration::semantic, and
                                            // then we don't need to make sparam if flags == 0
    }

    if (!flag)
    {
        /* Any parameter left without a type gets the type of
         * its corresponding arg
         */
        for (size_t i = 0; i < dedtypes_dim; i++)
        {
            if (!(*dedtypes)[i])
            {
                assert(i < ti->tiargs->dim);
                (*dedtypes)[i] = (Type *)(*ti->tiargs)[i];
            }
        }
    }

    if (m > MATCHnomatch && constraint && !flag)
    {
        if (ti->hasNestedArgs(ti->tiargs, this->isstatic))  // TODO: should gag error
            ti->parent = ti->enclosing;
        else
            ti->parent = this->parent;

        // Similar to doHeaderInstantiation
        FuncDeclaration *fd = onemember ? onemember->isFuncDeclaration() : NULL;
        if (fd)
        {
            assert(fd->type->ty == Tfunction);
            TypeFunction *tf = (TypeFunction *)fd->type->syntaxCopy();

            fd = new FuncDeclaration(fd->loc, fd->endloc, fd->ident, fd->storage_class, tf);
            fd->parent = ti;
            fd->inferRetType = true;

            // Shouldn't run semantic on default arguments and return type.
            for (size_t i = 0; i < tf->parameters->dim; i++)
                (*tf->parameters)[i]->defaultArg = NULL;
            tf->next = NULL;

            // Resolve parameter types and 'auto ref's.
            tf->fargs = fargs;
            unsigned olderrors = global.startGagging();
            fd->type = tf->semantic(loc, paramscope);
            if (global.endGagging(olderrors))
            {
                assert(fd->type->ty != Tfunction);
                goto Lnomatch;
            }
            assert(fd->type->ty == Tfunction);
            fd->originalType = fd->type;    // for mangling
        }

        // TODO: dedtypes => ti->tiargs ?
        if (!evaluateConstraint(ti, sc, paramscope, dedtypes, fd))
            goto Lnomatch;
    }

    goto Lret;

Lnomatch:
    m = MATCHnomatch;

Lret:
    paramscope->pop();
    return m;
}

/********************************************
 * Determine partial specialization order of 'this' vs td2.
 * Returns:
 *      match   this is at least as specialized as td2
 *      0       td2 is more specialized than this
 */

MATCH TemplateDeclaration::leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs)
{
    /* This works by taking the template parameters to this template
     * declaration and feeding them to td2 as if it were a template
     * instance.
     * If it works, then this template is at least as specialized
     * as td2.
     */

    TemplateInstance ti(Loc(), ident);      // create dummy template instance
    // Set type arguments to dummy template instance to be types
    // generated from the parameters to this template declaration
    ti.tiargs = new Objects();
    ti.tiargs->reserve(parameters->dim);
    for (size_t i = 0; i < parameters->dim; i++)
    {
        TemplateParameter *tp = (*parameters)[i];
        if (tp->dependent)
            break;
        RootObject *p = (RootObject *)tp->dummyArg();
        if (!p)
            break;

        ti.tiargs->push(p);
    }

    // Temporary Array to hold deduced types
    Objects dedtypes;
    dedtypes.setDim(td2->parameters->dim);

    // Attempt a type deduction
    MATCH m = td2->matchWithInstance(sc, &ti, &dedtypes, fargs, 1);
    if (m > MATCHnomatch)
    {
        /* A non-variadic template is more specialized than a
         * variadic one.
         */
        TemplateTupleParameter *tp = isVariadic();
        if (tp && !tp->dependent && !td2->isVariadic())
            goto L1;

        return m;
    }
  L1:
    return MATCHnomatch;
}

static Expression *emptyArrayElement = NULL;

class TypeDeduced : public Type
{
public:
    Type *tded;
    Expressions argexps;    // corresponding expressions
    Types tparams;          // tparams[i]->mod

    TypeDeduced(Type *tt, Expression *e, Type *tparam)
        : Type(Tnone)
    {
        tded = tt;
        argexps.push(e);
        tparams.push(tparam);
    }

    virtual ~TypeDeduced()
    {
    }

    void update(Expression *e, Type *tparam)
    {
        argexps.push(e);
        tparams.push(tparam);
    }
    void update(Type *tt, Expression *e, Type *tparam)
    {
        tded = tt;
        argexps.push(e);
        tparams.push(tparam);
    }
    MATCH matchAll(Type *tt)
    {
        MATCH match = MATCHexact;
        for (size_t j = 0; j < argexps.dim; j++)
        {
            Expression *e = argexps[j];
            assert(e);
            if (e == emptyArrayElement)
                continue;

            Type *t = tt->addMod(tparams[j]->mod)->substWildTo(MODconst);

            MATCH m = e->implicitConvTo(t);
            if (match > m)
                match = m;
            if (match <= MATCHnomatch)
                break;
        }
        return match;
    }
};

/*************************************************
 * Match function arguments against a specific template function.
 * Input:
 *      ti
 *      sc              instantiation scope
 *      fd
 *      tthis           'this' argument if !NULL
 *      fargs           arguments to function
 * Output:
 *      fd              Partially instantiated function declaration
 *      ti->tdtypes     Expression/Type deduced template arguments
 * Returns:
 *      match level
 *          bit 0-3     Match template parameters by inferred template arguments
 *          bit 4-7     Match template parameters by initial template arguments
 */

MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
        TemplateInstance *ti, Scope *sc,
        FuncDeclaration *&fd, Type *tthis, Expressions *fargs)
{
    size_t nfparams;
    size_t nfargs;
    size_t ntargs;              // array size of tiargs
    size_t fptupindex = IDX_NOTFOUND;
    MATCH match = MATCHexact;
    MATCH matchTiargs = MATCHexact;
    Parameters *fparameters;            // function parameter list
    int fvarargs;                       // function varargs
    unsigned wildmatch = 0;
    size_t inferStart = 0;

    Loc instLoc = ti->loc;
    Objects *tiargs = ti->tiargs;
    Objects *dedargs = new Objects();
    Objects* dedtypes = &ti->tdtypes;   // for T:T*, the dedargs is the T*, dedtypes is the T

    assert(_scope);

    dedargs->setDim(parameters->dim);
    dedargs->zero();

    dedtypes->setDim(parameters->dim);
    dedtypes->zero();

    if (errors || fd->errors)
        return MATCHnomatch;

    // Set up scope for parameters
    ScopeDsymbol *paramsym = new ScopeDsymbol();
    paramsym->parent = _scope->parent;   // should use hasnestedArgs and enclosing?
    Scope *paramscope = _scope->push(paramsym);
    paramscope->tinst = ti;
    paramscope->minst = sc->minst;
    paramscope->callsc = sc;
    paramscope->stc = 0;

    TemplateTupleParameter *tp = isVariadic();
    Tuple *declaredTuple = NULL;

    ntargs = 0;
    if (tiargs)
    {
        // Set initial template arguments
        ntargs = tiargs->dim;
        size_t n = parameters->dim;
        if (tp)
            n--;
        if (ntargs > n)
        {
            if (!tp)
                goto Lnomatch;

            /* The extra initial template arguments
             * now form the tuple argument.
             */
            Tuple *t = new Tuple();
            assert(parameters->dim);
            (*dedargs)[parameters->dim - 1] = t;

            t->objects.setDim(ntargs - n);
            for (size_t i = 0; i < t->objects.dim; i++)
            {
                t->objects[i] = (*tiargs)[n + i];
            }
            declareParameter(paramscope, tp, t);
            declaredTuple = t;
        }
        else
            n = ntargs;

        memcpy(dedargs->tdata(), tiargs->tdata(), n * sizeof(*dedargs->tdata()));

        for (size_t i = 0; i < n; i++)
        {
            assert(i < parameters->dim);
            Declaration *sparam = NULL;
            MATCH m = (*parameters)[i]->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, &sparam);
            //printf("\tdeduceType m = %d\n", m);
            if (m <= MATCHnomatch)
                goto Lnomatch;
            if (m < matchTiargs)
                matchTiargs = m;

            sparam->semantic(paramscope);
            if (!paramscope->insert(sparam))
                goto Lnomatch;
        }
        if (n < parameters->dim && !declaredTuple)
        {
            inferStart = n;
        }
        else
            inferStart = parameters->dim;
        //printf("tiargs matchTiargs = %d\n", matchTiargs);
    }

    fparameters = fd->getParameters(&fvarargs);
    nfparams = Parameter::dim(fparameters);     // number of function parameters
    nfargs = fargs ? fargs->dim : 0;            // number of function arguments

    /* Check for match of function arguments with variadic template
     * parameter, such as:
     *
     * void foo(T, A...)(T t, A a);
     * void main() { foo(1,2,3); }
     */
    if (tp)                             // if variadic
    {
        // TemplateTupleParameter always makes most lesser matching.
        matchTiargs = MATCHconvert;

        if (nfparams == 0 && nfargs != 0)               // if no function parameters
        {
            if (!declaredTuple)
            {
                Tuple *t = new Tuple();
                //printf("t = %p\n", t);
                (*dedargs)[parameters->dim - 1] = t;
                declareParameter(paramscope, tp, t);
                declaredTuple = t;
            }
        }
        else
        {
            /* Figure out which of the function parameters matches
             * the tuple template parameter. Do this by matching
             * type identifiers.
             * Set the index of this function parameter to fptupindex.
             */
            for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
            {
                Parameter *fparam = (*fparameters)[fptupindex];
                if (fparam->type->ty != Tident)
                    continue;
                TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
                if (!tp->ident->equals(tid->ident) || tid->idents.dim)
                    continue;

                if (fvarargs)           // variadic function doesn't
                    goto Lnomatch;      // go with variadic template

                goto L1;
            }
            fptupindex = IDX_NOTFOUND;
        L1:
            ;
        }
    }

    if (toParent()->isModule() || (_scope->stc & STCstatic))
        tthis = NULL;
    if (tthis)
    {
        bool hasttp = false;

        // Match 'tthis' to any TemplateThisParameter's
        for (size_t i = 0; i < parameters->dim; i++)
        {
            TemplateThisParameter *ttp = (*parameters)[i]->isTemplateThisParameter();
            if (ttp)
            {
                hasttp = true;

                Type *t = new TypeIdentifier(Loc(), ttp->ident);
                MATCH m = deduceType(tthis, paramscope, t, parameters, dedtypes);
                if (m <= MATCHnomatch)
                    goto Lnomatch;
                if (m < match)
                    match = m;          // pick worst match
            }
        }

        // Match attributes of tthis against attributes of fd
        if (fd->type && !fd->isCtorDeclaration())
        {
            StorageClass stc = _scope->stc | fd->storage_class2;
            // Propagate parent storage class (see bug 5504)
            Dsymbol *p = parent;
            while (p->isTemplateDeclaration() || p->isTemplateInstance())
                p = p->parent;
            AggregateDeclaration *ad = p->isAggregateDeclaration();
            if (ad)
                stc |= ad->storage_class;

            unsigned char mod = fd->type->mod;
            if (stc & STCimmutable)
                mod = MODimmutable;
            else
            {
                if (stc & (STCshared | STCsynchronized))
                    mod |= MODshared;
                if (stc & STCconst)
                    mod |= MODconst;
                if (stc & STCwild)
                    mod |= MODwild;
            }

            unsigned char thismod = tthis->mod;
            if (hasttp)
                mod = MODmerge(thismod, mod);
            MATCH m = MODmethodConv(thismod, mod);
            if (m <= MATCHnomatch)
                goto Lnomatch;
            if (m < match)
                match = m;
        }
    }

    // Loop through the function parameters
    {
    //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple->objects.dim : 0);
    //printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple->toChars() : NULL);
    size_t argi = 0;
    size_t nfargs2 = nfargs;    // nfargs + supplied defaultArgs
    for (size_t parami = 0; parami < nfparams; parami++)
    {
        Parameter *fparam = Parameter::getNth(fparameters, parami);

        // Apply function parameter storage classes to parameter types
        Type *prmtype = fparam->type->addStorageClass(fparam->storageClass);

        Expression *farg;

        /* See function parameters which wound up
         * as part of a template tuple parameter.
         */
        if (fptupindex != IDX_NOTFOUND && parami == fptupindex)
        {
            assert(prmtype->ty == Tident);
            TypeIdentifier *tid = (TypeIdentifier *)prmtype;
            if (!declaredTuple)
            {
                /* The types of the function arguments
                 * now form the tuple argument.
                 */
                declaredTuple = new Tuple();
                (*dedargs)[parameters->dim - 1] = declaredTuple;

                /* Count function parameters following a tuple parameter.
                 * void foo(U, T...)(int y, T, U, int) {}  // rem == 2 (U, int)
                 */
                size_t rem = 0;
                for (size_t j = parami + 1; j < nfparams; j++)
                {
                    Parameter *p = Parameter::getNth(fparameters, j);
                    if (!reliesOnTident(p->type, parameters, inferStart))
                    {
                        Type *pt = p->type->syntaxCopy()->semantic(fd->loc, paramscope);
                        rem += pt->ty == Ttuple ? ((TypeTuple *)pt)->arguments->dim : 1;
                    }
                    else
                    {
                        ++rem;
                    }
                }

                if (nfargs2 - argi < rem)
                    goto Lnomatch;
                declaredTuple->objects.setDim(nfargs2 - argi - rem);
                for (size_t i = 0; i < declaredTuple->objects.dim; i++)
                {
                    farg = (*fargs)[argi + i];

                    // Check invalid arguments to detect errors early.
                    if (farg->op == TOKerror || farg->type->ty == Terror)
                        goto Lnomatch;

                    if (!(fparam->storageClass & STClazy) && farg->type->ty == Tvoid)
                        goto Lnomatch;

                    Type *tt;
                    MATCH m;
                    if (unsigned char wm = deduceWildHelper(farg->type, &tt, tid))
                    {
                        wildmatch |= wm;
                        m = MATCHconst;
                    }
                    else
                    {
                        m = deduceTypeHelper(farg->type, &tt, tid);
                    }
                    if (m <= MATCHnomatch)
                        goto Lnomatch;
                    if (m < match)
                        match = m;

                    /* Remove top const for dynamic array types and pointer types
                     */
                    if ((tt->ty == Tarray || tt->ty == Tpointer) &&
                        !tt->isMutable() &&
                        (!(fparam->storageClass & STCref) ||
                         ((fparam->storageClass & STCauto) && !farg->isLvalue())))
                    {
                        tt = tt->mutableOf();
                    }
                    declaredTuple->objects[i] = tt;
                }
                declareParameter(paramscope, tp, declaredTuple);
            }
            else
            {
                // Bugzilla 6810: If declared tuple is not a type tuple,
                // it cannot be function parameter types.
                for (size_t i = 0; i < declaredTuple->objects.dim; i++)
                {
                    if (!isType(declaredTuple->objects[i]))
                        goto Lnomatch;
                }
            }
            assert(declaredTuple);
            argi += declaredTuple->objects.dim;
            continue;
        }

        // If parameter type doesn't depend on inferred template parameters,
        // semantic it to get actual type.
        if (!reliesOnTident(prmtype, parameters, inferStart))
        {
            // should copy prmtype to avoid affecting semantic result
            prmtype = prmtype->syntaxCopy()->semantic(fd->loc, paramscope);

            if (prmtype->ty == Ttuple)
            {
                TypeTuple *tt = (TypeTuple *)prmtype;
                size_t tt_dim = tt->arguments->dim;
                for (size_t j = 0; j < tt_dim; j++, ++argi)
                {
                    Parameter *p = (*tt->arguments)[j];
                    if (j == tt_dim - 1 && fvarargs == 2 && parami + 1 == nfparams && argi < nfargs)
                    {
                        prmtype = p->type;
                        goto Lvarargs;
                    }
                    if (argi >= nfargs)
                    {
                        if (p->defaultArg)
                            continue;
                        goto Lnomatch;
                    }
                    farg = (*fargs)[argi];
                    if (!farg->implicitConvTo(p->type))
                        goto Lnomatch;
                }
                continue;
            }
        }

        if (argi >= nfargs)                // if not enough arguments
        {
            if (!fparam->defaultArg)
                goto Lvarargs;

            /* Bugzilla 2803: Before the starting of type deduction from the function
             * default arguments, set the already deduced parameters into paramscope.
             * It's necessary to avoid breaking existing acceptable code. Cases:
             *
             * 1. Already deduced template parameters can appear in fparam->defaultArg:
             *  auto foo(A, B)(A a, B b = A.stringof);
             *  foo(1);
             *  // at fparam == 'B b = A.string', A is equivalent with the deduced type 'int'
             *
             * 2. If prmtype depends on default-specified template parameter, the
             * default type should be preferred.
             *  auto foo(N = size_t, R)(R r, N start = 0)
             *  foo([1,2,3]);
             *  // at fparam `N start = 0`, N should be 'size_t' before
             *  // the deduction result from fparam->defaultArg.
             */
            if (argi == nfargs)
            {
                for (size_t i = 0; i < dedtypes->dim; i++)
                {
                    Type *at = isType((*dedtypes)[i]);
                    if (at && at->ty == Tnone)
                    {
                        TypeDeduced *xt = (TypeDeduced *)at;
                        (*dedtypes)[i] = xt->tded;  // 'unbox'
                        delete xt;
                    }
                }
                for (size_t i = ntargs; i < dedargs->dim; i++)
                {
                    TemplateParameter *tparam = (*parameters)[i];

                    RootObject *oarg = (*dedargs)[i];
                    RootObject *oded = (*dedtypes)[i];
                    if (!oarg)
                    {
                        if (oded)
                        {
                            if (tparam->specialization() || !tparam->isTemplateTypeParameter())
                            {
                                /* The specialization can work as long as afterwards
                                 * the oded == oarg
                                 */
                                (*dedargs)[i] = oded;
                                MATCH m2 = tparam->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, NULL);
                                //printf("m2 = %d\n", m2);
                                if (m2 <= MATCHnomatch)
                                    goto Lnomatch;
                                if (m2 < matchTiargs)
                                    matchTiargs = m2;             // pick worst match
                                if (!(*dedtypes)[i]->equals(oded))
                                    error("specialization not allowed for deduced parameter %s", tparam->ident->toChars());
                            }
                            else
                            {
                                if (MATCHconvert < matchTiargs)
                                    matchTiargs = MATCHconvert;
                            }
                            (*dedargs)[i] = declareParameter(paramscope, tparam, oded);
                        }
                        else
                        {
                            oded = tparam->defaultArg(instLoc, paramscope);
                            if (oded)
                                (*dedargs)[i] = declareParameter(paramscope, tparam, oded);
                        }
                    }
                }
            }
            nfargs2 = argi + 1;

            /* If prmtype does not depend on any template parameters:
             *
             *  auto foo(T)(T v, double x = 0);
             *  foo("str");
             *  // at fparam == 'double x = 0'
             *
             * or, if all template parameters in the prmtype are already deduced:
             *
             *  auto foo(R)(R range, ElementType!R sum = 0);
             *  foo([1,2,3]);
             *  // at fparam == 'ElementType!R sum = 0'
             *
             * Deducing prmtype from fparam->defaultArg is not necessary.
             */
            if (prmtype->deco ||
                prmtype->syntaxCopy()->trySemantic(loc, paramscope))
            {
                ++argi;
                continue;
            }

            // Deduce prmtype from the defaultArg.
            farg = fparam->defaultArg->syntaxCopy();
            farg = ::semantic(farg, paramscope);
            farg = resolveProperties(paramscope, farg);
        }
        else
        {
            farg = (*fargs)[argi];
        }
        {
            // Check invalid arguments to detect errors early.
            if (farg->op == TOKerror || farg->type->ty == Terror)
                goto Lnomatch;

            Type *att = NULL;
        Lretry:
            Type *argtype = farg->type;

            if (!(fparam->storageClass & STClazy) && argtype->ty == Tvoid && farg->op != TOKfunction)
                goto Lnomatch;

            // Bugzilla 12876: optimize arugument to allow CT-known length matching
            farg = farg->optimize(WANTvalue, (fparam->storageClass & (STCref | STCout)) != 0);
            //printf("farg = %s %s\n", farg->type->toChars(), farg->toChars());

            RootObject *oarg = farg;
            if ((fparam->storageClass & STCref) &&
                (!(fparam->storageClass & STCauto) || farg->isLvalue()))
            {
                /* Allow expressions that have CT-known boundaries and type [] to match with [dim]
                 */
                Type *taai;
                if (argtype->ty == Tarray &&
                    (prmtype->ty == Tsarray ||
                     (prmtype->ty == Taarray && (taai = ((TypeAArray *)prmtype)->index)->ty == Tident &&
                      ((TypeIdentifier *)taai)->idents.dim == 0)))
                {
                    if (farg->op == TOKstring)
                    {
                        StringExp *se = (StringExp *)farg;
                        argtype = se->type->nextOf()->sarrayOf(se->len);
                    }
                    else if (farg->op == TOKarrayliteral)
                    {
                        ArrayLiteralExp *ae = (ArrayLiteralExp *)farg;
                        argtype = ae->type->nextOf()->sarrayOf(ae->elements->dim);
                    }
                    else if (farg->op == TOKslice)
                    {
                        SliceExp *se = (SliceExp *)farg;
                        if (Type *tsa = toStaticArrayType(se))
                            argtype = tsa;
                    }
                }

                oarg = argtype;
            }
            else if ((fparam->storageClass & STCout) == 0 &&
                     (argtype->ty == Tarray || argtype->ty == Tpointer) &&
                     templateParameterLookup(prmtype, parameters) != IDX_NOTFOUND &&
                     ((TypeIdentifier *)prmtype)->idents.dim == 0)
            {
                /* The farg passing to the prmtype always make a copy. Therefore,
                 * we can shrink the set of the deduced type arguments for prmtype
                 * by adjusting top-qualifier of the argtype.
                 *
                 *  prmtype         argtype     ta
                 *  T            <- const(E)[]  const(E)[]
                 *  T            <- const(E[])  const(E)[]
                 *  qualifier(T) <- const(E)[]  const(E[])
                 *  qualifier(T) <- const(E[])  const(E[])
                 */
                Type *ta = argtype->castMod(prmtype->mod ? argtype->nextOf()->mod : 0);
                if (ta != argtype)
                {
                    Expression *ea = farg->copy();
                    ea->type = ta;
                    oarg = ea;
                }
            }

            if (fvarargs == 2 && parami + 1 == nfparams && argi + 1 < nfargs)
                goto Lvarargs;

            unsigned wm = 0;
            MATCH m = deduceType(oarg, paramscope, prmtype, parameters, dedtypes, &wm, inferStart);
            //printf("\tL%d deduceType m = %d, wm = x%x, wildmatch = x%x\n", __LINE__, m, wm, wildmatch);
            wildmatch |= wm;

            /* If no match, see if the argument can be matched by using
             * implicit conversions.
             */
            if (m == MATCHnomatch && prmtype->deco)
                m = farg->implicitConvTo(prmtype);

            if (m == MATCHnomatch)
            {
                AggregateDeclaration *ad = isAggregate(farg->type);
                if (ad && ad->aliasthis && argtype != att)
                {
                    if (!att && argtype->checkAliasThisRec())   // Bugzilla 12537
                        att = argtype;

                    /* If a semantic error occurs while doing alias this,
                     * eg purity(bug 7295), just regard it as not a match.
                     */
                    if (Expression *e = resolveAliasThis(sc, farg, true))
                    {
                        farg = e;
                        goto Lretry;
                    }
                }
            }

            if (m > MATCHnomatch && (fparam->storageClass & (STCref | STCauto)) == STCref)
            {
                if (!farg->isLvalue())
                {
                    if ((farg->op == TOKstring || farg->op == TOKslice) &&
                        (prmtype->ty == Tsarray || prmtype->ty == Taarray))
                    {
                        // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
                    }
                    else
                        goto Lnomatch;
                }
            }
            if (m > MATCHnomatch && (fparam->storageClass & STCout))
            {
                if (!farg->isLvalue())
                    goto Lnomatch;
                if (!farg->type->isMutable())   // Bugzilla 11916
                    goto Lnomatch;
            }
            if (m == MATCHnomatch && (fparam->storageClass & STClazy) && prmtype->ty == Tvoid &&
                    farg->type->ty != Tvoid)
                m = MATCHconvert;

            if (m != MATCHnomatch)
            {
                if (m < match)
                    match = m;          // pick worst match
                argi++;
                continue;
            }
        }

    Lvarargs:
        /* The following code for variadic arguments closely
         * matches TypeFunction::callMatch()
         */
        if (!(fvarargs == 2 && parami + 1 == nfparams))
            goto Lnomatch;

        /* Check for match with function parameter T...
         */
        Type *tb = prmtype->toBasetype();
        switch (tb->ty)
        {
            // 6764 fix - TypeAArray may be TypeSArray have not yet run semantic().
            case Tsarray:
            case Taarray:
                // Perhaps we can do better with this, see TypeFunction::callMatch()
                if (tb->ty == Tsarray)
                {
                    TypeSArray *tsa = (TypeSArray *)tb;
                    dinteger_t sz = tsa->dim->toInteger();
                    if (sz != nfargs - argi)
                        goto Lnomatch;
                }
                else if (tb->ty == Taarray)
                {
                    TypeAArray *taa = (TypeAArray *)tb;
                    Expression *dim = new IntegerExp(instLoc, nfargs - argi, Type::tsize_t);

                    size_t i = templateParameterLookup(taa->index, parameters);
                    if (i == IDX_NOTFOUND)
                    {
                        Expression *e;
                        Type *t;
                        Dsymbol *s;
                        Scope *sco;

                        unsigned errors = global.startGagging();
                        /* ref: https://issues.dlang.org/show_bug.cgi?id=11118
                         * The parameter isn't part of the template
                         * ones, let's try to find it in the
                         * instantiation scope 'sc' and the one
                         * belonging to the template itself. */
                        sco = sc;
                        taa->index->resolve(instLoc, sco, &e, &t, &s);
                        if (!e)
                        {
                            sco = paramscope;
                            taa->index->resolve(instLoc, sco, &e, &t, &s);
                        }
                        global.endGagging(errors);

                        if (!e)
                        {
                            goto Lnomatch;
                        }

                        e = e->ctfeInterpret();
                        e = e->implicitCastTo(sco, Type::tsize_t);
                        e = e->optimize(WANTvalue);
                        if (!dim->equals(e))
                            goto Lnomatch;
                    }
                    else
                    {
                        // This code matches code in TypeInstance::deduceType()
                        TemplateParameter *tprm = (*parameters)[i];
                        TemplateValueParameter *tvp = tprm->isTemplateValueParameter();
                        if (!tvp)
                            goto Lnomatch;
                        Expression *e = (Expression *)(*dedtypes)[i];
                        if (e)
                        {
                            if (!dim->equals(e))
                                goto Lnomatch;
                        }
                        else
                        {
                            Type *vt = tvp->valType->semantic(Loc(), sc);
                            MATCH m = (MATCH)dim->implicitConvTo(vt);
                            if (m <= MATCHnomatch)
                                goto Lnomatch;
                            (*dedtypes)[i] = dim;
                        }
                    }
                }
                /* fall through */
            case Tarray:
            {
                TypeArray *ta = (TypeArray *)tb;
                Type *tret = fparam->isLazyArray();
                for (; argi < nfargs; argi++)
                {
                    Expression *arg = (*fargs)[argi];
                    assert(arg);

                    MATCH m;
                    /* If lazy array of delegates,
                     * convert arg(s) to delegate(s)
                     */
                    if (tret)
                    {
                        if (ta->next->equals(arg->type))
                        {
                            m = MATCHexact;
                        }
                        else
                        {
                            m = arg->implicitConvTo(tret);
                            if (m == MATCHnomatch)
                            {
                                if (tret->toBasetype()->ty == Tvoid)
                                    m = MATCHconvert;
                            }
                        }
                    }
                    else
                    {
                        unsigned wm = 0;
                        m = deduceType(arg, paramscope, ta->next, parameters, dedtypes, &wm, inferStart);
                        wildmatch |= wm;
                    }
                    if (m == MATCHnomatch)
                        goto Lnomatch;
                    if (m < match)
                        match = m;
                }
                goto Lmatch;
            }
            case Tclass:
            case Tident:
                goto Lmatch;

            default:
                goto Lnomatch;
        }
        ++argi;
    }
    //printf("-> argi = %d, nfargs = %d, nfargs2 = %d\n", argi, nfargs, nfargs2);
    if (argi != nfargs2 && !fvarargs)
        goto Lnomatch;
    }

Lmatch:

    for (size_t i = 0; i < dedtypes->dim; i++)
    {
        Type *at = isType((*dedtypes)[i]);
        if (at)
        {
            if (at->ty == Tnone)
            {
                TypeDeduced *xt = (TypeDeduced *)at;
                at = xt->tded;  // 'unbox'
                delete xt;
            }
            (*dedtypes)[i] = at->merge2();
        }
    }
    for (size_t i = ntargs; i < dedargs->dim; i++)
    {
        TemplateParameter *tparam = (*parameters)[i];
        //printf("tparam[%d] = %s\n", i, tparam->ident->toChars());
        /* For T:T*, the dedargs is the T*, dedtypes is the T
         * But for function templates, we really need them to match
         */
        RootObject *oarg = (*dedargs)[i];
        RootObject *oded = (*dedtypes)[i];
        //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
        //if (oarg) printf("oarg: %s\n", oarg->toChars());
        //if (oded) printf("oded: %s\n", oded->toChars());
        if (!oarg)
        {
            if (oded)
            {
                if (tparam->specialization() || !tparam->isTemplateTypeParameter())
                {
                    /* The specialization can work as long as afterwards
                     * the oded == oarg
                     */
                    (*dedargs)[i] = oded;
                    MATCH m2 = tparam->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, NULL);
                    //printf("m2 = %d\n", m2);
                    if (m2 <= MATCHnomatch)
                        goto Lnomatch;
                    if (m2 < matchTiargs)
                        matchTiargs = m2;             // pick worst match
                    if (!(*dedtypes)[i]->equals(oded))
                        error("specialization not allowed for deduced parameter %s", tparam->ident->toChars());
                }
                else
                {
                    if (MATCHconvert < matchTiargs)
                        matchTiargs = MATCHconvert;
                }
            }
            else
            {
                oded = tparam->defaultArg(instLoc, paramscope);
                if (!oded)
                {
                    // if tuple parameter and
                    // tuple parameter was not in function parameter list and
                    // we're one or more arguments short (i.e. no tuple argument)
                    if (tparam == tp &&
                        fptupindex == IDX_NOTFOUND &&
                        ntargs <= dedargs->dim - 1)
                    {
                        // make tuple argument an empty tuple
                        oded = (RootObject *)new Tuple();
                    }
                    else
                        goto Lnomatch;
                }
                if (isError(oded))
                    goto Lerror;
                ntargs++;

                /* At the template parameter T, the picked default template argument
                 * X!int should be matched to T in order to deduce dependent
                 * template parameter A.
                 *  auto foo(T : X!A = X!int, A...)() { ... }
                 *  foo();  // T <-- X!int, A <-- (int)
                 */
                if (tparam->specialization())
                {
                    (*dedargs)[i] = oded;
                    MATCH m2 = tparam->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, NULL);
                    //printf("m2 = %d\n", m2);
                    if (m2 <= MATCHnomatch)
                        goto Lnomatch;
                    if (m2 < matchTiargs)
                        matchTiargs = m2;             // pick worst match
                    if (!(*dedtypes)[i]->equals(oded))
                        error("specialization not allowed for deduced parameter %s", tparam->ident->toChars());
                }
            }
            oded = declareParameter(paramscope, tparam, oded);
            (*dedargs)[i] = oded;
        }
    }

    /* Bugzilla 7469: As same as the code for 7469 in findBestMatch,
     * expand a Tuple in dedargs to normalize template arguments.
     */
    if (size_t d = dedargs->dim)
    {
        if (Tuple *va = isTuple((*dedargs)[d - 1]))
        {
            if (va->objects.dim)
            {
                dedargs->setDim(d - 1);
                dedargs->insert(d - 1, &va->objects);
            }
        }
    }
    ti->tiargs = dedargs; // update to the normalized template arguments.

    // Partially instantiate function for constraint and fd->leastAsSpecialized()
    {
        assert(paramsym);
        Scope *sc2 = _scope;
        sc2 = sc2->push(paramsym);
        sc2 = sc2->push(ti);
        sc2->parent = ti;
        sc2->tinst = ti;
        sc2->minst = sc->minst;

        fd = doHeaderInstantiation(ti, sc2, fd, tthis, fargs);

        sc2 = sc2->pop();
        sc2 = sc2->pop();

        if (!fd)
            goto Lnomatch;
    }

    if (constraint)
    {
        if (!evaluateConstraint(ti, sc, paramscope, dedargs, fd))
            goto Lnomatch;
    }

    paramscope->pop();
    //printf("\tmatch %d\n", match);
    return (MATCH)(match | (matchTiargs<<4));

Lnomatch:
    paramscope->pop();
    //printf("\tnomatch\n");
    return MATCHnomatch;

Lerror: // todo: for the future improvement
    paramscope->pop();
    //printf("\terror\n");
    return MATCHnomatch;
}

/**************************************************
 * Declare template parameter tp with value o, and install it in the scope sc.
 */

RootObject *TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o)
{
    //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o);

    Type *ta = isType(o);
    Expression *ea = isExpression(o);
    Dsymbol *sa = isDsymbol(o);
    Tuple *va = isTuple(o);

    Declaration *d;
    VarDeclaration *v = NULL;

    if (ea && ea->op == TOKtype)
        ta = ea->type;
    else if (ea && ea->op == TOKscope)
        sa = ((ScopeExp *)ea)->sds;
    else if (ea && (ea->op == TOKthis || ea->op == TOKsuper))
        sa = ((ThisExp *)ea)->var;
    else if (ea && ea->op == TOKfunction)
    {
        if (((FuncExp *)ea)->td)
            sa = ((FuncExp *)ea)->td;
        else
            sa = ((FuncExp *)ea)->fd;
    }

    if (ta)
    {
        //printf("type %s\n", ta->toChars());
        d = new AliasDeclaration(Loc(), tp->ident, ta);
    }
    else if (sa)
    {
        //printf("Alias %s %s;\n", sa->ident->toChars(), tp->ident->toChars());
        d = new AliasDeclaration(Loc(), tp->ident, sa);
    }
    else if (ea)
    {
        // tdtypes.data[i] always matches ea here
        Initializer *init = new ExpInitializer(loc, ea);
        TemplateValueParameter *tvp = tp->isTemplateValueParameter();

        Type *t = tvp ? tvp->valType : NULL;

        v = new VarDeclaration(loc, t, tp->ident, init);
        v->storage_class = STCmanifest | STCtemplateparameter;
        d = v;
    }
    else if (va)
    {
        //printf("\ttuple\n");
        d = new TupleDeclaration(loc, tp->ident, &va->objects);
    }
    else
    {
        assert(0);
    }

    d->storage_class |= STCtemplateparameter;
    if (ta)
    {
        Type *t = ta;
        // consistent with Type::checkDeprecated()
        while (t->ty != Tenum)
        {
            if (!t->nextOf()) break;
            t = ((TypeNext *)t)->next;
        }
        if (Dsymbol *s = t->toDsymbol(sc))
        {
            if (s->isDeprecated())
                d->storage_class |= STCdeprecated;
        }
    }
    else if (sa)
    {
        if (sa->isDeprecated())
            d->storage_class |= STCdeprecated;
    }

    if (!sc->insert(d))
        error("declaration %s is already defined", tp->ident->toChars());
    d->semantic(sc);

    /* So the caller's o gets updated with the result of semantic() being run on o
     */
    if (v)
        o = initializerToExpression(v->_init);
    return o;
}

/**************************************
 * Determine if TemplateDeclaration is variadic.
 */

TemplateTupleParameter *isVariadic(TemplateParameters *parameters)
{
    size_t dim = parameters->dim;
    TemplateTupleParameter *tp = NULL;

    if (dim)
        tp = ((*parameters)[dim - 1])->isTemplateTupleParameter();
    return tp;
}

TemplateTupleParameter *TemplateDeclaration::isVariadic()
{
    return ::isVariadic(parameters);
}

/***********************************
 * We can overload templates.
 */

bool TemplateDeclaration::isOverloadable()
{
    return true;
}

/*************************************************
 * Given function arguments, figure out which template function
 * to expand, and return matching result.
 * Input:
 *      m               matching result
 *      dstart          the root of overloaded function templates
 *      loc             instantiation location
 *      sc              instantiation scope
 *      tiargs          initial list of template arguments
 *      tthis           if !NULL, the 'this' pointer argument
 *      fargs           arguments to function
 */

void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
        Objects *tiargs, Type *tthis, Expressions *fargs)
{
    struct ParamDeduce
    {
        // context
        Loc loc;
        Scope *sc;
        Type *tthis;
        Objects *tiargs;
        Expressions *fargs;
        // result
        Match *m;
        int property;   // 0: unintialized
                        // 1: seen @property
                        // 2: not @property
        size_t ov_index;
        TemplateDeclaration *td_best;
        TemplateInstance *ti_best;
        MATCH ta_last;
        Type *tthis_best;

        static int fp(void *param, Dsymbol *s)
        {
            if (s->errors)
                return 0;
            if (FuncDeclaration *fd = s->isFuncDeclaration())
                return ((ParamDeduce *)param)->applyFunction(fd);
            if (TemplateDeclaration *td = s->isTemplateDeclaration())
                return ((ParamDeduce *)param)->applyTemplate(td);
            return 0;
        }

        int applyFunction(FuncDeclaration *fd)
        {
            // skip duplicates
            if (fd == m->lastf)
                return 0;
            // explicitly specified tiargs never match to non template function
            if (tiargs && tiargs->dim > 0)
                return 0;

            if (fd->semanticRun == PASSinit && fd->_scope)
            {
                Ungag ungag = fd->ungagSpeculative();
                fd->semantic(fd->_scope);
            }
            if (fd->semanticRun == PASSinit)
            {
                ::error(loc, "forward reference to template %s", fd->toChars());
                return 1;
            }
            //printf("fd = %s %s, fargs = %s\n", fd->toChars(), fd->type->toChars(), fargs->toChars());
            m->anyf = fd;
            TypeFunction *tf = (TypeFunction *)fd->type;

            int prop = (tf->isproperty) ? 1 : 2;
            if (property == 0)
                property = prop;
            else if (property != prop)
                error(fd->loc, "cannot overload both property and non-property functions");

            /* For constructors, qualifier check will be opposite direction.
             * Qualified constructor always makes qualified object, then will be checked
             * that it is implicitly convertible to tthis.
             */
            Type *tthis_fd = fd->needThis() ? tthis : NULL;
            bool isCtorCall = tthis_fd && fd->isCtorDeclaration();
            if (isCtorCall)
            {
                //printf("%s tf->mod = x%x tthis_fd->mod = x%x %d\n", tf->toChars(),
                //        tf->mod, tthis_fd->mod, fd->isolateReturn());
                if (MODimplicitConv(tf->mod, tthis_fd->mod) ||
                    (tf->isWild() && tf->isShared() == tthis_fd->isShared()) ||
                    fd->isolateReturn())
                {
                    /* && tf->isShared() == tthis_fd->isShared()*/
                    // Uniquely constructed object can ignore shared qualifier.
                    // TODO: Is this appropriate?
                    tthis_fd = NULL;
                }
                else
                    return 0;   // MATCHnomatch
            }
            MATCH mfa = tf->callMatch(tthis_fd, fargs);
            //printf("test1: mfa = %d\n", mfa);
            if (mfa > MATCHnomatch)
            {
                if (mfa > m->last) goto LfIsBetter;
                if (mfa < m->last) goto LlastIsBetter;

                /* See if one of the matches overrides the other.
                */
                assert(m->lastf);
                if (m->lastf->overrides(fd)) goto LlastIsBetter;
                if (fd->overrides(m->lastf)) goto LfIsBetter;

                /* Try to disambiguate using template-style partial ordering rules.
                 * In essence, if f() and g() are ambiguous, if f() can call g(),
                 * but g() cannot call f(), then pick f().
                 * This is because f() is "more specialized."
                 */
                {
                    MATCH c1 = fd->leastAsSpecialized(m->lastf);
                    MATCH c2 = m->lastf->leastAsSpecialized(fd);
                    //printf("c1 = %d, c2 = %d\n", c1, c2);
                    if (c1 > c2) goto LfIsBetter;
                    if (c1 < c2) goto LlastIsBetter;
                }

                /* The 'overrides' check above does covariant checking only
                 * for virtual member functions. It should do it for all functions,
                 * but in order to not risk breaking code we put it after
                 * the 'leastAsSpecialized' check.
                 * In the future try moving it before.
                 * I.e. a not-the-same-but-covariant match is preferred,
                 * as it is more restrictive.
                 */
                if (!m->lastf->type->equals(fd->type))
                {
                    //printf("cov: %d %d\n", m->lastf->type->covariant(fd->type), fd->type->covariant(m->lastf->type));
                    if (m->lastf->type->covariant(fd->type) == 1) goto LlastIsBetter;
                    if (fd->type->covariant(m->lastf->type) == 1) goto LfIsBetter;
                }

                /* If the two functions are the same function, like:
                 *    int foo(int);
                 *    int foo(int x) { ... }
                 * then pick the one with the body.
                 */
                if (tf->equals(m->lastf->type) &&
                    fd->storage_class == m->lastf->storage_class &&
                    fd->parent == m->lastf->parent &&
                    fd->protection == m->lastf->protection &&
                    fd->linkage == m->lastf->linkage)
                {
                    if ( fd->fbody && !m->lastf->fbody) goto LfIsBetter;
                    if (!fd->fbody &&  m->lastf->fbody) goto LlastIsBetter;
                }

                // Bugzilla 14450: Prefer exact qualified constructor for the creating object type
                if (isCtorCall && tf->mod != m->lastf->type->mod)
                {
                    if (tthis->mod == tf->mod) goto LfIsBetter;
                    if (tthis->mod == m->lastf->type->mod) goto LlastIsBetter;
                }

                m->nextf = fd;
                m->count++;
                return 0;

            LlastIsBetter:
                return 0;

            LfIsBetter:
                td_best = NULL;
                ti_best = NULL;
                ta_last = MATCHexact;
                m->last = mfa;
                m->lastf = fd;
                tthis_best = tthis_fd;
                ov_index = 0;
                m->count = 1;
                return 0;
            }
            return 0;
        }

        int applyTemplate(TemplateDeclaration *td)
        {
            //printf("applyTemplate()\n");
            // skip duplicates
            if (td == td_best)
                return 0;

            if (!sc)
                sc = td->_scope; // workaround for Type::aliasthisOf

            if (td->semanticRun == PASSinit && td->_scope)
            {
                // Try to fix forward reference. Ungag errors while doing so.
                Ungag ungag = td->ungagSpeculative();
                td->semantic(td->_scope);
            }
            if (td->semanticRun == PASSinit)
            {
                ::error(loc, "forward reference to template %s", td->toChars());
            Lerror:
                m->lastf = NULL;
                m->count = 0;
                m->last = MATCHnomatch;
                return 1;
            }
            //printf("td = %s\n", td->toChars());

            FuncDeclaration *f;
            f = td->onemember ? td->onemember->isFuncDeclaration() : NULL;
            if (!f)
            {
                if (!tiargs)
                    tiargs = new Objects();
                TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
                Objects dedtypes;
                dedtypes.setDim(td->parameters->dim);
                assert(td->semanticRun != PASSinit);
                MATCH mta = td->matchWithInstance(sc, ti, &dedtypes, fargs, 0);
                //printf("matchWithInstance = %d\n", mta);
                if (mta <= MATCHnomatch || mta < ta_last)      // no match or less match
                    return 0;

                ti->semantic(sc, fargs);
                if (!ti->inst)                  // if template failed to expand
                    return 0;

                Dsymbol *s = ti->inst->toAlias();
                FuncDeclaration *fd;
                if (TemplateDeclaration *tdx = s->isTemplateDeclaration())
                {
                    Objects dedtypesX;  // empty tiargs

                    // Bugzilla 11553: Check for recursive instantiation of tdx.
                    for (TemplatePrevious *p = tdx->previous; p; p = p->prev)
                    {
                        if (arrayObjectMatch(p->dedargs, &dedtypesX))
                        {
                            //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
                            /* It must be a subscope of p->sc, other scope chains are not recursive
                             * instantiations.
                             */
                            for (Scope *scx = sc; scx; scx = scx->enclosing)
                            {
                                if (scx == p->sc)
                                {
                                    error(loc, "recursive template expansion while looking for %s.%s", ti->toChars(), tdx->toChars());
                                    goto Lerror;
                                }
                            }
                        }
                        /* BUG: should also check for ref param differences
                        */
                    }

                    TemplatePrevious pr;
                    pr.prev = tdx->previous;
                    pr.sc = sc;
                    pr.dedargs = &dedtypesX;
                    tdx->previous = &pr;                 // add this to threaded list

                    fd = resolveFuncCall(loc, sc, s, NULL, tthis, fargs, 1);

                    tdx->previous = pr.prev;             // unlink from threaded list
                }
                else if (s->isFuncDeclaration())
                {
                    fd = resolveFuncCall(loc, sc, s, NULL, tthis, fargs, 1);
                }
                else
                    goto Lerror;

                if (!fd)
                    return 0;

                if (fd->type->ty != Tfunction)
                {
                    m->lastf = fd;   // to propagate "error match"
                    m->count = 1;
                    m->last = MATCHnomatch;
                    return 1;
                }

                Type *tthis_fd = fd->needThis() && !fd->isCtorDeclaration() ? tthis : NULL;

                TypeFunction *tf = (TypeFunction *)fd->type;
                MATCH mfa = tf->callMatch(tthis_fd, fargs);
                if (mfa < m->last)
                    return 0;

                if (mta < ta_last) goto Ltd_best2;
                if (mta > ta_last) goto Ltd2;

                if (mfa < m->last) goto Ltd_best2;
                if (mfa > m->last) goto Ltd2;

                //printf("Lambig2\n");
                m->nextf = fd;
                m->count++;
                return 0;

            Ltd_best2:
                return 0;

            Ltd2:
                // td is the new best match
                assert(td->_scope);
                td_best = td;
                ti_best = NULL;
                property = 0;   // (backward compatibility)
                ta_last = mta;
                m->last = mfa;
                m->lastf = fd;
                tthis_best = tthis_fd;
                ov_index = 0;
                m->nextf = NULL;
                m->count = 1;
                return 0;
            }

            //printf("td = %s\n", td->toChars());
            for (size_t ovi = 0; f; f = f->overnext0, ovi++)
            {
                if (f->type->ty != Tfunction || f->errors)
                    goto Lerror;

                /* This is a 'dummy' instance to evaluate constraint properly.
                */
                TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
                ti->parent = td->parent;    // Maybe calculating valid 'enclosing' is unnecessary.

                FuncDeclaration *fd = f;
                int x = td->deduceFunctionTemplateMatch(ti, sc, fd, tthis, fargs);
                MATCH mta = (MATCH)(x >> 4);
                MATCH mfa = (MATCH)(x & 0xF);
                //printf("match:t/f = %d/%d\n", mta, mfa);
                if (!fd || mfa == MATCHnomatch)
                    continue;

                Type *tthis_fd = fd->needThis() ? tthis : NULL;

                bool isCtorCall = tthis_fd && fd->isCtorDeclaration();
                if (isCtorCall)
                {
                    // Constructor call requires additional check.

                    TypeFunction *tf = (TypeFunction *)fd->type;
                    assert(tf->next);
                    if (MODimplicitConv(tf->mod, tthis_fd->mod) ||
                        (tf->isWild() && tf->isShared() == tthis_fd->isShared()) ||
                        fd->isolateReturn())
                    {
                        tthis_fd = NULL;
                    }
                    else
                        continue;   // MATCHnomatch
                }

                if (mta < ta_last) goto Ltd_best;
                if (mta > ta_last) goto Ltd;

                if (mfa < m->last) goto Ltd_best;
                if (mfa > m->last) goto Ltd;

                if (td_best)
                {
                    // Disambiguate by picking the most specialized TemplateDeclaration
                    MATCH c1 = td->leastAsSpecialized(sc, td_best, fargs);
                    MATCH c2 = td_best->leastAsSpecialized(sc, td, fargs);
                    //printf("1: c1 = %d, c2 = %d\n", c1, c2);
                    if (c1 > c2) goto Ltd;
                    if (c1 < c2) goto Ltd_best;
                }
                assert(fd && m->lastf);
                {
                    // Disambiguate by tf->callMatch
                    TypeFunction *tf1 = (TypeFunction *)fd->type;
                    assert(tf1->ty == Tfunction);
                    TypeFunction *tf2 = (TypeFunction *)m->lastf->type;
                    assert(tf2->ty == Tfunction);
                    MATCH c1 = tf1->callMatch(tthis_fd,   fargs);
                    MATCH c2 = tf2->callMatch(tthis_best, fargs);
                    //printf("2: c1 = %d, c2 = %d\n", c1, c2);
                    if (c1 > c2) goto Ltd;
                    if (c1 < c2) goto Ltd_best;
                }
                {
                    // Disambiguate by picking the most specialized FunctionDeclaration
                    MATCH c1 = fd->leastAsSpecialized(m->lastf);
                    MATCH c2 = m->lastf->leastAsSpecialized(fd);
                    //printf("3: c1 = %d, c2 = %d\n", c1, c2);
                    if (c1 > c2) goto Ltd;
                    if (c1 < c2) goto Ltd_best;
                }

                // Bugzilla 14450: Prefer exact qualified constructor for the creating object type
                if (isCtorCall && fd->type->mod != m->lastf->type->mod)
                {
                    if (tthis->mod == fd->type->mod) goto Ltd;
                    if (tthis->mod == m->lastf->type->mod) goto Ltd_best;
                }

                m->nextf = fd;
                m->count++;
                continue;

            Ltd_best:         // td_best is the best match so far
                //printf("Ltd_best\n");
                continue;

            Ltd:              // td is the new best match
                //printf("Ltd\n");
                assert(td->_scope);
                td_best = td;
                ti_best = ti;
                property = 0;   // (backward compatibility)
                ta_last = mta;
                m->last = mfa;
                m->lastf = fd;
                tthis_best = tthis_fd;
                ov_index = ovi;
                m->nextf = NULL;
                m->count = 1;
                continue;
            }
            return 0;
        }
    };
    ParamDeduce p;
    // context
    p.loc    = loc;
    p.sc     = sc;
    p.tthis  = tthis;
    p.tiargs = tiargs;
    p.fargs  = fargs;

    // result
    p.m          = m;
    p.property   = 0;
    p.ov_index   = 0;
    p.td_best    = NULL;
    p.ti_best    = NULL;
    p.ta_last    = m->last != MATCHnomatch ? MATCHexact : MATCHnomatch;
    p.tthis_best = NULL;

    TemplateDeclaration *td = dstart->isTemplateDeclaration();
    if (td && td->funcroot)
        dstart = td->funcroot;

    overloadApply(dstart, &p, &ParamDeduce::fp);

    //printf("td_best = %p, m->lastf = %p\n", p.td_best, m->lastf);
    if (p.td_best && p.ti_best && m->count == 1)
    {
        // Matches to template function
        assert(p.td_best->onemember && p.td_best->onemember->isFuncDeclaration());

        /* The best match is td_best with arguments tdargs.
         * Now instantiate the template.
         */
        assert(p.td_best->_scope);
        if (!sc)
            sc = p.td_best->_scope; // workaround for Type::aliasthisOf

        TemplateInstance *ti = new TemplateInstance(loc, p.td_best, p.ti_best->tiargs);
        ti->semantic(sc, fargs);

        m->lastf = ti->toAlias()->isFuncDeclaration();
        if (!m->lastf)
            goto Lnomatch;
        if (ti->errors)
        {
        Lerror:
            m->count = 1;
            assert(m->lastf);
            m->last = MATCHnomatch;
            return;
        }

        // look forward instantiated overload function
        // Dsymbol::oneMembers is alredy called in TemplateInstance::semantic.
        // it has filled overnext0d
        while (p.ov_index--)
        {
            m->lastf = m->lastf->overnext0;
            assert(m->lastf);
        }

        p.tthis_best = m->lastf->needThis() && !m->lastf->isCtorDeclaration() ? tthis : NULL;

        TypeFunction *tf = (TypeFunction *)m->lastf->type;
        if (tf->ty == Terror)
            goto Lerror;
        assert(tf->ty == Tfunction);
        if (!tf->callMatch(p.tthis_best, fargs))
            goto Lnomatch;

        /* As Bugzilla 3682 shows, a template instance can be matched while instantiating
         * that same template. Thus, the function type can be incomplete. Complete it.
         *
         * Bugzilla 9208: For auto function, completion should be deferred to the end of
         * its semantic3. Should not complete it in here.
         */
        if (tf->next && !m->lastf->inferRetType)
        {
            m->lastf->type = tf->semantic(loc, sc);
        }
    }
    else if (m->lastf)
    {
        // Matches to non template function,
        // or found matches were ambiguous.
        assert(m->count >= 1);
    }
    else
    {
    Lnomatch:
        m->count = 0;
        m->lastf = NULL;
        m->last = MATCHnomatch;
    }
}

/*************************************************
 * Limited function template instantiation for using fd->leastAsSpecialized()
 */
FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(
        TemplateInstance *ti, Scope *sc2,
        FuncDeclaration *fd, Type *tthis, Expressions *fargs)
{
    assert(fd);

    // function body and contracts are not need
    if (fd->isCtorDeclaration())
        fd = new CtorDeclaration(fd->loc, fd->endloc, fd->storage_class, fd->type->syntaxCopy());
    else
        fd = new FuncDeclaration(fd->loc, fd->endloc, fd->ident, fd->storage_class, fd->type->syntaxCopy());
    fd->parent = ti;

    assert(fd->type->ty == Tfunction);
    TypeFunction *tf = (TypeFunction *)fd->type;
    tf->fargs = fargs;

    if (tthis)
    {
        // Match 'tthis' to any TemplateThisParameter's
        bool hasttp = false;
        for (size_t i = 0; i < parameters->dim; i++)
        {
            TemplateParameter *tp = (*parameters)[i];
            TemplateThisParameter *ttp = tp->isTemplateThisParameter();
            if (ttp)
                hasttp = true;
        }
        if (hasttp)
        {
            tf = (TypeFunction *)tf->addSTC(ModToStc(tthis->mod));
            assert(!tf->deco);
        }
    }

    Scope *scx = sc2->push();

    // Shouldn't run semantic on default arguments and return type.
    for (size_t i = 0; i < tf->parameters->dim; i++)
        (*tf->parameters)[i]->defaultArg = NULL;
    if (fd->isCtorDeclaration())
    {
        // For constructors, emitting return type is necessary for
        // isolateReturn() in functionResolve.
        scx->flags |= SCOPEctor;

        Dsymbol *parent = toParent2();
        Type *tret;
        AggregateDeclaration *ad = parent->isAggregateDeclaration();
        if (!ad || parent->isUnionDeclaration())
        {
            tret = Type::tvoid;
        }
        else
        {
            tret = ad->handleType();
            assert(tret);
            tret = tret->addStorageClass(fd->storage_class | scx->stc);
            tret = tret->addMod(tf->mod);
        }
        tf->next = tret;
        if (ad && ad->isStructDeclaration())
            tf->isref = 1;
        //printf("tf = %s\n", tf->toChars());
    }
    else
        tf->next = NULL;
    fd->type = tf;
    fd->type = fd->type->addSTC(scx->stc);
    fd->type = fd->type->semantic(fd->loc, scx);
    scx = scx->pop();

    if (fd->type->ty != Tfunction)
        return NULL;

    fd->originalType = fd->type;    // for mangling
    //printf("\t[%s] fd->type = %s, mod = %x, ", loc.toChars(), fd->type->toChars(), fd->type->mod);
    //printf("fd->needThis() = %d\n", fd->needThis());

    return fd;
}

bool TemplateDeclaration::hasStaticCtorOrDtor()
{
    return false;               // don't scan uninstantiated templates
}

const char *TemplateDeclaration::toChars()
{
    if (literal)
        return Dsymbol::toChars();

    OutBuffer buf;
    HdrGenState hgs;

    buf.writestring(ident->toChars());
    buf.writeByte('(');
    for (size_t i = 0; i < parameters->dim; i++)
    {
        TemplateParameter *tp = (*parameters)[i];
        if (i)
            buf.writestring(", ");
        ::toCBuffer(tp, &buf, &hgs);
    }
    buf.writeByte(')');

    if (onemember)
    {
        FuncDeclaration *fd = onemember->isFuncDeclaration();
        if (fd && fd->type)
        {
            TypeFunction *tf = (TypeFunction *)fd->type;
            buf.writestring(parametersTypeToChars(tf->parameters, tf->varargs));
        }
    }

    if (constraint)
    {
        buf.writestring(" if (");
        ::toCBuffer(constraint, &buf, &hgs);
        buf.writeByte(')');
    }
    return buf.extractString();
}

Prot TemplateDeclaration::prot()
{
    return protection;
}

/****************************************************
 * Given a new instance tithis of this TemplateDeclaration,
 * see if there already exists an instance.
 * If so, return that existing instance.
 */

TemplateInstance *TemplateDeclaration::findExistingInstance(TemplateInstance *tithis, Expressions *fargs)
{
    //printf("findExistingInstance(%p)\n", tithis);
    tithis->fargs = fargs;
    TemplateInstances *tinstances = (TemplateInstances *)dmd_aaGetRvalue((AA *)instances, (void *)tithis->toHash());
    if (tinstances)
    {
        for (size_t i = 0; i < tinstances->dim; i++)
        {
            TemplateInstance *ti = (*tinstances)[i];
            if (tithis->compare(ti) == 0)
                return ti;
        }
    }
    return NULL;
}

/********************************************
 * Add instance ti to TemplateDeclaration's table of instances.
 * Return a handle we can use to later remove it if it fails instantiation.
 */

TemplateInstance *TemplateDeclaration::addInstance(TemplateInstance *ti)
{
    //printf("addInstance() %p %p\n", instances, ti);
    TemplateInstances **ptinstances = (TemplateInstances **)dmd_aaGet((AA **)&instances, (void *)ti->toHash());
    if (!*ptinstances)
        *ptinstances = new TemplateInstances();
    (*ptinstances)->push(ti);
    return ti;
}

/*******************************************
 * Remove TemplateInstance from table of instances.
 * Input:
 *      handle returned by addInstance()
 */

void TemplateDeclaration::removeInstance(TemplateInstance *handle)
{
    //printf("removeInstance()\n");
    TemplateInstances *tinstances = (TemplateInstances *)dmd_aaGetRvalue((AA *)instances, (void *)handle->toHash());
    if (tinstances)
    {
        for (size_t i = 0; i < tinstances->dim; i++)
        {
            TemplateInstance *ti = (*tinstances)[i];
            if (handle == ti)
            {
                tinstances->remove(i);
                break;
            }
        }
    }
}

/* ======================== Type ============================================ */

/****
 * Given an identifier, figure out which TemplateParameter it is.
 * Return IDX_NOTFOUND if not found.
 */

static size_t templateIdentifierLookup(Identifier *id, TemplateParameters *parameters)
{
    for (size_t i = 0; i < parameters->dim; i++)
    {
        TemplateParameter *tp = (*parameters)[i];
        if (tp->ident->equals(id))
            return i;
    }
    return IDX_NOTFOUND;
}

size_t templateParameterLookup(Type *tparam, TemplateParameters *parameters)
{
    if (tparam->ty == Tident)
    {
        TypeIdentifier *tident = (TypeIdentifier *)tparam;
        //printf("\ttident = '%s'\n", tident->toChars());
        return templateIdentifierLookup(tident->ident, parameters);
    }
    return IDX_NOTFOUND;
}

unsigned char deduceWildHelper(Type *t, Type **at, Type *tparam)
{
    if ((tparam->mod & MODwild) == 0)
        return 0;

    *at = NULL;

    #define X(U,T)  ((U) << 4) | (T)
    switch (X(tparam->mod, t->mod))
    {
        case X(MODwild,                     0):
        case X(MODwild,                     MODconst):
        case X(MODwild,                     MODshared):
        case X(MODwild,                     MODshared | MODconst):
        case X(MODwild,                     MODimmutable):
        case X(MODwildconst,                0):
        case X(MODwildconst,                MODconst):
        case X(MODwildconst,                MODshared):
        case X(MODwildconst,                MODshared | MODconst):
        case X(MODwildconst,                MODimmutable):
        case X(MODshared | MODwild,         MODshared):
        case X(MODshared | MODwild,         MODshared | MODconst):
        case X(MODshared | MODwild,         MODimmutable):
        case X(MODshared | MODwildconst,    MODshared):
        case X(MODshared | MODwildconst,    MODshared | MODconst):
        case X(MODshared | MODwildconst,    MODimmutable):
        {
            unsigned char wm = (t->mod & ~MODshared);
            if (wm == 0)
                wm = MODmutable;
            unsigned char m = (t->mod & (MODconst | MODimmutable)) | (tparam->mod & t->mod & MODshared);
            *at = t->unqualify(m);
            return wm;
        }

        case X(MODwild,                     MODwild):
        case X(MODwild,                     MODwildconst):
        case X(MODwild,                     MODshared | MODwild):
        case X(MODwild,                     MODshared | MODwildconst):
        case X(MODwildconst,                MODwild):
        case X(MODwildconst,                MODwildconst):
        case X(MODwildconst,                MODshared | MODwild):
        case X(MODwildconst,                MODshared | MODwildconst):
        case X(MODshared | MODwild,         MODshared | MODwild):
        case X(MODshared | MODwild,         MODshared | MODwildconst):
        case X(MODshared | MODwildconst,    MODshared | MODwild):
        case X(MODshared | MODwildconst,    MODshared | MODwildconst):
        {
            *at = t->unqualify(tparam->mod & t->mod);
            return MODwild;
        }

        default:
            return 0;
    }
    #undef X
}

MATCH deduceTypeHelper(Type *t, Type **at, Type *tparam)
{
    // 9*9 == 81 cases

    #define X(U,T)  ((U) << 4) | (T)
    switch (X(tparam->mod, t->mod))
    {
        case X(0, 0):
        case X(0, MODconst):
        case X(0, MODwild):
        case X(0, MODwildconst):
        case X(0, MODshared):
        case X(0, MODshared | MODconst):
        case X(0, MODshared | MODwild):
        case X(0, MODshared | MODwildconst):
        case X(0, MODimmutable):
            // foo(U)                       T                       => T
            // foo(U)                       const(T)                => const(T)
            // foo(U)                       inout(T)                => inout(T)
            // foo(U)                       inout(const(T))         => inout(const(T))
            // foo(U)                       shared(T)               => shared(T)
            // foo(U)                       shared(const(T))        => shared(const(T))
            // foo(U)                       shared(inout(T))        => shared(inout(T))
            // foo(U)                       shared(inout(const(T))) => shared(inout(const(T)))
            // foo(U)                       immutable(T)            => immutable(T)
        {
            *at = t;
            return MATCHexact;
        }

        case X(MODconst,                    MODconst):
        case X(MODwild,                     MODwild):
        case X(MODwildconst,                MODwildconst):
        case X(MODshared,                   MODshared):
        case X(MODshared | MODconst,        MODshared | MODconst):
        case X(MODshared | MODwild,         MODshared | MODwild):
        case X(MODshared | MODwildconst,    MODshared | MODwildconst):
        case X(MODimmutable,                MODimmutable):
            // foo(const(U))                const(T)                => T
            // foo(inout(U))                inout(T)                => T
            // foo(inout(const(U)))         inout(const(T))         => T
            // foo(shared(U))               shared(T)               => T
            // foo(shared(const(U)))        shared(const(T))        => T
            // foo(shared(inout(U)))        shared(inout(T))        => T
            // foo(shared(inout(const(U)))) shared(inout(const(T))) => T
            // foo(immutable(U))            immutable(T)            => T
        {
            *at = t->mutableOf()->unSharedOf();
            return MATCHexact;
        }

        case X(MODconst,                    0):
        case X(MODconst,                    MODwild):
        case X(MODconst,                    MODwildconst):
        case X(MODconst,                    MODshared | MODconst):
        case X(MODconst,                    MODshared | MODwild):
        case X(MODconst,                    MODshared | MODwildconst):
        case X(MODconst,                    MODimmutable):
        case X(MODwild,                     MODshared | MODwild):
        case X(MODwildconst,                MODshared | MODwildconst):
        case X(MODshared | MODconst,        MODimmutable):
            // foo(const(U))                T                       => T
            // foo(const(U))                inout(T)                => T
            // foo(const(U))                inout(const(T))         => T
            // foo(const(U))                shared(const(T))        => shared(T)
            // foo(const(U))                shared(inout(T))        => shared(T)
            // foo(const(U))                shared(inout(const(T))) => shared(T)
            // foo(const(U))                immutable(T)            => T
            // foo(inout(U))                shared(inout(T))        => shared(T)
            // foo(inout(const(U)))         shared(inout(const(T))) => shared(T)
            // foo(shared(const(U)))        immutable(T)            => T
        {
            *at = t->mutableOf();
            return MATCHconst;
        }

        case X(MODconst,                    MODshared):
            // foo(const(U))                shared(T)               => shared(T)
        {
            *at = t;
            return MATCHconst;
        }

        case X(MODshared,                   MODshared | MODconst):
        case X(MODshared,                   MODshared | MODwild):
        case X(MODshared,                   MODshared | MODwildconst):
        case X(MODshared | MODconst,        MODshared):
            // foo(shared(U))               shared(const(T))        => const(T)
            // foo(shared(U))               shared(inout(T))        => inout(T)
            // foo(shared(U))               shared(inout(const(T))) => inout(const(T))
            // foo(shared(const(U)))        shared(T)               => T
        {
            *at = t->unSharedOf();
            return MATCHconst;
        }

        case X(MODwildconst,                MODimmutable):
        case X(MODshared | MODconst,        MODshared | MODwildconst):
        case X(MODshared | MODwildconst,    MODimmutable):
        case X(MODshared | MODwildconst,    MODshared | MODwild):
            // foo(inout(const(U)))         immutable(T)            => T
            // foo(shared(const(U)))        shared(inout(const(T))) => T
            // foo(shared(inout(const(U)))) immutable(T)            => T
            // foo(shared(inout(const(U)))) shared(inout(T))        => T
        {
            *at = t->unSharedOf()->mutableOf();
            return MATCHconst;
        }

        case X(MODshared | MODconst,        MODshared | MODwild):
            // foo(shared(const(U)))        shared(inout(T))        => T
        {
            *at = t->unSharedOf()->mutableOf();
            return MATCHconst;
        }

        case X(MODwild,                     0):
        case X(MODwild,                     MODconst):
        case X(MODwild,                     MODwildconst):
        case X(MODwild,                     MODimmutable):
        case X(MODwild,                     MODshared):
        case X(MODwild,                     MODshared | MODconst):
        case X(MODwild,                     MODshared | MODwildconst):
        case X(MODwildconst,                0):
        case X(MODwildconst,                MODconst):
        case X(MODwildconst,                MODwild):
        case X(MODwildconst,                MODshared):
        case X(MODwildconst,                MODshared | MODconst):
        case X(MODwildconst,                MODshared | MODwild):
        case X(MODshared,                   0):
        case X(MODshared,                   MODconst):
        case X(MODshared,                   MODwild):
        case X(MODshared,                   MODwildconst):
        case X(MODshared,                   MODimmutable):
        case X(MODshared | MODconst,        0):
        case X(MODshared | MODconst,        MODconst):
        case X(MODshared | MODconst,        MODwild):
        case X(MODshared | MODconst,        MODwildconst):
        case X(MODshared | MODwild,         0):
        case X(MODshared | MODwild,         MODconst):
        case X(MODshared | MODwild,         MODwild):
        case X(MODshared | MODwild,         MODwildconst):
        case X(MODshared | MODwild,         MODimmutable):
        case X(MODshared | MODwild,         MODshared):
        case X(MODshared | MODwild,         MODshared | MODconst):
        case X(MODshared | MODwild,         MODshared | MODwildconst):
        case X(MODshared | MODwildconst,    0):
        case X(MODshared | MODwildconst,    MODconst):
        case X(MODshared | MODwildconst,    MODwild):
        case X(MODshared | MODwildconst,    MODwildconst):
        case X(MODshared | MODwildconst,    MODshared):
        case X(MODshared | MODwildconst,    MODshared | MODconst):
        case X(MODimmutable,                0):
        case X(MODimmutable,                MODconst):
        case X(MODimmutable,                MODwild):
        case X(MODimmutable,                MODwildconst):
        case X(MODimmutable,                MODshared):
        case X(MODimmutable,                MODshared | MODconst):
        case X(MODimmutable,                MODshared | MODwild):
        case X(MODimmutable,                MODshared | MODwildconst):
            // foo(inout(U))                T                       => nomatch
            // foo(inout(U))                const(T)                => nomatch
            // foo(inout(U))                inout(const(T))         => nomatch
            // foo(inout(U))                immutable(T)            => nomatch
            // foo(inout(U))                shared(T)               => nomatch
            // foo(inout(U))                shared(const(T))        => nomatch
            // foo(inout(U))                shared(inout(const(T))) => nomatch
            // foo(inout(const(U)))         T                       => nomatch
            // foo(inout(const(U)))         const(T)                => nomatch
            // foo(inout(const(U)))         inout(T)                => nomatch
            // foo(inout(const(U)))         shared(T)               => nomatch
            // foo(inout(const(U)))         shared(const(T))        => nomatch
            // foo(inout(const(U)))         shared(inout(T))        => nomatch
            // foo(shared(U))               T                       => nomatch
            // foo(shared(U))               const(T)                => nomatch
            // foo(shared(U))               inout(T)                => nomatch
            // foo(shared(U))               inout(const(T))         => nomatch
            // foo(shared(U))               immutable(T)            => nomatch
            // foo(shared(const(U)))        T                       => nomatch
            // foo(shared(const(U)))        const(T)                => nomatch
            // foo(shared(const(U)))        inout(T)                => nomatch
            // foo(shared(const(U)))        inout(const(T))         => nomatch
            // foo(shared(inout(U)))        T                       => nomatch
            // foo(shared(inout(U)))        const(T)                => nomatch
            // foo(shared(inout(U)))        inout(T)                => nomatch
            // foo(shared(inout(U)))        inout(const(T))         => nomatch
            // foo(shared(inout(U)))        immutable(T)            => nomatch
            // foo(shared(inout(U)))        shared(T)               => nomatch
            // foo(shared(inout(U)))        shared(const(T))        => nomatch
            // foo(shared(inout(U)))        shared(inout(const(T))) => nomatch
            // foo(shared(inout(const(U)))) T                       => nomatch
            // foo(shared(inout(const(U)))) const(T)                => nomatch
            // foo(shared(inout(const(U)))) inout(T)                => nomatch
            // foo(shared(inout(const(U)))) inout(const(T))         => nomatch
            // foo(shared(inout(const(U)))) shared(T)               => nomatch
            // foo(shared(inout(const(U)))) shared(const(T))        => nomatch
            // foo(immutable(U))            T                       => nomatch
            // foo(immutable(U))            const(T)                => nomatch
            // foo(immutable(U))            inout(T)                => nomatch
            // foo(immutable(U))            inout(const(T))         => nomatch
            // foo(immutable(U))            shared(T)               => nomatch
            // foo(immutable(U))            shared(const(T))        => nomatch
            // foo(immutable(U))            shared(inout(T))        => nomatch
            // foo(immutable(U))            shared(inout(const(T))) => nomatch
            return MATCHnomatch;

        default:
            assert(0);
            return MATCHnomatch; // silence compiler warning about missing return
    }
    #undef X
}

/* These form the heart of template argument deduction.
 * Given 'this' being the type argument to the template instance,
 * it is matched against the template declaration parameter specialization
 * 'tparam' to determine the type to be used for the parameter.
 * Example:
 *      template Foo(T:T*)      // template declaration
 *      Foo!(int*)              // template instantiation
 * Input:
 *      this = int*
 *      tparam = T*
 *      parameters = [ T:T* ]   // Array of TemplateParameter's
 * Output:
 *      dedtypes = [ int ]      // Array of Expression/Type's
 */
MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *parameters,
        Objects *dedtypes, unsigned *wm, size_t inferStart)
{
    class DeduceType : public Visitor
    {
    public:
        Scope *sc;
        Type *tparam;
        TemplateParameters *parameters;
        Objects *dedtypes;
        unsigned *wm;
        size_t inferStart;
        MATCH result;

        DeduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm, size_t inferStart)
            : sc(sc), tparam(tparam), parameters(parameters), dedtypes(dedtypes), wm(wm), inferStart(inferStart)
        {
            result = MATCHnomatch;
        }

        void visit(Type *t)
        {
            if (!tparam)
                goto Lnomatch;

            if (t == tparam)
                goto Lexact;

            if (tparam->ty == Tident)
            {
                // Determine which parameter tparam is
                size_t i = templateParameterLookup(tparam, parameters);
                if (i == IDX_NOTFOUND)
                {
                    if (!sc)
                        goto Lnomatch;

                    /* Need a loc to go with the semantic routine.
                     */
                    Loc loc;
                    if (parameters->dim)
                    {
                        TemplateParameter *tp = (*parameters)[0];
                        loc = tp->loc;
                    }

                    /* BUG: what if tparam is a template instance, that
                     * has as an argument another Tident?
                     */
                    tparam = tparam->semantic(loc, sc);
                    assert(tparam->ty != Tident);
                    result = deduceType(t, sc, tparam, parameters, dedtypes, wm);
                    return;
                }

                TemplateParameter *tp = (*parameters)[i];

                TypeIdentifier *tident = (TypeIdentifier *)tparam;
                if (tident->idents.dim > 0)
                {
                    //printf("matching %s to %s\n", tparam->toChars(), t->toChars());
                    Dsymbol *s = t->toDsymbol(sc);
                    for (size_t j = tident->idents.dim; j-- > 0; )
                    {
                        RootObject *id = tident->idents[j];
                        if (id->dyncast() == DYNCAST_IDENTIFIER)
                        {
                            if (!s || !s->parent)
                                goto Lnomatch;
                            Dsymbol *s2 = s->parent->search(Loc(), (Identifier *)id);
                            if (!s2)
                                goto Lnomatch;
                            s2 = s2->toAlias();
                            //printf("[%d] s = %s %s, s2 = %s %s\n", j, s->kind(), s->toChars(), s2->kind(), s2->toChars());
                            if (s != s2)
                            {
                                if (Type *tx = s2->getType())
                                {
                                    if (s != tx->toDsymbol(sc))
                                        goto Lnomatch;
                                }
                                else
                                    goto Lnomatch;
                            }
                            s = s->parent;
                        }
                        else
                            goto Lnomatch;
                    }
                    //printf("[e] s = %s\n", s?s->toChars():"(null)");
                    if (tp->isTemplateTypeParameter())
                    {
                        Type *tt = s->getType();
                        if (!tt)
                            goto Lnomatch;
                        Type *at = (Type *)(*dedtypes)[i];
                        if (at && at->ty == Tnone)
                            at = ((TypeDeduced *)at)->tded;
                        if (!at || tt->equals(at))
                        {
                            (*dedtypes)[i] = tt;
                            goto Lexact;
                        }
                    }
                    if (tp->isTemplateAliasParameter())
                    {
                        Dsymbol *s2 = (Dsymbol *)(*dedtypes)[i];
                        if (!s2 || s == s2)
                        {
                            (*dedtypes)[i] = s;
                            goto Lexact;
                        }
                    }
                    goto Lnomatch;
                }

                // Found the corresponding parameter tp
                if (!tp->isTemplateTypeParameter())
                    goto Lnomatch;

                Type *at = (Type *)(*dedtypes)[i];
                Type *tt;
                if (unsigned char wx = wm ? deduceWildHelper(t, &tt, tparam) : 0)
                {
                    // type vs (none)
                    if (!at)
                    {
                        (*dedtypes)[i] = tt;
                        *wm |= wx;
                        result = MATCHconst;
                        return;
                    }

                    // type vs expressions
                    if (at->ty == Tnone)
                    {
                        TypeDeduced *xt = (TypeDeduced *)at;
                        result = xt->matchAll(tt);
                        if (result > MATCHnomatch)
                        {
                            (*dedtypes)[i] = tt;
                            if (result > MATCHconst)
                                result = MATCHconst;    // limit level for inout matches
                            delete xt;
                        }
                        return;
                    }

                    // type vs type
                    if (tt->equals(at))
                    {
                        (*dedtypes)[i] = tt;    // Prefer current type match
                        goto Lconst;
                    }
                    if (tt->implicitConvTo(at->constOf()))
                    {
                        (*dedtypes)[i] = at->constOf()->mutableOf();
                        *wm |= MODconst;
                        goto Lconst;
                    }
                    if (at->implicitConvTo(tt->constOf()))
                    {
                        (*dedtypes)[i] = tt->constOf()->mutableOf();
                        *wm |= MODconst;
                        goto Lconst;
                    }
                    goto Lnomatch;
                }
                else if (MATCH m = deduceTypeHelper(t, &tt, tparam))
                {
                    // type vs (none)
                    if (!at)
                    {
                        (*dedtypes)[i] = tt;
                        result = m;
                        return;
                    }

                    // type vs expressions
                    if (at->ty == Tnone)
                    {
                        TypeDeduced *xt = (TypeDeduced *)at;
                        result = xt->matchAll(tt);
                        if (result > MATCHnomatch)
                        {
                            (*dedtypes)[i] = tt;
                            delete xt;
                        }
                        return;
                    }

                    // type vs type
                    if (tt->equals(at))
                    {
                        goto Lexact;
                    }
                    if (tt->ty == Tclass && at->ty == Tclass)
                    {
                        result = tt->implicitConvTo(at);
                        return;
                    }
                    if (tt->ty == Tsarray && at->ty == Tarray &&
                        tt->nextOf()->implicitConvTo(at->nextOf()) >= MATCHconst)
                    {
                        goto Lexact;
                    }
                }
                goto Lnomatch;
            }

            if (tparam->ty == Ttypeof)
            {
                /* Need a loc to go with the semantic routine.
                 */
                Loc loc;
                if (parameters->dim)
                {
                    TemplateParameter *tp = (*parameters)[0];
                    loc = tp->loc;
                }

                tparam = tparam->semantic(loc, sc);
            }
            if (t->ty != tparam->ty)
            {
                if (Dsymbol *sym = t->toDsymbol(sc))
                {
                    if (sym->isforwardRef() && !tparam->deco)
                        goto Lnomatch;
                }

                MATCH m = t->implicitConvTo(tparam);
                if (m == MATCHnomatch)
                {
                    if (t->ty == Tclass)
                    {
                        TypeClass *tc = (TypeClass *)t;
                        if (tc->sym->aliasthis && !(tc->att & RECtracingDT))
                        {
                            tc->att = (AliasThisRec)(tc->att | RECtracingDT);
                            m = deduceType(t->aliasthisOf(), sc, tparam, parameters, dedtypes, wm);
                            tc->att = (AliasThisRec)(tc->att & ~RECtracingDT);
                        }
                    }
                    else if (t->ty == Tstruct)
                    {
                        TypeStruct *ts = (TypeStruct *)t;
                        if (ts->sym->aliasthis && !(ts->att & RECtracingDT))
                        {
                            ts->att = (AliasThisRec)(ts->att | RECtracingDT);
                            m = deduceType(t->aliasthisOf(), sc, tparam, parameters, dedtypes, wm);
                            ts->att = (AliasThisRec)(ts->att & ~RECtracingDT);
                        }
                    }
                }
                result = m;
                return;
            }

            if (t->nextOf())
            {
                if (tparam->deco && !tparam->hasWild())
                {
                    result = t->implicitConvTo(tparam);
                    return;
                }

                Type *tpn = tparam->nextOf();
                if (wm && t->ty == Taarray && tparam->isWild())
                {
                    // Bugzilla 12403: In IFTI, stop inout matching on transitive part of AA types.
                    tpn = tpn->substWildTo(MODmutable);
                }

                result = deduceType(t->nextOf(), sc, tpn, parameters, dedtypes, wm);
                return;
            }

        Lexact:
            result = MATCHexact;
            return;

        Lnomatch:
            result = MATCHnomatch;
            return;

        Lconst:
            result = MATCHconst;
        }

        void visit(TypeVector *t)
        {
            if (tparam->ty == Tvector)
            {
                TypeVector *tp = (TypeVector *)tparam;
                result = deduceType(t->basetype, sc, tp->basetype, parameters, dedtypes, wm);
                return;
            }
            visit((Type *)t);
        }

        void visit(TypeDArray *t)
        {
            visit((Type *)t);
        }

        void visit(TypeSArray *t)
        {
            // Extra check that array dimensions must match
            if (tparam)
            {
                if (tparam->ty == Tarray)
                {
                    MATCH m = deduceType(t->next, sc, tparam->nextOf(), parameters, dedtypes, wm);
                    result = (m >= MATCHconst) ? MATCHconvert : MATCHnomatch;
                    return;
                }

                TemplateParameter *tp = NULL;
                Expression *edim = NULL;
                size_t i;
                if (tparam->ty == Tsarray)
                {
                    TypeSArray *tsa = (TypeSArray *)tparam;
                    if (tsa->dim->op == TOKvar &&
                        ((VarExp *)tsa->dim)->var->storage_class & STCtemplateparameter)
                    {
                        Identifier *id = ((VarExp *)tsa->dim)->var->ident;
                        i = templateIdentifierLookup(id, parameters);
                        assert(i != IDX_NOTFOUND);
                        tp = (*parameters)[i];
                    }
                    else
                        edim = tsa->dim;
                }
                else if (tparam->ty == Taarray)
                {
                    TypeAArray *taa = (TypeAArray *)tparam;
                    i = templateParameterLookup(taa->index, parameters);
                    if (i != IDX_NOTFOUND)
                        tp = (*parameters)[i];
                    else
                    {
                        Expression *e;
                        Type *tx;
                        Dsymbol *s;
                        taa->index->resolve(Loc(), sc, &e, &tx, &s);
                        edim = s ? getValue(s) : getValue(e);
                    }
                }
                if ((tp && tp->matchArg(sc, t->dim, i, parameters, dedtypes, NULL)) ||
                    (edim && edim->toInteger() == t->dim->toInteger()))
                {
                    result = deduceType(t->next, sc, tparam->nextOf(), parameters, dedtypes, wm);
                    return;
                }
            }
            visit((Type *)t);
            return;

            result = MATCHnomatch;
        }

        void visit(TypeAArray *t)
        {
            // Extra check that index type must match
            if (tparam && tparam->ty == Taarray)
            {
                TypeAArray *tp = (TypeAArray *)tparam;
                if (!deduceType(t->index, sc, tp->index, parameters, dedtypes))
                {
                    result = MATCHnomatch;
                    return;
                }
            }
            visit((Type *)t);
        }

        void visit(TypeFunction *t)
        {
            //printf("TypeFunction::deduceType()\n");
            //printf("\tthis   = %d, ", t->ty); t->print();
            //printf("\ttparam = %d, ", tparam->ty); tparam->print();

            // Extra check that function characteristics must match
            if (tparam && tparam->ty == Tfunction)
            {
                TypeFunction *tp = (TypeFunction *)tparam;
                if (t->varargs != tp->varargs ||
                    t->linkage != tp->linkage)
                {
                    result = MATCHnomatch;
                    return;
                }

                size_t nfargs = Parameter::dim(t->parameters);
                size_t nfparams = Parameter::dim(tp->parameters);

                // bug 2579 fix: Apply function parameter storage classes to parameter types
                for (size_t i = 0; i < nfparams; i++)
                {
                    Parameter *fparam = Parameter::getNth(tp->parameters, i);
                    fparam->type = fparam->type->addStorageClass(fparam->storageClass);
                    fparam->storageClass &= ~(STC_TYPECTOR | STCin);
                }
                //printf("\t-> this   = %d, ", t->ty); t->print();
                //printf("\t-> tparam = %d, ", tparam->ty); tparam->print();

                /* See if tuple match
                 */
                if (nfparams > 0 && nfargs >= nfparams - 1)
                {
                    /* See if 'A' of the template parameter matches 'A'
                     * of the type of the last function parameter.
                     */
                    Parameter *fparam = Parameter::getNth(tp->parameters, nfparams - 1);
                    assert(fparam);
                    assert(fparam->type);
                    if (fparam->type->ty != Tident)
                        goto L1;
                    TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
                    if (tid->idents.dim)
                        goto L1;

                    /* Look through parameters to find tuple matching tid->ident
                     */
                    size_t tupi = 0;
                    for (; 1; tupi++)
                    {
                        if (tupi == parameters->dim)
                            goto L1;
                        TemplateParameter *tx = (*parameters)[tupi];
                        TemplateTupleParameter *tup = tx->isTemplateTupleParameter();
                        if (tup && tup->ident->equals(tid->ident))
                            break;
                    }

                    /* The types of the function arguments [nfparams - 1 .. nfargs]
                     * now form the tuple argument.
                     */
                    size_t tuple_dim = nfargs - (nfparams - 1);

                    /* See if existing tuple, and whether it matches or not
                     */
                    RootObject *o = (*dedtypes)[tupi];
                    if (o)
                    {
                        // Existing deduced argument must be a tuple, and must match
                        Tuple *tup = isTuple(o);
                        if (!tup || tup->objects.dim != tuple_dim)
                        {
                            result = MATCHnomatch;
                            return;
                        }
                        for (size_t i = 0; i < tuple_dim; i++)
                        {
                            Parameter *arg = Parameter::getNth(t->parameters, nfparams - 1 + i);
                            if (!arg->type->equals(tup->objects[i]))
                            {
                                result = MATCHnomatch;
                                return;
                            }
                        }
                    }
                    else
                    {
                        // Create new tuple
                        Tuple *tup = new Tuple();
                        tup->objects.setDim(tuple_dim);
                        for (size_t i = 0; i < tuple_dim; i++)
                        {
                            Parameter *arg = Parameter::getNth(t->parameters, nfparams - 1 + i);
                            tup->objects[i] = arg->type;
                        }
                        (*dedtypes)[tupi] = tup;
                    }
                    nfparams--; // don't consider the last parameter for type deduction
                    goto L2;
                }

            L1:
                if (nfargs != nfparams)
                {
                    result = MATCHnomatch;
                    return;
                }
            L2:
                for (size_t i = 0; i < nfparams; i++)
                {
                    Parameter *a = Parameter::getNth(t->parameters, i);
                    Parameter *ap = Parameter::getNth(tp->parameters, i);

                    if (!a->isCovariant(t->isref, ap) ||
                        !deduceType(a->type, sc, ap->type, parameters, dedtypes))
                    {
                        result = MATCHnomatch;
                        return;
                    }
                }
            }
            visit((Type *)t);
        }

        void visit(TypeIdentifier *t)
        {
            // Extra check
            if (tparam && tparam->ty == Tident)
            {
                TypeIdentifier *tp = (TypeIdentifier *)tparam;

                for (size_t i = 0; i < t->idents.dim; i++)
                {
                    RootObject *id1 = t->idents[i];
                    RootObject *id2 = tp->idents[i];

                    if (!id1->equals(id2))
                    {
                        result = MATCHnomatch;
                        return;
                    }
                }
            }
            visit((Type *)t);
        }

        void visit(TypeInstance *t)
        {
            // Extra check
            if (tparam && tparam->ty == Tinstance && t->tempinst->tempdecl)
            {
                TemplateDeclaration *tempdecl = t->tempinst->tempdecl->isTemplateDeclaration();
                assert(tempdecl);

                TypeInstance *tp = (TypeInstance *)tparam;

                //printf("tempinst->tempdecl = %p\n", tempdecl);
                //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl);
                if (!tp->tempinst->tempdecl)
                {
                    //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars());

                    /* Handle case of:
                     *  template Foo(T : sa!(T), alias sa)
                     */
                    size_t i = templateIdentifierLookup(tp->tempinst->name, parameters);
                    if (i == IDX_NOTFOUND)
                    {
                        /* Didn't find it as a parameter identifier. Try looking
                         * it up and seeing if is an alias. See Bugzilla 1454
                         */
                        TypeIdentifier *tid = new TypeIdentifier(tp->loc, tp->tempinst->name);
                        Type *tx;
                        Expression *e;
                        Dsymbol *s;
                        tid->resolve(tp->loc, sc, &e, &tx, &s);
                        if (tx)
                        {
                            s = tx->toDsymbol(sc);
                            if (TemplateInstance *ti = s ? s->parent->isTemplateInstance() : NULL)
                            {
                                // Bugzilla 14290: Try to match with ti->tempecl,
                                // only when ti is an enclosing instance.
                                Dsymbol *p = sc->parent;
                                while (p && p != ti)
                                    p = p->parent;
                                if (p)
                                    s = ti->tempdecl;
                            }
                        }
                        if (s)
                        {
                            s = s->toAlias();
                            TemplateDeclaration *td = s->isTemplateDeclaration();
                            if (td)
                            {
                                if (td->overroot)
                                    td = td->overroot;
                                for (; td; td = td->overnext)
                                {
                                    if (td == tempdecl)
                                        goto L2;
                                }
                            }
                        }
                        goto Lnomatch;
                    }
                    TemplateParameter *tpx = (*parameters)[i];
                    if (!tpx->matchArg(sc, tempdecl, i, parameters, dedtypes, NULL))
                        goto Lnomatch;
                }
                else if (tempdecl != tp->tempinst->tempdecl)
                    goto Lnomatch;

              L2:

                for (size_t i = 0; 1; i++)
                {
                    //printf("\ttest: tempinst->tiargs[%d]\n", i);
                    RootObject *o1 = NULL;
                    if (i < t->tempinst->tiargs->dim)
                        o1 = (*t->tempinst->tiargs)[i];
                    else if (i < t->tempinst->tdtypes.dim && i < tp->tempinst->tiargs->dim)
                    {
                        // Pick up default arg
                        o1 = t->tempinst->tdtypes[i];
                    }
                    else if (i >= tp->tempinst->tiargs->dim)
                        break;

                    if (i >= tp->tempinst->tiargs->dim)
                    {
                        size_t dim = tempdecl->parameters->dim - (tempdecl->isVariadic() ? 1 : 0);
                        while (i < dim && ((*tempdecl->parameters)[i]->dependent ||
                                           (*tempdecl->parameters)[i]->hasDefaultArg()))
                        {
                            i++;
                        }
                        if (i >= dim)
                            break;  // match if all remained parameters are dependent
                        goto Lnomatch;
                    }

                    RootObject *o2 = (*tp->tempinst->tiargs)[i];
                    Type *t2 = isType(o2);

                    size_t j = (t2 && t2->ty == Tident && i == tp->tempinst->tiargs->dim - 1)
                        ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
                    if (j != IDX_NOTFOUND && j == parameters->dim - 1 &&
                        (*parameters)[j]->isTemplateTupleParameter())
                    {
                        /* Given:
                         *  struct A(B...) {}
                         *  alias A!(int, float) X;
                         *  static if (is(X Y == A!(Z), Z...)) {}
                         * deduce that Z is a tuple(int, float)
                         */

                        /* Create tuple from remaining args
                         */
                        Tuple *vt = new Tuple();
                        size_t vtdim = (tempdecl->isVariadic()
                                        ? t->tempinst->tiargs->dim : t->tempinst->tdtypes.dim) - i;
                        vt->objects.setDim(vtdim);
                        for (size_t k = 0; k < vtdim; k++)
                        {
                            RootObject *o;
                            if (k < t->tempinst->tiargs->dim)
                                o = (*t->tempinst->tiargs)[i + k];
                            else    // Pick up default arg
                                o = t->tempinst->tdtypes[i + k];
                            vt->objects[k] = o;
                        }

                        Tuple *v = (Tuple *)(*dedtypes)[j];
                        if (v)
                        {
                            if (!match(v, vt))
                                goto Lnomatch;
                        }
                        else
                            (*dedtypes)[j] = vt;
                        break;
                    }
                    else if (!o1)
                        break;

                    Type *t1 = isType(o1);
                    Dsymbol *s1 = isDsymbol(o1);
                    Dsymbol *s2 = isDsymbol(o2);
                    Expression *e1 = s1 ? getValue(s1) : getValue(isExpression(o1));
                    Expression *e2 = isExpression(o2);

                    if (t1 && t2)
                    {
                        if (!deduceType(t1, sc, t2, parameters, dedtypes))
                            goto Lnomatch;
                    }
                    else if (e1 && e2)
                    {
                    Le:
                        e1 = e1->ctfeInterpret();

                        /* If it is one of the template parameters for this template,
                         * we should not attempt to interpret it. It already has a value.
                         */
                        if (e2->op == TOKvar &&
                            (((VarExp *)e2)->var->storage_class & STCtemplateparameter))
                        {
                            /*
                             * (T:Number!(e2), int e2)
                             */
                            j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters);
                            if (j != IDX_NOTFOUND)
                                goto L1;
                            // The template parameter was not from this template
                            // (it may be from a parent template, for example)
                        }

                        e2 = ::semantic(e2, sc);      // Bugzilla 13417
                        e2 = e2->ctfeInterpret();

                        //printf("e1 = %s, type = %s %d\n", e1->toChars(), e1->type->toChars(), e1->type->ty);
                        //printf("e2 = %s, type = %s %d\n", e2->toChars(), e2->type->toChars(), e2->type->ty);
                        if (!e1->equals(e2))
                        {
                            if (!e2->implicitConvTo(e1->type))
                                goto Lnomatch;

                            e2 = e2->implicitCastTo(sc, e1->type);
                            e2 = e2->ctfeInterpret();
                            if (!e1->equals(e2))
                                goto Lnomatch;
                        }
                    }
                    else if (e1 && t2 && t2->ty == Tident)
                    {
                        j = templateParameterLookup(t2, parameters);
                    L1:
                        if (j == IDX_NOTFOUND)
                        {
                            t2->resolve(((TypeIdentifier *)t2)->loc, sc, &e2, &t2, &s2);
                            if (e2)
                                goto Le;
                            goto Lnomatch;
                        }
                        if (!(*parameters)[j]->matchArg(sc, e1, j, parameters, dedtypes, NULL))
                            goto Lnomatch;
                    }
                    else if (s1 && s2)
                    {
                    Ls:
                        if (!s1->equals(s2))
                            goto Lnomatch;
                    }
                    else if (s1 && t2 && t2->ty == Tident)
                    {
                        j = templateParameterLookup(t2, parameters);
                        if (j == IDX_NOTFOUND)
                        {
                            t2->resolve(((TypeIdentifier *)t2)->loc, sc, &e2, &t2, &s2);
                            if (s2)
                                goto Ls;
                            goto Lnomatch;
                        }
                        if (!(*parameters)[j]->matchArg(sc, s1, j, parameters, dedtypes, NULL))
                            goto Lnomatch;
                    }
                    else
                        goto Lnomatch;
                }
            }
            visit((Type *)t);
            return;

        Lnomatch:
            //printf("no match\n");
            result = MATCHnomatch;
        }

        void visit(TypeStruct *t)
        {
            /* If this struct is a template struct, and we're matching
             * it against a template instance, convert the struct type
             * to a template instance, too, and try again.
             */
            TemplateInstance *ti = t->sym->parent->isTemplateInstance();

            if (tparam && tparam->ty == Tinstance)
            {
                if (ti && ti->toAlias() == t->sym)
                {
                    TypeInstance *tx = new TypeInstance(Loc(), ti);
                    result = deduceType(tx, sc, tparam, parameters, dedtypes, wm);
                    return;
                }

                /* Match things like:
                 *  S!(T).foo
                 */
                TypeInstance *tpi = (TypeInstance *)tparam;
                if (tpi->idents.dim)
                {
                    RootObject *id = tpi->idents[tpi->idents.dim - 1];
                    if (id->dyncast() == DYNCAST_IDENTIFIER && t->sym->ident->equals((Identifier *)id))
                    {
                        Type *tparent = t->sym->parent->getType();
                        if (tparent)
                        {
                            /* Slice off the .foo in S!(T).foo
                             */
                            tpi->idents.dim--;
                            result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm);
                            tpi->idents.dim++;
                            return;
                        }
                    }
                }
            }

            // Extra check
            if (tparam && tparam->ty == Tstruct)
            {
                TypeStruct *tp = (TypeStruct *)tparam;

                //printf("\t%d\n", (MATCH) t->implicitConvTo(tp));
                if (wm && t->deduceWild(tparam, false))
                {
                    result = MATCHconst;
                    return;
                }
                result = t->implicitConvTo(tp);
                return;
            }
            visit((Type *)t);
        }

        void visit(TypeEnum *t)
        {
            // Extra check
            if (tparam && tparam->ty == Tenum)
            {
                TypeEnum *tp = (TypeEnum *)tparam;
                if (t->sym == tp->sym)
                    visit((Type *)t);
                else
                    result = MATCHnomatch;
                return;
            }
            Type *tb = t->toBasetype();
            if (tb->ty == tparam->ty ||
                (tb->ty == Tsarray && tparam->ty == Taarray))
            {
                result = deduceType(tb, sc, tparam, parameters, dedtypes, wm);
                return;
            }
            visit((Type *)t);
        }

        /* Helper for TypeClass::deduceType().
         * Classes can match with implicit conversion to a base class or interface.
         * This is complicated, because there may be more than one base class which
         * matches. In such cases, one or more parameters remain ambiguous.
         * For example,
         *
         *   interface I(X, Y) {}
         *   class C : I(uint, double), I(char, double) {}
         *   C x;
         *   foo(T, U)( I!(T, U) x)
         *
         *   deduces that U is double, but T remains ambiguous (could be char or uint).
         *
         * Given a baseclass b, and initial deduced types 'dedtypes', this function
         * tries to match tparam with b, and also tries all base interfaces of b.
         * If a match occurs, numBaseClassMatches is incremented, and the new deduced
         * types are ANDed with the current 'best' estimate for dedtypes.
         */
        static void deduceBaseClassParameters(BaseClass *b,
            Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes,
            Objects *best, int &numBaseClassMatches)
        {
            TemplateInstance *parti = b->sym ? b->sym->parent->isTemplateInstance() : NULL;
            if (parti)
            {
                // Make a temporary copy of dedtypes so we don't destroy it
                Objects *tmpdedtypes = new Objects();
                tmpdedtypes->setDim(dedtypes->dim);
                memcpy(tmpdedtypes->tdata(), dedtypes->tdata(), dedtypes->dim * sizeof(void *));

                TypeInstance *t = new TypeInstance(Loc(), parti);
                MATCH m = deduceType(t, sc, tparam, parameters, tmpdedtypes);
                if (m > MATCHnomatch)
                {
                    // If this is the first ever match, it becomes our best estimate
                    if (numBaseClassMatches==0)
                        memcpy(best->tdata(), tmpdedtypes->tdata(), tmpdedtypes->dim * sizeof(void *));
                    else for (size_t k = 0; k < tmpdedtypes->dim; ++k)
                    {
                        // If we've found more than one possible type for a parameter,
                        // mark it as unknown.
                        if ((*tmpdedtypes)[k] != (*best)[k])
                            (*best)[k] = (*dedtypes)[k];
                    }
                    ++numBaseClassMatches;
                }
            }
            // Now recursively test the inherited interfaces
            for (size_t j = 0; j < b->baseInterfaces.length; ++j)
            {
                BaseClass *bi = &b->baseInterfaces.ptr[j];
                deduceBaseClassParameters(bi,
                    sc, tparam, parameters, dedtypes,
                    best, numBaseClassMatches);
            }

        }

        void visit(TypeClass *t)
        {
            //printf("TypeClass::deduceType(this = %s)\n", t->toChars());

            /* If this class is a template class, and we're matching
             * it against a template instance, convert the class type
             * to a template instance, too, and try again.
             */
            TemplateInstance *ti = t->sym->parent->isTemplateInstance();

            if (tparam && tparam->ty == Tinstance)
            {
                if (ti && ti->toAlias() == t->sym)
                {
                    TypeInstance *tx = new TypeInstance(Loc(), ti);
                    MATCH m = deduceType(tx, sc, tparam, parameters, dedtypes, wm);
                    // Even if the match fails, there is still a chance it could match
                    // a base class.
                    if (m != MATCHnomatch)
                    {
                        result = m;
                        return;
                    }
                }

                /* Match things like:
                 *  S!(T).foo
                 */
                TypeInstance *tpi = (TypeInstance *)tparam;
                if (tpi->idents.dim)
                {
                    RootObject *id = tpi->idents[tpi->idents.dim - 1];
                    if (id->dyncast() == DYNCAST_IDENTIFIER && t->sym->ident->equals((Identifier *)id))
                    {
                        Type *tparent = t->sym->parent->getType();
                        if (tparent)
                        {
                            /* Slice off the .foo in S!(T).foo
                             */
                            tpi->idents.dim--;
                            result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm);
                            tpi->idents.dim++;
                            return;
                        }
                    }
                }

                // If it matches exactly or via implicit conversion, we're done
                visit((Type *)t);
                if (result != MATCHnomatch)
                    return;

                /* There is still a chance to match via implicit conversion to
                 * a base class or interface. Because there could be more than one such
                 * match, we need to check them all.
                 */

                int numBaseClassMatches = 0; // Have we found an interface match?

                // Our best guess at dedtypes
                Objects *best = new Objects();
                best->setDim(dedtypes->dim);

                ClassDeclaration *s = t->sym;
                while (s && s->baseclasses->dim > 0)
                {
                    // Test the base class
                    deduceBaseClassParameters((*s->baseclasses)[0],
                        sc, tparam, parameters, dedtypes,
                        best, numBaseClassMatches);

                    // Test the interfaces inherited by the base class
                    for (size_t i = 0; i < s->interfaces.length; ++i)
                    {
                        BaseClass *b = s->interfaces.ptr[i];
                        deduceBaseClassParameters(b, sc, tparam, parameters, dedtypes,
                            best, numBaseClassMatches);
                    }
                    s = (*s->baseclasses)[0]->sym;
                }

                if (numBaseClassMatches == 0)
                {
                    result = MATCHnomatch;
                    return;
                }

                // If we got at least one match, copy the known types into dedtypes
                memcpy(dedtypes->tdata(), best->tdata(), best->dim * sizeof(void *));
                result = MATCHconvert;
                return;
            }

            // Extra check
            if (tparam && tparam->ty == Tclass)
            {
                TypeClass *tp = (TypeClass *)tparam;

                //printf("\t%d\n", (MATCH) t->implicitConvTo(tp));
                if (wm && t->deduceWild(tparam, false))
                {
                    result = MATCHconst;
                    return;
                }
                result = t->implicitConvTo(tp);
                return;
            }
            visit((Type *)t);
        }

        void visit(Expression *e)
        {
            //printf("Expression::deduceType(e = %s)\n", e->toChars());
            size_t i = templateParameterLookup(tparam, parameters);
            if (i == IDX_NOTFOUND || ((TypeIdentifier *)tparam)->idents.dim > 0)
            {
                if (e == emptyArrayElement && tparam->ty == Tarray)
                {
                    Type *tn = ((TypeNext *)tparam)->next;
                    result = deduceType(emptyArrayElement, sc, tn, parameters, dedtypes, wm);
                    return;
                }
                e->type->accept(this);
                return;
            }

            TemplateTypeParameter *tp = (*parameters)[i]->isTemplateTypeParameter();
            if (!tp)
                return; // nomatch

            if (e == emptyArrayElement)
            {
                if ((*dedtypes)[i])
                {
                    result = MATCHexact;
                    return;
                }
                if (tp->defaultType)
                {
                    tp->defaultType->accept(this);
                    return;
                }
            }

            Type *at = (Type *)(*dedtypes)[i];
            Type *tt;
            if (unsigned char wx = deduceWildHelper(e->type, &tt, tparam))
            {
                *wm |= wx;
                result = MATCHconst;
            }
            else if (MATCH m = deduceTypeHelper(e->type, &tt, tparam))
            {
                result = m;
            }
            else
                return; // nomatch

            // expression vs (none)
            if (!at)
            {
                (*dedtypes)[i] = new TypeDeduced(tt, e, tparam);
                return;
            }

            TypeDeduced *xt = NULL;
            if (at->ty == Tnone)
            {
                xt = (TypeDeduced *)at;
                at = xt->tded;
            }

            // From previous matched expressions to current deduced type
            MATCH match1 = xt ? xt->matchAll(tt) : MATCHnomatch;

            // From current expresssion to previous deduced type
            Type *pt = at->addMod(tparam->mod);
            if (*wm)
                pt = pt->substWildTo(*wm);
            MATCH match2 = e->implicitConvTo(pt);

            if (match1 > MATCHnomatch && match2 > MATCHnomatch)
            {
                if (at->implicitConvTo(tt) <= MATCHnomatch)
                    match1 = MATCHnomatch;  // Prefer at
                else if (tt->implicitConvTo(at) <= MATCHnomatch)
                    match2 = MATCHnomatch;  // Prefer tt
                else if (tt->isTypeBasic() && tt->ty == at->ty && tt->mod != at->mod)
                {
                    if (!tt->isMutable() && !at->isMutable())
                        tt = tt->mutableOf()->addMod(MODmerge(tt->mod, at->mod));
                    else if (tt->isMutable())
                    {
                        if (at->mod == 0)   // Prefer unshared
                            match1 = MATCHnomatch;
                        else
                            match2 = MATCHnomatch;
                    }
                    else if (at->isMutable())
                    {
                        if (tt->mod == 0)   // Prefer unshared
                            match2 = MATCHnomatch;
                        else
                            match1 = MATCHnomatch;
                    }
                    //printf("tt = %s, at = %s\n", tt->toChars(), at->toChars());
                }
                else
                {
                    match1 = MATCHnomatch;
                    match2 = MATCHnomatch;
                }
            }
            if (match1 > MATCHnomatch)
            {
                // Prefer current match: tt
                if (xt)
                    xt->update(tt, e, tparam);
                else
                    (*dedtypes)[i] = tt;
                result = match1;
                return;
            }
            if (match2 > MATCHnomatch)
            {
                // Prefer previous match: (*dedtypes)[i]
                if (xt)
                    xt->update(e, tparam);
                result = match2;
                return;
            }

            /* Deduce common type
             */
            if (Type *t = rawTypeMerge(at, tt))
            {
                if (xt)
                    xt->update(t, e, tparam);
                else
                    (*dedtypes)[i] = t;

                pt = tt->addMod(tparam->mod);
                if (*wm)
                    pt = pt->substWildTo(*wm);
                result = e->implicitConvTo(pt);
                return;
            }

            result = MATCHnomatch;
        }

        MATCH deduceEmptyArrayElement()
        {
            if (!emptyArrayElement)
            {
                emptyArrayElement = new IdentifierExp(Loc(), Id::p);    // dummy
                emptyArrayElement->type = Type::tvoid;
            }
            assert(tparam->ty == Tarray);

            Type *tn = ((TypeNext *)tparam)->next;
            return deduceType(emptyArrayElement, sc, tn, parameters, dedtypes, wm);
        }

        void visit(NullExp *e)
        {
            if (tparam->ty == Tarray && e->type->ty == Tnull)
            {
                // tparam:T[] <- e:null (void[])
                result = deduceEmptyArrayElement();
                return;
            }
            visit((Expression *)e);
        }

        void visit(StringExp *e)
        {
            Type *taai;
            if (e->type->ty == Tarray &&
                (tparam->ty == Tsarray ||
                 (tparam->ty == Taarray && (taai = ((TypeAArray *)tparam)->index)->ty == Tident &&
                  ((TypeIdentifier *)taai)->idents.dim == 0)))
            {
                // Consider compile-time known boundaries
                e->type->nextOf()->sarrayOf(e->len)->accept(this);
                return;
            }
            visit((Expression *)e);
        }

        void visit(ArrayLiteralExp *e)
        {
            if ((!e->elements || !e->elements->dim) &&
                e->type->toBasetype()->nextOf()->ty == Tvoid &&
                tparam->ty == Tarray)
            {
                // tparam:T[] <- e:[] (void[])
                result = deduceEmptyArrayElement();
                return;
            }

            if (tparam->ty == Tarray && e->elements && e->elements->dim)
            {
                Type *tn = ((TypeDArray *)tparam)->next;
                result = MATCHexact;
                if (e->basis)
                {
                    MATCH m = deduceType(e->basis, sc, tn, parameters, dedtypes, wm);
                    if (m < result)
                        result = m;
                }
                for (size_t i = 0; i < e->elements->dim; i++)
                {
                    if (result <= MATCHnomatch)
                        break;
                    Expression *el = (*e->elements)[i];
                    if (!el)
                        continue;
                    MATCH m = deduceType(el, sc, tn, parameters, dedtypes, wm);
                    if (m < result)
                        result = m;
                }
                return;
            }

            Type *taai;
            if (e->type->ty == Tarray &&
                (tparam->ty == Tsarray ||
                 (tparam->ty == Taarray && (taai = ((TypeAArray *)tparam)->index)->ty == Tident &&
                  ((TypeIdentifier *)taai)->idents.dim == 0)))
            {
                // Consider compile-time known boundaries
                e->type->nextOf()->sarrayOf(e->elements->dim)->accept(this);
                return;
            }
            visit((Expression *)e);
        }

        void visit(AssocArrayLiteralExp *e)
        {
            if (tparam->ty == Taarray && e->keys && e->keys->dim)
            {
                TypeAArray *taa = (TypeAArray *)tparam;
                result = MATCHexact;
                for (size_t i = 0; i < e->keys->dim; i++)
                {
                    MATCH m1 = deduceType((*e->keys)[i], sc, taa->index, parameters, dedtypes, wm);
                    if (m1 < result)
                        result = m1;
                    if (result <= MATCHnomatch)
                        break;
                    MATCH m2 = deduceType((*e->values)[i], sc, taa->next, parameters, dedtypes, wm);
                    if (m2 < result)
                        result = m2;
                    if (result <= MATCHnomatch)
                        break;
                }
                return;
            }
            visit((Expression *)e);
        }

        void visit(FuncExp *e)
        {
            //printf("e->type = %s, tparam = %s\n", e->type->toChars(), tparam->toChars());
            if (e->td)
            {
                Type *to = tparam;
                if (!to->nextOf() || to->nextOf()->ty != Tfunction)
                    return;
                TypeFunction *tof = (TypeFunction *)to->nextOf();

                // Parameter types inference from 'tof'
                assert(e->td->_scope);
                TypeFunction *tf = (TypeFunction *)e->fd->type;
                //printf("\ttof = %s\n", tof->toChars());
                //printf("\ttf  = %s\n", tf->toChars());
                size_t dim = Parameter::dim(tf->parameters);

                if (Parameter::dim(tof->parameters) != dim ||
                    tof->varargs != tf->varargs)
                    return;

                Objects *tiargs = new Objects();
                tiargs->reserve(e->td->parameters->dim);

                for (size_t i = 0; i < e->td->parameters->dim; i++)
                {
                    TemplateParameter *tp = (*e->td->parameters)[i];
                    size_t u = 0;
                    for (; u < dim; u++)
                    {
                        Parameter *p = Parameter::getNth(tf->parameters, u);
                        if (p->type->ty == Tident &&
                            ((TypeIdentifier *)p->type)->ident == tp->ident)
                        {
                            break;
                        }
                    }
                    assert(u < dim);
                    Parameter *pto = Parameter::getNth(tof->parameters, u);
                    if (!pto)
                        break;
                    Type *t = pto->type->syntaxCopy();  // Bugzilla 11774
                    if (reliesOnTident(t, parameters, inferStart))
                        return;
                    t = t->semantic(e->loc, sc);
                    if (t->ty == Terror)
                        return;
                    tiargs->push(t);
                }

                // Set target of return type inference
                if (!tf->next && tof->next)
                    e->fd->treq = tparam;

                TemplateInstance *ti = new TemplateInstance(e->loc, e->td, tiargs);
                Expression *ex = new ScopeExp(e->loc, ti);
                ex = ::semantic(ex, e->td->_scope);

                // Reset inference target for the later re-semantic
                e->fd->treq = NULL;

                if (ex->op == TOKerror)
                    return;
                if (ex->op != TOKfunction)
                    return;
                visit(ex->type);
                return;
            }

            Type *t = e->type;

            if (t->ty == Tdelegate && tparam->ty == Tpointer)
                return;

            // Allow conversion from implicit function pointer to delegate
            if (e->tok == TOKreserved &&
                t->ty == Tpointer && tparam->ty == Tdelegate)
            {
                TypeFunction *tf = (TypeFunction *)t->nextOf();
                t = (new TypeDelegate(tf))->merge();
            }
            //printf("tparam = %s <= e->type = %s, t = %s\n", tparam->toChars(), e->type->toChars(), t->toChars());
            visit(t);
        }

        void visit(SliceExp *e)
        {
            Type *taai;
            if (e->type->ty == Tarray &&
                (tparam->ty == Tsarray ||
                 (tparam->ty == Taarray && (taai = ((TypeAArray *)tparam)->index)->ty == Tident &&
                  ((TypeIdentifier *)taai)->idents.dim == 0)))
            {
                // Consider compile-time known boundaries
                if (Type *tsa = toStaticArrayType(e))
                {
                    tsa->accept(this);
                    return;
                }
            }
            visit((Expression *)e);
        }

        void visit(CommaExp *e)
        {
            ((CommaExp *)e)->e2->accept(this);
        }
    };

    DeduceType v(sc, tparam, parameters, dedtypes, wm, inferStart);
    if (Type *t = isType(o))
        t->accept(&v);
    else
    {
        assert(isExpression(o) && wm);
        ((Expression *)o)->accept(&v);
    }
    return v.result;
}

/*******************************
 * Input:
 *      t           Tested type, if NULL, returns NULL.
 *      tparams     Optional template parameters.
 *                  == NULL:
 *                      If one of the subtypes of this type is a TypeIdentifier,
 *                      i.e. it's an unresolved type, return that type.
 *                  != NULL:
 *                      Only when the TypeIdentifier is one of template parameters,
 *                      return that type.
 */

bool reliesOnTident(Type *t, TemplateParameters *tparams, size_t iStart)
{
    class ReliesOnTident : public Visitor
    {
    public:
        TemplateParameters *tparams;
        size_t iStart;
        bool result;

        ReliesOnTident(TemplateParameters *tparams, size_t iStart)
            : tparams(tparams), iStart(iStart)
        {
            result = false;
        }

        void visit(Type *)
        {
        }

        void visit(TypeNext *t)
        {
            t->next->accept(this);
        }

        void visit(TypeVector *t)
        {
            t->basetype->accept(this);
        }

        void visit(TypeAArray *t)
        {
            visit((TypeNext *)t);
            if (!result)
                t->index->accept(this);
        }

        void visit(TypeFunction *t)
        {
            size_t dim = Parameter::dim(t->parameters);
            for (size_t i = 0; i < dim; i++)
            {
                Parameter *fparam = Parameter::getNth(t->parameters, i);
                fparam->type->accept(this);
                if (result)
                    return;
            }
            if (t->next)
                t->next->accept(this);
        }

        void visit(TypeIdentifier *t)
        {
            if (!tparams)
            {
                result = true;
                return;
            }

            for (size_t i = iStart; i < tparams->dim; i++)
            {
                TemplateParameter *tp = (*tparams)[i];
                if (tp->ident->equals(t->ident))
                {
                    result = true;
                    return;
                }
            }
        }

        void visit(TypeInstance *t)
        {
            if (!tparams)
                return;

            for (size_t i = iStart; i < tparams->dim; i++)
            {
                TemplateParameter *tp = (*tparams)[i];
                if (t->tempinst->name == tp->ident)
                {
                    result = true;
                    return;
                }
            }
            if (!t->tempinst->tiargs)
                return;
            for (size_t i = 0; i < t->tempinst->tiargs->dim; i++)
            {
                Type *ta = isType((*t->tempinst->tiargs)[i]);
                if (ta)
                {
                    ta->accept(this);
                    if (result)
                        return;
                }
            }
        }

        void visit(TypeTypeof *t)
        {
            //printf("TypeTypeof::reliesOnTident('%s')\n", t->toChars());
            t->exp->accept(this);
        }

        void visit(TypeTuple *t)
        {
            if (t->arguments)
            {
                for (size_t i = 0; i < t->arguments->dim; i++)
                {
                    Parameter *arg = (*t->arguments)[i];
                    arg->type->accept(this);
                    if (result)
                        return;
                }
            }
        }

        void visit(Expression *)
        {
            //printf("Expression::reliesOnTident('%s')\n", e->toChars());
        }

        void visit(IdentifierExp *e)
        {
            //printf("IdentifierExp::reliesOnTident('%s')\n", e->toChars());
            for (size_t i = iStart; i < tparams->dim; i++)
            {
                TemplateParameter *tp = (*tparams)[i];
                if (e->ident == tp->ident)
                {
                    result = true;
                    return;
                }
            }
        }

        void visit(TupleExp *e)
        {
            //printf("TupleExp::reliesOnTident('%s')\n", e->toChars());
            if (e->exps)
            {
                for (size_t i = 0; i < e->exps->dim; i++)
                {
                    Expression *ea = (*e->exps)[i];
                    ea->accept(this);
                    if (result)
                        return;
                }
            }
        }

        void visit(ArrayLiteralExp *e)
        {
            //printf("ArrayLiteralExp::reliesOnTident('%s')\n", e->toChars());
            if (e->elements)
            {
                for (size_t i = 0; i < e->elements->dim; i++)
                {
                    Expression *el = (*e->elements)[i];
                    el->accept(this);
                    if (result)
                        return;
                }
            }
        }

        void visit(AssocArrayLiteralExp *e)
        {
            //printf("AssocArrayLiteralExp::reliesOnTident('%s')\n", e->toChars());
            for (size_t i = 0; i < e->keys->dim; i++)
            {
                Expression *ek = (*e->keys)[i];
                ek->accept(this);
                if (result)
                    return;
            }
            for (size_t i = 0; i < e->values->dim; i++)
            {
                Expression *ev = (*e->values)[i];
                ev->accept(this);
                if (result)
                    return;
            }
        }

        void visit(StructLiteralExp *e)
        {
            //printf("StructLiteralExp::reliesOnTident('%s')\n", e->toChars());
            if (e->elements)
            {
                for (size_t i = 0; i < e->elements->dim; i++)
                {
                    Expression *ea = (*e->elements)[i];
                    ea->accept(this);
                    if (result)
                        return;
                }
            }
        }

        void visit(TypeExp *e)
        {
            //printf("TypeExp::reliesOnTident('%s')\n", e->toChars());
            e->type->accept(this);
        }

        void visit(NewExp *e)
        {
            //printf("NewExp::reliesOnTident('%s')\n", e->toChars());
            if (e->thisexp)
                e->thisexp->accept(this);
            if (!result && e->newargs)
            {
                for (size_t i = 0; i < e->newargs->dim; i++)
                {
                    Expression *ea = (*e->newargs)[i];
                    ea->accept(this);
                    if (result)
                        return;
                }
            }
            e->newtype->accept(this);
            if (!result && e->arguments)
            {
                for (size_t i = 0; i < e->arguments->dim; i++)
                {
                    Expression *ea = (*e->arguments)[i];
                    ea->accept(this);
                    if (result)
                        return;
                }
            }
        }

        void visit(NewAnonClassExp *)
        {
            //printf("NewAnonClassExp::reliesOnTident('%s')\n", e->toChars());
            result = true;
        }

        void visit(FuncExp *)
        {
            //printf("FuncExp::reliesOnTident('%s')\n", e->toChars());
            result = true;
        }

        void visit(TypeidExp *e)
        {
            //printf("TypeidExp::reliesOnTident('%s')\n", e->toChars());
            if (Expression *ea = isExpression(e->obj))
                ea->accept(this);
            else if (Type *ta = isType(e->obj))
                ta->accept(this);
        }

        void visit(TraitsExp *e)
        {
            //printf("TraitsExp::reliesOnTident('%s')\n", e->toChars());
            if (e->args)
            {
                for (size_t i = 0; i < e->args->dim; i++)
                {
                    RootObject *oa = (*e->args)[i];
                    if (Expression *ea = isExpression(oa))
                        ea->accept(this);
                    else if (Type *ta = isType(oa))
                        ta->accept(this);
                    if (result)
                        return;
                }
            }
        }

        void visit(IsExp *e)
        {
            //printf("IsExp::reliesOnTident('%s')\n", e->toChars());
            e->targ->accept(this);
        }

        void visit(UnaExp *e)
        {
            //printf("UnaExp::reliesOnTident('%s')\n", e->toChars());
            e->e1->accept(this);
        }

        void visit(DotTemplateInstanceExp *e)
        {
            //printf("DotTemplateInstanceExp::reliesOnTident('%s')\n", e->toChars());
            visit((UnaExp *)e);
            if (!result && e->ti->tiargs)
            {
                for (size_t i = 0; i < e->ti->tiargs->dim; i++)
                {
                    RootObject *oa = (*e->ti->tiargs)[i];
                    if (Expression *ea = isExpression(oa))
                        ea->accept(this);
                    else if (Type *ta = isType(oa))
                        ta->accept(this);
                    if (result)
                        return;
                }
            }
        }

        void visit(CallExp *e)
        {
            //printf("CallExp::reliesOnTident('%s')\n", e->toChars());
            visit((UnaExp *)e);
            if (!result && e->arguments)
            {
                for (size_t i = 0; i < e->arguments->dim; i++)
                {
                    Expression *ea = (*e->arguments)[i];
                    ea->accept(this);
                    if (result)
                        return;
                }
            }
        }

        void visit(CastExp *e)
        {
            //printf("CastExp::reliesOnTident('%s')\n", e->toChars());
            visit((UnaExp *)e);
            // e.to can be null for cast() with no type
            if (!result && e->to)
                e->to->accept(this);
        }

        void visit(SliceExp *e)
        {
            //printf("SliceExp::reliesOnTident('%s')\n", e->toChars());
            visit((UnaExp *)e);
            if (!result && e->lwr)
                e->lwr->accept(this);
            if (!result && e->upr)
                e->upr->accept(this);
        }

        void visit(IntervalExp *e)
        {
            //printf("IntervalExp::reliesOnTident('%s')\n", e->toChars());
            e->lwr->accept(this);
            if (!result)
                e->upr->accept(this);
        }

        void visit(ArrayExp *e)
        {
            //printf("ArrayExp::reliesOnTident('%s')\n", e->toChars());
            visit((UnaExp *)e);
            if (!result && e->arguments)
            {
                for (size_t i = 0; i < e->arguments->dim; i++)
                {
                    Expression *ea = (*e->arguments)[i];
                    ea->accept(this);
                }
            }
        }

        void visit(BinExp *e)
        {
            //printf("BinExp::reliesOnTident('%s')\n", e->toChars());
            e->e1->accept(this);
            if (!result)
                e->e2->accept(this);
        }

        void visit(CondExp *e)
        {
            //printf("BinExp::reliesOnTident('%s')\n", e->toChars());
            e->econd->accept(this);
            if (!result)
                visit((BinExp *)e);
        }
    };

    if (!t)
        return false;

    ReliesOnTident v(tparams, iStart);
    t->accept(&v);
    return v.result;
}

/* ======================== TemplateParameter =============================== */

TemplateParameter::TemplateParameter(Loc loc, Identifier *ident)
{
    this->loc = loc;
    this->ident = ident;
    this->dependent = false;
}

TemplateTypeParameter  *TemplateParameter::isTemplateTypeParameter()
{
    return NULL;
}

TemplateValueParameter *TemplateParameter::isTemplateValueParameter()
{
    return NULL;
}

TemplateAliasParameter *TemplateParameter::isTemplateAliasParameter()
{
    return NULL;
}

TemplateTupleParameter *TemplateParameter::isTemplateTupleParameter()
{
    return NULL;
}

TemplateThisParameter  *TemplateParameter::isTemplateThisParameter()
{
    return NULL;
}

/*******************************************
 * Match to a particular TemplateParameter.
 * Input:
 *      instLoc         location that the template is instantiated.
 *      tiargs[]        actual arguments to template instance
 *      i               i'th argument
 *      parameters[]    template parameters
 *      dedtypes[]      deduced arguments to template instance
 *      *psparam        set to symbol declared and initialized to dedtypes[i]
 */
MATCH TemplateParameter::matchArg(Loc instLoc, Scope *sc, Objects *tiargs,
        size_t i, TemplateParameters *parameters, Objects *dedtypes,
        Declaration **psparam)
{
    RootObject *oarg;

    if (i < tiargs->dim)
        oarg = (*tiargs)[i];
    else
    {
        // Get default argument instead
        oarg = defaultArg(instLoc, sc);
        if (!oarg)
        {
            assert(i < dedtypes->dim);
            // It might have already been deduced
            oarg = (*dedtypes)[i];
            if (!oarg)
                goto Lnomatch;
        }
    }
    return matchArg(sc, oarg, i, parameters, dedtypes, psparam);

Lnomatch:
    if (psparam)
        *psparam = NULL;
    return MATCHnomatch;
}

/* ======================== TemplateTypeParameter =========================== */

// type-parameter

Type *TemplateTypeParameter::tdummy = NULL;

TemplateTypeParameter::TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType,
        Type *defaultType)
    : TemplateParameter(loc, ident)
{
    this->ident = ident;
    this->specType = specType;
    this->defaultType = defaultType;
}

TemplateTypeParameter  *TemplateTypeParameter::isTemplateTypeParameter()
{
    return this;
}

TemplateParameter *TemplateTypeParameter::syntaxCopy()
{
    return new TemplateTypeParameter(loc, ident,
        specType    ? specType->syntaxCopy()    : NULL,
        defaultType ? defaultType->syntaxCopy() : NULL);
}

bool TemplateTypeParameter::declareParameter(Scope *sc)
{
    //printf("TemplateTypeParameter::declareParameter('%s')\n", ident->toChars());
    TypeIdentifier *ti = new TypeIdentifier(loc, ident);
    Declaration *ad = new AliasDeclaration(loc, ident, ti);
    return sc->insert(ad) != NULL;
}

bool TemplateTypeParameter::semantic(Scope *sc, TemplateParameters *parameters)
{
    //printf("TemplateTypeParameter::semantic('%s')\n", ident->toChars());
    if (specType && !reliesOnTident(specType, parameters))
    {
        specType = specType->semantic(loc, sc);
    }
    return !(specType && isError(specType));
}

MATCH TemplateTypeParameter::matchArg(Scope *sc, RootObject *oarg,
        size_t i, TemplateParameters *parameters, Objects *dedtypes,
        Declaration **psparam)
{
    //printf("TemplateTypeParameter::matchArg('%s')\n", ident->toChars());
    MATCH m = MATCHexact;
    Type *ta = isType(oarg);
    if (!ta)
    {
        //printf("%s %p %p %p\n", oarg->toChars(), isExpression(oarg), isDsymbol(oarg), isTuple(oarg));
        goto Lnomatch;
    }
    //printf("ta is %s\n", ta->toChars());

    if (specType)
    {
        if (!ta || ta == tdummy)
            goto Lnomatch;

        //printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta->toChars(), specType->toChars());
        MATCH m2 = deduceType(ta, sc, specType, parameters, dedtypes);
        if (m2 <= MATCHnomatch)
        {
            //printf("\tfailed deduceType\n");
            goto Lnomatch;
        }

        if (m2 < m)
            m = m2;
        if ((*dedtypes)[i])
        {
            Type *t = (Type *)(*dedtypes)[i];

            if (dependent && !t->equals(ta))    // Bugzilla 14357
                goto Lnomatch;

            /* This is a self-dependent parameter. For example:
             *  template X(T : T*) {}
             *  template X(T : S!T, alias S) {}
             */
            //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
            ta = t;
        }
    }
    else
    {
        if ((*dedtypes)[i])
        {
            // Must match already deduced type
            Type *t = (Type *)(*dedtypes)[i];

            if (!t->equals(ta))
            {
                //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
                goto Lnomatch;
            }
        }
        else
        {
            // So that matches with specializations are better
            m = MATCHconvert;
        }
    }
    (*dedtypes)[i] = ta;

    if (psparam)
        *psparam = new AliasDeclaration(loc, ident, ta);
    //printf("\tm = %d\n", m);
    return dependent ? MATCHexact : m;

Lnomatch:
    if (psparam)
        *psparam = NULL;
    //printf("\tm = %d\n", MATCHnomatch);
    return MATCHnomatch;
}


void TemplateTypeParameter::print(RootObject *oarg, RootObject *oded)
{
    printf(" %s\n", ident->toChars());

    Type *t  = isType(oarg);
    Type *ta = isType(oded);

    assert(ta);

    if (specType)
        printf("\tSpecialization: %s\n", specType->toChars());
    if (defaultType)
        printf("\tDefault:        %s\n", defaultType->toChars());
    printf("\tParameter:       %s\n", t ? t->toChars() : "NULL");
    printf("\tDeduced Type:   %s\n", ta->toChars());
}

void *TemplateTypeParameter::dummyArg()
{
    Type *t = specType;
    if (!t)
    {
        // Use this for alias-parameter's too (?)
        if (!tdummy)
            tdummy = new TypeIdentifier(loc, ident);
        t = tdummy;
    }
    return (void *)t;
}


RootObject *TemplateTypeParameter::specialization()
{
    return specType;
}

RootObject *TemplateTypeParameter::defaultArg(Loc, Scope *sc)
{
    Type *t = defaultType;
    if (t)
    {
        t = t->syntaxCopy();
        t = t->semantic(loc, sc);   // use the parameter loc
    }
    return t;
}

bool TemplateTypeParameter::hasDefaultArg()
{
    return defaultType != NULL;
}

/* ======================== TemplateThisParameter =========================== */

// this-parameter

TemplateThisParameter::TemplateThisParameter(Loc loc, Identifier *ident,
        Type *specType,
        Type *defaultType)
    : TemplateTypeParameter(loc, ident, specType, defaultType)
{
}

TemplateThisParameter  *TemplateThisParameter::isTemplateThisParameter()
{
    return this;
}

TemplateParameter *TemplateThisParameter::syntaxCopy()
{
    return new TemplateThisParameter(loc, ident,
        specType    ? specType->syntaxCopy()    : NULL,
        defaultType ? defaultType->syntaxCopy() : NULL);
}

/* ======================== TemplateAliasParameter ========================== */

// alias-parameter

Dsymbol *TemplateAliasParameter::sdummy = NULL;

TemplateAliasParameter::TemplateAliasParameter(Loc loc, Identifier *ident,
        Type *specType, RootObject *specAlias, RootObject *defaultAlias)
    : TemplateParameter(loc, ident)
{
    this->ident = ident;
    this->specType = specType;
    this->specAlias = specAlias;
    this->defaultAlias = defaultAlias;
}

TemplateAliasParameter *TemplateAliasParameter::isTemplateAliasParameter()
{
    return this;
}

TemplateParameter *TemplateAliasParameter::syntaxCopy()
{
    return new TemplateAliasParameter(loc, ident,
        specType ? specType->syntaxCopy() : NULL,
        objectSyntaxCopy(specAlias),
        objectSyntaxCopy(defaultAlias));
}

bool TemplateAliasParameter::declareParameter(Scope *sc)
{
    TypeIdentifier *ti = new TypeIdentifier(loc, ident);
    Declaration *ad = new AliasDeclaration(loc, ident, ti);
    return sc->insert(ad) != NULL;
}

static RootObject *aliasParameterSemantic(Loc loc, Scope *sc, RootObject *o, TemplateParameters *parameters)
{
    if (o)
    {
        Expression *ea = isExpression(o);
        Type *ta = isType(o);
        if (ta && (!parameters || !reliesOnTident(ta, parameters)))
        {
            Dsymbol *s = ta->toDsymbol(sc);
            if (s)
                o = s;
            else
                o = ta->semantic(loc, sc);
        }
        else if (ea)
        {
            sc = sc->startCTFE();
            ea = ::semantic(ea, sc);
            sc = sc->endCTFE();
            o = ea->ctfeInterpret();
        }
    }
    return o;
}

bool TemplateAliasParameter::semantic(Scope *sc, TemplateParameters *parameters)
{
    if (specType && !reliesOnTident(specType, parameters))
    {
        specType = specType->semantic(loc, sc);
    }
    specAlias = aliasParameterSemantic(loc, sc, specAlias, parameters);
    return !(specType  && isError(specType)) &&
           !(specAlias && isError(specAlias));
}

MATCH TemplateAliasParameter::matchArg(Scope *sc, RootObject *oarg,
        size_t i, TemplateParameters *parameters, Objects *dedtypes,
        Declaration **psparam)
{
    //printf("TemplateAliasParameter::matchArg('%s')\n", ident->toChars());
    MATCH m = MATCHexact;
    Type *ta = isType(oarg);
    RootObject *sa = ta && !ta->deco ? NULL : getDsymbol(oarg);
    Expression *ea = isExpression(oarg);
    if (ea && (ea->op == TOKthis || ea->op == TOKsuper))
        sa = ((ThisExp *)ea)->var;
    else if (ea && ea->op == TOKscope)
        sa = ((ScopeExp *)ea)->sds;
    if (sa)
    {
        if (((Dsymbol *)sa)->isAggregateDeclaration())
            m = MATCHconvert;

        /* specType means the alias must be a declaration with a type
         * that matches specType.
         */
        if (specType)
        {
            Declaration *d = ((Dsymbol *)sa)->isDeclaration();
            if (!d)
                goto Lnomatch;
            if (!d->type->equals(specType))
                goto Lnomatch;
        }
    }
    else
    {
        sa = oarg;
        if (ea)
        {
            if (specType)
            {
                if (!ea->type->equals(specType))
                    goto Lnomatch;
            }
        }
        else if (ta && ta->ty == Tinstance && !specAlias)
        {
            /* Bugzilla xxxxx: Specialized parameter should be prefeerd
             * match to the template type parameter.
             *  template X(alias a) {}                      // a == this
             *  template X(alias a : B!A, alias B, A...) {} // B!A => ta
             */
        }
        else if (sa && sa == TemplateTypeParameter::tdummy)
        {
            /* Bugzilla 2025: Aggregate Types should preferentially
             * match to the template type parameter.
             *  template X(alias a) {}  // a == this
             *  template X(T) {}        // T => sa
             */
        }
        else
            goto Lnomatch;
    }

    if (specAlias)
    {
        if (sa == sdummy)
            goto Lnomatch;
        Dsymbol *sx = isDsymbol(sa);
        if (sa != specAlias && sx)
        {
            Type *talias = isType(specAlias);
            if (!talias)
                goto Lnomatch;

            TemplateInstance *ti = sx->isTemplateInstance();
            if (!ti && sx->parent)
            {
                ti = sx->parent->isTemplateInstance();
                if (ti && ti->name != sx->ident)
                    goto Lnomatch;
            }
            if (!ti)
                goto Lnomatch;

            Type *t = new TypeInstance(Loc(), ti);
            MATCH m2 = deduceType(t, sc, talias, parameters, dedtypes);
            if (m2 <= MATCHnomatch)
                goto Lnomatch;
        }
    }
    else if ((*dedtypes)[i])
    {
        // Must match already deduced symbol
        RootObject *si = (*dedtypes)[i];
        if (!sa || si != sa)
            goto Lnomatch;
    }
    (*dedtypes)[i] = sa;

    if (psparam)
    {
        if (Dsymbol *s = isDsymbol(sa))
        {
            *psparam = new AliasDeclaration(loc, ident, s);
        }
        else if (Type *t = isType(sa))
        {
            *psparam = new AliasDeclaration(loc, ident, t);
        }
        else
        {
            assert(ea);

            // Declare manifest constant
            Initializer *init = new ExpInitializer(loc, ea);
            VarDeclaration *v = new VarDeclaration(loc, NULL, ident, init);
            v->storage_class = STCmanifest;
            v->semantic(sc);
            *psparam = v;
        }
    }
    return dependent ? MATCHexact : m;

Lnomatch:
    if (psparam)
        *psparam = NULL;
    //printf("\tm = %d\n", MATCHnomatch);
    return MATCHnomatch;
}


void TemplateAliasParameter::print(RootObject *, RootObject *oded)
{
    printf(" %s\n", ident->toChars());

    Dsymbol *sa = isDsymbol(oded);
    assert(sa);

    printf("\tParameter alias: %s\n", sa->toChars());
}

void *TemplateAliasParameter::dummyArg()
{
    RootObject *s = specAlias;
    if (!s)
    {
        if (!sdummy)
            sdummy = new Dsymbol();
        s = sdummy;
    }
    return (void*)s;
}


RootObject *TemplateAliasParameter::specialization()
{
    return specAlias;
}

RootObject *TemplateAliasParameter::defaultArg(Loc, Scope *sc)
{
    RootObject *da = defaultAlias;
    Type *ta = isType(defaultAlias);
    if (ta)
    {
       if (ta->ty == Tinstance)
       {
           // If the default arg is a template, instantiate for each type
           da = ta->syntaxCopy();
       }
    }

    RootObject *o = aliasParameterSemantic(loc, sc, da, NULL);  // use the parameter loc
    return o;
}

bool TemplateAliasParameter::hasDefaultArg()
{
    return defaultAlias != NULL;
}

/* ======================== TemplateValueParameter ========================== */

// value-parameter

AA *TemplateValueParameter::edummies = NULL;

TemplateValueParameter::TemplateValueParameter(Loc loc, Identifier *ident, Type *valType,
        Expression *specValue, Expression *defaultValue)
    : TemplateParameter(loc, ident)
{
    this->ident = ident;
    this->valType = valType;
    this->specValue = specValue;
    this->defaultValue = defaultValue;
}

TemplateValueParameter *TemplateValueParameter::isTemplateValueParameter()
{
    return this;
}

TemplateParameter *TemplateValueParameter::syntaxCopy()
{
    return new TemplateValueParameter(loc, ident,
        valType->syntaxCopy(),
        specValue    ? specValue->syntaxCopy()    : NULL,
        defaultValue ? defaultValue->syntaxCopy() : NULL);
}

bool TemplateValueParameter::declareParameter(Scope *sc)
{
    VarDeclaration *v = new VarDeclaration(loc, valType, ident, NULL);
    v->storage_class = STCtemplateparameter;
    return sc->insert(v) != NULL;
}

bool TemplateValueParameter::semantic(Scope *sc, TemplateParameters *)
{
    valType = valType->semantic(loc, sc);

    return !isError(valType);
}

MATCH TemplateValueParameter::matchArg(Scope *sc, RootObject *oarg,
        size_t i, TemplateParameters *, Objects *dedtypes, Declaration **psparam)
{
    //printf("TemplateValueParameter::matchArg('%s')\n", ident->toChars());

    MATCH m = MATCHexact;

    Expression *ei = isExpression(oarg);
    Type *vt;

    if (!ei && oarg)
    {
        Dsymbol *si = isDsymbol(oarg);
        FuncDeclaration *f = si ? si->isFuncDeclaration() : NULL;
        if (!f || !f->fbody || f->needThis())
            goto Lnomatch;

        ei = new VarExp(loc, f);
        ei = ::semantic(ei, sc);

        /* If a function is really property-like, and then
         * it's CTFEable, ei will be a literal expression.
         */
        unsigned int olderrors = global.startGagging();
        ei = resolveProperties(sc, ei);
        ei = ei->ctfeInterpret();
        if (global.endGagging(olderrors) || ei->op == TOKerror)
            goto Lnomatch;

        /* Bugzilla 14520: A property-like function can match to both
         * TemplateAlias and ValueParameter. But for template overloads,
         * it should always prefer alias parameter to be consistent
         * template match result.
         *
         *   template X(alias f) { enum X = 1; }
         *   template X(int val) { enum X = 2; }
         *   int f1() { return 0; }  // CTFEable
         *   int f2();               // body-less function is not CTFEable
         *   enum x1 = X!f1;    // should be 1
         *   enum x2 = X!f2;    // should be 1
         *
         * e.g. The x1 value must be same even if the f1 definition will be moved
         *      into di while stripping body code.
         */
        m = MATCHconvert;
    }

    if (ei && ei->op == TOKvar)
    {
        // Resolve const variables that we had skipped earlier
        ei = ei->ctfeInterpret();
    }

    //printf("\tvalType: %s, ty = %d\n", valType->toChars(), valType->ty);
    vt = valType->semantic(loc, sc);
    //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars());
    //printf("vt = %s\n", vt->toChars());

    if (ei->type)
    {
        MATCH m2 = ei->implicitConvTo(vt);
        //printf("m: %d\n", m);
        if (m2 < m)
            m = m2;
        if (m <= MATCHnomatch)
            goto Lnomatch;
        ei = ei->implicitCastTo(sc, vt);
        ei = ei->ctfeInterpret();
    }

    if (specValue)
    {
        if (!ei || (Expression *)dmd_aaGetRvalue(edummies, (void *)ei->type) == ei)
            goto Lnomatch;

        Expression *e = specValue;

        sc = sc->startCTFE();
        e = ::semantic(e, sc);
        e = resolveProperties(sc, e);
        sc = sc->endCTFE();
        e = e->implicitCastTo(sc, vt);
        e = e->ctfeInterpret();

        ei = ei->syntaxCopy();
        sc = sc->startCTFE();
        ei = ::semantic(ei, sc);
        sc = sc->endCTFE();
        ei = ei->implicitCastTo(sc, vt);
        ei = ei->ctfeInterpret();
        //printf("\tei: %s, %s\n", ei->toChars(), ei->type->toChars());
        //printf("\te : %s, %s\n", e->toChars(), e->type->toChars());
        if (!ei->equals(e))
            goto Lnomatch;
    }
    else
    {
        if ((*dedtypes)[i])
        {
            // Must match already deduced value
            Expression *e = (Expression *)(*dedtypes)[i];

            if (!ei || !ei->equals(e))
                goto Lnomatch;
        }
    }
    (*dedtypes)[i] = ei;

    if (psparam)
    {
        Initializer *init = new ExpInitializer(loc, ei);
        Declaration *sparam = new VarDeclaration(loc, vt, ident, init);
        sparam->storage_class = STCmanifest;
        *psparam = sparam;
    }
    return dependent ? MATCHexact : m;

Lnomatch:
    //printf("\tno match\n");
    if (psparam)
        *psparam = NULL;
    return MATCHnomatch;
}


void TemplateValueParameter::print(RootObject *, RootObject *oded)
{
    printf(" %s\n", ident->toChars());

    Expression *ea = isExpression(oded);

    if (specValue)
        printf("\tSpecialization: %s\n", specValue->toChars());
    printf("\tParameter Value: %s\n", ea ? ea->toChars() : "NULL");
}

void *TemplateValueParameter::dummyArg()
{
    Expression *e = specValue;
    if (!e)
    {
        // Create a dummy value
        Expression **pe = (Expression **)dmd_aaGet(&edummies, (void *)valType);
        if (!*pe)
            *pe = valType->defaultInit();
        e = *pe;
    }
    return (void *)e;
}


RootObject *TemplateValueParameter::specialization()
{
    return specValue;
}

RootObject *TemplateValueParameter::defaultArg(Loc instLoc, Scope *sc)
{
    Expression *e = defaultValue;
    if (e)
    {
        e = e->syntaxCopy();
        if ((e = ::semantic(e, sc)) == NULL)
            return NULL;
        if ((e = resolveProperties(sc, e)) == NULL)
            return NULL;
        e = e->resolveLoc(instLoc, sc);     // use the instantiated loc
        e = e->optimize(WANTvalue);
    }
    return e;
}

bool TemplateValueParameter::hasDefaultArg()
{
    return defaultValue != NULL;
}

/* ======================== TemplateTupleParameter ========================== */

// variadic-parameter

TemplateTupleParameter::TemplateTupleParameter(Loc loc, Identifier *ident)
    : TemplateParameter(loc, ident)
{
    this->ident = ident;
}

TemplateTupleParameter *TemplateTupleParameter::isTemplateTupleParameter()
{
    return this;
}

TemplateParameter *TemplateTupleParameter::syntaxCopy()
{
    return new TemplateTupleParameter(loc, ident);
}

bool TemplateTupleParameter::declareParameter(Scope *sc)
{
    TypeIdentifier *ti = new TypeIdentifier(loc, ident);
    Declaration *ad = new AliasDeclaration(loc, ident, ti);
    return sc->insert(ad) != NULL;
}

bool TemplateTupleParameter::semantic(Scope *, TemplateParameters *)
{
    return true;
}

MATCH TemplateTupleParameter::matchArg(Loc, Scope *sc, Objects *tiargs,
        size_t i, TemplateParameters *parameters, Objects *dedtypes,
        Declaration **psparam)
{
    /* The rest of the actual arguments (tiargs[]) form the match
     * for the variadic parameter.
     */
    assert(i + 1 == dedtypes->dim);     // must be the last one
    Tuple *ovar;

    if (Tuple *u = isTuple((*dedtypes)[i]))
    {
        // It has already been deduced
        ovar = u;
    }
    else if (i + 1 == tiargs->dim && isTuple((*tiargs)[i]))
        ovar = isTuple((*tiargs)[i]);
    else
    {
        ovar = new Tuple();
        //printf("ovar = %p\n", ovar);
        if (i < tiargs->dim)
        {
            //printf("i = %d, tiargs->dim = %d\n", i, tiargs->dim);
            ovar->objects.setDim(tiargs->dim - i);
            for (size_t j = 0; j < ovar->objects.dim; j++)
                ovar->objects[j] = (*tiargs)[i + j];
        }
    }
    return matchArg(sc, ovar, i, parameters, dedtypes, psparam);
}

MATCH TemplateTupleParameter::matchArg(Scope *, RootObject *oarg,
        size_t i, TemplateParameters *, Objects *dedtypes, Declaration **psparam)
{
    //printf("TemplateTupleParameter::matchArg('%s')\n", ident->toChars());
    Tuple *ovar = isTuple(oarg);
    if (!ovar)
        return MATCHnomatch;
    if ((*dedtypes)[i])
    {
        Tuple *tup = isTuple((*dedtypes)[i]);
        if (!tup)
            return MATCHnomatch;
        if (!match(tup, ovar))
            return MATCHnomatch;
    }
    (*dedtypes)[i] = ovar;

    if (psparam)
        *psparam = new TupleDeclaration(loc, ident, &ovar->objects);
    return dependent ? MATCHexact : MATCHconvert;
}


void TemplateTupleParameter::print(RootObject *, RootObject *oded)
{
    printf(" %s... [", ident->toChars());
    Tuple *v = isTuple(oded);
    assert(v);

    //printf("|%d| ", v->objects.dim);
    for (size_t i = 0; i < v->objects.dim; i++)
    {
        if (i)
            printf(", ");

        RootObject *o = v->objects[i];

        Dsymbol *sa = isDsymbol(o);
        if (sa)
            printf("alias: %s", sa->toChars());

        Type *ta = isType(o);
        if (ta)
            printf("type: %s", ta->toChars());

        Expression *ea = isExpression(o);
        if (ea)
            printf("exp: %s", ea->toChars());

        assert(!isTuple(o));            // no nested Tuple arguments
    }

    printf("]\n");
}

void *TemplateTupleParameter::dummyArg()
{
    return NULL;
}


RootObject *TemplateTupleParameter::specialization()
{
    return NULL;
}

RootObject *TemplateTupleParameter::defaultArg(Loc, Scope *)
{
    return NULL;
}

bool TemplateTupleParameter::hasDefaultArg()
{
    return false;
}

/* ======================== TemplateInstance ================================ */

TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
    : ScopeDsymbol(NULL)
{
    this->loc = loc;
    this->name = ident;
    this->tiargs = NULL;
    this->tempdecl = NULL;
    this->inst = NULL;
    this->tinst = NULL;
    this->tnext = NULL;
    this->minst = NULL;
    this->deferred = NULL;
    this->memberOf = NULL;
    this->argsym = NULL;
    this->aliasdecl = NULL;
    this->semantictiargsdone = false;
    this->inuse = 0;
    this->nest = 0;
    this->havetempdecl = false;
    this->enclosing = NULL;
    this->gagged = false;
    this->hash = 0;
    this->fargs = NULL;
}

/*****************
 * This constructor is only called when we figured out which function
 * template to instantiate.
 */

TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs)
    : ScopeDsymbol(NULL)
{
    this->loc = loc;
    this->name = td->ident;
    this->tiargs = tiargs;
    this->tempdecl = td;
    this->inst = NULL;
    this->tinst = NULL;
    this->tnext = NULL;
    this->minst = NULL;
    this->deferred = NULL;
    this->memberOf = NULL;
    this->argsym = NULL;
    this->aliasdecl = NULL;
    this->semantictiargsdone = true;
    this->inuse = 0;
    this->nest = 0;
    this->havetempdecl = true;
    this->enclosing = NULL;
    this->gagged = false;
    this->hash = 0;
    this->fargs = NULL;

    assert(tempdecl->_scope);
}


Objects *TemplateInstance::arraySyntaxCopy(Objects *objs)
{
    Objects *a = NULL;
    if (objs)
    {
        a = new Objects();
        a->setDim(objs->dim);
        for (size_t i = 0; i < objs->dim; i++)
            (*a)[i] = objectSyntaxCopy((*objs)[i]);
    }
    return a;
}

Dsymbol *TemplateInstance::syntaxCopy(Dsymbol *s)
{
    TemplateInstance *ti =
        s ? (TemplateInstance *)s
          : new TemplateInstance(loc, name);
    ti->tiargs = arraySyntaxCopy(tiargs);
    TemplateDeclaration *td;
    if (inst && tempdecl && (td = tempdecl->isTemplateDeclaration()) != NULL)
        td->ScopeDsymbol::syntaxCopy(ti);
    else
        ScopeDsymbol::syntaxCopy(ti);
    return ti;
}

void TemplateInstance::semantic(Scope *sc)
{
    semantic(sc, NULL);
}

void TemplateInstance::expandMembers(Scope *sc2)
{
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->setScope(sc2);
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->importAll(sc2);
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars());
        //printf("test: enclosing = %d, sc2->parent = %s\n", enclosing, sc2->parent->toChars());
//      if (enclosing)
//          s->parent = sc->parent;
        //printf("test3: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars());
        s->semantic(sc2);
        //printf("test4: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars());
        Module::runDeferredSemantic();
    }
}

void TemplateInstance::tryExpandMembers(Scope *sc2)
{
    static int nest;
    // extracted to a function to allow windows SEH to work without destructors in the same function
    //printf("%d\n", nest);
    if (++nest > 500)
    {
        global.gag = 0;                 // ensure error message gets printed
        error("recursive expansion");
        fatal();
    }

    expandMembers(sc2);

    nest--;
}

void TemplateInstance::trySemantic3(Scope *sc2)
{
    // extracted to a function to allow windows SEH to work without destructors in the same function
    static int nest;
    //printf("%d\n", nest);
    if (++nest > 300)
    {
        global.gag = 0;            // ensure error message gets printed
        error("recursive expansion");
        fatal();
    }
    semantic3(sc2);

    --nest;
}

void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
{
    //printf("[%s] TemplateInstance::semantic('%s', this=%p, gag = %d, sc = %p)\n", loc.toChars(), toChars(), this, global.gag, sc);
    if (inst)           // if semantic() was already run
    {
        return;
    }
    if (semanticRun != PASSinit)
    {
        Ungag ungag(global.gag);
        if (!gagged)
            global.gag = 0;
        error(loc, "recursive template expansion");
        if (gagged)
            semanticRun = PASSinit;
        else
            inst = this;
        errors = true;
        return;
    }

    // Get the enclosing template instance from the scope tinst
    tinst = sc->tinst;

    // Get the instantiating module from the scope minst
    minst = sc->minst;
    // Bugzilla 10920: If the enclosing function is non-root symbol,
    // this instance should be speculative.
    if (!tinst && sc->func && sc->func->inNonRoot())
    {
        minst = NULL;
    }

    gagged = (global.gag > 0);

    semanticRun = PASSsemantic;

    /* Find template declaration first,
     * then run semantic on each argument (place results in tiargs[]),
     * last find most specialized template from overload list/set.
     */
    if (!findTempDecl(sc, NULL) ||
        !semanticTiargs(sc) ||
        !findBestMatch(sc, fargs))
    {
Lerror:
        if (gagged)
        {
            // Bugzilla 13220: Rollback status for later semantic re-running.
            semanticRun = PASSinit;
        }
        else
            inst = this;
        errors = true;
        return;
    }
    TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration();
    assert(tempdecl);

    // If tempdecl is a mixin, disallow it
    if (tempdecl->ismixin)
    {
        error("mixin templates are not regular templates");
        goto Lerror;
    }

    hasNestedArgs(tiargs, tempdecl->isstatic);
    if (errors)
        goto Lerror;

    /* See if there is an existing TemplateInstantiation that already
     * implements the typeargs. If so, just refer to that one instead.
     */
    inst = tempdecl->findExistingInstance(this, fargs);
    TemplateInstance *errinst = NULL;
    if (!inst)
    {
        // So, we need to implement 'this' instance.
    }
    else if (inst->gagged && !gagged && inst->errors)
    {
        // If the first instantiation had failed, re-run semantic,
        // so that error messages are shown.
        errinst = inst;
    }
    else
    {
        // It's a match
        parent = inst->parent;
        errors = inst->errors;

        // If both this and the previous instantiation were gagged,
        // use the number of errors that happened last time.
        global.errors += errors;
        global.gaggedErrors += errors;

        // If the first instantiation was gagged, but this is not:
        if (inst->gagged)
        {
            // It had succeeded, mark it is a non-gagged instantiation,
            // and reuse it.
            inst->gagged = gagged;
        }

        this->tnext = inst->tnext;
        inst->tnext = this;

        /* A module can have explicit template instance and its alias
         * in module scope (e,g, `alias Base64 = Base64Impl!('+', '/');`).
         * If the first instantiation 'inst' had happened in non-root module,
         * compiler can assume that its instantiated code would be included
         * in the separately compiled obj/lib file (e.g. phobos.lib).
         *
         * However, if 'this' second instantiation happened in root module,
         * compiler might need to invoke its codegen (Bugzilla 2500 & 2644).
         * But whole import graph is not determined until all semantic pass finished,
         * so 'inst' should conservatively finish the semantic3 pass for the codegen.
         */
        if (minst && minst->isRoot() && !(inst->minst && inst->minst->isRoot()))
        {
            /* Swap the position of 'inst' and 'this' in the instantiation graph.
             * Then, the primary instance `inst` will be changed to a root instance.
             *
             * Before:
             *  non-root -> A!() -> B!()[inst] -> C!()
             *                      |
             *  root     -> D!() -> B!()[this]
             *
             * After:
             *  non-root -> A!() -> B!()[this]
             *                      |
             *  root     -> D!() -> B!()[inst] -> C!()
             */
            Module *mi = minst;
            TemplateInstance *ti = tinst;
            minst = inst->minst;
            tinst = inst->tinst;
            inst->minst = mi;
            inst->tinst = ti;

            if (minst)  // if inst was not speculative
            {
                /* Add 'inst' once again to the root module members[], then the
                 * instance members will get codegen chances.
                 */
                inst->appendToModuleMember();
            }
        }

        return;
    }
    unsigned errorsave = global.errors;

    inst = this;
    parent = enclosing ? enclosing : tempdecl->parent;
    //printf("parent = '%s'\n", parent->kind());

    TemplateInstance *tempdecl_instance_idx = tempdecl->addInstance(this);

    //getIdent();

    // Store the place we added it to in target_symbol_list(_idx) so we can
    // remove it later if we encounter an error.
    Dsymbols *target_symbol_list = appendToModuleMember();
    size_t target_symbol_list_idx = target_symbol_list ? target_symbol_list->dim - 1 : 0;

    // Copy the syntax trees from the TemplateDeclaration
    members = Dsymbol::arraySyntaxCopy(tempdecl->members);

    // resolve TemplateThisParameter
    for (size_t i = 0; i < tempdecl->parameters->dim; i++)
    {
        if ((*tempdecl->parameters)[i]->isTemplateThisParameter() == NULL)
            continue;
        Type *t = isType((*tiargs)[i]);
        assert(t);
        if (StorageClass stc = ModToStc(t->mod))
        {
            //printf("t = %s, stc = x%llx\n", t->toChars(), stc);
            Dsymbols *s = new Dsymbols();
            s->push(new StorageClassDeclaration(stc, members));
            members = s;
        }
        break;
    }

    // Create our own scope for the template parameters
    Scope *scope = tempdecl->_scope;
    if (tempdecl->semanticRun == PASSinit)
    {
        error("template instantiation %s forward references template declaration %s", toChars(), tempdecl->toChars());
        return;
    }

    argsym = new ScopeDsymbol();
    argsym->parent = scope->parent;
    scope = scope->push(argsym);
    scope->tinst = this;
    scope->minst = minst;
    //scope->stc = 0;

    // Declare each template parameter as an alias for the argument type
    Scope *paramscope = scope->push();
    paramscope->stc = 0;
    paramscope->protection = Prot(PROTpublic);  // Bugzilla 14169: template parameters should be public
    declareParameters(paramscope);
    paramscope->pop();

    // Add members of template instance to template instance symbol table
//    parent = scope->scopesym;
    symtab = new DsymbolTable();
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->addMember(scope, this);
    }

    /* See if there is only one member of template instance, and that
     * member has the same name as the template instance.
     * If so, this template instance becomes an alias for that member.
     */
    //printf("members->dim = %d\n", members->dim);
    if (members->dim)
    {
        Dsymbol *s;
        if (Dsymbol::oneMembers(members, &s, tempdecl->ident) && s)
        {
            //printf("tempdecl->ident = %s, s = '%s'\n", tempdecl->ident->toChars(), s->kind(), s->toPrettyChars());
            //printf("setting aliasdecl\n");
            aliasdecl = s;
        }
    }

    /* If function template declaration
     */
    if (fargs && aliasdecl)
    {
        FuncDeclaration *fd = aliasdecl->isFuncDeclaration();
        if (fd)
        {
            /* Transmit fargs to type so that TypeFunction::semantic() can
             * resolve any "auto ref" storage classes.
             */
            TypeFunction *tf = (TypeFunction *)fd->type;
            if (tf && tf->ty == Tfunction)
                tf->fargs = fargs;
        }
    }

    // Do semantic() analysis on template instance members
    Scope *sc2;
    sc2 = scope->push(this);
    //printf("enclosing = %d, sc->parent = %s\n", enclosing, sc->parent->toChars());
    sc2->parent = this;
    sc2->tinst = this;
    sc2->minst = minst;

    tryExpandMembers(sc2);

    semanticRun = PASSsemanticdone;

    /* ConditionalDeclaration may introduce eponymous declaration,
     * so we should find it once again after semantic.
     */
    if (members->dim)
    {
        Dsymbol *s;
        if (Dsymbol::oneMembers(members, &s, tempdecl->ident) && s)
        {
            if (!aliasdecl || aliasdecl != s)
            {
                //printf("tempdecl->ident = %s, s = '%s'\n", tempdecl->ident->toChars(), s->kind(), s->toPrettyChars());
                //printf("setting aliasdecl 2\n");
                aliasdecl = s;
            }
        }
    }

    if (global.errors != errorsave)
        goto Laftersemantic;

    /* If any of the instantiation members didn't get semantic() run
     * on them due to forward references, we cannot run semantic2()
     * or semantic3() yet.
     */
    {
    bool found_deferred_ad = false;
    for (size_t i = 0; i < Module::deferred.dim; i++)
    {
        Dsymbol *sd = Module::deferred[i];
        AggregateDeclaration *ad = sd->isAggregateDeclaration();
        if (ad && ad->parent && ad->parent->isTemplateInstance())
        {
            //printf("deferred template aggregate: %s %s\n",
            //        sd->parent->toChars(), sd->toChars());
            found_deferred_ad = true;
            if (ad->parent == this)
            {
                ad->deferred = this;
                break;
            }
        }
    }
    if (found_deferred_ad || Module::deferred.dim)
        goto Laftersemantic;
    }

    /* The problem is when to parse the initializer for a variable.
     * Perhaps VarDeclaration::semantic() should do it like it does
     * for initializers inside a function.
     */
    //if (sc->parent->isFuncDeclaration())
    {
        /* BUG 782: this has problems if the classes this depends on
         * are forward referenced. Find a way to defer semantic()
         * on this template.
         */
        semantic2(sc2);
    }
    if (global.errors != errorsave)
        goto Laftersemantic;

    if ((sc->func || (sc->flags & SCOPEfullinst)) && !tinst)
    {
        /* If a template is instantiated inside function, the whole instantiation
         * should be done at that position. But, immediate running semantic3 of
         * dependent templates may cause unresolved forward reference (Bugzilla 9050).
         * To avoid the issue, don't run semantic3 until semantic and semantic2 done.
         */
        TemplateInstances deferred;
        this->deferred = &deferred;

        //printf("Run semantic3 on %s\n", toChars());
        trySemantic3(sc2);

        for (size_t i = 0; i < deferred.dim; i++)
        {
            //printf("+ run deferred semantic3 on %s\n", deferred[i]->toChars());
            deferred[i]->semantic3(NULL);
        }

        this->deferred = NULL;
    }
    else if (tinst)
    {
        bool doSemantic3 = false;
        if (sc->func && aliasdecl && aliasdecl->toAlias()->isFuncDeclaration())
        {
            /* Template function instantiation should run semantic3 immediately
             * for attribute inference.
             */
            trySemantic3(sc2);
        }
        else if (sc->func)
        {
            /* A lambda function in template arguments might capture the
             * instantiated scope context. For the correct context inference,
             * all instantiated functions should run the semantic3 immediately.
             * See also compilable/test14973.d
             */
            for (size_t i = 0; i < tdtypes.dim; i++)
            {
                RootObject *oarg = tdtypes[i];
                Dsymbol *s = getDsymbol(oarg);
                if (!s)
                    continue;

                if (TemplateDeclaration *td = s->isTemplateDeclaration())
                {
                    if (!td->literal)
                        continue;
                    assert(td->members && td->members->dim == 1);
                    s = (*td->members)[0];
                }
                if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
                {
                    if (fld->tok == TOKreserved)
                    {
                        doSemantic3 = true;
                        break;
                    }
                }
            }
            //printf("[%s] %s doSemantic3 = %d\n", loc.toChars(), toChars(), doSemantic3);
        }
        if (doSemantic3)
            trySemantic3(sc2);

        TemplateInstance *ti = tinst;
        int nest = 0;
        while (ti && !ti->deferred && ti->tinst)
        {
            ti = ti->tinst;
            if (++nest > 500)
            {
                global.gag = 0;            // ensure error message gets printed
                error("recursive expansion");
                fatal();
            }
        }
        if (ti && ti->deferred)
        {
            //printf("deferred semantic3 of %p %s, ti = %s, ti->deferred = %p\n", this, toChars(), ti->toChars());
            for (size_t i = 0; ; i++)
            {
                if (i == ti->deferred->dim)
                {
                    ti->deferred->push(this);
                    break;
                }
                if ((*ti->deferred)[i] == this)
                    break;
            }
        }
    }

    if (aliasdecl)
    {
        /* Bugzilla 13816: AliasDeclaration tries to resolve forward reference
         * twice (See inuse check in AliasDeclaration::toAlias()). It's
         * necessary to resolve mutual references of instantiated symbols, but
         * it will left a true recursive alias in tuple declaration - an
         * AliasDeclaration A refers TupleDeclaration B, and B contains A
         * in its elements.  To correctly make it an error, we strictly need to
         * resolve the alias of eponymous member.
         */
        aliasdecl = aliasdecl->toAlias2();
    }

  Laftersemantic:
    sc2->pop();

    scope->pop();

    // Give additional context info if error occurred during instantiation
    if (global.errors != errorsave)
    {
        if (!errors)
        {
            if (!tempdecl->literal)
                error(loc, "error instantiating");
            if (tinst)
                tinst->printInstantiationTrace();
        }
        errors = true;
        if (gagged)
        {
            // Errors are gagged, so remove the template instance from the
            // instance/symbol lists we added it to and reset our state to
            // finish clean and so we can try to instantiate it again later
            // (see bugzilla 4302 and 6602).
            tempdecl->removeInstance(tempdecl_instance_idx);
            if (target_symbol_list)
            {
                // Because we added 'this' in the last position above, we
                // should be able to remove it without messing other indices up.
                assert((*target_symbol_list)[target_symbol_list_idx] == this);
                target_symbol_list->remove(target_symbol_list_idx);
                memberOf = NULL;                    // no longer a member
            }
            semanticRun = PASSinit;
            inst = NULL;
            symtab = NULL;
        }
    }
    else if (errinst)
    {
        /* Bugzilla 14541: If the previous gagged instance had failed by
         * circular references, currrent "error reproduction instantiation"
         * might succeed, because of the difference of instantiated context.
         * On such case, the cached error instance needs to be overridden by the
         * succeeded instance.
         */
        //printf("replaceInstance()\n");
        TemplateInstances *tinstances = (TemplateInstances *)dmd_aaGetRvalue((AA *)tempdecl->instances, (void *)hash);
        assert(tinstances);
        for (size_t i = 0; i < tinstances->dim; i++)
        {
            TemplateInstance *ti = (*tinstances)[i];
            if (ti == errinst)
            {
                (*tinstances)[i] = this;     // override
                break;
            }
        }
    }
}


/**********************************************
 * Find template declaration corresponding to template instance.
 *
 * Returns:
 *      false if finding fails.
 * Note:
 *      This function is reentrant against error occurrence. If returns false,
 *      any members of this object won't be modified, and repetition call will
 *      reproduce same error.
 */

bool TemplateInstance::findTempDecl(Scope *sc, WithScopeSymbol **pwithsym)
{
    if (pwithsym)
        *pwithsym = NULL;

    if (havetempdecl)
        return true;

    //printf("TemplateInstance::findTempDecl() %s\n", toChars());
    if (!tempdecl)
    {
        /* Given:
         *    foo!( ... )
         * figure out which TemplateDeclaration foo refers to.
         */
        Identifier *id = name;
        Dsymbol *scopesym;
        Dsymbol *s = sc->search(loc, id, &scopesym);
        if (!s)
        {
            s = sc->search_correct(id);
            if (s)
                error("template '%s' is not defined, did you mean %s?", id->toChars(), s->toChars());
            else
                error("template '%s' is not defined", id->toChars());
            return false;
        }

        if (pwithsym)
            *pwithsym = scopesym->isWithScopeSymbol();

        /* We might have found an alias within a template when
         * we really want the template.
         */
        TemplateInstance *ti;
        if (s->parent &&
            (ti = s->parent->isTemplateInstance()) != NULL)
        {
            if (ti->tempdecl && ti->tempdecl->ident == id)
            {
                /* This is so that one can refer to the enclosing
                 * template, even if it has the same name as a member
                 * of the template, if it has a !(arguments)
                 */
                TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration();
                assert(td);
                if (td->overroot)       // if not start of overloaded list of TemplateDeclaration's
                    td = td->overroot;  // then get the start
                s = td;
            }
        }

        if (!updateTempDecl(sc, s))
        {
            return false;
        }
    }
    assert(tempdecl);

  struct ParamFwdTi
  {
    static int fp(void *param, Dsymbol *s)
    {
        TemplateDeclaration *td = s->isTemplateDeclaration();
        if (!td)
            return 0;

        TemplateInstance *ti = (TemplateInstance *)param;
        if (td->semanticRun == PASSinit)
        {
            if (td->_scope)
            {
                // Try to fix forward reference. Ungag errors while doing so.
                Ungag ungag = td->ungagSpeculative();
                td->semantic(td->_scope);
            }
            if (td->semanticRun == PASSinit)
            {
                ti->error("%s forward references template declaration %s", ti->toChars(), td->toChars());
                return 1;
            }
        }
        return 0;
    }
  };
    // Look for forward references
    OverloadSet *tovers = tempdecl->isOverloadSet();
    size_t overs_dim = tovers ? tovers->a.dim : 1;
    for (size_t oi = 0; oi < overs_dim; oi++)
    {
        if (overloadApply(tovers ? tovers->a[oi] : tempdecl, (void *)this, &ParamFwdTi::fp))
            return false;
    }
    return true;
}

/**********************************************
 * Confirm s is a valid template, then store it.
 * Input:
 *      sc
 *      s   candidate symbol of template. It may be:
 *          TemplateDeclaration
 *          FuncDeclaration with findTemplateDeclRoot() != NULL
 *          OverloadSet which contains candidates
 * Returns:
 *      true if updating succeeds.
 */

bool TemplateInstance::updateTempDecl(Scope *sc, Dsymbol *s)
{
    if (s)
    {
        Identifier *id = name;
        s = s->toAlias();

        /* If an OverloadSet, look for a unique member that is a template declaration
         */
        OverloadSet *os = s->isOverloadSet();
        if (os)
        {
            s = NULL;
            for (size_t i = 0; i < os->a.dim; i++)
            {
                Dsymbol *s2 = os->a[i];
                if (FuncDeclaration *f = s2->isFuncDeclaration())
                    s2 = f->findTemplateDeclRoot();
                else
                    s2 = s2->isTemplateDeclaration();
                if (s2)
                {
                    if (s)
                    {
                        tempdecl = os;
                        return true;
                    }
                    s = s2;
                }
            }
            if (!s)
            {
                error("template '%s' is not defined", id->toChars());
                return false;
            }
        }

        OverDeclaration *od = s->isOverDeclaration();
        if (od)
        {
            tempdecl = od;  // TODO: more strict check
            return true;
        }

        /* It should be a TemplateDeclaration, not some other symbol
         */
        if (FuncDeclaration *f = s->isFuncDeclaration())
            tempdecl = f->findTemplateDeclRoot();
        else
            tempdecl = s->isTemplateDeclaration();
        if (!tempdecl)
        {
            if (!s->parent && global.errors)
                return false;
            if (!s->parent && s->getType())
            {
                Dsymbol *s2 = s->getType()->toDsymbol(sc);
                if (!s2)
                {
                    error("%s is not a template declaration, it is a %s", id->toChars(), s->kind());
                    return false;
                }
                s = s2;
            }
            //assert(s->parent);
            TemplateInstance *ti = s->parent ? s->parent->isTemplateInstance() : NULL;
            if (ti &&
                (ti->name == s->ident ||
                 ti->toAlias()->ident == s->ident)
                &&
                ti->tempdecl)
            {
                /* This is so that one can refer to the enclosing
                 * template, even if it has the same name as a member
                 * of the template, if it has a !(arguments)
                 */
                TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration();
                assert(td);
                if (td->overroot)       // if not start of overloaded list of TemplateDeclaration's
                    td = td->overroot;  // then get the start
                tempdecl = td;
            }
            else
            {
                error("%s is not a template declaration, it is a %s", id->toChars(), s->kind());
                return false;
            }
        }
    }
    return (tempdecl != NULL);
}

/**********************************
 * Run semantic on the elements of tiargs.
 * Input:
 *      sc
 * Returns:
 *      false if one or more arguments have errors.
 * Note:
 *      This function is reentrant against error occurrence. If returns false,
 *      all elements of tiargs won't be modified.
 */

bool TemplateInstance::semanticTiargs(Scope *sc)
{
    //printf("+TemplateInstance::semanticTiargs() %s\n", toChars());
    if (semantictiargsdone)
        return true;
    if (semanticTiargs(loc, sc, tiargs, 0))
    {
        // cache the result iff semantic analysis succeeded entirely
        semantictiargsdone = 1;
        return true;
    }
    return false;
}

/**********************************
 * Run semantic of tiargs as arguments of template.
 * Input:
 *      loc
 *      sc
 *      tiargs  array of template arguments
 *      flags   1: replace const variables with their initializers
 *              2: don't devolve Parameter to Type
 * Returns:
 *      false if one or more arguments have errors.
 */

bool TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags)
{
    // Run semantic on each argument, place results in tiargs[]
    //printf("+TemplateInstance::semanticTiargs()\n");
    if (!tiargs)
        return true;
    bool err = false;
    for (size_t j = 0; j < tiargs->dim; j++)
    {
        RootObject *o = (*tiargs)[j];
        Type *ta = isType(o);
        Expression *ea = isExpression(o);
        Dsymbol *sa = isDsymbol(o);

        //printf("1: (*tiargs)[%d] = %p, s=%p, v=%p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
        if (ta)
        {
            //printf("type %s\n", ta->toChars());
            // It might really be an Expression or an Alias
            ta->resolve(loc, sc, &ea, &ta, &sa);
            if (ea) goto Lexpr;
            if (sa) goto Ldsym;
            if (ta == NULL)
            {
                assert(global.errors);
                ta = Type::terror;
            }

        Ltype:
            if (ta->ty == Ttuple)
            {
                // Expand tuple
                TypeTuple *tt = (TypeTuple *)ta;
                size_t dim = tt->arguments->dim;
                tiargs->remove(j);
                if (dim)
                {
                    tiargs->reserve(dim);
                    for (size_t i = 0; i < dim; i++)
                    {
                        Parameter *arg = (*tt->arguments)[i];
                        if (flags & 2 && arg->ident)
                            tiargs->insert(j + i, arg);
                        else
                            tiargs->insert(j + i, arg->type);
                    }
                }
                j--;
                continue;
            }
            if (ta->ty == Terror)
            {
                err = true;
                continue;
            }
            (*tiargs)[j] = ta->merge2();
        }
        else if (ea)
        {
        Lexpr:
            //printf("+[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
            if (flags & 1) // only used by __traits
            {
                ea = ::semantic(ea, sc);

                // must not interpret the args, excepting template parameters
                if (ea->op != TOKvar ||
                    (((VarExp *)ea)->var->storage_class & STCtemplateparameter))
                {
                    ea = ea->optimize(WANTvalue);
                }
            }
            else
            {
                sc = sc->startCTFE();
                ea = ::semantic(ea, sc);
                sc = sc->endCTFE();

                if (ea->op == TOKvar)
                {
                    /* This test is to skip substituting a const var with
                     * its initializer. The problem is the initializer won't
                     * match with an 'alias' parameter. Instead, do the
                     * const substitution in TemplateValueParameter::matchArg().
                     */
                }
                else if (definitelyValueParameter(ea))
                {
                    if (ea->checkValue())   // check void expression
                        ea = new ErrorExp();
                    unsigned int olderrs = global.errors;
                    ea = ea->ctfeInterpret();
                    if (global.errors != olderrs)
                        ea = new ErrorExp();
                }
            }
            //printf("-[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars());
            if (ea->op == TOKtuple)
            {
                // Expand tuple
                TupleExp *te = (TupleExp *)ea;
                size_t dim = te->exps->dim;
                tiargs->remove(j);
                if (dim)
                {
                    tiargs->reserve(dim);
                    for (size_t i = 0; i < dim; i++)
                        tiargs->insert(j + i, (*te->exps)[i]);
                }
                j--;
                continue;
            }
            if (ea->op == TOKerror)
            {
                err = true;
                continue;
            }
            (*tiargs)[j] = ea;

            if (ea->op == TOKtype)
            {
                ta = ea->type;
                goto Ltype;
            }
            if (ea->op == TOKscope)
            {
                sa = ((ScopeExp *)ea)->sds;
                goto Ldsym;
            }
            if (ea->op == TOKfunction)
            {
                FuncExp *fe = (FuncExp *)ea;
                /* A function literal, that is passed to template and
                 * already semanticed as function pointer, never requires
                 * outer frame. So convert it to global function is valid.
                 */
                if (fe->fd->tok == TOKreserved && fe->type->ty == Tpointer)
                {
                    // change to non-nested
                    fe->fd->tok = TOKfunction;
                    fe->fd->vthis = NULL;
                }
                else if (fe->td)
                {
                    /* If template argument is a template lambda,
                     * get template declaration itself. */
                    //sa = fe->td;
                    //goto Ldsym;
                }
            }
            if (ea->op == TOKdotvar)
            {
                // translate expression to dsymbol.
                sa = ((DotVarExp *)ea)->var;
                goto Ldsym;
            }
            if (ea->op == TOKtemplate)
            {
                sa = ((TemplateExp *)ea)->td;
                goto Ldsym;
            }
            if (ea->op == TOKdottd)
            {
                // translate expression to dsymbol.
                sa = ((DotTemplateExp *)ea)->td;
                goto Ldsym;
            }
        }
        else if (sa)
        {
        Ldsym:
            //printf("dsym %s %s\n", sa->kind(), sa->toChars());
            if (sa->errors)
            {
                err = true;
                continue;
            }

            TupleDeclaration *d = sa->toAlias()->isTupleDeclaration();
            if (d)
            {
                // Expand tuple
                tiargs->remove(j);
                tiargs->insert(j, d->objects);
                j--;
                continue;
            }
            if (FuncAliasDeclaration *fa = sa->isFuncAliasDeclaration())
            {
                FuncDeclaration *f = fa->toAliasFunc();
                if (!fa->hasOverloads && f->isUnique())
                {
                    // Strip FuncAlias only when the aliased function
                    // does not have any overloads.
                    sa = f;
                }
            }
            (*tiargs)[j] = sa;

            TemplateDeclaration *td = sa->isTemplateDeclaration();
            if (td && td->semanticRun == PASSinit && td->literal)
            {
                td->semantic(sc);
            }
            FuncDeclaration *fd = sa->isFuncDeclaration();
            if (fd)
                fd->functionSemantic();
        }
        else if (isParameter(o))
        {
        }
        else
        {
            assert(0);
        }
        //printf("1: (*tiargs)[%d] = %p\n", j, (*tiargs)[j]);
    }
    return !err;
}

bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs)
{
    if (havetempdecl)
    {
        TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration();
        assert(tempdecl);
        assert(tempdecl->_scope);
        // Deduce tdtypes
        tdtypes.setDim(tempdecl->parameters->dim);
        if (!tempdecl->matchWithInstance(sc, this, &tdtypes, fargs, 2))
        {
            error("incompatible arguments for template instantiation");
            return false;
        }
        // TODO: Normalizing tiargs for bugzilla 7469 is necessary?
        return true;
    }

    unsigned errs = global.errors;

  struct ParamBest
  {
    // context
    Scope *sc;
    TemplateInstance *ti;
    Objects dedtypes;
    // result
    TemplateDeclaration *td_best;
    TemplateDeclaration *td_ambig;
    MATCH m_best;

    static int fp(void *param, Dsymbol *s)
    {
        return ((ParamBest *)param)->fp(s);
    }
    int fp(Dsymbol *s)
    {
        TemplateDeclaration *td = s->isTemplateDeclaration();
        if (!td)
            return 0;

        if (td == td_best)          // skip duplicates
            return 0;

        //printf("td = %s\n", td->toPrettyChars());

        // If more arguments than parameters,
        // then this is no match.
        if (td->parameters->dim < ti->tiargs->dim)
        {
            if (!td->isVariadic())
                return 0;
        }

        dedtypes.setDim(td->parameters->dim);
        dedtypes.zero();
        assert(td->semanticRun != PASSinit);
        MATCH m = td->matchWithInstance(sc, ti, &dedtypes, ti->fargs, 0);
        //printf("matchWithInstance = %d\n", m);
        if (m <= MATCHnomatch)                 // no match at all
            return 0;

        if (m < m_best) goto Ltd_best;
        if (m > m_best) goto Ltd;

        {
        // Disambiguate by picking the most specialized TemplateDeclaration
        MATCH c1 = td->leastAsSpecialized(sc, td_best, ti->fargs);
        MATCH c2 = td_best->leastAsSpecialized(sc, td, ti->fargs);
        //printf("c1 = %d, c2 = %d\n", c1, c2);
        if (c1 > c2) goto Ltd;
        if (c1 < c2) goto Ltd_best;
        }

        td_ambig = td;
        return 0;

      Ltd_best:         // td_best is the best match so far
        td_ambig = NULL;
        return 0;

      Ltd:              // td is the new best match
        td_ambig = NULL;
        td_best = td;
        m_best = m;
        ti->tdtypes.setDim(dedtypes.dim);
        memcpy(ti->tdtypes.tdata(), dedtypes.tdata(), ti->tdtypes.dim * sizeof(void *));
        return 0;
    }
  };
    ParamBest p;
    // context
    p.ti = this;
    p.sc = sc;

    /* Since there can be multiple TemplateDeclaration's with the same
     * name, look for the best match.
     */
    TemplateDeclaration *td_last = NULL;

    OverloadSet *tovers = tempdecl->isOverloadSet();
    size_t overs_dim = tovers ? tovers->a.dim : 1;
    for (size_t oi = 0; oi < overs_dim; oi++)
    {
        // result
        p.td_best  = NULL;
        p.td_ambig = NULL;
        p.m_best   = MATCHnomatch;
        overloadApply(tovers ? tovers->a[oi] : tempdecl, &p, &ParamBest::fp);

        if (p.td_ambig)
        {
            ::error(loc, "%s %s.%s matches more than one template declaration:\n%s:     %s\nand\n%s:     %s",
                    p.td_best->kind(), p.td_best->parent->toPrettyChars(), p.td_best->ident->toChars(),
                    p.td_best->loc.toChars() , p.td_best->toChars(),
                    p.td_ambig->loc.toChars(), p.td_ambig->toChars());
            return false;
        }
        if (p.td_best)
        {
            if (!td_last)
                td_last = p.td_best;
            else if (td_last != p.td_best)
            {
                ScopeDsymbol::multiplyDefined(loc, td_last, p.td_best);
                return false;
            }
        }
    }

    if (td_last)
    {
        /* Bugzilla 7469: Normalize tiargs by using corresponding deduced
         * template value parameters and tuples for the correct mangling.
         *
         * By doing this before hasNestedArgs, CTFEable local variable will be
         * accepted as a value parameter. For example:
         *
         *  void foo() {
         *    struct S(int n) {}   // non-global template
         *    const int num = 1;   // CTFEable local variable
         *    S!num s;             // S!1 is instantiated, not S!num
         *  }
         */
        size_t dim = td_last->parameters->dim - (td_last->isVariadic() ? 1 : 0);
        for (size_t i = 0; i < dim; i++)
        {
            if (tiargs->dim <= i)
                tiargs->push(tdtypes[i]);
            assert(i < tiargs->dim);

            TemplateValueParameter *tvp = (*td_last->parameters)[i]->isTemplateValueParameter();
            if (!tvp)
                continue;
            assert(tdtypes[i]);
            // tdtypes[i] is already normalized to the required type in matchArg

            (*tiargs)[i] = tdtypes[i];
        }
        if (td_last->isVariadic() && tiargs->dim == dim && tdtypes[dim])
        {
            Tuple *va = isTuple(tdtypes[dim]);
            assert(va);
            for (size_t i = 0; i < va->objects.dim; i++)
                tiargs->push(va->objects[i]);
        }
    }
    else if (errors && inst)
    {
        // instantiation was failed with error reporting
        assert(global.errors);
        return false;
    }
    else
    {
        TemplateDeclaration *tdecl = tempdecl->isTemplateDeclaration();

        if (errs != global.errors)
            errorSupplemental(loc, "while looking for match for %s", toChars());
        else if (tdecl && !tdecl->overnext)
        {
            // Only one template, so we can give better error message
            error("does not match template declaration %s", tdecl->toChars());
        }
        else
            ::error(loc, "%s %s.%s does not match any template declaration",
                    tempdecl->kind(), tempdecl->parent->toPrettyChars(), tempdecl->ident->toChars());
        return false;
    }

    /* The best match is td_last
     */
    tempdecl = td_last;

    return (errs == global.errors);
}

/*****************************************************
 * Determine if template instance is really a template function,
 * and that template function needs to infer types from the function
 * arguments.
 *
 * Like findBestMatch, iterate possible template candidates,
 * but just looks only the necessity of type inference.
 */

bool TemplateInstance::needsTypeInference(Scope *sc, int flag)
{
    //printf("TemplateInstance::needsTypeInference() %s\n", toChars());
    if (semanticRun != PASSinit)
        return false;

  struct ParamNeedsInf
  {
    // context
    Scope *sc;
    TemplateInstance *ti;
    int flag;
    // result
    Objects dedtypes;
    size_t count;

    static int fp(void *param, Dsymbol *s)
    {
        return ((ParamNeedsInf *)param)->fp(s);
    }
    int fp(Dsymbol *s)
    {
        TemplateDeclaration *td = s->isTemplateDeclaration();
        if (!td)
        {
            return 0;
        }

        /* If any of the overloaded template declarations need inference,
         * then return true
         */
        FuncDeclaration *fd;
        if (!td->onemember)
            return 0;
        if (TemplateDeclaration *td2 = td->onemember->isTemplateDeclaration())
        {
            if (!td2->onemember || !td2->onemember->isFuncDeclaration())
                return 0;
            if (ti->tiargs->dim >= td->parameters->dim - (td->isVariadic() ? 1 : 0))
                return 0;
            return 1;
        }
        if ((fd = td->onemember->isFuncDeclaration()) == NULL ||
            fd->type->ty != Tfunction)
        {
            return 0;
        }

        for (size_t i = 0; i < td->parameters->dim; i++)
        {
            if ((*td->parameters)[i]->isTemplateThisParameter())
                return 1;
        }

        /* Determine if the instance arguments, tiargs, are all that is necessary
         * to instantiate the template.
         */
        //printf("tp = %p, td->parameters->dim = %d, tiargs->dim = %d\n", tp, td->parameters->dim, ti->tiargs->dim);
        TypeFunction *tf = (TypeFunction *)fd->type;
        if (size_t dim = Parameter::dim(tf->parameters))
        {
            TemplateParameter *tp = td->isVariadic();
            if (tp && td->parameters->dim > 1)
                return 1;

            if (!tp && ti->tiargs->dim < td->parameters->dim)
            {
                // Can remain tiargs be filled by default arguments?
                for (size_t i = ti->tiargs->dim; i < td->parameters->dim; i++)
                {
                    if (!(*td->parameters)[i]->hasDefaultArg())
                        return 1;
                }
            }

            for (size_t i = 0; i < dim; i++)
            {
                // 'auto ref' needs inference.
                if (Parameter::getNth(tf->parameters, i)->storageClass & STCauto)
                    return 1;
            }
        }

        if (!flag)
        {
            /* Calculate the need for overload resolution.
             * When only one template can match with tiargs, inference is not necessary.
             */
            dedtypes.setDim(td->parameters->dim);
            dedtypes.zero();
            if (td->semanticRun == PASSinit)
            {
                if (td->_scope)
                {
                    // Try to fix forward reference. Ungag errors while doing so.
                    Ungag ungag = td->ungagSpeculative();
                    td->semantic(td->_scope);
                }
                if (td->semanticRun == PASSinit)
                {
                    ti->error("%s forward references template declaration %s", ti->toChars(), td->toChars());
                    return 1;
                }
            }
            assert(td->semanticRun != PASSinit);
            MATCH m = td->matchWithInstance(sc, ti, &dedtypes, NULL, 0);
            if (m <= MATCHnomatch)
                return 0;
        }

        /* If there is more than one function template which matches, we may
         * need type inference (see Bugzilla 4430)
         */
        if (++count > 1)
            return 1;

        return 0;
    }
  };
    ParamNeedsInf p;
    // context
    p.ti    = this;
    p.sc    = sc;
    p.flag  = flag;
    // result
    p.count = 0;

    OverloadSet *tovers = tempdecl->isOverloadSet();
    size_t overs_dim = tovers ? tovers->a.dim : 1;
    unsigned olderrs = global.errors;
    for (size_t oi = 0; oi < overs_dim; oi++)
    {
        if (overloadApply(tovers ? tovers->a[oi] : tempdecl, &p, &ParamNeedsInf::fp))
            return true;
    }
    if (olderrs != global.errors)
    {
        if (!global.gag)
        {
            errorSupplemental(loc, "while looking for match for %s", toChars());
            semanticRun = PASSsemanticdone;
            inst = this;
        }
        errors = true;
    }
    //printf("false\n");
    return false;
}


/*****************************************
 * Determines if a TemplateInstance will need a nested
 * generation of the TemplateDeclaration.
 * Sets enclosing property if so, and returns != 0;
 */

bool TemplateInstance::hasNestedArgs(Objects *args, bool isstatic)
{
    int nested = 0;
    //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());

    /* A nested instance happens when an argument references a local
     * symbol that is on the stack.
     */
    for (size_t i = 0; i < args->dim; i++)
    {
        RootObject *o = (*args)[i];
        Expression *ea = isExpression(o);
        Dsymbol *sa = isDsymbol(o);
        Tuple *va = isTuple(o);
        if (ea)
        {
            if (ea->op == TOKvar)
            {
                sa = ((VarExp *)ea)->var;
                goto Lsa;
            }
            if (ea->op == TOKthis)
            {
                sa = ((ThisExp *)ea)->var;
                goto Lsa;
            }
            if (ea->op == TOKfunction)
            {
                if (((FuncExp *)ea)->td)
                    sa = ((FuncExp *)ea)->td;
                else
                    sa = ((FuncExp *)ea)->fd;
                goto Lsa;
            }
            // Emulate Expression::toMangleBuffer call that had exist in TemplateInstance::genIdent.
            if (ea->op != TOKint64 &&
                ea->op != TOKfloat64 &&
                ea->op != TOKcomplex80 &&
                ea->op != TOKnull &&
                ea->op != TOKstring &&
                ea->op != TOKarrayliteral &&
                ea->op != TOKassocarrayliteral &&
                ea->op != TOKstructliteral)
            {
                ea->error("expression %s is not a valid template value argument", ea->toChars());
                errors = true;
            }
        }
        else if (sa)
        {
          Lsa:
            sa = sa->toAlias();
            TemplateDeclaration *td = sa->isTemplateDeclaration();
            if (td)
            {
                TemplateInstance *ti = sa->toParent()->isTemplateInstance();
                if (ti && ti->enclosing)
                    sa = ti;
            }
            TemplateInstance *ti = sa->isTemplateInstance();
            Declaration *d = sa->isDeclaration();
            if ((td && td->literal) ||
                (ti && ti->enclosing) ||
                (d && !d->isDataseg() &&
                 !(d->storage_class & STCmanifest) &&
                 (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) &&
                 !isTemplateMixin()
                ))
            {
                // if module level template
                if (isstatic)
                {
                    Dsymbol *dparent = sa->toParent2();
                    if (!enclosing)
                        enclosing = dparent;
                    else if (enclosing != dparent)
                    {
                        /* Select the more deeply nested of the two.
                         * Error if one is not nested inside the other.
                         */
                        for (Dsymbol *p = enclosing; p; p = p->parent)
                        {
                            if (p == dparent)
                                goto L1;        // enclosing is most nested
                        }
                        for (Dsymbol *p = dparent; p; p = p->parent)
                        {
                            if (p == enclosing)
                            {
                                enclosing = dparent;
                                goto L1;        // dparent is most nested
                            }
                        }
                        error("%s is nested in both %s and %s",
                                toChars(), enclosing->toChars(), dparent->toChars());
                        errors = true;
                    }
                  L1:
                    //printf("\tnested inside %s\n", enclosing->toChars());
                    nested |= 1;
                }
                else
                {
                    error("cannot use local '%s' as parameter to non-global template %s", sa->toChars(), tempdecl->toChars());
                    errors = true;
                }
            }
        }
        else if (va)
        {
            nested |= (int)hasNestedArgs(&va->objects, isstatic);
        }
    }
    //printf("-TemplateInstance::hasNestedArgs('%s') = %d\n", tempdecl->ident->toChars(), nested);
    return nested != 0;
}

/*****************************************
 * Append 'this' to the specific module members[]
 */
Dsymbols *TemplateInstance::appendToModuleMember()
{
    Module *mi = minst;     // instantiated -> inserted module

    if (global.params.useUnitTests ||
        global.params.debuglevel)
    {
        // Turn all non-root instances to speculative
        if (mi && !mi->isRoot())
            mi = NULL;
    }

    //printf("%s->appendToModuleMember() enclosing = %s mi = %s\n",
    //    toPrettyChars(),
    //    enclosing ? enclosing->toPrettyChars() : NULL,
    //    mi ? mi->toPrettyChars() : NULL);
    if (!mi || mi->isRoot())
    {
        /* If the instantiated module is speculative or root, insert to the
         * member of a root module. Then:
         *  - semantic3 pass will get called on the instance members.
         *  - codegen pass will get a selection chance to do/skip it.
         */

        struct N
        {
            static Dsymbol *getStrictEnclosing(TemplateInstance *ti)
            {
                do
                {
                    if (ti->enclosing)
                        return ti->enclosing;
                    ti = ti->tempdecl->isInstantiated();
                }
                while (ti);
                return NULL;
            }
        };
        Dsymbol *enc = N::getStrictEnclosing(this);

        // insert target is made stable by using the module
        // where tempdecl is declared.
        mi = (enc ? enc : tempdecl)->getModule();
        if (!mi->isRoot())
            mi = mi->importedFrom;
        assert(mi->isRoot());
    }
    else
    {
        /* If the instantiated module is non-root, insert to the member of the
         * non-root module. Then:
         *  - semantic3 pass won't be called on the instance.
         *  - codegen pass won't reach to the instance.
         */
    }
    //printf("\t--> mi = %s\n", mi->toPrettyChars());

    if (memberOf == mi)     // already a member
    {
        return NULL;
    }

    Dsymbols *a = mi->members;
    a->push(this);
    memberOf = mi;
    if (mi->semanticRun >= PASSsemantic2done && mi->isRoot())
        Module::addDeferredSemantic2(this);
    if (mi->semanticRun >= PASSsemantic3done && mi->isRoot())
        Module::addDeferredSemantic3(this);
    return a;
}

/****************************************
 * This instance needs an identifier for name mangling purposes.
 * Create one by taking the template declaration name and adding
 * the type signature for it.
 */

Identifier *TemplateInstance::genIdent(Objects *args)
{
    TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration();
    assert(tempdecl);

    //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
    OutBuffer buf;
    const char *id = tempdecl->ident->toChars();
    if (!members)
    {
        // Use "__U" for the symbols declared inside template constraint.
        buf.printf("__U%llu%s", (ulonglong)strlen(id), id);
    }
    else
        buf.printf("__T%llu%s", (ulonglong)strlen(id), id);
    size_t nparams = tempdecl->parameters->dim - (tempdecl->isVariadic() ? 1 : 0);
    for (size_t i = 0; i < args->dim; i++)
    {
        RootObject *o = (*args)[i];
        Type *ta = isType(o);
        Expression *ea = isExpression(o);
        Dsymbol *sa = isDsymbol(o);
        Tuple *va = isTuple(o);
        //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va);
        if (i < nparams && (*tempdecl->parameters)[i]->specialization())
            buf.writeByte('H');     // Bugzilla 6574
        if (ta)
        {
            buf.writeByte('T');
            if (ta->deco)
                buf.writestring(ta->deco);
            else
            {
                assert(global.errors);
            }
        }
        else if (ea)
        {
            // Don't interpret it yet, it might actually be an alias template parameter.
            // Only constfold manifest constants, not const/immutable lvalues, see https://issues.dlang.org/show_bug.cgi?id=17339.
            const bool keepLvalue = true;
            ea = ea->optimize(WANTvalue, keepLvalue);
            if (ea->op == TOKvar)
            {
                sa = ((VarExp *)ea)->var;
                ea = NULL;
                goto Lsa;
            }
            if (ea->op == TOKthis)
            {
                sa = ((ThisExp *)ea)->var;
                ea = NULL;
                goto Lsa;
            }
            if (ea->op == TOKfunction)
            {
                if (((FuncExp *)ea)->td)
                    sa = ((FuncExp *)ea)->td;
                else
                    sa = ((FuncExp *)ea)->fd;
                ea = NULL;
                goto Lsa;
            }
            buf.writeByte('V');
            if (ea->op == TOKtuple)
            {
                ea->error("tuple is not a valid template value argument");
                continue;
            }
            // Now that we know it is not an alias, we MUST obtain a value
            unsigned olderr = global.errors;
            ea = ea->ctfeInterpret();
            if (ea->op == TOKerror || olderr != global.errors)
                continue;

            /* Use deco that matches what it would be for a function parameter
             */
            buf.writestring(ea->type->deco);
            mangleToBuffer(ea, &buf);
        }
        else if (sa)
        {
          Lsa:
            buf.writeByte('S');
            sa = sa->toAlias();
            Declaration *d = sa->isDeclaration();
            if (d && (!d->type || !d->type->deco))
            {
                error("forward reference of %s %s", d->kind(), d->toChars());
                continue;
            }

            OutBuffer bufsa;
            mangleToBuffer(sa, &bufsa);
            const char *s = bufsa.extractString();

            /* Bugzilla 3043: if the first character of s is a digit this
             * causes ambiguity issues because the digits of the two numbers are adjacent.
             * Current demanglers resolve this by trying various places to separate the
             * numbers until one gets a successful demangle.
             * Unfortunately, fixing this ambiguity will break existing binary
             * compatibility and the demanglers, so we'll leave it as is.
             */
            buf.printf("%u%s", (unsigned)strlen(s), s);
        }
        else if (va)
        {
            assert(i + 1 == args->dim);         // must be last one
            args = &va->objects;
            i = -(size_t)1;
        }
        else
            assert(0);
    }
    buf.writeByte('Z');
    id = buf.peekString();
    //printf("\tgenIdent = %s\n", id);
    return Identifier::idPool(id);
}

/*************************************
 * Lazily generate identifier for template instance.
 * This is because 75% of the ident's are never needed.
 */

Identifier *TemplateInstance::getIdent()
{
    if (!ident && inst && !errors)
        ident = genIdent(tiargs);         // need an identifier for name mangling purposes.
    return ident;
}

/****************************************************
 * Declare parameters of template instance, initialize them with the
 * template instance arguments.
 */

void TemplateInstance::declareParameters(Scope *sc)
{
    TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration();
    assert(tempdecl);

    //printf("TemplateInstance::declareParameters()\n");
    for (size_t i = 0; i < tdtypes.dim; i++)
    {
        TemplateParameter *tp = (*tempdecl->parameters)[i];
        //RootObject *o = (*tiargs)[i];
        RootObject *o = tdtypes[i];          // initializer for tp

        //printf("\ttdtypes[%d] = %p\n", i, o);
        tempdecl->declareParameter(sc, tp, o);
    }
}

void TemplateInstance::semantic2(Scope *sc)
{
    if (semanticRun >= PASSsemantic2)
        return;
    semanticRun = PASSsemantic2;
    if (!errors && members)
    {
        TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration();
        assert(tempdecl);

        sc = tempdecl->_scope;
        assert(sc);
        sc = sc->push(argsym);
        sc = sc->push(this);
        sc->tinst = this;
        sc->minst = minst;

        int needGagging = (gagged && !global.gag);
        unsigned int olderrors = global.errors;
        int oldGaggedErrors = -1;       // dead-store to prevent spurious warning
        if (needGagging)
            oldGaggedErrors = global.startGagging();

        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            s->semantic2(sc);
            if (gagged && global.errors != olderrors)
                break;
        }

        if (global.errors != olderrors)
        {
            if (!errors)
            {
                if (!tempdecl->literal)
                    error(loc, "error instantiating");
                if (tinst)
                    tinst->printInstantiationTrace();
            }
            errors = true;
        }
        if (needGagging)
            global.endGagging(oldGaggedErrors);

        sc = sc->pop();
        sc->pop();
    }
}

void TemplateInstance::semantic3(Scope *sc)
{
//if (toChars()[0] == 'D') *(char*)0=0;
    if (semanticRun >= PASSsemantic3)
        return;
    semanticRun = PASSsemantic3;
    if (!errors && members)
    {
        TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration();
        assert(tempdecl);

        sc = tempdecl->_scope;
        sc = sc->push(argsym);
        sc = sc->push(this);
        sc->tinst = this;
        sc->minst = minst;

        int needGagging = (gagged && !global.gag);
        unsigned int olderrors = global.errors;
        int oldGaggedErrors = -1;       // dead-store to prevent spurious warning
        /* If this is a gagged instantiation, gag errors.
         * Future optimisation: If the results are actually needed, errors
         * would already be gagged, so we don't really need to run semantic
         * on the members.
         */
        if (needGagging)
            oldGaggedErrors = global.startGagging();

        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            s->semantic3(sc);
            if (gagged && global.errors != olderrors)
                break;
        }

        if (global.errors != olderrors)
        {
            if (!errors)
            {
                if (!tempdecl->literal)
                    error(loc, "error instantiating");
                if (tinst)
                    tinst->printInstantiationTrace();
            }
            errors = true;
        }
        if (needGagging)
            global.endGagging(oldGaggedErrors);

        sc = sc->pop();
        sc->pop();
    }
}

/**************************************
 * Given an error instantiating the TemplateInstance,
 * give the nested TemplateInstance instantiations that got
 * us here. Those are a list threaded into the nested scopes.
 */
void TemplateInstance::printInstantiationTrace()
{
    if (global.gag)
        return;

    const unsigned max_shown = 6;
    const char format[] = "instantiated from here: %s";

    // determine instantiation depth and number of recursive instantiations
    unsigned n_instantiations = 1;
    unsigned n_totalrecursions = 0;
    for (TemplateInstance *cur = this; cur; cur = cur->tinst)
    {
        ++n_instantiations;
        // If two instantiations use the same declaration, they are recursive.
        // (this works even if they are instantiated from different places in the
        // same template).
        // In principle, we could also check for multiple-template recursion, but it's
        // probably not worthwhile.
        if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl
            && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc))
            ++n_totalrecursions;
    }

    // show full trace only if it's short or verbose is on
    if (n_instantiations <= max_shown || global.params.verbose)
    {
        for (TemplateInstance *cur = this; cur; cur = cur->tinst)
        {
            cur->errors = true;
            errorSupplemental(cur->loc, format, cur->toChars());
        }
    }
    else if (n_instantiations - n_totalrecursions <= max_shown)
    {
        // By collapsing recursive instantiations into a single line,
        // we can stay under the limit.
        int recursionDepth=0;
        for (TemplateInstance *cur = this; cur; cur = cur->tinst)
        {
            cur->errors = true;
            if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl
                    && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc))
            {
                ++recursionDepth;
            }
            else
            {
                if (recursionDepth)
                    errorSupplemental(cur->loc, "%d recursive instantiations from here: %s", recursionDepth+2, cur->toChars());
                else
                    errorSupplemental(cur->loc, format, cur->toChars());
                recursionDepth = 0;
            }
        }
    }
    else
    {
        // Even after collapsing the recursions, the depth is too deep.
        // Just display the first few and last few instantiations.
        unsigned i = 0;
        for (TemplateInstance *cur = this; cur; cur = cur->tinst)
        {
            cur->errors = true;

            if (i == max_shown / 2)
                errorSupplemental(cur->loc, "... (%d instantiations, -v to show) ...", n_instantiations - max_shown);

            if (i < max_shown / 2 ||
                i >= n_instantiations - max_shown + max_shown / 2)
                errorSupplemental(cur->loc, format, cur->toChars());
            ++i;
        }
    }
}

Dsymbol *TemplateInstance::toAlias()
{
    if (!inst)
    {
        // Maybe we can resolve it
        if (_scope)
        {
            semantic(_scope);
        }
        if (!inst)
        {
            error("cannot resolve forward reference");
            errors = true;
            return this;
        }
    }

    if (inst != this)
        return inst->toAlias();

    if (aliasdecl)
    {
        return aliasdecl->toAlias();
    }

    return inst;
}

const char *TemplateInstance::kind() const
{
    return "template instance";
}

bool TemplateInstance::oneMember(Dsymbol **ps, Identifier *)
{
    *ps = NULL;
    return true;
}

const char *TemplateInstance::toChars()
{
    OutBuffer buf;
    toCBufferInstance(this, &buf);
    return buf.extractString();
}

const char *TemplateInstance::toPrettyCharsHelper()
{
    OutBuffer buf;
    toCBufferInstance(this, &buf, true);
    return buf.extractString();
}

/*************************************
 * Compare proposed template instantiation with existing template instantiation.
 * Note that this is not commutative because of the auto ref check.
 * Params:
 *  this = proposed template instantiation
 *  o = existing template instantiation
 * Returns:
 *  0 for match, 1 for no match
 */
int TemplateInstance::compare(RootObject *o)
{
    TemplateInstance *ti = (TemplateInstance *)o;

    //printf("this = %p, ti = %p\n", this, ti);
    assert(tdtypes.dim == ti->tdtypes.dim);

    // Nesting must match
    if (enclosing != ti->enclosing)
    {
        //printf("test2 enclosing %s ti->enclosing %s\n", enclosing ? enclosing->toChars() : "", ti->enclosing ? ti->enclosing->toChars() : "");
        goto Lnotequals;
    }
    //printf("parent = %s, ti->parent = %s\n", parent->toPrettyChars(), ti->parent->toPrettyChars());

    if (!arrayObjectMatch(&tdtypes, &ti->tdtypes))
        goto Lnotequals;

    /* Template functions may have different instantiations based on
     * "auto ref" parameters.
     */
    if (FuncDeclaration *fd = ti->toAlias()->isFuncDeclaration())
    {
        if (!fd->errors)
        {
            Parameters *fparameters = fd->getParameters(NULL);
            size_t nfparams = Parameter::dim(fparameters);   // Num function parameters
            for (size_t j = 0; j < nfparams; j++)
            {
                Parameter *fparam = Parameter::getNth(fparameters, j);
                if (fparam->storageClass & STCautoref)       // if "auto ref"
                {
                    if (!fargs)
                        goto Lnotequals;
                    if (fargs->dim <= j)
                        break;
                    Expression *farg = (*fargs)[j];
                    if (farg->isLvalue())
                    {
                        if (!(fparam->storageClass & STCref))
                            goto Lnotequals;                // auto ref's don't match
                    }
                    else
                    {
                        if (fparam->storageClass & STCref)
                            goto Lnotequals;                // auto ref's don't match
                    }
                }
            }
        }
    }
    return 0;

  Lnotequals:
    return 1;
}

hash_t TemplateInstance::toHash()
{
    if (!hash)
    {
        hash = (size_t)(void *)enclosing;
        hash += arrayObjectHash(&tdtypes);
        hash += hash == 0;
    }
    return hash;
}

/**************************************
 * IsExpression can evaluate the specified type speculatively, and even if
 * it instantiates any symbols, they are normally unnecessary for the
 * final executable.
 * However, if those symbols leak to the actual code, compiler should remark
 * them as non-speculative to generate their code and link to the final executable.
 */
void unSpeculative(Scope *sc, RootObject *o)
{
    if (!o)
        return;

    if (Tuple *tup = isTuple(o))
    {
        for (size_t i = 0; i < tup->objects.dim; i++)
        {
            unSpeculative(sc, tup->objects[i]);
        }
        return;
    }

    Dsymbol *s = getDsymbol(o);
    if (!s)
        return;

    if (Declaration *d = s->isDeclaration())
    {
        if (VarDeclaration *vd = d->isVarDeclaration())
            o = vd->type;
        else if (AliasDeclaration *ad = d->isAliasDeclaration())
        {
            o = ad->getType();
            if (!o)
                o = ad->toAlias();
        }
        else
            o = d->toAlias();

        s = getDsymbol(o);
        if (!s)
            return;
    }

    if (TemplateInstance *ti = s->isTemplateInstance())
    {
        // If the instance is already non-speculative,
        // or it is leaked to the speculative scope.
        if (ti->minst != NULL || sc->minst == NULL)
            return;

        // Remark as non-speculative instance.
        ti->minst = sc->minst;
        if (!ti->tinst)
            ti->tinst = sc->tinst;

        unSpeculative(sc, ti->tempdecl);
    }

    if (TemplateInstance *ti = s->isInstantiated())
        unSpeculative(sc, ti);
}

/***********************************************
 * Returns true if this is not instantiated in non-root module, and
 * is a part of non-speculative instantiatiation.
 *
 * Note: minst does not stabilize until semantic analysis is completed,
 * so don't call this function during semantic analysis to return precise result.
 */
bool TemplateInstance::needsCodegen()
{
    // Now -allInst is just for the backward compatibility.
    if (global.params.allInst)
    {
        //printf("%s minst = %s, enclosing (%s)->isNonRoot = %d\n",
        //    toPrettyChars(), minst ? minst->toChars() : NULL,
        //    enclosing ? enclosing->toPrettyChars() : NULL, enclosing && enclosing->inNonRoot());
        if (enclosing)
        {
            // Bugzilla 14588: If the captured context is not a function
            // (e.g. class), the instance layout determination is guaranteed,
            // because the semantic/semantic2 pass will be executed
            // even for non-root instances.
            if (!enclosing->isFuncDeclaration())
                return true;

            // Bugzilla 14834: If the captured context is a function,
            // this excessive instantiation may cause ODR violation, because
            // -allInst and others doesn't guarantee the semantic3 execution
            // for that function.

            // If the enclosing is also an instantiated function,
            // we have to rely on the ancestor's needsCodegen() result.
            if (TemplateInstance *ti = enclosing->isInstantiated())
                return ti->needsCodegen();

            // Bugzilla 13415: If and only if the enclosing scope needs codegen,
            // this nested templates would also need code generation.
            return !enclosing->inNonRoot();
        }
        return true;
    }

    if (!minst)
    {
        // If this is a speculative instantiation,
        // 1. do codegen if ancestors really needs codegen.
        // 2. become non-speculative if siblings are not speculative

        TemplateInstance *tnext = this->tnext;
        TemplateInstance *tinst = this->tinst;
        // At first, disconnect chain first to prevent infinite recursion.
        this->tnext = NULL;
        this->tinst = NULL;

        // Determine necessity of tinst before tnext.
        if (tinst && tinst->needsCodegen())
        {
            minst = tinst->minst;   // cache result
            assert(minst);
            assert(minst->isRoot() || minst->rootImports());
            return true;
        }
        if (tnext && (tnext->needsCodegen() || tnext->minst))
        {
            minst = tnext->minst;   // cache result
            assert(minst);
            return minst->isRoot() || minst->rootImports();
        }

        // Elide codegen because this is really speculative.
        return false;
    }

    /* Even when this is reached to the codegen pass,
     * a non-root nested template should not generate code,
     * due to avoid ODR violation.
     */
    if (enclosing && enclosing->inNonRoot())
    {
        if (tinst)
        {
            bool r = tinst->needsCodegen();
            minst = tinst->minst; // cache result
            return r;
        }
        if (tnext)
        {
            bool r = tnext->needsCodegen();
            minst = tnext->minst; // cache result
            return r;
        }
        return false;
    }

    /* The issue is that if the importee is compiled with a different -debug
     * setting than the importer, the importer may believe it exists
     * in the compiled importee when it does not, when the instantiation
     * is behind a conditional debug declaration.
     */
    // workaround for Bugzilla 11239
    if (global.params.useUnitTests ||
        global.params.debuglevel)
    {
        // Prefer instantiations from root modules, to maximize link-ability.
        if (minst->isRoot())
            return true;

        TemplateInstance *tnext = this->tnext;
        TemplateInstance *tinst = this->tinst;
        this->tnext = NULL;
        this->tinst = NULL;

        if (tinst && tinst->needsCodegen())
        {
            minst = tinst->minst;   // cache result
            assert(minst);
            assert(minst->isRoot() || minst->rootImports());
            return true;
        }
        if (tnext && tnext->needsCodegen())
        {
            minst = tnext->minst;   // cache result
            assert(minst);
            assert(minst->isRoot() || minst->rootImports());
            return true;
        }

        // Bugzilla 2500 case
        if (minst->rootImports())
            return true;

        // Elide codegen because this is not included in root instances.
        return false;
    }
    else
    {
        // Prefer instantiations from non-root module, to minimize object code size.

        /* If a TemplateInstance is ever instantiated by non-root modules,
         * we do not have to generate code for it,
         * because it will be generated when the non-root module is compiled.
         *
         * But, if the non-root 'minst' imports any root modules, it might still need codegen.
         *
         * The problem is if A imports B, and B imports A, and both A
         * and B instantiate the same template, does the compilation of A
         * or the compilation of B do the actual instantiation?
         *
         * See Bugzilla 2500.
         */
        if (!minst->isRoot() && !minst->rootImports())
            return false;

        TemplateInstance *tnext = this->tnext;
        this->tnext = NULL;

        if (tnext && !tnext->needsCodegen() && tnext->minst)
        {
            minst = tnext->minst;   // cache result
            assert(!minst->isRoot());
            return false;
        }

        // Do codegen because this is not included in non-root instances.
        return true;
    }
}

/* ======================== TemplateMixin ================================ */

TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, TypeQualified *tqual, Objects *tiargs)
        : TemplateInstance(loc, tqual->idents.dim ? (Identifier *)tqual->idents[tqual->idents.dim - 1]
                                                  : ((TypeIdentifier *)tqual)->ident)
{
    //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : "");
    this->ident = ident;
    this->tqual = tqual;
    this->tiargs = tiargs ? tiargs : new Objects();
}

Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *)
{
    TemplateMixin *tm = new TemplateMixin(loc, ident,
                (TypeQualified *)tqual->syntaxCopy(), tiargs);
    return TemplateInstance::syntaxCopy(tm);
}

bool TemplateMixin::findTempDecl(Scope *sc)
{
    // Follow qualifications to find the TemplateDeclaration
    if (!tempdecl)
    {
        Expression *e;
        Type *t;
        Dsymbol *s;
        tqual->resolve(loc, sc, &e, &t, &s);
        if (!s)
        {
            error("is not defined");
            return false;
        }
        s = s->toAlias();
        tempdecl = s->isTemplateDeclaration();
        OverloadSet *os = s->isOverloadSet();

        /* If an OverloadSet, look for a unique member that is a template declaration
         */
        if (os)
        {
            Dsymbol *ds = NULL;
            for (size_t i = 0; i < os->a.dim; i++)
            {
                Dsymbol *s2 = os->a[i]->isTemplateDeclaration();
                if (s2)
                {
                    if (ds)
                    {
                        tempdecl = os;
                        break;
                    }
                    ds = s2;
                }
            }
        }
        if (!tempdecl)
        {
            error("%s isn't a template", s->toChars());
            return false;
        }
    }
    assert(tempdecl);

  struct ParamFwdResTm
  {
    static int fp(void *param, Dsymbol *s)
    {
        TemplateDeclaration *td = s->isTemplateDeclaration();
        if (!td)
            return 0;

        TemplateMixin *tm = (TemplateMixin *)param;
        if (td->semanticRun == PASSinit)
        {
            if (td->_scope)
                td->semantic(td->_scope);
            else
            {
                tm->semanticRun = PASSinit;
                return 1;
            }
        }
        return 0;
    }
  };
    // Look for forward references
    OverloadSet *tovers = tempdecl->isOverloadSet();
    size_t overs_dim = tovers ? tovers->a.dim : 1;
    for (size_t oi = 0; oi < overs_dim; oi++)
    {
        if (overloadApply(tovers ? tovers->a[oi] : tempdecl, (void *)this, &ParamFwdResTm::fp))
            return false;
    }
    return true;
}

void TemplateMixin::semantic(Scope *sc)
{
    if (semanticRun != PASSinit)
    {
        // When a class/struct contains mixin members, and is done over
        // because of forward references, never reach here so semanticRun
        // has been reset to PASSinit.
        return;
    }
    semanticRun = PASSsemantic;

    Scope *scx = NULL;
    if (_scope)
    {
        sc = _scope;
        scx = _scope;            // save so we don't make redundant copies
        _scope = NULL;
    }

    /* Run semantic on each argument, place results in tiargs[],
     * then find best match template with tiargs
     */
    if (!findTempDecl(sc) ||
        !semanticTiargs(sc) ||
        !findBestMatch(sc, NULL))
    {
        if (semanticRun == PASSinit)    // forward reference had occured
        {
            //printf("forward reference - deferring\n");
            _scope = scx ? scx : sc->copy();
            _scope->setNoFree();
            _scope->_module->addDeferredSemantic(this);
            return;
        }

        inst = this;
        errors = true;
        return;         // error recovery
    }
    TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration();
    assert(tempdecl);

    if (!ident)
    {
        /* Assign scope local unique identifier, as same as lambdas.
         */
        const char *s = "__mixin";

        DsymbolTable *symtab;
        if (FuncDeclaration *func = sc->parent->isFuncDeclaration())
        {
            symtab = func->localsymtab;
            if (symtab)
            {
                // Inside template constraint, symtab is not set yet.
                goto L1;
            }
        }
        else
        {
            symtab = sc->parent->isScopeDsymbol()->symtab;
        L1:
            assert(symtab);
            int num = (int)dmd_aaLen(symtab->tab) + 1;
            ident = Identifier::generateId(s, num);
            symtab->insert(this);
        }
    }

    inst = this;
    parent = sc->parent;

    /* Detect recursive mixin instantiations.
     */
    for (Dsymbol *s = parent; s; s = s->parent)
    {
        //printf("\ts = '%s'\n", s->toChars());
        TemplateMixin *tm = s->isTemplateMixin();
        if (!tm || tempdecl != tm->tempdecl)
            continue;

        /* Different argument list lengths happen with variadic args
         */
        if (tiargs->dim != tm->tiargs->dim)
            continue;

        for (size_t i = 0; i < tiargs->dim; i++)
        {
            RootObject *o = (*tiargs)[i];
            Type *ta = isType(o);
            Expression *ea = isExpression(o);
            Dsymbol *sa = isDsymbol(o);
            RootObject *tmo = (*tm->tiargs)[i];
            if (ta)
            {
                Type *tmta = isType(tmo);
                if (!tmta)
                    goto Lcontinue;
                if (!ta->equals(tmta))
                    goto Lcontinue;
            }
            else if (ea)
            {
                Expression *tme = isExpression(tmo);
                if (!tme || !ea->equals(tme))
                    goto Lcontinue;
            }
            else if (sa)
            {
                Dsymbol *tmsa = isDsymbol(tmo);
                if (sa != tmsa)
                    goto Lcontinue;
            }
            else
                assert(0);
        }
        error("recursive mixin instantiation");
        return;

    Lcontinue:
        continue;
    }

    // Copy the syntax trees from the TemplateDeclaration
    members = Dsymbol::arraySyntaxCopy(tempdecl->members);
    if (!members)
        return;

    symtab = new DsymbolTable();

    for (Scope *sce = sc; 1; sce = sce->enclosing)
    {
        ScopeDsymbol *sds = (ScopeDsymbol *)sce->scopesym;
        if (sds)
        {
            sds->importScope(this, Prot(PROTpublic));
            break;
        }
    }

    Scope *scy = sc->push(this);
    scy->parent = this;

    argsym = new ScopeDsymbol();
    argsym->parent = scy->parent;
    Scope *argscope = scy->push(argsym);

    unsigned errorsave = global.errors;

    // Declare each template parameter as an alias for the argument type
    declareParameters(argscope);

    // Add members to enclosing scope, as well as this scope
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->addMember(argscope, this);
        //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym);
        //printf("s->parent = %s\n", s->parent->toChars());
    }

    // Do semantic() analysis on template instance members
    Scope *sc2 = argscope->push(this);
    //size_t deferred_dim = Module::deferred.dim;

    static int nest;
    //printf("%d\n", nest);
    if (++nest > 500)
    {
        global.gag = 0;                 // ensure error message gets printed
        error("recursive expansion");
        fatal();
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->setScope(sc2);
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->importAll(sc2);
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->semantic(sc2);
    }

    nest--;

    /* In DeclDefs scope, TemplateMixin does not have to handle deferred symbols.
     * Because the members would already call Module::addDeferredSemantic() for themselves.
     * See Struct, Class, Interface, and EnumDeclaration::semantic().
     */
    //if (!sc->func && Module::deferred.dim > deferred_dim) {}

    AggregateDeclaration *ad = toParent()->isAggregateDeclaration();
    if (sc->func && !ad)
    {
        semantic2(sc2);
        semantic3(sc2);
    }

    // Give additional context info if error occurred during instantiation
    if (global.errors != errorsave)
    {
        error("error instantiating");
        errors = true;
    }

    sc2->pop();
    argscope->pop();
    scy->pop();
}

void TemplateMixin::semantic2(Scope *sc)
{
    if (semanticRun >= PASSsemantic2)
        return;
    semanticRun = PASSsemantic2;
    if (members)
    {
        assert(sc);
        sc = sc->push(argsym);
        sc = sc->push(this);
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            s->semantic2(sc);
        }
        sc = sc->pop();
        sc->pop();
    }
}

void TemplateMixin::semantic3(Scope *sc)
{
    if (semanticRun >= PASSsemantic3)
        return;
    semanticRun = PASSsemantic3;
    if (members)
    {
        sc = sc->push(argsym);
        sc = sc->push(this);
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            s->semantic3(sc);
        }
        sc = sc->pop();
        sc->pop();
    }
}

const char *TemplateMixin::kind() const
{
    return "mixin";
}

bool TemplateMixin::oneMember(Dsymbol **ps, Identifier *ident)
{
    return Dsymbol::oneMember(ps, ident);
}

int TemplateMixin::apply(Dsymbol_apply_ft_t fp, void *param)
{
    if (_scope) // if fwd reference
        semantic(NULL); // try to resolve it
    if (members)
    {
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            if (s)
            {
                if (s->apply(fp, param))
                    return 1;
            }
        }
    }
    return 0;
}

bool TemplateMixin::hasPointers()
{
    //printf("TemplateMixin::hasPointers() %s\n", toChars());

    if (members)
    {
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            //printf(" s = %s %s\n", s->kind(), s->toChars());
            if (s->hasPointers())
            {
                return true;
            }
        }
    }
    return false;
}

void TemplateMixin::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
{
    //printf("TemplateMixin::setFieldOffset() %s\n", toChars());
    if (_scope)                  // if fwd reference
        semantic(NULL);         // try to resolve it
    if (members)
    {
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            //printf("\t%s\n", s->toChars());
            s->setFieldOffset(ad, poffset, isunion);
        }
    }
}

const char *TemplateMixin::toChars()
{
    OutBuffer buf;
    toCBufferInstance(this, &buf);
    return buf.extractString();
}
