
/* 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/mtype.c
 */

#include "root/dsystem.h"
#include "root/checkedint.h"
#include "root/rmem.h"

#include "mars.h"
#include "mangle.h"
#include "dsymbol.h"
#include "mtype.h"
#include "scope.h"
#include "init.h"
#include "expression.h"
#include "statement.h"
#include "attrib.h"
#include "declaration.h"
#include "template.h"
#include "id.h"
#include "enum.h"
#include "module.h"
#include "import.h"
#include "aggregate.h"
#include "hdrgen.h"
#include "target.h"

bool symbolIsVisible(Scope *sc, Dsymbol *s);
typedef int (*ForeachDg)(void *ctx, size_t paramidx, Parameter *param);
int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn = NULL);
FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL);
Expression *extractSideEffect(Scope *sc, const char *name, Expression **e0, Expression *e, bool alwaysCopy = false);
Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
Expression *semantic(Expression *e, Scope *sc);
Expression *semanticY(DotIdExp *exp, Scope *sc, int flag);
Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag);
Expression *typeToExpression(Type *t);
Expression *typeToExpressionHelper(TypeQualified *t, Expression *e, size_t i = 0);
Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);

int Tsize_t = Tuns32;
int Tptrdiff_t = Tint32;

/***************************** Type *****************************/

ClassDeclaration *Type::dtypeinfo;
ClassDeclaration *Type::typeinfoclass;
ClassDeclaration *Type::typeinfointerface;
ClassDeclaration *Type::typeinfostruct;
ClassDeclaration *Type::typeinfopointer;
ClassDeclaration *Type::typeinfoarray;
ClassDeclaration *Type::typeinfostaticarray;
ClassDeclaration *Type::typeinfoassociativearray;
ClassDeclaration *Type::typeinfovector;
ClassDeclaration *Type::typeinfoenum;
ClassDeclaration *Type::typeinfofunction;
ClassDeclaration *Type::typeinfodelegate;
ClassDeclaration *Type::typeinfotypelist;
ClassDeclaration *Type::typeinfoconst;
ClassDeclaration *Type::typeinfoinvariant;
ClassDeclaration *Type::typeinfoshared;
ClassDeclaration *Type::typeinfowild;

TemplateDeclaration *Type::rtinfo;

Type *Type::tvoid;
Type *Type::tint8;
Type *Type::tuns8;
Type *Type::tint16;
Type *Type::tuns16;
Type *Type::tint32;
Type *Type::tuns32;
Type *Type::tint64;
Type *Type::tuns64;
Type *Type::tint128;
Type *Type::tuns128;
Type *Type::tfloat32;
Type *Type::tfloat64;
Type *Type::tfloat80;

Type *Type::timaginary32;
Type *Type::timaginary64;
Type *Type::timaginary80;

Type *Type::tcomplex32;
Type *Type::tcomplex64;
Type *Type::tcomplex80;

Type *Type::tbool;
Type *Type::tchar;
Type *Type::twchar;
Type *Type::tdchar;

Type *Type::tshiftcnt;
Type *Type::terror;
Type *Type::tnull;

Type *Type::tsize_t;
Type *Type::tptrdiff_t;
Type *Type::thash_t;

Type *Type::tvoidptr;
Type *Type::tstring;
Type *Type::twstring;
Type *Type::tdstring;
Type *Type::tvalist;
Type *Type::basic[TMAX];
unsigned char Type::sizeTy[TMAX];
StringTable Type::stringtable;

void initTypeMangle();

Type::Type(TY ty)
{
    this->ty = ty;
    this->mod = 0;
    this->deco = NULL;
    this->cto = NULL;
    this->ito = NULL;
    this->sto = NULL;
    this->scto = NULL;
    this->wto = NULL;
    this->wcto = NULL;
    this->swto = NULL;
    this->swcto = NULL;
    this->pto = NULL;
    this->rto = NULL;
    this->arrayof = NULL;
    this->vtinfo = NULL;
    this->ctype = NULL;
}

const char *Type::kind()
{
    assert(false); // should be overridden
    return NULL;
}

Type *Type::copy()
{
    void *pt = mem.xmalloc(sizeTy[ty]);
    Type *t = (Type *)memcpy(pt, (void *)this, sizeTy[ty]);
    return t;
}

Type *Type::syntaxCopy()
{
    print();
    fprintf(stderr, "ty = %d\n", ty);
    assert(0);
    return this;
}

bool Type::equals(RootObject *o)
{
    Type *t = (Type *)o;
    //printf("Type::equals(%s, %s)\n", toChars(), t->toChars());
    // deco strings are unique
    // and semantic() has been run
    if (this == o || ((t && deco == t->deco) && deco != NULL))
    {
        //printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
        return true;
    }
    //if (deco && t && t->deco) printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
    return false;
}

bool Type::equivalent(Type *t)
{
    return immutableOf()->equals(t->immutableOf());
}

void Type::_init()
{
    stringtable._init(14000);

    for (size_t i = 0; i < TMAX; i++)
        sizeTy[i] = sizeof(TypeBasic);
    sizeTy[Tsarray] = sizeof(TypeSArray);
    sizeTy[Tarray] = sizeof(TypeDArray);
    sizeTy[Taarray] = sizeof(TypeAArray);
    sizeTy[Tpointer] = sizeof(TypePointer);
    sizeTy[Treference] = sizeof(TypeReference);
    sizeTy[Tfunction] = sizeof(TypeFunction);
    sizeTy[Tdelegate] = sizeof(TypeDelegate);
    sizeTy[Tident] = sizeof(TypeIdentifier);
    sizeTy[Tinstance] = sizeof(TypeInstance);
    sizeTy[Ttypeof] = sizeof(TypeTypeof);
    sizeTy[Tenum] = sizeof(TypeEnum);
    sizeTy[Tstruct] = sizeof(TypeStruct);
    sizeTy[Tclass] = sizeof(TypeClass);
    sizeTy[Ttuple] = sizeof(TypeTuple);
    sizeTy[Tslice] = sizeof(TypeSlice);
    sizeTy[Treturn] = sizeof(TypeReturn);
    sizeTy[Terror] = sizeof(TypeError);
    sizeTy[Tnull] = sizeof(TypeNull);
    sizeTy[Tvector] = sizeof(TypeVector);

    initTypeMangle();

    // Set basic types
    static TY basetab[] =
        { Tvoid, Tint8, Tuns8, Tint16, Tuns16, Tint32, Tuns32, Tint64, Tuns64,
          Tint128, Tuns128,
          Tfloat32, Tfloat64, Tfloat80,
          Timaginary32, Timaginary64, Timaginary80,
          Tcomplex32, Tcomplex64, Tcomplex80,
          Tbool,
          Tchar, Twchar, Tdchar, Terror };

    for (size_t i = 0; basetab[i] != Terror; i++)
    {
        Type *t = new TypeBasic(basetab[i]);
        t = t->merge();
        basic[basetab[i]] = t;
    }
    basic[Terror] = new TypeError();

    tvoid = basic[Tvoid];
    tint8 = basic[Tint8];
    tuns8 = basic[Tuns8];
    tint16 = basic[Tint16];
    tuns16 = basic[Tuns16];
    tint32 = basic[Tint32];
    tuns32 = basic[Tuns32];
    tint64 = basic[Tint64];
    tuns64 = basic[Tuns64];
    tint128 = basic[Tint128];
    tuns128 = basic[Tuns128];
    tfloat32 = basic[Tfloat32];
    tfloat64 = basic[Tfloat64];
    tfloat80 = basic[Tfloat80];

    timaginary32 = basic[Timaginary32];
    timaginary64 = basic[Timaginary64];
    timaginary80 = basic[Timaginary80];

    tcomplex32 = basic[Tcomplex32];
    tcomplex64 = basic[Tcomplex64];
    tcomplex80 = basic[Tcomplex80];

    tbool = basic[Tbool];
    tchar = basic[Tchar];
    twchar = basic[Twchar];
    tdchar = basic[Tdchar];

    tshiftcnt = tint32;
    terror = basic[Terror];
    tnull = basic[Tnull];
    tnull = new TypeNull();
    tnull->deco = tnull->merge()->deco;

    tvoidptr = tvoid->pointerTo();
    tstring = tchar->immutableOf()->arrayOf();
    twstring = twchar->immutableOf()->arrayOf();
    tdstring = tdchar->immutableOf()->arrayOf();
    tvalist = Target::va_listType();

    if (global.params.isLP64)
    {
        Tsize_t = Tuns64;
        Tptrdiff_t = Tint64;
    }
    else
    {
        Tsize_t = Tuns32;
        Tptrdiff_t = Tint32;
    }

    tsize_t = basic[Tsize_t];
    tptrdiff_t = basic[Tptrdiff_t];
    thash_t = tsize_t;
}

d_uns64 Type::size()
{
    return size(Loc());
}

d_uns64 Type::size(Loc loc)
{
    error(loc, "no size for type %s", toChars());
    return SIZE_INVALID;
}

unsigned Type::alignsize()
{
    return (unsigned)size(Loc());
}

Type *Type::semantic(Loc loc, Scope *)
{
    if (ty == Tint128 || ty == Tuns128)
    {
        error(loc, "cent and ucent types not implemented");
        return terror;
    }

    return merge();
}

Type *Type::trySemantic(Loc loc, Scope *sc)
{
    //printf("+trySemantic(%s) %d\n", toChars(), global.errors);
    unsigned errors = global.startGagging();
    Type *t = semantic(loc, sc);
    if (global.endGagging(errors) || t->ty == Terror)        // if any errors happened
    {
        t = NULL;
    }
    //printf("-trySemantic(%s) %d\n", toChars(), global.errors);
    return t;
}

/********************************
 * Return a copy of this type with all attributes null-initialized.
 * Useful for creating a type with different modifiers.
 */

Type *Type::nullAttributes()
{
    unsigned sz = sizeTy[ty];
    void *pt = mem.xmalloc(sz);
    Type *t = (Type *)memcpy(pt, (void *)this, sz);
    t->deco = NULL;
    t->arrayof = NULL;
    t->pto = NULL;
    t->rto = NULL;
    t->cto = NULL;
    t->ito = NULL;
    t->sto = NULL;
    t->scto = NULL;
    t->wto = NULL;
    t->wcto = NULL;
    t->swto = NULL;
    t->swcto = NULL;
    t->vtinfo = NULL;
    t->ctype = NULL;
    if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref;
    if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref;
    return t;
}

/********************************
 * Convert to 'const'.
 */

Type *Type::constOf()
{
    //printf("Type::constOf() %p %s\n", this, toChars());
    if (mod == MODconst)
        return this;
    if (cto)
    {
        assert(cto->mod == MODconst);
        return cto;
    }
    Type *t = makeConst();
    t = t->merge();
    t->fixTo(this);
    //printf("-Type::constOf() %p %s\n", t, t->toChars());
    return t;
}

/********************************
 * Convert to 'immutable'.
 */

Type *Type::immutableOf()
{
    //printf("Type::immutableOf() %p %s\n", this, toChars());
    if (isImmutable())
        return this;
    if (ito)
    {
        assert(ito->isImmutable());
        return ito;
    }
    Type *t = makeImmutable();
    t = t->merge();
    t->fixTo(this);
    //printf("\t%p\n", t);
    return t;
}

/********************************
 * Make type mutable.
 */

Type *Type::mutableOf()
{
    //printf("Type::mutableOf() %p, %s\n", this, toChars());
    Type *t = this;
    if (isImmutable())
    {
        t = ito;                // immutable => naked
        assert(!t || (t->isMutable() && !t->isShared()));
    }
    else if (isConst())
    {
        if (isShared())
        {
            if (isWild())
                t = swcto;      // shared wild const -> shared
            else
                t = sto;        // shared const => shared
        }
        else
        {
            if (isWild())
                t = wcto;       // wild const -> naked
            else
                t = cto;        // const => naked
        }
        assert(!t || t->isMutable());
    }
    else if (isWild())
    {
        if (isShared())
            t = sto;            // shared wild => shared
        else
            t = wto;            // wild => naked
        assert(!t || t->isMutable());
    }
    if (!t)
    {
        t = makeMutable();
        t = t->merge();
        t->fixTo(this);
    }
    else
        t = t->merge();
    assert(t->isMutable());
    return t;
}

Type *Type::sharedOf()
{
    //printf("Type::sharedOf() %p, %s\n", this, toChars());
    if (mod == MODshared)
        return this;
    if (sto)
    {
        assert(sto->mod == MODshared);
        return sto;
    }
    Type *t = makeShared();
    t = t->merge();
    t->fixTo(this);
    //printf("\t%p\n", t);
    return t;
}

Type *Type::sharedConstOf()
{
    //printf("Type::sharedConstOf() %p, %s\n", this, toChars());
    if (mod == (MODshared | MODconst))
        return this;
    if (scto)
    {
        assert(scto->mod == (MODshared | MODconst));
        return scto;
    }
    Type *t = makeSharedConst();
    t = t->merge();
    t->fixTo(this);
    //printf("\t%p\n", t);
    return t;
}


/********************************
 * Make type unshared.
 *      0            => 0
 *      const        => const
 *      immutable    => immutable
 *      shared       => 0
 *      shared const => const
 *      wild         => wild
 *      wild const   => wild const
 *      shared wild  => wild
 *      shared wild const => wild const
 */

Type *Type::unSharedOf()
{
    //printf("Type::unSharedOf() %p, %s\n", this, toChars());
    Type *t = this;

    if (isShared())
    {
        if (isWild())
        {
            if (isConst())
                t = wcto;   // shared wild const => wild const
            else
                t = wto;    // shared wild => wild
        }
        else
        {
            if (isConst())
                t = cto;    // shared const => const
            else
                t = sto;    // shared => naked
        }
        assert(!t || !t->isShared());
    }

    if (!t)
    {
        t = this->nullAttributes();
        t->mod = mod & ~MODshared;
        t->ctype = ctype;
        t = t->merge();

        t->fixTo(this);
    }
    else
        t = t->merge();
    assert(!t->isShared());
    return t;
}

/********************************
 * Convert to 'wild'.
 */

Type *Type::wildOf()
{
    //printf("Type::wildOf() %p %s\n", this, toChars());
    if (mod == MODwild)
        return this;
    if (wto)
    {
        assert(wto->mod == MODwild);
        return wto;
    }
    Type *t = makeWild();
    t = t->merge();
    t->fixTo(this);
    //printf("\t%p %s\n", t, t->toChars());
    return t;
}

Type *Type::wildConstOf()
{
    //printf("Type::wildConstOf() %p %s\n", this, toChars());
    if (mod == MODwildconst)
        return this;
    if (wcto)
    {
        assert(wcto->mod == MODwildconst);
        return wcto;
    }
    Type *t = makeWildConst();
    t = t->merge();
    t->fixTo(this);
    //printf("\t%p %s\n", t, t->toChars());
    return t;
}

Type *Type::sharedWildOf()
{
    //printf("Type::sharedWildOf() %p, %s\n", this, toChars());
    if (mod == (MODshared | MODwild))
        return this;
    if (swto)
    {
        assert(swto->mod == (MODshared | MODwild));
        return swto;
    }
    Type *t = makeSharedWild();
    t = t->merge();
    t->fixTo(this);
    //printf("\t%p %s\n", t, t->toChars());
    return t;
}

Type *Type::sharedWildConstOf()
{
    //printf("Type::sharedWildConstOf() %p, %s\n", this, toChars());
    if (mod == (MODshared | MODwildconst))
        return this;
    if (swcto)
    {
        assert(swcto->mod == (MODshared | MODwildconst));
        return swcto;
    }
    Type *t = makeSharedWildConst();
    t = t->merge();
    t->fixTo(this);
    //printf("\t%p %s\n", t, t->toChars());
    return t;
}

/**********************************
 * For our new type 'this', which is type-constructed from t,
 * fill in the cto, ito, sto, scto, wto shortcuts.
 */

void Type::fixTo(Type *t)
{
    // If fixing this: immutable(T*) by t: immutable(T)*,
    // cache t to this->xto won't break transitivity.
    Type *mto = NULL;
    Type *tn = nextOf();
    if (!tn || (ty != Tsarray && tn->mod == t->nextOf()->mod))
    {
        switch (t->mod)
        {
            case 0:                           mto = t;  break;
            case MODconst:                    cto = t;  break;
            case MODwild:                     wto = t;  break;
            case MODwildconst:               wcto = t;  break;
            case MODshared:                   sto = t;  break;
            case MODshared | MODconst:       scto = t;  break;
            case MODshared | MODwild:        swto = t;  break;
            case MODshared | MODwildconst:  swcto = t;  break;
            case MODimmutable:                ito = t;  break;
        }
    }

    assert(mod != t->mod);
#define X(m, n) (((m) << 4) | (n))
    switch (mod)
    {
        case 0:
            break;

        case MODconst:
            cto = mto;
            t->cto = this;
            break;

        case MODwild:
            wto = mto;
            t->wto = this;
            break;

        case MODwildconst:
            wcto = mto;
            t->wcto = this;
            break;

        case MODshared:
            sto = mto;
            t->sto = this;
            break;

        case MODshared | MODconst:
            scto = mto;
            t->scto = this;
            break;

        case MODshared | MODwild:
            swto = mto;
            t->swto = this;
            break;

        case MODshared | MODwildconst:
            swcto = mto;
            t->swcto = this;
            break;

        case MODimmutable:
            t->ito = this;
            if (t->  cto) t->  cto->ito = this;
            if (t->  sto) t->  sto->ito = this;
            if (t-> scto) t-> scto->ito = this;
            if (t->  wto) t->  wto->ito = this;
            if (t-> wcto) t-> wcto->ito = this;
            if (t-> swto) t-> swto->ito = this;
            if (t->swcto) t->swcto->ito = this;
            break;

        default:
            assert(0);
    }
#undef X

    check();
    t->check();
    //printf("fixTo: %s, %s\n", toChars(), t->toChars());
}

/***************************
 * Look for bugs in constructing types.
 */

void Type::check()
{
    switch (mod)
    {
        case 0:
            if (cto) assert(cto->mod == MODconst);
            if (ito) assert(ito->mod == MODimmutable);
            if (sto) assert(sto->mod == MODshared);
            if (scto) assert(scto->mod == (MODshared | MODconst));
            if (wto) assert(wto->mod == MODwild);
            if (wcto) assert(wcto->mod == MODwildconst);
            if (swto) assert(swto->mod == (MODshared | MODwild));
            if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
            break;

        case MODconst:
            if (cto) assert(cto->mod == 0);
            if (ito) assert(ito->mod == MODimmutable);
            if (sto) assert(sto->mod == MODshared);
            if (scto) assert(scto->mod == (MODshared | MODconst));
            if (wto) assert(wto->mod == MODwild);
            if (wcto) assert(wcto->mod == MODwildconst);
            if (swto) assert(swto->mod == (MODshared | MODwild));
            if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
            break;

        case MODwild:
            if (cto) assert(cto->mod == MODconst);
            if (ito) assert(ito->mod == MODimmutable);
            if (sto) assert(sto->mod == MODshared);
            if (scto) assert(scto->mod == (MODshared | MODconst));
            if (wto) assert(wto->mod == 0);
            if (wcto) assert(wcto->mod == MODwildconst);
            if (swto) assert(swto->mod == (MODshared | MODwild));
            if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
            break;

        case MODwildconst:
            assert(!  cto ||   cto->mod == MODconst);
            assert(!  ito ||   ito->mod == MODimmutable);
            assert(!  sto ||   sto->mod == MODshared);
            assert(! scto ||  scto->mod == (MODshared | MODconst));
            assert(!  wto ||   wto->mod == MODwild);
            assert(! wcto ||  wcto->mod == 0);
            assert(! swto ||  swto->mod == (MODshared | MODwild));
            assert(!swcto || swcto->mod == (MODshared | MODwildconst));
            break;

        case MODshared:
            if (cto) assert(cto->mod == MODconst);
            if (ito) assert(ito->mod == MODimmutable);
            if (sto) assert(sto->mod == 0);
            if (scto) assert(scto->mod == (MODshared | MODconst));
            if (wto) assert(wto->mod == MODwild);
            if (wcto) assert(wcto->mod == MODwildconst);
            if (swto) assert(swto->mod == (MODshared | MODwild));
            if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
            break;

        case MODshared | MODconst:
            if (cto) assert(cto->mod == MODconst);
            if (ito) assert(ito->mod == MODimmutable);
            if (sto) assert(sto->mod == MODshared);
            if (scto) assert(scto->mod == 0);
            if (wto) assert(wto->mod == MODwild);
            if (wcto) assert(wcto->mod == MODwildconst);
            if (swto) assert(swto->mod == (MODshared | MODwild));
            if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
            break;

        case MODshared | MODwild:
            if (cto) assert(cto->mod == MODconst);
            if (ito) assert(ito->mod == MODimmutable);
            if (sto) assert(sto->mod == MODshared);
            if (scto) assert(scto->mod == (MODshared | MODconst));
            if (wto) assert(wto->mod == MODwild);
            if (wcto) assert(wcto->mod == MODwildconst);
            if (swto) assert(swto->mod == 0);
            if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
            break;

        case MODshared | MODwildconst:
            assert(!  cto ||   cto->mod == MODconst);
            assert(!  ito ||   ito->mod == MODimmutable);
            assert(!  sto ||   sto->mod == MODshared);
            assert(! scto ||  scto->mod == (MODshared | MODconst));
            assert(!  wto ||   wto->mod == MODwild);
            assert(! wcto ||  wcto->mod == MODwildconst);
            assert(! swto ||  swto->mod == (MODshared | MODwild));
            assert(!swcto || swcto->mod == 0);
            break;

        case MODimmutable:
            if (cto) assert(cto->mod == MODconst);
            if (ito) assert(ito->mod == 0);
            if (sto) assert(sto->mod == MODshared);
            if (scto) assert(scto->mod == (MODshared | MODconst));
            if (wto) assert(wto->mod == MODwild);
            if (wcto) assert(wcto->mod == MODwildconst);
            if (swto) assert(swto->mod == (MODshared | MODwild));
            if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
            break;

        default:
            assert(0);
    }

    Type *tn = nextOf();
    if (tn && ty != Tfunction && tn->ty != Tfunction && ty != Tenum)
    {
        // Verify transitivity
        switch (mod)
        {
            case 0:
            case MODconst:
            case MODwild:
            case MODwildconst:
            case MODshared:
            case MODshared | MODconst:
            case MODshared | MODwild:
            case MODshared | MODwildconst:
            case MODimmutable:
                assert(tn->mod == MODimmutable || (tn->mod & mod) == mod);
                break;

            default:
                assert(0);
        }
        tn->check();
    }
}

Type *Type::makeConst()
{
    //printf("Type::makeConst() %p, %s\n", this, toChars());
    if (cto) return cto;
    Type *t = this->nullAttributes();
    t->mod = MODconst;
    //printf("-Type::makeConst() %p, %s\n", t, toChars());
    return t;
}

Type *Type::makeImmutable()
{
    if (ito) return ito;
    Type *t = this->nullAttributes();
    t->mod = MODimmutable;
    return t;
}

Type *Type::makeShared()
{
    if (sto) return sto;
    Type *t = this->nullAttributes();
    t->mod = MODshared;
    return t;
}

Type *Type::makeSharedConst()
{
    if (scto) return scto;
    Type *t = this->nullAttributes();
    t->mod = MODshared | MODconst;
    return t;
}

Type *Type::makeWild()
{
    if (wto) return wto;
    Type *t = this->nullAttributes();
    t->mod = MODwild;
    return t;
}

Type *Type::makeWildConst()
{
    if (wcto) return wcto;
    Type *t = this->nullAttributes();
    t->mod = MODwildconst;
    return t;
}

Type *Type::makeSharedWild()
{
    if (swto) return swto;
    Type *t = this->nullAttributes();
    t->mod = MODshared | MODwild;
    return t;
}

Type *Type::makeSharedWildConst()
{
    if (swcto) return swcto;
    Type *t = this->nullAttributes();
    t->mod = MODshared | MODwildconst;
    return t;
}

Type *Type::makeMutable()
{
    Type *t = this->nullAttributes();
    t->mod = mod & MODshared;
    return t;
}

/*************************************
 * Apply STCxxxx bits to existing type.
 * Use *before* semantic analysis is run.
 */

Type *Type::addSTC(StorageClass stc)
{
    Type *t = this;
    if (t->isImmutable())
        ;
    else if (stc & STCimmutable)
    {
        t = t->makeImmutable();
    }
    else
    {
        if ((stc & STCshared) && !t->isShared())
        {
            if (t->isWild())
            {
                if (t->isConst())
                    t = t->makeSharedWildConst();
                else
                    t = t->makeSharedWild();
            }
            else
            {
                if (t->isConst())
                    t = t->makeSharedConst();
                else
                    t = t->makeShared();
            }
        }
        if ((stc & STCconst) && !t->isConst())
        {
            if (t->isShared())
            {
                if (t->isWild())
                    t = t->makeSharedWildConst();
                else
                    t = t->makeSharedConst();
            }
            else
            {
                if (t->isWild())
                    t = t->makeWildConst();
                else
                    t = t->makeConst();
            }
        }
        if ((stc & STCwild) && !t->isWild())
        {
            if (t->isShared())
            {
                if (t->isConst())
                    t = t->makeSharedWildConst();
                else
                    t = t->makeSharedWild();
            }
            else
            {
                if (t->isConst())
                    t = t->makeWildConst();
                else
                    t = t->makeWild();
            }
        }
    }
    return t;
}

/************************************
 * Convert MODxxxx to STCxxx
 */

StorageClass ModToStc(unsigned mod)
{
    StorageClass stc = 0;
    if (mod & MODimmutable) stc |= STCimmutable;
    if (mod & MODconst)     stc |= STCconst;
    if (mod & MODwild)      stc |= STCwild;
    if (mod & MODshared)    stc |= STCshared;
    return stc;
}

/************************************
 * Apply MODxxxx bits to existing type.
 */

Type *Type::castMod(MOD mod)
{   Type *t;

    switch (mod)
    {
        case 0:
            t = unSharedOf()->mutableOf();
            break;

        case MODconst:
            t = unSharedOf()->constOf();
            break;

        case MODwild:
            t = unSharedOf()->wildOf();
            break;

        case MODwildconst:
            t = unSharedOf()->wildConstOf();
            break;

        case MODshared:
            t = mutableOf()->sharedOf();
            break;

        case MODshared | MODconst:
            t = sharedConstOf();
            break;

        case MODshared | MODwild:
            t = sharedWildOf();
            break;

        case MODshared | MODwildconst:
            t = sharedWildConstOf();
            break;

        case MODimmutable:
            t = immutableOf();
            break;

        default:
            assert(0);
    }
    return t;
}

/************************************
 * Add MODxxxx bits to existing type.
 * We're adding, not replacing, so adding const to
 * a shared type => "shared const"
 */

Type *Type::addMod(MOD mod)
{
    /* Add anything to immutable, and it remains immutable
     */
    Type *t = this;
    if (!t->isImmutable())
    {
        //printf("addMod(%x) %s\n", mod, toChars());
        switch (mod)
        {
            case 0:
                break;

            case MODconst:
                if (isShared())
                {
                    if (isWild())
                        t = sharedWildConstOf();
                    else
                        t = sharedConstOf();
                }
                else
                {
                    if (isWild())
                        t = wildConstOf();
                    else
                        t = constOf();
                }
                break;

            case MODwild:
                if (isShared())
                {
                    if (isConst())
                        t = sharedWildConstOf();
                    else
                        t = sharedWildOf();
                }
                else
                {
                    if (isConst())
                        t = wildConstOf();
                    else
                        t = wildOf();
                }
                break;

            case MODwildconst:
                if (isShared())
                    t = sharedWildConstOf();
                else
                    t = wildConstOf();
                break;

            case MODshared:
                if (isWild())
                {
                    if (isConst())
                        t = sharedWildConstOf();
                    else
                        t = sharedWildOf();
                }
                else
                {
                    if (isConst())
                        t = sharedConstOf();
                    else
                        t = sharedOf();
                }
                break;

            case MODshared | MODconst:
                if (isWild())
                    t = sharedWildConstOf();
                else
                    t = sharedConstOf();
                break;

            case MODshared | MODwild:
                if (isConst())
                    t = sharedWildConstOf();
                else
                    t = sharedWildOf();
                break;

            case MODshared | MODwildconst:
                t = sharedWildConstOf();
                break;

            case MODimmutable:
                t = immutableOf();
                break;

            default:
                assert(0);
        }
    }
    return t;
}

/************************************
 * Add storage class modifiers to type.
 */

Type *Type::addStorageClass(StorageClass stc)
{
    /* Just translate to MOD bits and let addMod() do the work
     */
    MOD mod = 0;

    if (stc & STCimmutable)
        mod = MODimmutable;
    else
    {
        if (stc & (STCconst | STCin))
            mod |= MODconst;
        if (stc & STCwild)
            mod |= MODwild;
        if (stc & STCshared)
            mod |= MODshared;
    }
    return addMod(mod);
}

Type *Type::pointerTo()
{
    if (ty == Terror)
        return this;
    if (!pto)
    {
        Type *t = new TypePointer(this);
        if (ty == Tfunction)
        {
            t->deco = t->merge()->deco;
            pto = t;
        }
        else
            pto = t->merge();
    }
    return pto;
}

Type *Type::referenceTo()
{
    if (ty == Terror)
        return this;
    if (!rto)
    {
        Type *t = new TypeReference(this);
        rto = t->merge();
    }
    return rto;
}

Type *Type::arrayOf()
{
    if (ty == Terror)
        return this;
    if (!arrayof)
    {
        Type *t = new TypeDArray(this);
        arrayof = t->merge();
    }
    return arrayof;
}

// Make corresponding static array type without semantic
Type *Type::sarrayOf(dinteger_t dim)
{
    assert(deco);
    Type *t = new TypeSArray(this, new IntegerExp(Loc(), dim, Type::tsize_t));

    // according to TypeSArray::semantic()
    t = t->addMod(mod);
    t = t->merge();

    return t;
}

Type *Type::aliasthisOf()
{
    AggregateDeclaration *ad = isAggregate(this);
    if (ad && ad->aliasthis)
    {
        Dsymbol *s = ad->aliasthis;
        if (s->isAliasDeclaration())
            s = s->toAlias();
        Declaration *d = s->isDeclaration();
        if (d && !d->isTupleDeclaration())
        {
            assert(d->type);
            Type *t = d->type;
            if (d->isVarDeclaration() && d->needThis())
            {
                t = t->addMod(this->mod);
            }
            else if (d->isFuncDeclaration())
            {
                FuncDeclaration *fd = resolveFuncCall(Loc(), NULL, d, NULL, this, NULL, 1);
                if (fd && fd->errors)
                    return Type::terror;
                if (fd && !fd->type->nextOf() && !fd->functionSemantic())
                    fd = NULL;
                if (fd)
                {
                    t = fd->type->nextOf();
                    if (!t) // issue 14185
                        return Type::terror;
                    t = t->substWildTo(mod == 0 ? MODmutable : (MODFlags)mod);
                }
                else
                    return Type::terror;
            }
            return t;
        }
        EnumDeclaration *ed = s->isEnumDeclaration();
        if (ed)
        {
            Type *t = ed->type;
            return t;
        }
        TemplateDeclaration *td = s->isTemplateDeclaration();
        if (td)
        {
            assert(td->_scope);
            FuncDeclaration *fd = resolveFuncCall(Loc(), NULL, td, NULL, this, NULL, 1);
            if (fd && fd->errors)
                return Type::terror;
            if (fd && fd->functionSemantic())
            {
                Type *t = fd->type->nextOf();
                t = t->substWildTo(mod == 0 ? MODmutable : (MODFlags)mod);
                return t;
            }
            else
                return Type::terror;
        }
        //printf("%s\n", s->kind());
    }
    return NULL;
}

bool Type::checkAliasThisRec()
{
    Type *tb = toBasetype();
    AliasThisRec* pflag;
    if (tb->ty == Tstruct)
        pflag = &((TypeStruct *)tb)->att;
    else if (tb->ty == Tclass)
        pflag = &((TypeClass *)tb)->att;
    else
        return false;

    AliasThisRec flag = (AliasThisRec)(*pflag & RECtypeMask);
    if (flag == RECfwdref)
    {
        Type *att = aliasthisOf();
        flag = att && att->implicitConvTo(this) ? RECyes : RECno;
    }
    *pflag = (AliasThisRec)(flag | (*pflag & ~RECtypeMask));
    return flag == RECyes;
}

Dsymbol *Type::toDsymbol(Scope *)
{
    return NULL;
}

/*******************************
 * If this is a shell around another type,
 * get that other type.
 */

Type *Type::toBasetype()
{
    return this;
}

/***************************
 * Return !=0 if modfrom can be implicitly converted to modto
 */
bool MODimplicitConv(MOD modfrom, MOD modto)
{
    if (modfrom == modto)
        return true;

    //printf("MODimplicitConv(from = %x, to = %x)\n", modfrom, modto);
    #define X(m, n) (((m) << 4) | (n))
    switch (X(modfrom & ~MODshared, modto & ~MODshared))
    {
        case X(0,            MODconst):
        case X(MODwild,      MODconst):
        case X(MODwild,      MODwildconst):
        case X(MODwildconst, MODconst):
            return (modfrom & MODshared) == (modto & MODshared);

        case X(MODimmutable, MODconst):
        case X(MODimmutable, MODwildconst):
            return true;

        default:
            return false;
    }
    #undef X
}

/***************************
 * Return MATCHexact or MATCHconst if a method of type '() modfrom' can call a method of type '() modto'.
 */
MATCH MODmethodConv(MOD modfrom, MOD modto)
{
    if (modfrom == modto)
        return MATCHexact;
    if (MODimplicitConv(modfrom, modto))
        return MATCHconst;

    #define X(m, n) (((m) << 4) | (n))
    switch (X(modfrom, modto))
    {
        case X(0,            MODwild):
        case X(MODimmutable, MODwild):
        case X(MODconst,     MODwild):
        case X(MODwildconst, MODwild):
        case X(MODshared,              MODshared|MODwild):
        case X(MODshared|MODimmutable, MODshared|MODwild):
        case X(MODshared|MODconst,     MODshared|MODwild):
        case X(MODshared|MODwildconst, MODshared|MODwild):
            return MATCHconst;

        default:
            return MATCHnomatch;
    }
    #undef X
}

/***************************
 * Merge mod bits to form common mod.
 */
MOD MODmerge(MOD mod1, MOD mod2)
{
    if (mod1 == mod2)
        return mod1;

    //printf("MODmerge(1 = %x, 2 = %x)\n", mod1, mod2);
    MOD result = 0;
    if ((mod1 | mod2) & MODshared)
    {
        // If either type is shared, the result will be shared
        result |= MODshared;
        mod1 &= ~MODshared;
        mod2 &= ~MODshared;
    }
    if (mod1 == 0 || mod1 == MODmutable || mod1 == MODconst ||
        mod2 == 0 || mod2 == MODmutable || mod2 == MODconst)
    {
        // If either type is mutable or const, the result will be const.
        result |= MODconst;
    }
    else
    {
        // MODimmutable vs MODwild
        // MODimmutable vs MODwildconst
        //      MODwild vs MODwildconst
        assert(mod1 & MODwild || mod2 & MODwild);
        result |= MODwildconst;
    }
    return result;
}

/*********************************
 * Store modifier name into buf.
 */
void MODtoBuffer(OutBuffer *buf, MOD mod)
{
    switch (mod)
    {
        case 0:
            break;

        case MODimmutable:
            buf->writestring(Token::tochars[TOKimmutable]);
            break;

        case MODshared:
            buf->writestring(Token::tochars[TOKshared]);
            break;

        case MODshared | MODconst:
            buf->writestring(Token::tochars[TOKshared]);
            buf->writeByte(' ');
            /* fall through */
        case MODconst:
            buf->writestring(Token::tochars[TOKconst]);
            break;

        case MODshared | MODwild:
            buf->writestring(Token::tochars[TOKshared]);
            buf->writeByte(' ');
            /* fall through */
        case MODwild:
            buf->writestring(Token::tochars[TOKwild]);
            break;

        case MODshared | MODwildconst:
            buf->writestring(Token::tochars[TOKshared]);
            buf->writeByte(' ');
            /* fall through */
        case MODwildconst:
            buf->writestring(Token::tochars[TOKwild]);
            buf->writeByte(' ');
            buf->writestring(Token::tochars[TOKconst]);
            break;

        default:
            assert(0);
    }
}


/*********************************
 * Return modifier name.
 */
char *MODtoChars(MOD mod)
{
    OutBuffer buf;
    buf.reserve(16);
    MODtoBuffer(&buf, mod);
    return buf.extractString();
}

/********************************
 * For pretty-printing a type.
 */

const char *Type::toChars()
{
    OutBuffer buf;
    buf.reserve(16);
    HdrGenState hgs;
    hgs.fullQual = (ty == Tclass && !mod);

    ::toCBuffer(this, &buf, NULL, &hgs);
    return buf.extractString();
}

char *Type::toPrettyChars(bool QualifyTypes)
{
    OutBuffer buf;
    buf.reserve(16);
    HdrGenState hgs;
    hgs.fullQual = QualifyTypes;

    ::toCBuffer(this, &buf, NULL, &hgs);
    return buf.extractString();
}

/*********************************
 * Store this type's modifier name into buf.
 */
void Type::modToBuffer(OutBuffer *buf)
{
    if (mod)
    {
        buf->writeByte(' ');
        MODtoBuffer(buf, mod);
    }
}

/*********************************
 * Return this type's modifier name.
 */
char *Type::modToChars()
{
    OutBuffer buf;
    buf.reserve(16);
    modToBuffer(&buf);
    return buf.extractString();
}

/** For each active modifier (MODconst, MODimmutable, etc) call fp with a
void* for the work param and a string representation of the attribute. */
int Type::modifiersApply(void *param, int (*fp)(void *, const char *))
{
    static unsigned char modsArr[] = { MODconst, MODimmutable, MODwild, MODshared };

    for (size_t idx = 0; idx < 4; ++idx)
    {
        if (mod & modsArr[idx])
        {
            if (int res = fp(param, MODtoChars(modsArr[idx])))
                return res;
        }
    }
    return 0;
}

/************************************
 * Strip all parameter's idenfiers and their default arguments for merging types.
 * If some of parameter types or return type are function pointer, delegate, or
 * the types which contains either, then strip also from them.
 */

Type *stripDefaultArgs(Type *t)
{
  struct N
  {
    static Parameters *stripParams(Parameters *parameters)
    {
        Parameters *params = parameters;
        if (params && params->dim > 0)
        {
            for (size_t i = 0; i < params->dim; i++)
            {
                Parameter *p = (*params)[i];
                Type *ta = stripDefaultArgs(p->type);
                if (ta != p->type || p->defaultArg || p->ident)
                {
                    if (params == parameters)
                    {
                        params = new Parameters();
                        params->setDim(parameters->dim);
                        for (size_t j = 0; j < params->dim; j++)
                            (*params)[j] = (*parameters)[j];
                    }
                    (*params)[i] = new Parameter(p->storageClass, ta, NULL, NULL);
                }
            }
        }
        return params;
    }
  };

    if (t == NULL)
        return t;

    if (t->ty == Tfunction)
    {
        TypeFunction *tf = (TypeFunction *)t;
        Type *tret = stripDefaultArgs(tf->next);
        Parameters *params = N::stripParams(tf->parameters);
        if (tret == tf->next && params == tf->parameters)
            goto Lnot;
        tf = (TypeFunction *)tf->copy();
        tf->parameters = params;
        tf->next = tret;
        //printf("strip %s\n   <- %s\n", tf->toChars(), t->toChars());
        t = tf;
    }
    else if (t->ty == Ttuple)
    {
        TypeTuple *tt = (TypeTuple *)t;
        Parameters *args = N::stripParams(tt->arguments);
        if (args == tt->arguments)
            goto Lnot;
        t = t->copy();
        ((TypeTuple *)t)->arguments = args;
    }
    else if (t->ty == Tenum)
    {
        // TypeEnum::nextOf() may be != NULL, but it's not necessary here.
        goto Lnot;
    }
    else
    {
        Type *tn = t->nextOf();
        Type *n = stripDefaultArgs(tn);
        if (n == tn)
            goto Lnot;
        t = t->copy();
        ((TypeNext *)t)->next = n;
    }
    //printf("strip %s\n", t->toChars());
Lnot:
    return t;
}

/************************************
 */

Type *Type::merge()
{
    if (ty == Terror) return this;
    if (ty == Ttypeof) return this;
    if (ty == Tident) return this;
    if (ty == Tinstance) return this;
    if (ty == Taarray && !((TypeAArray *)this)->index->merge()->deco)
        return this;
    if (ty != Tenum && nextOf() && !nextOf()->deco)
        return this;

    //printf("merge(%s)\n", toChars());
    Type *t = this;
    assert(t);
    if (!deco)
    {
        OutBuffer buf;
        buf.reserve(32);

        mangleToBuffer(this, &buf);

        StringValue *sv = stringtable.update((char *)buf.data, buf.offset);
        if (sv->ptrvalue)
        {
            t = (Type *) sv->ptrvalue;
            assert(t->deco);
            //printf("old value, deco = '%s' %p\n", t->deco, t->deco);
        }
        else
        {
            sv->ptrvalue = (char *)(t = stripDefaultArgs(t));
            deco = t->deco = const_cast<char *>(sv->toDchars());
            //printf("new value, deco = '%s' %p\n", t->deco, t->deco);
        }
    }
    return t;
}

/*************************************
 * This version does a merge even if the deco is already computed.
 * Necessary for types that have a deco, but are not merged.
 */
Type *Type::merge2()
{
    //printf("merge2(%s)\n", toChars());
    Type *t = this;
    assert(t);
    if (!t->deco)
        return t->merge();

    StringValue *sv = stringtable.lookup((char *)t->deco, strlen(t->deco));
    if (sv && sv->ptrvalue)
    {   t = (Type *) sv->ptrvalue;
        assert(t->deco);
    }
    else
        assert(0);
    return t;
}

bool Type::isintegral()
{
    return false;
}

bool Type::isfloating()
{
    return false;
}

bool Type::isreal()
{
    return false;
}

bool Type::isimaginary()
{
    return false;
}

bool Type::iscomplex()
{
    return false;
}

bool Type::isscalar()
{
    return false;
}

bool Type::isunsigned()
{
    return false;
}

ClassDeclaration *Type::isClassHandle()
{
    return NULL;
}

bool Type::isscope()
{
    return false;
}

bool Type::isString()
{
    return false;
}

/**************************
 * When T is mutable,
 * Given:
 *      T a, b;
 * Can we bitwise assign:
 *      a = b;
 * ?
 */
bool Type::isAssignable()
{
    return true;
}

/**************************
 * Returns true if T can be converted to boolean value.
 */
bool Type::isBoolean()
{
    return isscalar();
}

/********************************
 * true if when type goes out of scope, it needs a destructor applied.
 * Only applies to value types, not ref types.
 */
bool Type::needsDestruction()
{
    return false;
}

/*********************************
 *
 */

bool Type::needsNested()
{
    return false;
}

/*********************************
 * Check type to see if it is based on a deprecated symbol.
 */

void Type::checkDeprecated(Loc loc, Scope *sc)
{
    Dsymbol *s = toDsymbol(sc);

    if (s)
        s->checkDeprecated(loc, sc);
}


Expression *Type::defaultInit(Loc)
{
    return NULL;
}

/***************************************
 * Use when we prefer the default initializer to be a literal,
 * rather than a global immutable variable.
 */
Expression *Type::defaultInitLiteral(Loc loc)
{
    return defaultInit(loc);
}

bool Type::isZeroInit(Loc)
{
    return false;           // assume not
}

bool Type::isBaseOf(Type *, int *)
{
    return 0;           // assume not
}

/********************************
 * Determine if 'this' can be implicitly converted
 * to type 'to'.
 * Returns:
 *      MATCHnomatch, MATCHconvert, MATCHconst, MATCHexact
 */

MATCH Type::implicitConvTo(Type *to)
{
    //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to);
    //printf("from: %s\n", toChars());
    //printf("to  : %s\n", to->toChars());
    if (this->equals(to))
        return MATCHexact;
    return MATCHnomatch;
}

/*******************************
 * Determine if converting 'this' to 'to' is an identity operation,
 * a conversion to const operation, or the types aren't the same.
 * Returns:
 *      MATCHexact      'this' == 'to'
 *      MATCHconst      'to' is const
 *      MATCHnomatch    conversion to mutable or invariant
 */

MATCH Type::constConv(Type *to)
{
    //printf("Type::constConv(this = %s, to = %s)\n", toChars(), to->toChars());
    if (equals(to))
        return MATCHexact;
    if (ty == to->ty && MODimplicitConv(mod, to->mod))
        return MATCHconst;
    return MATCHnomatch;
}

/***************************************
 * Return MOD bits matching this type to wild parameter type (tprm).
 */

unsigned char Type::deduceWild(Type *t, bool)
{
    //printf("Type::deduceWild this = '%s', tprm = '%s'\n", toChars(), tprm->toChars());

    if (t->isWild())
    {
        if (isImmutable())
            return MODimmutable;
        else if (isWildConst())
        {
            if (t->isWildConst())
                return MODwild;
            else
                return MODwildconst;
        }
        else if (isWild())
            return MODwild;
        else if (isConst())
            return MODconst;
        else if (isMutable())
            return MODmutable;
        else
            assert(0);
    }
    return 0;
}

Type *Type::unqualify(unsigned m)
{
    Type *t = mutableOf()->unSharedOf();

    Type *tn = ty == Tenum ? NULL : nextOf();
    if (tn && tn->ty != Tfunction)
    {
        Type *utn = tn->unqualify(m);
        if (utn != tn)
        {
            if (ty == Tpointer)
                t = utn->pointerTo();
            else if (ty == Tarray)
                t = utn->arrayOf();
            else if (ty == Tsarray)
                t = new TypeSArray(utn, ((TypeSArray *)this)->dim);
            else if (ty == Taarray)
            {
                t = new TypeAArray(utn, ((TypeAArray *)this)->index);
                ((TypeAArray *)t)->sc = ((TypeAArray *)this)->sc;   // duplicate scope
            }
            else
                assert(0);

            t = t->merge();
        }
    }
    t = t->addMod(mod & ~m);
    return t;
}

Type *Type::substWildTo(unsigned mod)
{
    //printf("+Type::substWildTo this = %s, mod = x%x\n", toChars(), mod);
    Type *t;

    if (Type *tn = nextOf())
    {
        // substitution has no effect on function pointer type.
        if (ty == Tpointer && tn->ty == Tfunction)
        {
            t = this;
            goto L1;
        }

        t = tn->substWildTo(mod);
        if (t == tn)
            t = this;
        else
        {
            if (ty == Tpointer)
                t = t->pointerTo();
            else if (ty == Tarray)
                t = t->arrayOf();
            else if (ty == Tsarray)
                t = new TypeSArray(t, ((TypeSArray *)this)->dim->syntaxCopy());
            else if (ty == Taarray)
            {
                t = new TypeAArray(t, ((TypeAArray *)this)->index->syntaxCopy());
                ((TypeAArray *)t)->sc = ((TypeAArray *)this)->sc;   // duplicate scope
            }
            else if (ty == Tdelegate)
            {
                t = new TypeDelegate(t);
            }
            else
                assert(0);

            t = t->merge();
        }
    }
    else
        t = this;

L1:
    if (isWild())
    {
        if (mod == MODimmutable)
        {
            t = t->immutableOf();
        }
        else if (mod == MODwildconst)
        {
            t = t->wildConstOf();
        }
        else if (mod == MODwild)
        {
            if (isWildConst())
                t = t->wildConstOf();
            else
                t = t->wildOf();
        }
        else if (mod == MODconst)
        {
            t = t->constOf();
        }
        else
        {
            if (isWildConst())
                t = t->constOf();
            else
                t = t->mutableOf();
        }
    }
    if (isConst())
        t = t->addMod(MODconst);
    if (isShared())
        t = t->addMod(MODshared);

    //printf("-Type::substWildTo t = %s\n", t->toChars());
    return t;
}

Type *TypeFunction::substWildTo(unsigned)
{
    if (!iswild && !(mod & MODwild))
        return this;

    // Substitude inout qualifier of function type to mutable or immutable
    // would break type system. Instead substitude inout to the most weak
    // qualifer - const.
    unsigned m = MODconst;

    assert(next);
    Type *tret = next->substWildTo(m);
    Parameters *params = parameters;
    if (mod & MODwild)
        params = parameters->copy();
    for (size_t i = 0; i < params->dim; i++)
    {
        Parameter *p = (*params)[i];
        Type *t = p->type->substWildTo(m);
        if (t == p->type)
            continue;
        if (params == parameters)
            params = parameters->copy();
        (*params)[i] = new Parameter(p->storageClass, t, NULL, NULL);
    }
    if (next == tret && params == parameters)
        return this;

    // Similar to TypeFunction::syntaxCopy;
    TypeFunction *t = new TypeFunction(params, tret, varargs, linkage);
    t->mod = ((mod & MODwild) ? (mod & ~MODwild) | MODconst : mod);
    t->isnothrow = isnothrow;
    t->isnogc = isnogc;
    t->purity = purity;
    t->isproperty = isproperty;
    t->isref = isref;
    t->isreturn = isreturn;
    t->isscope = isscope;
    t->isscopeinferred = isscopeinferred;
    t->iswild = 0;
    t->trust = trust;
    t->fargs = fargs;
    return t->merge();
}

/**************************
 * Return type with the top level of it being mutable.
 */
Type *Type::toHeadMutable()
{
    if (!mod)
        return this;
    return mutableOf();
}

/***************************************
 * Calculate built-in properties which just the type is necessary.
 *
 * If flag & 1, don't report "not a property" error and just return NULL.
 */
Expression *Type::getProperty(Loc loc, Identifier *ident, int flag)
{
    Expression *e;

    if (ident == Id::__sizeof)
    {
        d_uns64 sz = size(loc);
        if (sz == SIZE_INVALID)
            return new ErrorExp();
        e = new IntegerExp(loc, sz, Type::tsize_t);
    }
    else if (ident == Id::__xalignof)
    {
        unsigned explicitAlignment = alignment();
        unsigned naturalAlignment = alignsize();
        unsigned actualAlignment = (explicitAlignment == STRUCTALIGN_DEFAULT ? naturalAlignment : explicitAlignment);
        e = new IntegerExp(loc, actualAlignment, Type::tsize_t);
    }
    else if (ident == Id::_init)
    {
        Type *tb = toBasetype();
        e = defaultInitLiteral(loc);
        if (tb->ty == Tstruct && tb->needsNested())
        {
            StructLiteralExp *se = (StructLiteralExp *)e;
            se->useStaticInit = true;
        }
    }
    else if (ident == Id::_mangleof)
    {
        if (!deco)
        {
            error(loc, "forward reference of type %s.mangleof", toChars());
            e = new ErrorExp();
        }
        else
        {
            e = new StringExp(loc, (char *)deco, strlen(deco));
            Scope sc;
            e = ::semantic(e, &sc);
        }
    }
    else if (ident == Id::stringof)
    {
        const char *s = toChars();
        e = new StringExp(loc, const_cast<char *>(s), strlen(s));
        Scope sc;
        e = ::semantic(e, &sc);
    }
    else if (flag && this != Type::terror)
    {
        return NULL;
    }
    else
    {
        Dsymbol *s = NULL;
        if (ty == Tstruct || ty == Tclass || ty == Tenum)
            s = toDsymbol(NULL);
        if (s)
            s = s->search_correct(ident);
        if (this != Type::terror)
        {
            if (s)
                error(loc, "no property '%s' for type '%s', did you mean '%s'?", ident->toChars(), toChars(), s->toChars());
            else
                error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars());
        }
        e = new ErrorExp();
    }
    return e;
}

/***************************************
 * Access the members of the object e. This type is same as e->type.
 *
 * If flag & 1, don't report "not a property" error and just return NULL.
 */
Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    VarDeclaration *v = NULL;

    Expression *ex = e;
    while (ex->op == TOKcomma)
        ex = ((CommaExp *)ex)->e2;
    if (ex->op == TOKdotvar)
    {
        DotVarExp *dv = (DotVarExp *)ex;
        v = dv->var->isVarDeclaration();
    }
    else if (ex->op == TOKvar)
    {
        VarExp *ve = (VarExp *)ex;
        v = ve->var->isVarDeclaration();
    }
    if (v)
    {
        if (ident == Id::offsetof)
        {
            if (v->isField())
            {
                AggregateDeclaration *ad = v->toParent()->isAggregateDeclaration();
                ad->size(e->loc);
                if (ad->sizeok != SIZEOKdone)
                    return new ErrorExp();
                e = new IntegerExp(e->loc, v->offset, Type::tsize_t);
                return e;
            }
        }
        else if (ident == Id::_init)
        {
            Type *tb = toBasetype();
            e = defaultInitLiteral(e->loc);
            if (tb->ty == Tstruct && tb->needsNested())
            {
                StructLiteralExp *se = (StructLiteralExp *)e;
                se->useStaticInit = true;
            }
            goto Lreturn;
        }
    }
    if (ident == Id::stringof)
    {
        /* Bugzilla 3796: this should demangle e->type->deco rather than
         * pretty-printing the type.
         */
        const char *s = e->toChars();
        e = new StringExp(e->loc, const_cast<char *>(s), strlen(s));
    }
    else
        e = getProperty(e->loc, ident, flag & 1);

Lreturn:
    if (e)
        e = ::semantic(e, sc);
    return e;
}

/************************************
 * Return alignment to use for this type.
 */

structalign_t Type::alignment()
{
    return STRUCTALIGN_DEFAULT;
}

/***************************************
 * Figures out what to do with an undefined member reference
 * for classes and structs.
 *
 * If flag & 1, don't report "not a property" error and just return NULL.
 */
Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    //printf("Type::noMember(e: %s ident: %s flag: %d)\n", e->toChars(), ident->toChars(), flag);

    static int nest;      // https://issues.dlang.org/show_bug.cgi?id=17380

    if (++nest > 500)
    {
      ::error(e->loc, "cannot resolve identifier `%s`", ident->toChars());
      --nest;
      return (flag & 1) ? NULL : new ErrorExp();
    }

    assert(ty == Tstruct || ty == Tclass);
    AggregateDeclaration *sym = toDsymbol(sc)->isAggregateDeclaration();
    assert(sym);

    if (ident != Id::__sizeof &&
        ident != Id::__xalignof &&
        ident != Id::_init &&
        ident != Id::_mangleof &&
        ident != Id::stringof &&
        ident != Id::offsetof &&
        // Bugzilla 15045: Don't forward special built-in member functions.
        ident != Id::ctor &&
        ident != Id::dtor &&
        ident != Id::__xdtor &&
        ident != Id::postblit &&
        ident != Id::__xpostblit)
    {
        /* Look for overloaded opDot() to see if we should forward request
         * to it.
         */
        if (Dsymbol *fd = search_function(sym, Id::opDot))
        {
            /* Rewrite e.ident as:
             *  e.opDot().ident
             */
            e = build_overload(e->loc, sc, e, NULL, fd);
            e = new DotIdExp(e->loc, e, ident);
            e = ::semantic(e, sc);
            --nest;
            return e;
        }

        /* Look for overloaded opDispatch to see if we should forward request
         * to it.
         */
        if (Dsymbol *fd = search_function(sym, Id::opDispatch))
        {
            /* Rewrite e.ident as:
             *  e.opDispatch!("ident")
             */
            TemplateDeclaration *td = fd->isTemplateDeclaration();
            if (!td)
            {
                fd->error("must be a template opDispatch(string s), not a %s", fd->kind());
                --nest;
                return new ErrorExp();
            }
            StringExp *se = new StringExp(e->loc, const_cast<char *>(ident->toChars()));
            Objects *tiargs = new Objects();
            tiargs->push(se);
            DotTemplateInstanceExp *dti = new DotTemplateInstanceExp(e->loc, e, Id::opDispatch, tiargs);
            dti->ti->tempdecl = td;

            /* opDispatch, which doesn't need IFTI,  may occur instantiate error.
             * It should be gagged if flag & 1.
             * e.g.
             *  template opDispatch(name) if (isValid!name) { ... }
             */
            unsigned errors = flag & 1 ? global.startGagging() : 0;
            e = semanticY(dti, sc, 0);
            if (flag & 1 && global.endGagging(errors))
                e = NULL;
            --nest;
            return e;
        }

        /* See if we should forward to the alias this.
         */
        if (sym->aliasthis)
        {   /* Rewrite e.ident as:
             *  e.aliasthis.ident
             */
            e = resolveAliasThis(sc, e);
            DotIdExp *die = new DotIdExp(e->loc, e, ident);
            e = semanticY(die, sc, flag & 1);
            --nest;
            return e;
        }
    }

    e = Type::dotExp(sc, e, ident, flag);
    --nest;
    return e;
}

void Type::error(Loc loc, const char *format, ...)
{
    va_list ap;
    va_start(ap, format);
    ::verror(loc, format, ap);
    va_end( ap );
}

void Type::warning(Loc loc, const char *format, ...)
{
    va_list ap;
    va_start(ap, format);
    ::vwarning(loc, format, ap);
    va_end( ap );
}

Identifier *Type::getTypeInfoIdent()
{
    // _init_10TypeInfo_%s
    OutBuffer buf;
    buf.reserve(32);
    mangleToBuffer(this, &buf);

    size_t len = buf.offset;
    buf.writeByte(0);

    // Allocate buffer on stack, fail over to using malloc()
    char namebuf[128];
    size_t namelen = 19 + sizeof(len) * 3 + len + 1;
    char *name = namelen <= sizeof(namebuf) ? namebuf : (char *)mem.xmalloc(namelen);

    int length = sprintf(name, "_D%lluTypeInfo_%s6__initZ", (unsigned long long) 9 + len, buf.data);
    //printf("%p, deco = %s, name = %s\n", this, deco, name);
    assert(0 < length && (size_t)length < namelen);     // don't overflow the buffer

    Identifier *id = Identifier::idPool(name, length);

    if (name != namebuf)
        free(name);
    return id;
}

TypeBasic *Type::isTypeBasic()
{
    return NULL;
}

TypeFunction *Type::toTypeFunction()
{
    if (ty != Tfunction)
        assert(0);
    return (TypeFunction *)this;
}

/***************************************
 * Resolve 'this' type to either type, symbol, or expression.
 * If errors happened, resolved to Type.terror.
 */
void Type::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool)
{
    //printf("Type::resolve() %s, %d\n", toChars(), ty);
    Type *t = semantic(loc, sc);
    *pt = t;
    *pe = NULL;
    *ps = NULL;
}

/***************************************
 * Normalize `e` as the result of Type::resolve() process.
 */
void Type::resolveExp(Expression *e, Type **pt, Expression **pe, Dsymbol **ps)
{
    *pt = NULL;
    *pe = NULL;
    *ps = NULL;

    Dsymbol *s;
    switch (e->op)
    {
        case TOKerror:
            *pt = Type::terror;
            return;

        case TOKtype:
            *pt = e->type;
            return;

        case TOKvar:
            s = ((VarExp *)e)->var;
            if (s->isVarDeclaration())
                goto Ldefault;
            //if (s->isOverDeclaration())
            //    todo;
            break;

        case TOKtemplate:
            // TemplateDeclaration
            s = ((TemplateExp *)e)->td;
            break;

        case TOKimport:
            s = ((ScopeExp *)e)->sds;
            // TemplateDeclaration, TemplateInstance, Import, Package, Module
            break;

        case TOKfunction:
            s = getDsymbol(e);
            break;

        //case TOKthis:
        //case TOKsuper:

        //case TOKtuple:

        //case TOKoverloadset:

        //case TOKdotvar:
        //case TOKdottd:
        //case TOKdotti:
        //case TOKdottype:
        //case TOKdot:

        default:
    Ldefault:
            *pe = e;
            return;
    }

    *ps = s;
}

/***************************************
 * Return !=0 if the type or any of its subtypes is wild.
 */

int Type::hasWild() const
{
    return mod & MODwild;
}

/***************************************
 * Return !=0 if type has pointers that need to
 * be scanned by the GC during a collection cycle.
 */
bool Type::hasPointers()
{
    //printf("Type::hasPointers() %s, %d\n", toChars(), ty);
    return false;
}

/*************************************
 * Detect if type has pointer fields that are initialized to void.
 * Local stack variables with such void fields can remain uninitialized,
 * leading to pointer bugs.
 * Returns:
 *  true if so
 */
bool Type::hasVoidInitPointers()
{
    return false;
}

/*************************************
 * If this is a type of something, return that something.
 */

Type *Type::nextOf()
{
    return NULL;
}

/*************************************
 * If this is a type of static array, return its base element type.
 */

Type *Type::baseElemOf()
{
    Type *t = toBasetype();
    while (t->ty == Tsarray)
        t = ((TypeSArray *)t)->next->toBasetype();
    return t;
}

/*************************************
 * Bugzilla 14488: Check if the inner most base type is complex or imaginary.
 * Should only give alerts when set to emit transitional messages.
 */

void Type::checkComplexTransition(Loc loc)
{
    Type *t = baseElemOf();
    while (t->ty == Tpointer || t->ty == Tarray)
        t = t->nextOf()->baseElemOf();

    if (t->isimaginary() || t->iscomplex())
    {
        Type *rt;
        switch (t->ty)
        {
            case Tcomplex32:
            case Timaginary32:
                rt = Type::tfloat32; break;
            case Tcomplex64:
            case Timaginary64:
                rt = Type::tfloat64; break;
            case Tcomplex80:
            case Timaginary80:
                rt = Type::tfloat80; break;
            default:
                assert(0);
        }
        if (t->iscomplex())
        {
            message(loc, "use of complex type `%s` is scheduled for deprecation, "
                    "use `std.complex.Complex!(%s)` instead", toChars(), rt->toChars());
        }
        else
        {
            message(loc, "use of imaginary type `%s` is scheduled for deprecation, "
                    "use `%s` instead\n", toChars(), rt->toChars());
        }
    }
}

/****************************************
 * Return the mask that an integral type will
 * fit into.
 */
uinteger_t Type::sizemask()
{   uinteger_t m;

    switch (toBasetype()->ty)
    {
        case Tbool:     m = 1;                          break;
        case Tchar:
        case Tint8:
        case Tuns8:     m = 0xFF;                       break;
        case Twchar:
        case Tint16:
        case Tuns16:    m = 0xFFFFUL;                   break;
        case Tdchar:
        case Tint32:
        case Tuns32:    m = 0xFFFFFFFFUL;               break;
        case Tint64:
        case Tuns64:    m = 0xFFFFFFFFFFFFFFFFULL;      break;
        default:
                assert(0);
    }
    return m;
}

/* ============================= TypeError =========================== */

TypeError::TypeError()
        : Type(Terror)
{
}

Type *TypeError::syntaxCopy()
{
    // No semantic analysis done, no need to copy
    return this;
}

d_uns64 TypeError::size(Loc) { return SIZE_INVALID; }
Expression *TypeError::getProperty(Loc, Identifier *, int) { return new ErrorExp(); }
Expression *TypeError::dotExp(Scope *, Expression *, Identifier *, int) { return new ErrorExp(); }
Expression *TypeError::defaultInit(Loc) { return new ErrorExp(); }
Expression *TypeError::defaultInitLiteral(Loc) { return new ErrorExp(); }

/* ============================= TypeNext =========================== */

TypeNext::TypeNext(TY ty, Type *next)
        : Type(ty)
{
    this->next = next;
}

void TypeNext::checkDeprecated(Loc loc, Scope *sc)
{
    Type::checkDeprecated(loc, sc);
    if (next)   // next can be NULL if TypeFunction and auto return type
        next->checkDeprecated(loc, sc);
}

int TypeNext::hasWild() const
{
    if (ty == Tfunction)
        return 0;
    if (ty == Tdelegate)
        return Type::hasWild();
    return mod & MODwild || (next && next->hasWild());
}


/*******************************
 * For TypeFunction, nextOf() can return NULL if the function return
 * type is meant to be inferred, and semantic() hasn't yet ben run
 * on the function. After semantic(), it must no longer be NULL.
 */

Type *TypeNext::nextOf()
{
    return next;
}

Type *TypeNext::makeConst()
{
    //printf("TypeNext::makeConst() %p, %s\n", this, toChars());
    if (cto)
    {
        assert(cto->mod == MODconst);
        return cto;
    }
    TypeNext *t = (TypeNext *)Type::makeConst();
    if (ty != Tfunction && next->ty != Tfunction &&
        !next->isImmutable())
    {
        if (next->isShared())
        {
            if (next->isWild())
                t->next = next->sharedWildConstOf();
            else
                t->next = next->sharedConstOf();
        }
        else
        {
            if (next->isWild())
                t->next = next->wildConstOf();
            else
                t->next = next->constOf();
        }
    }
    //printf("TypeNext::makeConst() returns %p, %s\n", t, t->toChars());
    return t;
}

Type *TypeNext::makeImmutable()
{
    //printf("TypeNext::makeImmutable() %s\n", toChars());
    if (ito)
    {
        assert(ito->isImmutable());
        return ito;
    }
    TypeNext *t = (TypeNext *)Type::makeImmutable();
    if (ty != Tfunction && next->ty != Tfunction &&
        !next->isImmutable())
    {
        t->next = next->immutableOf();
    }
    return t;
}

Type *TypeNext::makeShared()
{
    //printf("TypeNext::makeShared() %s\n", toChars());
    if (sto)
    {
        assert(sto->mod == MODshared);
        return sto;
    }
    TypeNext *t = (TypeNext *)Type::makeShared();
    if (ty != Tfunction && next->ty != Tfunction &&
        !next->isImmutable())
    {
        if (next->isWild())
        {
            if (next->isConst())
                t->next = next->sharedWildConstOf();
            else
                t->next = next->sharedWildOf();
        }
        else
        {
            if (next->isConst())
                t->next = next->sharedConstOf();
            else
                t->next = next->sharedOf();
        }
    }
    //printf("TypeNext::makeShared() returns %p, %s\n", t, t->toChars());
    return t;
}

Type *TypeNext::makeSharedConst()
{
    //printf("TypeNext::makeSharedConst() %s\n", toChars());
    if (scto)
    {
        assert(scto->mod == (MODshared | MODconst));
        return scto;
    }
    TypeNext *t = (TypeNext *)Type::makeSharedConst();
    if (ty != Tfunction && next->ty != Tfunction &&
        !next->isImmutable())
    {
        if (next->isWild())
            t->next = next->sharedWildConstOf();
        else
            t->next = next->sharedConstOf();
    }
    //printf("TypeNext::makeSharedConst() returns %p, %s\n", t, t->toChars());
    return t;
}

Type *TypeNext::makeWild()
{
    //printf("TypeNext::makeWild() %s\n", toChars());
    if (wto)
    {
        assert(wto->mod == MODwild);
        return wto;
    }
    TypeNext *t = (TypeNext *)Type::makeWild();
    if (ty != Tfunction && next->ty != Tfunction &&
        !next->isImmutable())
    {
        if (next->isShared())
        {
            if (next->isConst())
                t->next = next->sharedWildConstOf();
            else
                t->next = next->sharedWildOf();
        }
        else
        {
            if (next->isConst())
                t->next = next->wildConstOf();
            else
                t->next = next->wildOf();
        }
    }
    //printf("TypeNext::makeWild() returns %p, %s\n", t, t->toChars());
    return t;
}

Type *TypeNext::makeWildConst()
{
    //printf("TypeNext::makeWildConst() %s\n", toChars());
    if (wcto)
    {
        assert(wcto->mod == MODwildconst);
        return wcto;
    }
    TypeNext *t = (TypeNext *)Type::makeWildConst();
    if (ty != Tfunction && next->ty != Tfunction &&
        !next->isImmutable())
    {
        if (next->isShared())
            t->next = next->sharedWildConstOf();
        else
            t->next = next->wildConstOf();
    }
    //printf("TypeNext::makeWildConst() returns %p, %s\n", t, t->toChars());
    return t;
}

Type *TypeNext::makeSharedWild()
{
    //printf("TypeNext::makeSharedWild() %s\n", toChars());
    if (swto)
    {
        assert(swto->isSharedWild());
        return swto;
    }
    TypeNext *t = (TypeNext *)Type::makeSharedWild();
    if (ty != Tfunction && next->ty != Tfunction &&
        !next->isImmutable())
    {
        if (next->isConst())
            t->next = next->sharedWildConstOf();
        else
            t->next = next->sharedWildOf();
    }
    //printf("TypeNext::makeSharedWild() returns %p, %s\n", t, t->toChars());
    return t;
}

Type *TypeNext::makeSharedWildConst()
{
    //printf("TypeNext::makeSharedWildConst() %s\n", toChars());
    if (swcto)
    {
        assert(swcto->mod == (MODshared | MODwildconst));
        return swcto;
    }
    TypeNext *t = (TypeNext *)Type::makeSharedWildConst();
    if (ty != Tfunction && next->ty != Tfunction &&
        !next->isImmutable())
    {
        t->next = next->sharedWildConstOf();
    }
    //printf("TypeNext::makeSharedWildConst() returns %p, %s\n", t, t->toChars());
    return t;
}

Type *TypeNext::makeMutable()
{
    //printf("TypeNext::makeMutable() %p, %s\n", this, toChars());
    TypeNext *t = (TypeNext *)Type::makeMutable();
    if (ty == Tsarray)
    {
        t->next = next->mutableOf();
    }
    //printf("TypeNext::makeMutable() returns %p, %s\n", t, t->toChars());
    return t;
}

MATCH TypeNext::constConv(Type *to)
{
    //printf("TypeNext::constConv from = %s, to = %s\n", toChars(), to->toChars());
    if (equals(to))
        return MATCHexact;

    if (!(ty == to->ty && MODimplicitConv(mod, to->mod)))
        return MATCHnomatch;

    Type *tn = to->nextOf();
    if (!(tn && next->ty == tn->ty))
        return MATCHnomatch;

    MATCH m;
    if (to->isConst())  // whole tail const conversion
    {   // Recursive shared level check
        m = next->constConv(tn);
        if (m == MATCHexact)
            m = MATCHconst;
    }
    else
    {   //printf("\tnext => %s, to->next => %s\n", next->toChars(), tn->toChars());
        m = next->equals(tn) ? MATCHconst : MATCHnomatch;
    }
    return m;
}

unsigned char TypeNext::deduceWild(Type *t, bool isRef)
{
    if (ty == Tfunction)
        return 0;

    unsigned char wm;

    Type *tn = t->nextOf();
    if (!isRef && (ty == Tarray || ty == Tpointer) && tn)
    {
        wm = next->deduceWild(tn, true);
        if (!wm)
            wm = Type::deduceWild(t, true);
    }
    else
    {
        wm = Type::deduceWild(t, isRef);
        if (!wm && tn)
            wm = next->deduceWild(tn, true);
    }

    return wm;
}


void TypeNext::transitive()
{
    /* Invoke transitivity of type attributes
     */
    next = next->addMod(mod);
}

/* ============================= TypeBasic =========================== */

#define TFLAGSintegral  1
#define TFLAGSfloating  2
#define TFLAGSunsigned  4
#define TFLAGSreal      8
#define TFLAGSimaginary 0x10
#define TFLAGScomplex   0x20

TypeBasic::TypeBasic(TY ty)
        : Type(ty)
{   const char *d;
    unsigned flags;

    flags = 0;
    switch (ty)
    {
        case Tvoid:     d = Token::toChars(TOKvoid);
                        break;

        case Tint8:     d = Token::toChars(TOKint8);
                        flags |= TFLAGSintegral;
                        break;

        case Tuns8:     d = Token::toChars(TOKuns8);
                        flags |= TFLAGSintegral | TFLAGSunsigned;
                        break;

        case Tint16:    d = Token::toChars(TOKint16);
                        flags |= TFLAGSintegral;
                        break;

        case Tuns16:    d = Token::toChars(TOKuns16);
                        flags |= TFLAGSintegral | TFLAGSunsigned;
                        break;

        case Tint32:    d = Token::toChars(TOKint32);
                        flags |= TFLAGSintegral;
                        break;

        case Tuns32:    d = Token::toChars(TOKuns32);
                        flags |= TFLAGSintegral | TFLAGSunsigned;
                        break;

        case Tfloat32:  d = Token::toChars(TOKfloat32);
                        flags |= TFLAGSfloating | TFLAGSreal;
                        break;

        case Tint64:    d = Token::toChars(TOKint64);
                        flags |= TFLAGSintegral;
                        break;

        case Tuns64:    d = Token::toChars(TOKuns64);
                        flags |= TFLAGSintegral | TFLAGSunsigned;
                        break;

        case Tint128:   d = Token::toChars(TOKint128);
                        flags |= TFLAGSintegral;
                        break;

        case Tuns128:   d = Token::toChars(TOKuns128);
                        flags |= TFLAGSintegral | TFLAGSunsigned;
                        break;

        case Tfloat64:  d = Token::toChars(TOKfloat64);
                        flags |= TFLAGSfloating | TFLAGSreal;
                        break;

        case Tfloat80:  d = Token::toChars(TOKfloat80);
                        flags |= TFLAGSfloating | TFLAGSreal;
                        break;

        case Timaginary32: d = Token::toChars(TOKimaginary32);
                        flags |= TFLAGSfloating | TFLAGSimaginary;
                        break;

        case Timaginary64: d = Token::toChars(TOKimaginary64);
                        flags |= TFLAGSfloating | TFLAGSimaginary;
                        break;

        case Timaginary80: d = Token::toChars(TOKimaginary80);
                        flags |= TFLAGSfloating | TFLAGSimaginary;
                        break;

        case Tcomplex32: d = Token::toChars(TOKcomplex32);
                        flags |= TFLAGSfloating | TFLAGScomplex;
                        break;

        case Tcomplex64: d = Token::toChars(TOKcomplex64);
                        flags |= TFLAGSfloating | TFLAGScomplex;
                        break;

        case Tcomplex80: d = Token::toChars(TOKcomplex80);
                        flags |= TFLAGSfloating | TFLAGScomplex;
                        break;

        case Tbool:     d = "bool";
                        flags |= TFLAGSintegral | TFLAGSunsigned;
                        break;

        case Tchar:     d = Token::toChars(TOKchar);
                        flags |= TFLAGSintegral | TFLAGSunsigned;
                        break;

        case Twchar:    d = Token::toChars(TOKwchar);
                        flags |= TFLAGSintegral | TFLAGSunsigned;
                        break;

        case Tdchar:    d = Token::toChars(TOKdchar);
                        flags |= TFLAGSintegral | TFLAGSunsigned;
                        break;

        default:        assert(0);
    }
    this->dstring = d;
    this->flags = flags;
    merge();
}

const char *TypeBasic::kind()
{
    return dstring;
}

Type *TypeBasic::syntaxCopy()
{
    // No semantic analysis done on basic types, no need to copy
    return this;
}

d_uns64 TypeBasic::size(Loc)
{   unsigned size;

    //printf("TypeBasic::size()\n");
    switch (ty)
    {
        case Tint8:
        case Tuns8:     size = 1;       break;
        case Tint16:
        case Tuns16:    size = 2;       break;
        case Tint32:
        case Tuns32:
        case Tfloat32:
        case Timaginary32:
                        size = 4;       break;
        case Tint64:
        case Tuns64:
        case Tfloat64:
        case Timaginary64:
                        size = 8;       break;
        case Tfloat80:
        case Timaginary80:
                        size = Target::realsize; break;
        case Tcomplex32:
                        size = 8;               break;
        case Tcomplex64:
        case Tint128:
        case Tuns128:
                        size = 16;              break;
        case Tcomplex80:
                        size = Target::realsize * 2; break;

        case Tvoid:
            //size = Type::size();      // error message
            size = 1;
            break;

        case Tbool:     size = 1;               break;
        case Tchar:     size = 1;               break;
        case Twchar:    size = 2;               break;
        case Tdchar:    size = 4;               break;

        default:
            assert(0);
            break;
    }
    //printf("TypeBasic::size() = %d\n", size);
    return size;
}

unsigned TypeBasic::alignsize()
{
    return Target::alignsize(this);
}


Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
{
    Expression *e;
    dinteger_t ivalue;
    real_t fvalue;

    //printf("TypeBasic::getProperty('%s')\n", ident->toChars());
    if (ident == Id::max)
    {
        switch (ty)
        {
        case Tint8:
            ivalue = 0x7F;
            goto Livalue;
        case Tuns8:
            ivalue = 0xFF;
            goto Livalue;
        case Tint16:
            ivalue = 0x7FFFUL;
            goto Livalue;
        case Tuns16:
            ivalue = 0xFFFFUL;
            goto Livalue;
        case Tint32:
            ivalue = 0x7FFFFFFFUL;
            goto Livalue;
        case Tuns32:
            ivalue = 0xFFFFFFFFUL;
            goto Livalue;
        case Tint64:
            ivalue = 0x7FFFFFFFFFFFFFFFLL;
            goto Livalue;
        case Tuns64:
            ivalue = 0xFFFFFFFFFFFFFFFFULL;
            goto Livalue;
        case Tbool:
            ivalue = 1;
            goto Livalue;
        case Tchar:
            ivalue = 0xFF;
            goto Livalue;
        case Twchar:
            ivalue = 0xFFFFUL;
            goto Livalue;
        case Tdchar:
            ivalue = 0x10FFFFUL;
            goto Livalue;
        case Tcomplex32:
        case Timaginary32:
        case Tfloat32:
            fvalue = Target::FloatProperties::max;
            goto Lfvalue;
        case Tcomplex64:
        case Timaginary64:
        case Tfloat64:
            fvalue = Target::DoubleProperties::max;
            goto Lfvalue;
        case Tcomplex80:
        case Timaginary80:
        case Tfloat80:
            fvalue = Target::RealProperties::max;
            goto Lfvalue;
        }
    }
    else if (ident == Id::min)
    {
        switch (ty)
        {
        case Tint8:
            ivalue = -128;
            goto Livalue;
        case Tuns8:
            ivalue = 0;
            goto Livalue;
        case Tint16:
            ivalue = -32768;
            goto Livalue;
        case Tuns16:
            ivalue = 0;
            goto Livalue;
        case Tint32:
            ivalue = -2147483647L - 1;
            goto Livalue;
        case Tuns32:
            ivalue = 0;
            goto Livalue;
        case Tint64:
            ivalue = (-9223372036854775807LL-1LL);
            goto Livalue;
        case Tuns64:
            ivalue = 0;
            goto Livalue;
        case Tbool:
            ivalue = 0;
            goto Livalue;
        case Tchar:
            ivalue = 0;
            goto Livalue;
        case Twchar:
            ivalue = 0;
            goto Livalue;
        case Tdchar:
            ivalue = 0;
            goto Livalue;

        case Tcomplex32:
        case Timaginary32:
        case Tfloat32:
        case Tcomplex64:
        case Timaginary64:
        case Tfloat64:
        case Tcomplex80:
        case Timaginary80:
        case Tfloat80:
            error(loc, "use .min_normal property instead of .min");
            return new ErrorExp();
        }
    }
    else if (ident == Id::min_normal)
    {
        switch (ty)
        {
        case Tcomplex32:
        case Timaginary32:
        case Tfloat32:
            fvalue = Target::FloatProperties::min_normal;
            goto Lfvalue;
        case Tcomplex64:
        case Timaginary64:
        case Tfloat64:
            fvalue = Target::DoubleProperties::min_normal;
            goto Lfvalue;
        case Tcomplex80:
        case Timaginary80:
        case Tfloat80:
            fvalue = Target::RealProperties::min_normal;
            goto Lfvalue;
        }
    }
    else if (ident == Id::nan)
    {
        switch (ty)
        {
        case Tcomplex32:
        case Tcomplex64:
        case Tcomplex80:
        case Timaginary32:
        case Timaginary64:
        case Timaginary80:
        case Tfloat32:
        case Tfloat64:
        case Tfloat80:
            fvalue = Target::RealProperties::nan;
            goto Lfvalue;
        }
    }
    else if (ident == Id::infinity)
    {
        switch (ty)
        {
        case Tcomplex32:
        case Tcomplex64:
        case Tcomplex80:
        case Timaginary32:
        case Timaginary64:
        case Timaginary80:
        case Tfloat32:
        case Tfloat64:
        case Tfloat80:
            fvalue = Target::RealProperties::infinity;
            goto Lfvalue;
        }
    }
    else if (ident == Id::dig)
    {
        switch (ty)
        {
        case Tcomplex32:
        case Timaginary32:
        case Tfloat32:
            ivalue = Target::FloatProperties::dig;
            goto Lint;
        case Tcomplex64:
        case Timaginary64:
        case Tfloat64:
            ivalue = Target::DoubleProperties::dig;
            goto Lint;
        case Tcomplex80:
        case Timaginary80:
        case Tfloat80:
            ivalue = Target::RealProperties::dig;
            goto Lint;
        }
    }
    else if (ident == Id::epsilon)
    {
        switch (ty)
        {
        case Tcomplex32:
        case Timaginary32:
        case Tfloat32:
            fvalue = Target::FloatProperties::epsilon;
            goto Lfvalue;
        case Tcomplex64:
        case Timaginary64:
        case Tfloat64:
            fvalue = Target::DoubleProperties::epsilon;
            goto Lfvalue;
        case Tcomplex80:
        case Timaginary80:
        case Tfloat80:
            fvalue = Target::RealProperties::epsilon;
            goto Lfvalue;
        }
    }
    else if (ident == Id::mant_dig)
    {
        switch (ty)
        {
        case Tcomplex32:
        case Timaginary32:
        case Tfloat32:
            ivalue = Target::FloatProperties::mant_dig;
            goto Lint;
        case Tcomplex64:
        case Timaginary64:
        case Tfloat64:
            ivalue = Target::DoubleProperties::mant_dig;
            goto Lint;
        case Tcomplex80:
        case Timaginary80:
        case Tfloat80:
            ivalue = Target::RealProperties::mant_dig;
            goto Lint;
        }
    }
    else if (ident == Id::max_10_exp)
    {
        switch (ty)
        {
        case Tcomplex32:
        case Timaginary32:
        case Tfloat32:
            ivalue = Target::FloatProperties::max_10_exp;
            goto Lint;
        case Tcomplex64:
        case Timaginary64:
        case Tfloat64:
            ivalue = Target::DoubleProperties::max_10_exp;
            goto Lint;
        case Tcomplex80:
        case Timaginary80:
        case Tfloat80:
            ivalue = Target::RealProperties::max_10_exp;
            goto Lint;
        }
    }
    else if (ident == Id::max_exp)
    {
        switch (ty)
        {
        case Tcomplex32:
        case Timaginary32:
        case Tfloat32:
            ivalue = Target::FloatProperties::max_exp;
            goto Lint;
        case Tcomplex64:
        case Timaginary64:
        case Tfloat64:
            ivalue = Target::DoubleProperties::max_exp;
            goto Lint;
        case Tcomplex80:
        case Timaginary80:
        case Tfloat80:
            ivalue = Target::RealProperties::max_exp;
            goto Lint;
        }
    }
    else if (ident == Id::min_10_exp)
    {
        switch (ty)
        {
        case Tcomplex32:
        case Timaginary32:
        case Tfloat32:
            ivalue = Target::FloatProperties::min_10_exp;
            goto Lint;
        case Tcomplex64:
        case Timaginary64:
        case Tfloat64:
            ivalue = Target::DoubleProperties::min_10_exp;
            goto Lint;
        case Tcomplex80:
        case Timaginary80:
        case Tfloat80:
            ivalue = Target::RealProperties::min_10_exp;
            goto Lint;
        }
    }
    else if (ident == Id::min_exp)
    {
        switch (ty)
        {
        case Tcomplex32:
        case Timaginary32:
        case Tfloat32:
            ivalue = Target::FloatProperties::min_exp;
            goto Lint;
        case Tcomplex64:
        case Timaginary64:
        case Tfloat64:
            ivalue = Target::DoubleProperties::min_exp;
            goto Lint;
        case Tcomplex80:
        case Timaginary80:
        case Tfloat80:
            ivalue = Target::RealProperties::min_exp;
            goto Lint;
        }
    }

    return Type::getProperty(loc, ident, flag);

Livalue:
    e = new IntegerExp(loc, ivalue, this);
    return e;

Lfvalue:
    if (isreal() || isimaginary())
        e = new RealExp(loc, fvalue, this);
    else
    {
        complex_t cvalue = complex_t(fvalue, fvalue);
        //for (int i = 0; i < 20; i++)
        //    printf("%02x ", ((unsigned char *)&cvalue)[i]);
        //printf("\n");
        e = new ComplexExp(loc, cvalue, this);
    }
    return e;

Lint:
    e = new IntegerExp(loc, ivalue, Type::tint32);
    return e;
}

Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    Type *t;

    if (ident == Id::re)
    {
        switch (ty)
        {
            case Tcomplex32:    t = tfloat32;           goto L1;
            case Tcomplex64:    t = tfloat64;           goto L1;
            case Tcomplex80:    t = tfloat80;           goto L1;
            L1:
                e = e->castTo(sc, t);
                break;

            case Tfloat32:
            case Tfloat64:
            case Tfloat80:
                break;

            case Timaginary32:  t = tfloat32;           goto L2;
            case Timaginary64:  t = tfloat64;           goto L2;
            case Timaginary80:  t = tfloat80;           goto L2;
            L2:
                e = new RealExp(e->loc, CTFloat::zero, t);
                break;

            default:
                e = Type::getProperty(e->loc, ident, flag);
                break;
        }
    }
    else if (ident == Id::im)
    {   Type *t2;

        switch (ty)
        {
            case Tcomplex32:    t = timaginary32;       t2 = tfloat32;  goto L3;
            case Tcomplex64:    t = timaginary64;       t2 = tfloat64;  goto L3;
            case Tcomplex80:    t = timaginary80;       t2 = tfloat80;  goto L3;
            L3:
                e = e->castTo(sc, t);
                e->type = t2;
                break;

            case Timaginary32:  t = tfloat32;   goto L4;
            case Timaginary64:  t = tfloat64;   goto L4;
            case Timaginary80:  t = tfloat80;   goto L4;
            L4:
                e = e->copy();
                e->type = t;
                break;

            case Tfloat32:
            case Tfloat64:
            case Tfloat80:
                e = new RealExp(e->loc, CTFloat::zero, this);
                break;

            default:
                e = Type::getProperty(e->loc, ident, flag);
                break;
        }
    }
    else
    {
        return Type::dotExp(sc, e, ident, flag);
    }
    if (!(flag & 1) || e)
        e = ::semantic(e, sc);
    return e;
}

Expression *TypeBasic::defaultInit(Loc loc)
{
    dinteger_t value = 0;

    switch (ty)
    {
        case Tchar:
            value = 0xFF;
            break;

        case Twchar:
        case Tdchar:
            value = 0xFFFF;
            break;

        case Timaginary32:
        case Timaginary64:
        case Timaginary80:
        case Tfloat32:
        case Tfloat64:
        case Tfloat80:
            return new RealExp(loc, Target::RealProperties::snan, this);

        case Tcomplex32:
        case Tcomplex64:
        case Tcomplex80:
        {   // Can't use fvalue + I*fvalue (the im part becomes a quiet NaN).
            complex_t cvalue = complex_t(Target::RealProperties::snan, Target::RealProperties::snan);
            return new ComplexExp(loc, cvalue, this);
        }

        case Tvoid:
            error(loc, "void does not have a default initializer");
            return new ErrorExp();
    }
    return new IntegerExp(loc, value, this);
}

bool TypeBasic::isZeroInit(Loc)
{
    switch (ty)
    {
        case Tchar:
        case Twchar:
        case Tdchar:
        case Timaginary32:
        case Timaginary64:
        case Timaginary80:
        case Tfloat32:
        case Tfloat64:
        case Tfloat80:
        case Tcomplex32:
        case Tcomplex64:
        case Tcomplex80:
            return false;       // no
        default:
            return true;        // yes
    }
}

bool TypeBasic::isintegral()
{
    //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags);
    return (flags & TFLAGSintegral) != 0;
}

bool TypeBasic::isfloating()
{
    return (flags & TFLAGSfloating) != 0;
}

bool TypeBasic::isreal()
{
    return (flags & TFLAGSreal) != 0;
}

bool TypeBasic::isimaginary()
{
    return (flags & TFLAGSimaginary) != 0;
}

bool TypeBasic::iscomplex()
{
    return (flags & TFLAGScomplex) != 0;
}

bool TypeBasic::isunsigned()
{
    return (flags & TFLAGSunsigned) != 0;
}

bool TypeBasic::isscalar()
{
    return (flags & (TFLAGSintegral | TFLAGSfloating)) != 0;
}

MATCH TypeBasic::implicitConvTo(Type *to)
{
    //printf("TypeBasic::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
    if (this == to)
        return MATCHexact;

    if (ty == to->ty)
    {
        if (mod == to->mod)
            return MATCHexact;
        else if (MODimplicitConv(mod, to->mod))
            return MATCHconst;
        else if (!((mod ^ to->mod) & MODshared))    // for wild matching
            return MATCHconst;
        else
            return MATCHconvert;
    }

    if (ty == Tvoid || to->ty == Tvoid)
        return MATCHnomatch;
    if (to->ty == Tbool)
        return MATCHnomatch;

    TypeBasic *tob;
    if (to->ty == Tvector && to->deco)
    {
        TypeVector *tv = (TypeVector *)to;
        tob = tv->elementType();
    }
    else if (to->ty == Tenum)
    {
        EnumDeclaration *ed = ((TypeEnum *)to)->sym;
        if (ed->isSpecial())
        {
            /* Special enums that allow implicit conversions to them.  */
            tob = to->toBasetype()->isTypeBasic();
            if (tob)
                return implicitConvTo(tob);
        }
        else
            return MATCHnomatch;
    }
    else
        tob = to->isTypeBasic();
    if (!tob)
        return MATCHnomatch;

    if (flags & TFLAGSintegral)
    {
        // Disallow implicit conversion of integers to imaginary or complex
        if (tob->flags & (TFLAGSimaginary | TFLAGScomplex))
            return MATCHnomatch;

        // If converting from integral to integral
        if (tob->flags & TFLAGSintegral)
        {   d_uns64 sz = size(Loc());
            d_uns64 tosz = tob->size(Loc());

            /* Can't convert to smaller size
             */
            if (sz > tosz)
                return MATCHnomatch;

            /* Can't change sign if same size
             */
            /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned)
                return MATCHnomatch;*/
        }
    }
    else if (flags & TFLAGSfloating)
    {
        // Disallow implicit conversion of floating point to integer
        if (tob->flags & TFLAGSintegral)
            return MATCHnomatch;

        assert(tob->flags & TFLAGSfloating || to->ty == Tvector);

        // Disallow implicit conversion from complex to non-complex
        if (flags & TFLAGScomplex && !(tob->flags & TFLAGScomplex))
            return MATCHnomatch;

        // Disallow implicit conversion of real or imaginary to complex
        if (flags & (TFLAGSreal | TFLAGSimaginary) &&
            tob->flags & TFLAGScomplex)
            return MATCHnomatch;

        // Disallow implicit conversion to-from real and imaginary
        if ((flags & (TFLAGSreal | TFLAGSimaginary)) !=
            (tob->flags & (TFLAGSreal | TFLAGSimaginary)))
            return MATCHnomatch;
    }
    return MATCHconvert;
}

TypeBasic *TypeBasic::isTypeBasic()
{
    return (TypeBasic *)this;
}

/* ============================= TypeVector =========================== */

/* The basetype must be one of:
 *   byte[16],ubyte[16],short[8],ushort[8],int[4],uint[4],long[2],ulong[2],float[4],double[2]
 * For AVX:
 *   byte[32],ubyte[32],short[16],ushort[16],int[8],uint[8],long[4],ulong[4],float[8],double[4]
 */
TypeVector::TypeVector(Type *basetype)
        : Type(Tvector)
{
    this->basetype = basetype;
}

TypeVector *TypeVector::create(Loc, Type *basetype)
{
    return new TypeVector(basetype);
}

const char *TypeVector::kind()
{
    return "vector";
}

Type *TypeVector::syntaxCopy()
{
    return new TypeVector(basetype->syntaxCopy());
}

Type *TypeVector::semantic(Loc loc, Scope *sc)
{
    unsigned int errors = global.errors;
    basetype = basetype->semantic(loc, sc);
    if (errors != global.errors)
        return terror;
    basetype = basetype->toBasetype()->mutableOf();
    if (basetype->ty != Tsarray)
    {
        error(loc, "T in __vector(T) must be a static array, not %s", basetype->toChars());
        return terror;
    }
    TypeSArray *t = (TypeSArray *)basetype;
    int sz = (int)t->size(loc);
    switch (Target::isVectorTypeSupported(sz, t->nextOf()))
    {
    case 0: // valid
        break;
    case 1: // no support at all
        error(loc, "SIMD vector types not supported on this platform");
        return terror;
    case 2: // invalid size
        error(loc, "%d byte vector type %s is not supported on this platform", sz, toChars());
        return terror;
    case 3: // invalid base type
        error(loc, "vector type %s is not supported on this platform", toChars());
        return terror;
    default:
        assert(0);
    }
    return merge();
}

TypeBasic *TypeVector::elementType()
{
    assert(basetype->ty == Tsarray);
    TypeSArray *t = (TypeSArray *)basetype;
    TypeBasic *tb = t->nextOf()->isTypeBasic();
    assert(tb);
    return tb;
}

bool TypeVector::isBoolean()
{
    return false;
}

d_uns64 TypeVector::size(Loc)
{
    return basetype->size();
}

unsigned TypeVector::alignsize()
{
    return (unsigned)basetype->size();
}

Expression *TypeVector::getProperty(Loc loc, Identifier *ident, int flag)
{
    return Type::getProperty(loc, ident, flag);
}

Expression *TypeVector::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    if (ident == Id::ptr && e->op == TOKcall)
    {
        /* The trouble with TOKcall is the return ABI for float[4] is different from
         * __vector(float[4]), and a type paint won't do.
         */
        e = new AddrExp(e->loc, e);
        e = ::semantic(e, sc);
        e = e->castTo(sc, basetype->nextOf()->pointerTo());
        return e;
    }
    if (ident == Id::array)
    {
        //e = e->castTo(sc, basetype);
        // Keep lvalue-ness
        e = new VectorArrayExp(e->loc, e);
        e = ::semantic(e, sc);
        return e;
    }
    if (ident == Id::_init || ident == Id::offsetof || ident == Id::stringof || ident == Id::__xalignof)
    {
        // init should return a new VectorExp (Bugzilla 12776)
        // offsetof does not work on a cast expression, so use e directly
        // stringof should not add a cast to the output
        return Type::dotExp(sc, e, ident, flag);
    }
    return basetype->dotExp(sc, e->castTo(sc, basetype), ident, flag);
}

Expression *TypeVector::defaultInit(Loc loc)
{
    //printf("TypeVector::defaultInit()\n");
    assert(basetype->ty == Tsarray);
    Expression *e = basetype->defaultInit(loc);
    VectorExp *ve = new VectorExp(loc, e, this);
    ve->type = this;
    ve->dim = (int)(basetype->size(loc) / elementType()->size(loc));
    return ve;
}

Expression *TypeVector::defaultInitLiteral(Loc loc)
{
    //printf("TypeVector::defaultInitLiteral()\n");
    assert(basetype->ty == Tsarray);
    Expression *e = basetype->defaultInitLiteral(loc);
    VectorExp *ve = new VectorExp(loc, e, this);
    ve->type = this;
    ve->dim = (int)(basetype->size(loc) / elementType()->size(loc));
    return ve;
}

bool TypeVector::isZeroInit(Loc loc)
{
    return basetype->isZeroInit(loc);
}

bool TypeVector::isintegral()
{
    //printf("TypeVector::isintegral('%s') x%x\n", toChars(), flags);
    return basetype->nextOf()->isintegral();
}

bool TypeVector::isfloating()
{
    return basetype->nextOf()->isfloating();
}

bool TypeVector::isunsigned()
{
    return basetype->nextOf()->isunsigned();
}

bool TypeVector::isscalar()
{
    return basetype->nextOf()->isscalar();
}

MATCH TypeVector::implicitConvTo(Type *to)
{
    //printf("TypeVector::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
    if (this == to)
        return MATCHexact;
#ifdef IN_GCC
    if (to->ty == Tvector)
    {
        TypeVector *tv = (TypeVector *)to;
        assert(basetype->ty == Tsarray && tv->basetype->ty == Tsarray);

        // Can't convert to a vector which has different size.
        if (basetype->size() != tv->basetype->size())
            return MATCHnomatch;

        // Allow conversion to void[]
        if (tv->basetype->nextOf()->ty == Tvoid)
            return MATCHconvert;

        // Otherwise implicitly convertible only if basetypes are.
        return basetype->implicitConvTo(tv->basetype);
    }
#else
    if (ty == to->ty)
        return MATCHconvert;
#endif
    return MATCHnomatch;
}

/***************************** TypeArray *****************************/

TypeArray::TypeArray(TY ty, Type *next)
    : TypeNext(ty, next)
{
}

Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    e = Type::dotExp(sc, e, ident, flag);

    if (!(flag & 1) || e)
        e = ::semantic(e, sc);
    return e;
}


/***************************** TypeSArray *****************************/

TypeSArray::TypeSArray(Type *t, Expression *dim)
    : TypeArray(Tsarray, t)
{
    //printf("TypeSArray(%s)\n", dim->toChars());
    this->dim = dim;
}

const char *TypeSArray::kind()
{
    return "sarray";
}

Type *TypeSArray::syntaxCopy()
{
    Type *t = next->syntaxCopy();
    Expression *e = dim->syntaxCopy();
    t = new TypeSArray(t, e);
    t->mod = mod;
    return t;
}

d_uns64 TypeSArray::size(Loc loc)
{
    //printf("TypeSArray::size()\n");
    dinteger_t sz;
    if (!dim)
        return Type::size(loc);
    sz = dim->toInteger();

    {
        bool overflow = false;

        sz = mulu(next->size(), sz, overflow);
        if (overflow)
            goto Loverflow;
    }
    if (sz > UINT32_MAX)
        goto Loverflow;
    return sz;

Loverflow:
    error(loc, "static array %s size overflowed to %lld", toChars(), (long long)sz);
    return SIZE_INVALID;
}

unsigned TypeSArray::alignsize()
{
    return next->alignsize();
}

/**************************
 * This evaluates exp while setting length to be the number
 * of elements in the tuple t.
 */
Expression *semanticLength(Scope *sc, Type *t, Expression *exp)
{
    if (t->ty == Ttuple)
    {
        ScopeDsymbol *sym = new ArrayScopeSymbol(sc, (TypeTuple *)t);
        sym->parent = sc->scopesym;
        sc = sc->push(sym);

        sc = sc->startCTFE();
        exp = ::semantic(exp, sc);
        sc = sc->endCTFE();

        sc->pop();
    }
    else
    {
        sc = sc->startCTFE();
        exp = ::semantic(exp, sc);
        sc = sc->endCTFE();
    }

    return exp;
}

Expression *semanticLength(Scope *sc, TupleDeclaration *s, Expression *exp)
{
    ScopeDsymbol *sym = new ArrayScopeSymbol(sc, s);
    sym->parent = sc->scopesym;
    sc = sc->push(sym);

    sc = sc->startCTFE();
    exp = ::semantic(exp, sc);
    sc = sc->endCTFE();

    sc->pop();
    return exp;
}

void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
{
    //printf("TypeSArray::resolve() %s\n", toChars());
    next->resolve(loc, sc, pe, pt, ps, intypeid);
    //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
    if (*pe)
    {
        // It's really an index expression
        if (Dsymbol *s = getDsymbol(*pe))
            *pe = new DsymbolExp(loc, s);
        *pe = new ArrayExp(loc, *pe, dim);
    }
    else if (*ps)
    {
        Dsymbol *s = *ps;
        TupleDeclaration *td = s->isTupleDeclaration();
        if (td)
        {
            ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td);
            sym->parent = sc->scopesym;
            sc = sc->push(sym);
            sc = sc->startCTFE();
            dim = ::semantic(dim, sc);
            sc = sc->endCTFE();
            sc = sc->pop();

            dim = dim->ctfeInterpret();
            uinteger_t d = dim->toUInteger();

            if (d >= td->objects->dim)
            {
                error(loc, "tuple index %llu exceeds length %u", d, td->objects->dim);
                *ps = NULL;
                *pt = Type::terror;
                return;
            }
            RootObject *o = (*td->objects)[(size_t)d];
            if (o->dyncast() == DYNCAST_DSYMBOL)
            {
                *ps = (Dsymbol *)o;
                return;
            }
            if (o->dyncast() == DYNCAST_EXPRESSION)
            {
                Expression *e = (Expression *)o;
                if (e->op == TOKdsymbol)
                {
                    *ps = ((DsymbolExp *)e)->s;
                    *pe = NULL;
                }
                else
                {
                    *ps = NULL;
                    *pe = e;
                }
                return;
            }
            if (o->dyncast() == DYNCAST_TYPE)
            {
                *ps = NULL;
                *pt = ((Type *)o)->addMod(this->mod);
                return;
            }

            /* Create a new TupleDeclaration which
             * is a slice [d..d+1] out of the old one.
             * Do it this way because TemplateInstance::semanticTiargs()
             * can handle unresolved Objects this way.
             */
            Objects *objects = new Objects;
            objects->setDim(1);
            (*objects)[0] = o;

            TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects);
            *ps = tds;
        }
        else
            goto Ldefault;
    }
    else
    {
        if ((*pt)->ty != Terror)
            next = *pt;     // prevent re-running semantic() on 'next'
     Ldefault:
        Type::resolve(loc, sc, pe, pt, ps, intypeid);
    }
}

Type *TypeSArray::semantic(Loc loc, Scope *sc)
{
    //printf("TypeSArray::semantic() %s\n", toChars());

    Type *t;
    Expression *e;
    Dsymbol *s;
    next->resolve(loc, sc, &e, &t, &s);
    if (dim && s && s->isTupleDeclaration())
    {   TupleDeclaration *sd = s->isTupleDeclaration();

        dim = semanticLength(sc, sd, dim);
        dim = dim->ctfeInterpret();
        uinteger_t d = dim->toUInteger();

        if (d >= sd->objects->dim)
        {   error(loc, "tuple index %llu exceeds %u", d, sd->objects->dim);
            return Type::terror;
        }
        RootObject *o = (*sd->objects)[(size_t)d];
        if (o->dyncast() != DYNCAST_TYPE)
        {   error(loc, "%s is not a type", toChars());
            return Type::terror;
        }
        t = ((Type *)o)->addMod(this->mod);
        return t;
    }

    Type *tn = next->semantic(loc, sc);
    if (tn->ty == Terror)
        return terror;

    Type *tbn = tn->toBasetype();

    if (dim)
    {
        unsigned int errors = global.errors;
        dim = semanticLength(sc, tbn, dim);
        if (errors != global.errors)
            goto Lerror;

        dim = dim->optimize(WANTvalue);
        dim = dim->ctfeInterpret();
        if (dim->op == TOKerror)
            goto Lerror;
        errors = global.errors;
        dinteger_t d1 = dim->toInteger();
        if (errors != global.errors)
            goto Lerror;

        dim = dim->implicitCastTo(sc, tsize_t);
        dim = dim->optimize(WANTvalue);
        if (dim->op == TOKerror)
            goto Lerror;
        errors = global.errors;
        dinteger_t d2 = dim->toInteger();
        if (errors != global.errors)
            goto Lerror;

        if (dim->op == TOKerror)
            goto Lerror;

        if (d1 != d2)
        {
        Loverflow:
            error(loc, "%s size %llu * %llu exceeds 0x%llx size limit for static array",
                toChars(), (unsigned long long)tbn->size(loc), (unsigned long long)d1, Target::maxStaticDataSize);
            goto Lerror;
        }

        Type *tbx = tbn->baseElemOf();
        if ((tbx->ty == Tstruct && !((TypeStruct *)tbx)->sym->members) ||
            (tbx->ty == Tenum && !((TypeEnum *)tbx)->sym->members))
        {
            /* To avoid meaningless error message, skip the total size limit check
             * when the bottom of element type is opaque.
             */
        }
        else if (tbn->isintegral() ||
                 tbn->isfloating() ||
                 tbn->ty == Tpointer ||
                 tbn->ty == Tarray ||
                 tbn->ty == Tsarray ||
                 tbn->ty == Taarray ||
                 (tbn->ty == Tstruct && (((TypeStruct *)tbn)->sym->sizeok == SIZEOKdone)) ||
                 tbn->ty == Tclass)
        {
            /* Only do this for types that don't need to have semantic()
             * run on them for the size, since they may be forward referenced.
             */
            bool overflow = false;
            if (mulu(tbn->size(loc), d2, overflow) >= Target::maxStaticDataSize || overflow)
                goto Loverflow;
        }
    }
    switch (tbn->ty)
    {
        case Ttuple:
        {   // Index the tuple to get the type
            assert(dim);
            TypeTuple *tt = (TypeTuple *)tbn;
            uinteger_t d = dim->toUInteger();

            if (d >= tt->arguments->dim)
            {   error(loc, "tuple index %llu exceeds %u", d, tt->arguments->dim);
                goto Lerror;
            }
            Type *telem = (*tt->arguments)[(size_t)d]->type;
            return telem->addMod(this->mod);
        }
        case Tfunction:
        case Tnone:
            error(loc, "can't have array of %s", tbn->toChars());
            goto Lerror;
        default:
            break;
    }
    if (tbn->isscope())
    {   error(loc, "cannot have array of scope %s", tbn->toChars());
        goto Lerror;
    }

    /* Ensure things like const(immutable(T)[3]) become immutable(T[3])
     * and const(T)[3] become const(T[3])
     */
    next = tn;
    transitive();
    t = addMod(tn->mod);

    return t->merge();

Lerror:
    return Type::terror;
}

Expression *TypeSArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    if (ident == Id::length)
    {
        Loc oldLoc = e->loc;
        e = dim->copy();
        e->loc = oldLoc;
    }
    else if (ident == Id::ptr)
    {
        if (e->op == TOKtype)
        {
            e->error("%s is not an expression", e->toChars());
            return new ErrorExp();
        }
        else if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
        {
            e->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e->toChars(), e->toChars());
            // return new ErrorExp();
        }
        e = e->castTo(sc, e->type->nextOf()->pointerTo());
    }
    else
    {
        e = TypeArray::dotExp(sc, e, ident, flag);
    }
    if (!(flag & 1) || e)
        e = ::semantic(e, sc);
    return e;
}

structalign_t TypeSArray::alignment()
{
    return next->alignment();
}

bool TypeSArray::isString()
{
    TY nty = next->toBasetype()->ty;
    return nty == Tchar || nty == Twchar || nty == Tdchar;
}

MATCH TypeSArray::constConv(Type *to)
{
    if (to->ty == Tsarray)
    {
        TypeSArray *tsa = (TypeSArray *)to;
        if (!dim->equals(tsa->dim))
            return MATCHnomatch;
    }
    return TypeNext::constConv(to);
}

MATCH TypeSArray::implicitConvTo(Type *to)
{
    //printf("TypeSArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());

    if (to->ty == Tarray)
    {
        TypeDArray *ta = (TypeDArray *)to;

        if (!MODimplicitConv(next->mod, ta->next->mod))
            return MATCHnomatch;

        /* Allow conversion to void[]
         */
        if (ta->next->ty == Tvoid)
        {
            return MATCHconvert;
        }

        MATCH m = next->constConv(ta->next);
        if (m > MATCHnomatch)
        {
            return MATCHconvert;
        }
        return MATCHnomatch;
    }

    if (to->ty == Tsarray)
    {
        if (this == to)
            return MATCHexact;

        TypeSArray *tsa = (TypeSArray *)to;

        if (dim->equals(tsa->dim))
        {
            /* Since static arrays are value types, allow
             * conversions from const elements to non-const
             * ones, just like we allow conversion from const int
             * to int.
             */
            MATCH m = next->implicitConvTo(tsa->next);
            if (m >= MATCHconst)
            {
                if (mod != to->mod)
                    m = MATCHconst;
                return m;
            }
        }
    }
    return MATCHnomatch;
}

Expression *TypeSArray::defaultInit(Loc loc)
{
    if (next->ty == Tvoid)
        return tuns8->defaultInit(loc);
    else
        return next->defaultInit(loc);
}

bool TypeSArray::isZeroInit(Loc loc)
{
    return next->isZeroInit(loc);
}

bool TypeSArray::needsDestruction()
{
    return next->needsDestruction();
}

/*********************************
 *
 */

bool TypeSArray::needsNested()
{
    return next->needsNested();
}

Expression *TypeSArray::defaultInitLiteral(Loc loc)
{
    size_t d = (size_t)dim->toInteger();
    Expression *elementinit;
    if (next->ty == Tvoid)
        elementinit = tuns8->defaultInitLiteral(loc);
    else
        elementinit = next->defaultInitLiteral(loc);
    Expressions *elements = new Expressions();
    elements->setDim(d);
    for (size_t i = 0; i < d; i++)
        (*elements)[i] = NULL;
    ArrayLiteralExp *ae = new ArrayLiteralExp(Loc(), this, elementinit, elements);
    return ae;
}

bool TypeSArray::hasPointers()
{
    /* Don't want to do this, because:
     *    struct S { T* array[0]; }
     * may be a variable length struct.
     */
    //if (dim->toInteger() == 0)
    //    return false;

    if (next->ty == Tvoid)
    {
        // Arrays of void contain arbitrary data, which may include pointers
        return true;
    }
    else
        return next->hasPointers();
}

/***************************** TypeDArray *****************************/

TypeDArray::TypeDArray(Type *t)
    : TypeArray(Tarray, t)
{
    //printf("TypeDArray(t = %p)\n", t);
}

const char *TypeDArray::kind()
{
    return "darray";
}

Type *TypeDArray::syntaxCopy()
{
    Type *t = next->syntaxCopy();
    if (t == next)
        t = this;
    else
    {
        t = new TypeDArray(t);
        t->mod = mod;
    }
    return t;
}

d_uns64 TypeDArray::size(Loc)
{
    //printf("TypeDArray::size()\n");
    return Target::ptrsize * 2;
}

unsigned TypeDArray::alignsize()
{
    // A DArray consists of two ptr-sized values, so align it on pointer size
    // boundary
    return Target::ptrsize;
}

Type *TypeDArray::semantic(Loc loc, Scope *sc)
{
    Type *tn = next->semantic(loc,sc);
    Type *tbn = tn->toBasetype();
    switch (tbn->ty)
    {
        case Ttuple:
            return tbn;
        case Tfunction:
        case Tnone:
            error(loc, "can't have array of %s", tbn->toChars());
            return Type::terror;
        case Terror:
            return Type::terror;
        default:
            break;
    }
    if (tn->isscope())
    {   error(loc, "cannot have array of scope %s", tn->toChars());
        return Type::terror;
    }
    next = tn;
    transitive();
    return merge();
}

void TypeDArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
{
    //printf("TypeDArray::resolve() %s\n", toChars());
    next->resolve(loc, sc, pe, pt, ps, intypeid);
    //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
    if (*pe)
    {
        // It's really a slice expression
        if (Dsymbol *s = getDsymbol(*pe))
            *pe = new DsymbolExp(loc, s);
        *pe = new ArrayExp(loc, *pe);
    }
    else if (*ps)
    {
        TupleDeclaration *td = (*ps)->isTupleDeclaration();
        if (td)
            ;   // keep *ps
        else
            goto Ldefault;
    }
    else
    {
        if ((*pt)->ty != Terror)
            next = *pt;     // prevent re-running semantic() on 'next'
     Ldefault:
        Type::resolve(loc, sc, pe, pt, ps, intypeid);
    }
}

Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    if (e->op == TOKtype &&
        (ident == Id::length || ident == Id::ptr))
    {
        e->error("%s is not an expression", e->toChars());
        return new ErrorExp();
    }
    if (ident == Id::length)
    {
        if (e->op == TOKstring)
        {
            StringExp *se = (StringExp *)e;
            return new IntegerExp(se->loc, se->len, Type::tsize_t);
        }
        if (e->op == TOKnull)
            return new IntegerExp(e->loc, 0, Type::tsize_t);
        e = new ArrayLengthExp(e->loc, e);
        e->type = Type::tsize_t;
        return e;
    }
    else if (ident == Id::ptr)
    {
        if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
        {
            e->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e->toChars(), e->toChars());
            // return new ErrorExp();
        }
        e = e->castTo(sc, next->pointerTo());
        return e;
    }
    else
    {
        e = TypeArray::dotExp(sc, e, ident, flag);
    }
    return e;
}

bool TypeDArray::isString()
{
    TY nty = next->toBasetype()->ty;
    return nty == Tchar || nty == Twchar || nty == Tdchar;
}

MATCH TypeDArray::implicitConvTo(Type *to)
{
    //printf("TypeDArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
    if (equals(to))
        return MATCHexact;

    if (to->ty == Tarray)
    {
        TypeDArray *ta = (TypeDArray *)to;

        if (!MODimplicitConv(next->mod, ta->next->mod))
            return MATCHnomatch;        // not const-compatible

        /* Allow conversion to void[]
         */
        if (next->ty != Tvoid && ta->next->ty == Tvoid)
        {
            return MATCHconvert;
        }

        MATCH m = next->constConv(ta->next);
        if (m > MATCHnomatch)
        {
            if (m == MATCHexact && mod != to->mod)
                m = MATCHconst;
            return m;
        }
    }
    return Type::implicitConvTo(to);
}

Expression *TypeDArray::defaultInit(Loc loc)
{
    return new NullExp(loc, this);
}

bool TypeDArray::isZeroInit(Loc)
{
    return true;
}

bool TypeDArray::isBoolean()
{
    return true;
}

bool TypeDArray::hasPointers()
{
    return true;
}


/***************************** TypeAArray *****************************/

TypeAArray::TypeAArray(Type *t, Type *index)
    : TypeArray(Taarray, t)
{
    this->index = index;
    this->loc = Loc();
    this->sc = NULL;
}

TypeAArray *TypeAArray::create(Type *t, Type *index)
{
    return new TypeAArray(t, index);
}

const char *TypeAArray::kind()
{
    return "aarray";
}

Type *TypeAArray::syntaxCopy()
{
    Type *t = next->syntaxCopy();
    Type *ti = index->syntaxCopy();
    if (t == next && ti == index)
        t = this;
    else
    {
        t = new TypeAArray(t, ti);
        t->mod = mod;
    }
    return t;
}

d_uns64 TypeAArray::size(Loc)
{
    return Target::ptrsize;
}

Type *TypeAArray::semantic(Loc loc, Scope *sc)
{
    //printf("TypeAArray::semantic() %s index->ty = %d\n", toChars(), index->ty);
    if (deco)
        return this;

    this->loc = loc;
    this->sc = sc;
    if (sc)
        sc->setNoFree();

    // Deal with the case where we thought the index was a type, but
    // in reality it was an expression.
    if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray ||
        index->ty == Ttypeof || index->ty == Treturn)
    {
        Expression *e;
        Type *t;
        Dsymbol *s;

        index->resolve(loc, sc, &e, &t, &s);
        if (e)
        {
            // It was an expression -
            // Rewrite as a static array
            TypeSArray *tsa = new TypeSArray(next, e);
            return tsa->semantic(loc, sc);
        }
        else if (t)
            index = t->semantic(loc, sc);
        else
        {
            index->error(loc, "index is not a type or an expression");
            return Type::terror;
        }
    }
    else
        index = index->semantic(loc,sc);
    index = index->merge2();

    if (index->nextOf() && !index->nextOf()->isImmutable())
    {
        index = index->constOf()->mutableOf();
    }

    switch (index->toBasetype()->ty)
    {
        case Tfunction:
        case Tvoid:
        case Tnone:
        case Ttuple:
            error(loc, "can't have associative array key of %s", index->toBasetype()->toChars());
            /* fall through */
        case Terror:
            return Type::terror;
        default:
            break;
    }
    Type *tbase = index->baseElemOf();
    while (tbase->ty == Tarray)
        tbase = tbase->nextOf()->baseElemOf();
    if (tbase->ty == Tstruct)
    {
        /* AA's need typeid(index).equals() and getHash(). Issue error if not correctly set up.
         */
        StructDeclaration *sd = ((TypeStruct *)tbase)->sym;
        if (sd->_scope)
            sd->semantic(NULL);

        // duplicate a part of StructDeclaration::semanticTypeInfoMembers
        //printf("AA = %s, key: xeq = %p, xerreq = %p xhash = %p\n", toChars(), sd->xeq, sd->xerreq, sd->xhash);
        if (sd->xeq &&
            sd->xeq->_scope &&
            sd->xeq->semanticRun < PASSsemantic3done)
        {
            unsigned errors = global.startGagging();
            sd->xeq->semantic3(sd->xeq->_scope);
            if (global.endGagging(errors))
                sd->xeq = sd->xerreq;
        }

        const char *s = (index->toBasetype()->ty != Tstruct) ? "bottom of " : "";
        if (!sd->xeq)
        {
            // If sd->xhash != NULL:
            //   sd or its fields have user-defined toHash.
            //   AA assumes that its result is consistent with bitwise equality.
            // else:
            //   bitwise equality & hashing
        }
        else if (sd->xeq == sd->xerreq)
        {
            if (search_function(sd, Id::eq))
            {
                error(loc, "%sAA key type %s does not have 'bool opEquals(ref const %s) const'",
                        s, sd->toChars(), sd->toChars());
            }
            else
            {
                error(loc, "%sAA key type %s does not support const equality",
                        s, sd->toChars());
            }
            return Type::terror;
        }
        else if (!sd->xhash)
        {
            if (search_function(sd, Id::eq))
            {
                error(loc, "%sAA key type %s should have 'size_t toHash() const nothrow @safe' if opEquals defined",
                        s, sd->toChars());
            }
            else
            {
                error(loc, "%sAA key type %s supports const equality but doesn't support const hashing",
                        s, sd->toChars());
            }
            return Type::terror;
        }
        else
        {
            // defined equality & hashing
            assert(sd->xeq && sd->xhash);

            /* xeq and xhash may be implicitly defined by compiler. For example:
             *   struct S { int[] arr; }
             * With 'arr' field equality and hashing, compiler will implicitly
             * generate functions for xopEquals and xtoHash in TypeInfo_Struct.
             */
        }
    }
    else if (tbase->ty == Tclass && !((TypeClass *)tbase)->sym->isInterfaceDeclaration())
    {
        ClassDeclaration *cd = ((TypeClass *)tbase)->sym;
        if (cd->_scope)
            cd->semantic(NULL);

        if (!ClassDeclaration::object)
        {
            error(Loc(), "missing or corrupt object.d");
            fatal();
        }

        static FuncDeclaration *feq   = NULL;
        static FuncDeclaration *fcmp  = NULL;
        static FuncDeclaration *fhash = NULL;
        if (!feq)   feq   = search_function(ClassDeclaration::object, Id::eq)->isFuncDeclaration();
        if (!fcmp)  fcmp  = search_function(ClassDeclaration::object, Id::cmp)->isFuncDeclaration();
        if (!fhash) fhash = search_function(ClassDeclaration::object, Id::tohash)->isFuncDeclaration();
        assert(fcmp && feq && fhash);

        if (feq->vtblIndex < (int)cd->vtbl.dim && cd->vtbl[feq ->vtblIndex] == feq)
        {
            if (fcmp->vtblIndex < (int)cd->vtbl.dim && cd->vtbl[fcmp->vtblIndex] != fcmp)
            {
                const char *s = (index->toBasetype()->ty != Tclass) ? "bottom of " : "";
                error(loc, "%sAA key type %s now requires equality rather than comparison",
                    s, cd->toChars());
                errorSupplemental(loc, "Please override Object.opEquals and toHash.");
            }
        }
    }
    next = next->semantic(loc,sc)->merge2();
    transitive();

    switch (next->toBasetype()->ty)
    {
        case Tfunction:
        case Tvoid:
        case Tnone:
        case Ttuple:
            error(loc, "can't have associative array of %s", next->toChars());
            /* fall through */
        case Terror:
            return Type::terror;
    }
    if (next->isscope())
    {   error(loc, "cannot have array of scope %s", next->toChars());
        return Type::terror;
    }
    return merge();
}

void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
{
    //printf("TypeAArray::resolve() %s\n", toChars());

    // Deal with the case where we thought the index was a type, but
    // in reality it was an expression.
    if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray)
    {
        Expression *e;
        Type *t;
        Dsymbol *s;

        index->resolve(loc, sc, &e, &t, &s, intypeid);
        if (e)
        {
            // It was an expression -
            // Rewrite as a static array
            TypeSArray *tsa = new TypeSArray(next, e);
            tsa->mod = this->mod;   // just copy mod field so tsa's semantic is not yet done
            return tsa->resolve(loc, sc, pe, pt, ps, intypeid);
        }
        else if (t)
            index = t;
        else
            index->error(loc, "index is not a type or an expression");
    }
    Type::resolve(loc, sc, pe, pt, ps, intypeid);
}


Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    if (ident == Id::length)
    {
        static FuncDeclaration *fd_aaLen = NULL;
        if (fd_aaLen == NULL)
        {
            Parameters *fparams = new Parameters();
            fparams->push(new Parameter(STCin, this, NULL, NULL));
            fd_aaLen = FuncDeclaration::genCfunc(fparams, Type::tsize_t, Id::aaLen);
            TypeFunction *tf = fd_aaLen->type->toTypeFunction();
            tf->purity = PUREconst;
            tf->isnothrow = true;
            tf->isnogc = false;
        }
        Expression *ev = new VarExp(e->loc, fd_aaLen, false);
        e = new CallExp(e->loc, ev, e);
        e->type = fd_aaLen->type->toTypeFunction()->next;
    }
    else
        e = Type::dotExp(sc, e, ident, flag);
    return e;
}

Expression *TypeAArray::defaultInit(Loc loc)
{
    return new NullExp(loc, this);
}

bool TypeAArray::isZeroInit(Loc)
{
    return true;
}

bool TypeAArray::isBoolean()
{
    return true;
}

bool TypeAArray::hasPointers()
{
    return true;
}

MATCH TypeAArray::implicitConvTo(Type *to)
{
    //printf("TypeAArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
    if (equals(to))
        return MATCHexact;

    if (to->ty == Taarray)
    {   TypeAArray *ta = (TypeAArray *)to;

        if (!MODimplicitConv(next->mod, ta->next->mod))
            return MATCHnomatch;        // not const-compatible

        if (!MODimplicitConv(index->mod, ta->index->mod))
            return MATCHnomatch;        // not const-compatible

        MATCH m = next->constConv(ta->next);
        MATCH mi = index->constConv(ta->index);
        if (m > MATCHnomatch && mi > MATCHnomatch)
        {
            return MODimplicitConv(mod, to->mod) ? MATCHconst : MATCHnomatch;
        }
    }
    return Type::implicitConvTo(to);
}

MATCH TypeAArray::constConv(Type *to)
{
    if (to->ty == Taarray)
    {
        TypeAArray *taa = (TypeAArray *)to;
        MATCH mindex = index->constConv(taa->index);
        MATCH mkey = next->constConv(taa->next);
        // Pick the worst match
        return mkey < mindex ? mkey : mindex;
    }
    return Type::constConv(to);
}

/***************************** TypePointer *****************************/

TypePointer::TypePointer(Type *t)
    : TypeNext(Tpointer, t)
{
}

TypePointer *TypePointer::create(Type *t)
{
    return new TypePointer(t);
}

const char *TypePointer::kind()
{
    return "pointer";
}

Type *TypePointer::syntaxCopy()
{
    Type *t = next->syntaxCopy();
    if (t == next)
        t = this;
    else
    {
        t = new TypePointer(t);
        t->mod = mod;
    }
    return t;
}

Type *TypePointer::semantic(Loc loc, Scope *sc)
{
    //printf("TypePointer::semantic() %s\n", toChars());
    if (deco)
        return this;
    Type *n = next->semantic(loc, sc);
    switch (n->toBasetype()->ty)
    {
        case Ttuple:
            error(loc, "can't have pointer to %s", n->toChars());
            /* fall through */
        case Terror:
            return Type::terror;
        default:
            break;
    }
    if (n != next)
    {
        deco = NULL;
    }
    next = n;
    if (next->ty != Tfunction)
    {   transitive();
        return merge();
    }
    deco = merge()->deco;
    /* Don't return merge(), because arg identifiers and default args
     * can be different
     * even though the types match
     */
    return this;
}


d_uns64 TypePointer::size(Loc)
{
    return Target::ptrsize;
}

MATCH TypePointer::implicitConvTo(Type *to)
{
    //printf("TypePointer::implicitConvTo(to = %s) %s\n", to->toChars(), toChars());

    if (equals(to))
        return MATCHexact;
    if (next->ty == Tfunction)
    {
        if (to->ty == Tpointer)
        {
            TypePointer *tp = (TypePointer *)to;
            if (tp->next->ty == Tfunction)
            {
                if (next->equals(tp->next))
                    return MATCHconst;

                if (next->covariant(tp->next) == 1)
                {
                    Type *tret = this->next->nextOf();
                    Type *toret = tp->next->nextOf();
                    if (tret->ty == Tclass && toret->ty == Tclass)
                    {
                        /* Bugzilla 10219: Check covariant interface return with offset tweaking.
                         * interface I {}
                         * class C : Object, I {}
                         * I function() dg = function C() {}    // should be error
                         */
                        int offset = 0;
                        if (toret->isBaseOf(tret, &offset) && offset != 0)
                            return MATCHnomatch;
                    }
                    return MATCHconvert;
                }
            }
            else if (tp->next->ty == Tvoid)
            {
                // Allow conversions to void*
                return MATCHconvert;
            }
        }
        return MATCHnomatch;
    }
    else if (to->ty == Tpointer)
    {
        TypePointer *tp = (TypePointer *)to;
        assert(tp->next);

        if (!MODimplicitConv(next->mod, tp->next->mod))
            return MATCHnomatch;        // not const-compatible

        /* Alloc conversion to void*
         */
        if (next->ty != Tvoid && tp->next->ty == Tvoid)
        {
            return MATCHconvert;
        }

        MATCH m = next->constConv(tp->next);
        if (m > MATCHnomatch)
        {
            if (m == MATCHexact && mod != to->mod)
                m = MATCHconst;
            return m;
        }
    }
    return MATCHnomatch;
}

MATCH TypePointer::constConv(Type *to)
{
    if (next->ty == Tfunction)
    {
        if (to->nextOf() && next->equals(((TypeNext *)to)->next))
            return Type::constConv(to);
        else
            return MATCHnomatch;
    }
    return TypeNext::constConv(to);
}

bool TypePointer::isscalar()
{
    return true;
}

Expression *TypePointer::defaultInit(Loc loc)
{
    return new NullExp(loc, this);
}

bool TypePointer::isZeroInit(Loc)
{
    return true;
}

bool TypePointer::hasPointers()
{
    return true;
}


/***************************** TypeReference *****************************/

TypeReference::TypeReference(Type *t)
    : TypeNext(Treference, t)
{
    // BUG: what about references to static arrays?
}

const char *TypeReference::kind()
{
    return "reference";
}

Type *TypeReference::syntaxCopy()
{
    Type *t = next->syntaxCopy();
    if (t == next)
        t = this;
    else
    {
        t = new TypeReference(t);
        t->mod = mod;
    }
    return t;
}

Type *TypeReference::semantic(Loc loc, Scope *sc)
{
    //printf("TypeReference::semantic()\n");
    Type *n = next->semantic(loc, sc);
    if (n != next)
        deco = NULL;
    next = n;
    transitive();
    return merge();
}


d_uns64 TypeReference::size(Loc)
{
    return Target::ptrsize;
}

Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    // References just forward things along
    return next->dotExp(sc, e, ident, flag);
}

Expression *TypeReference::defaultInit(Loc loc)
{
    return new NullExp(loc, this);
}

bool TypeReference::isZeroInit(Loc)
{
    return true;
}


/***************************** TypeFunction *****************************/

TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc)
    : TypeNext(Tfunction, treturn)
{
//if (!treturn) *(char*)0=0;
//    assert(treturn);
    assert(0 <= varargs && varargs <= 2);
    this->parameters = parameters;
    this->varargs = varargs;
    this->linkage = linkage;
    this->inuse = 0;
    this->isnothrow = false;
    this->isnogc = false;
    this->purity = PUREimpure;
    this->isproperty = false;
    this->isref = false;
    this->isreturn = false;
    this->isscope = false;
    this->isscopeinferred = false;
    this->iswild = 0;
    this->fargs = NULL;

    if (stc & STCpure)
        this->purity = PUREfwdref;
    if (stc & STCnothrow)
        this->isnothrow = true;
    if (stc & STCnogc)
        this->isnogc = true;
    if (stc & STCproperty)
        this->isproperty = true;

    if (stc & STCref)
        this->isref = true;
    if (stc & STCreturn)
        this->isreturn = true;
    if (stc & STCscope)
        this->isscope = true;
    if (stc & STCscopeinferred)
        this->isscopeinferred = true;

    this->trust = TRUSTdefault;
    if (stc & STCsafe)
        this->trust = TRUSTsafe;
    if (stc & STCsystem)
        this->trust = TRUSTsystem;
    if (stc & STCtrusted)
        this->trust = TRUSTtrusted;
}

TypeFunction *TypeFunction::create(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc)
{
    return new TypeFunction(parameters, treturn, varargs, linkage, stc);
}

const char *TypeFunction::kind()
{
    return "function";
}

Type *TypeFunction::syntaxCopy()
{
    Type *treturn = next ? next->syntaxCopy() : NULL;
    Parameters *params = Parameter::arraySyntaxCopy(parameters);
    TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage);
    t->mod = mod;
    t->isnothrow = isnothrow;
    t->isnogc = isnogc;
    t->purity = purity;
    t->isproperty = isproperty;
    t->isref = isref;
    t->isreturn = isreturn;
    t->isscope = isscope;
    t->isscopeinferred = isscopeinferred;
    t->iswild = iswild;
    t->trust = trust;
    t->fargs = fargs;
    return t;
}

/*******************************
 * Covariant means that 'this' can substitute for 't',
 * i.e. a pure function is a match for an impure type.
 * Params:
 *      t = type 'this' is covariant with
 *      pstc = if not null, store STCxxxx which would make it covariant
 *      fix17349 = enable fix https://issues.dlang.org/show_bug.cgi?id=17349
 * Returns:
 *      0       types are distinct
 *      1       this is covariant with t
 *      2       arguments match as far as overloading goes,
 *              but types are not covariant
 *      3       cannot determine covariance because of forward references
 *      *pstc   STCxxxx which would make it covariant
 */

int Type::covariant(Type *t, StorageClass *pstc, bool fix17349)
{
    if (pstc)
        *pstc = 0;
    StorageClass stc = 0;

    bool notcovariant = false;

    TypeFunction *t1;
    TypeFunction *t2;

    if (equals(t))
        return 1;                       // covariant

    if (ty != Tfunction || t->ty != Tfunction)
        goto Ldistinct;

    t1 = (TypeFunction *)this;
    t2 = (TypeFunction *)t;

    if (t1->varargs != t2->varargs)
        goto Ldistinct;

    if (t1->parameters && t2->parameters)
    {
        size_t dim = Parameter::dim(t1->parameters);
        if (dim != Parameter::dim(t2->parameters))
            goto Ldistinct;

        for (size_t i = 0; i < dim; i++)
        {
            Parameter *fparam1 = Parameter::getNth(t1->parameters, i);
            Parameter *fparam2 = Parameter::getNth(t2->parameters, i);

            if (!fparam1->type->equals(fparam2->type))
            {
                if (!fix17349)
                    goto Ldistinct;
                Type *tp1 = fparam1->type;
                Type *tp2 = fparam2->type;
                if (tp1->ty == tp2->ty)
                {
                    if (tp1->ty == Tclass)
                    {
                        if (((TypeClass *)tp1)->sym == ((TypeClass *)tp2)->sym && MODimplicitConv(tp2->mod, tp1->mod))
                            goto Lcov;
                    }
                    else if (tp1->ty == Tstruct)
                    {
                        if (((TypeStruct *)tp1)->sym == ((TypeStruct *)tp2)->sym && MODimplicitConv(tp2->mod, tp1->mod))
                            goto Lcov;
                    }
                    else if (tp1->ty == Tpointer)
                    {
                        if (tp2->implicitConvTo(tp1))
                            goto Lcov;
                    }
                    else if (tp1->ty == Tarray)
                    {
                        if (tp2->implicitConvTo(tp1))
                            goto Lcov;
                    }
                    else if (tp1->ty == Tdelegate)
                    {
                        if (tp1->implicitConvTo(tp2))
                            goto Lcov;
                    }
                }
                goto Ldistinct;
            }
        Lcov:
            notcovariant |= !fparam1->isCovariant(t1->isref, fparam2);
        }
    }
    else if (t1->parameters != t2->parameters)
    {
        size_t dim1 = !t1->parameters ? 0 : t1->parameters->dim;
        size_t dim2 = !t2->parameters ? 0 : t2->parameters->dim;
        if (dim1 || dim2)
            goto Ldistinct;
    }

    // The argument lists match
    if (notcovariant)
        goto Lnotcovariant;
    if (t1->linkage != t2->linkage)
        goto Lnotcovariant;

  {
    // Return types
    Type *t1n = t1->next;
    Type *t2n = t2->next;

    if (!t1n || !t2n)           // happens with return type inference
        goto Lnotcovariant;

    if (t1n->equals(t2n))
        goto Lcovariant;
    if (t1n->ty == Tclass && t2n->ty == Tclass)
    {
        /* If same class type, but t2n is const, then it's
         * covariant. Do this test first because it can work on
         * forward references.
         */
        if (((TypeClass *)t1n)->sym == ((TypeClass *)t2n)->sym &&
            MODimplicitConv(t1n->mod, t2n->mod))
            goto Lcovariant;

        // If t1n is forward referenced:
        ClassDeclaration *cd = ((TypeClass *)t1n)->sym;
        if (cd->_scope)
            cd->semantic(NULL);
        if (!cd->isBaseInfoComplete())
        {
            return 3;   // forward references
        }
    }
    if (t1n->ty == Tstruct && t2n->ty == Tstruct)
    {
        if (((TypeStruct *)t1n)->sym == ((TypeStruct *)t2n)->sym &&
            MODimplicitConv(t1n->mod, t2n->mod))
            goto Lcovariant;
    }
    else if (t1n->ty == t2n->ty && t1n->implicitConvTo(t2n))
        goto Lcovariant;
    else if (t1n->ty == Tnull)
    {
        // NULL is covariant with any pointer type, but not with any
        // dynamic arrays, associative arrays or delegates.
        // https://issues.dlang.org/show_bug.cgi?id=8589
        // https://issues.dlang.org/show_bug.cgi?id=19618
        Type *t2bn = t2n->toBasetype();
        if (t2bn->ty == Tnull || t2bn->ty == Tpointer || t2bn->ty == Tclass)
            goto Lcovariant;
    }
  }
    goto Lnotcovariant;

Lcovariant:
    if (t1->isref != t2->isref)
        goto Lnotcovariant;

    if (!t1->isref && (t1->isscope || t2->isscope))
    {
        StorageClass stc1 = t1->isscope ? STCscope : 0;
        StorageClass stc2 = t2->isscope ? STCscope : 0;
        if (t1->isreturn)
        {
            stc1 |= STCreturn;
            if (!t1->isscope)
                stc1 |= STCref;
        }
        if (t2->isreturn)
        {
            stc2 |= STCreturn;
            if (!t2->isscope)
                stc2 |= STCref;
        }
        if (!Parameter::isCovariantScope(t1->isref, stc1, stc2))
            goto Lnotcovariant;
    }

    // We can subtract 'return ref' from 'this', but cannot add it
    else if (t1->isreturn && !t2->isreturn)
        goto Lnotcovariant;

    /* Can convert mutable to const
     */
    if (!MODimplicitConv(t2->mod, t1->mod))
    {
        goto Ldistinct;
    }

    /* Can convert pure to impure, nothrow to throw, and nogc to gc
     */
    if (!t1->purity && t2->purity)
        stc |= STCpure;

    if (!t1->isnothrow && t2->isnothrow)
        stc |= STCnothrow;

    if (!t1->isnogc && t2->isnogc)
        stc |= STCnogc;

    /* Can convert safe/trusted to system
     */
    if (t1->trust <= TRUSTsystem && t2->trust >= TRUSTtrusted)
    {
        // Should we infer trusted or safe? Go with safe.
        stc |= STCsafe;
    }

    if (stc)
    {   if (pstc)
            *pstc = stc;
        goto Lnotcovariant;
    }

    //printf("\tcovaraint: 1\n");
    return 1;

Ldistinct:
    //printf("\tcovaraint: 0\n");
    return 0;

Lnotcovariant:
    //printf("\tcovaraint: 2\n");
    return 2;
}

Type *TypeFunction::semantic(Loc loc, Scope *sc)
{
    if (deco)                   // if semantic() already run
    {
        //printf("already done\n");
        return this;
    }
    //printf("TypeFunction::semantic() this = %p\n", this);
    //printf("TypeFunction::semantic() %s, sc->stc = %llx, fargs = %p\n", toChars(), sc->stc, fargs);

    bool errors = false;

    /* Copy in order to not mess up original.
     * This can produce redundant copies if inferring return type,
     * as semantic() will get called again on this.
     */
    TypeFunction *tf = copy()->toTypeFunction();
    if (parameters)
    {
        tf->parameters = parameters->copy();
        for (size_t i = 0; i < parameters->dim; i++)
        {
            void *pp = mem.xmalloc(sizeof(Parameter));
            Parameter *p = (Parameter *)memcpy(pp, (void *)(*parameters)[i], sizeof(Parameter));
            (*tf->parameters)[i] = p;
        }
    }

    if (sc->stc & STCpure)
        tf->purity = PUREfwdref;
    if (sc->stc & STCnothrow)
        tf->isnothrow = true;
    if (sc->stc & STCnogc)
        tf->isnogc = true;
    if (sc->stc & STCref)
        tf->isref = true;
    if (sc->stc & STCreturn)
        tf->isreturn = true;
    if (sc->stc & STCscope)
        tf->isscope = true;
    if (sc->stc & STCscopeinferred)
        tf->isscopeinferred = true;

//    if ((sc->stc & (STCreturn | STCref)) == STCreturn)
//        tf->isscope = true;                                 // return by itself means 'return scope'

    if (tf->trust == TRUSTdefault)
    {
        if (sc->stc & STCsafe)
            tf->trust = TRUSTsafe;
        if (sc->stc & STCsystem)
            tf->trust = TRUSTsystem;
        if (sc->stc & STCtrusted)
            tf->trust = TRUSTtrusted;
    }

    if (sc->stc & STCproperty)
        tf->isproperty = true;

    tf->linkage = sc->linkage;
    bool wildreturn = false;
    if (tf->next)
    {
        sc = sc->push();
        sc->stc &= ~(STC_TYPECTOR | STC_FUNCATTR);
        tf->next = tf->next->semantic(loc, sc);
        sc = sc->pop();
        errors |= tf->checkRetType(loc);
        if (tf->next->isscope() && !(sc->flags & SCOPEctor))
        {
            error(loc, "functions cannot return scope %s", tf->next->toChars());
            errors = true;
        }
        if (tf->next->hasWild())
            wildreturn = true;

        if (tf->isreturn && !tf->isref && !tf->next->hasPointers())
        {
            error(loc, "function type '%s' has 'return' but does not return any indirections", tf->toChars());
        }
    }

    unsigned char wildparams = 0;
    if (tf->parameters)
    {
        /* Create a scope for evaluating the default arguments for the parameters
         */
        Scope *argsc = sc->push();
        argsc->stc = 0;                 // don't inherit storage class
        argsc->protection = Prot(PROTpublic);
        argsc->func = NULL;

        size_t dim = Parameter::dim(tf->parameters);
        for (size_t i = 0; i < dim; i++)
        {
            Parameter *fparam = Parameter::getNth(tf->parameters, i);
            tf->inuse++;
            fparam->type = fparam->type->semantic(loc, argsc);
            if (tf->inuse == 1) tf->inuse--;

            if (fparam->type->ty == Terror)
            {
                errors = true;
                continue;
            }

            fparam->type = fparam->type->addStorageClass(fparam->storageClass);

            if (fparam->storageClass & (STCauto | STCalias | STCstatic))
            {
                if (!fparam->type)
                    continue;
            }

            Type *t = fparam->type->toBasetype();

            if (t->ty == Tfunction)
            {
                error(loc, "cannot have parameter of function type %s", fparam->type->toChars());
                errors = true;
            }
            else if (!(fparam->storageClass & (STCref | STCout)) &&
                     (t->ty == Tstruct || t->ty == Tsarray || t->ty == Tenum))
            {
                Type *tb2 = t->baseElemOf();
                if ((tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members) ||
                    (tb2->ty == Tenum && !((TypeEnum *)tb2)->sym->memtype))
                {
                    error(loc, "cannot have parameter of opaque type %s by value", fparam->type->toChars());
                    errors = true;
                }
            }
            else if (!(fparam->storageClass & STClazy) && t->ty == Tvoid)
            {
                error(loc, "cannot have parameter of type %s", fparam->type->toChars());
                errors = true;
            }

            if ((fparam->storageClass & (STCref | STCwild)) == (STCref | STCwild))
            {
                // 'ref inout' implies 'return'
                fparam->storageClass |= STCreturn;
            }

            if (fparam->storageClass & STCreturn)
            {
                if (fparam->storageClass & (STCref | STCout))
                {
                    // Disabled for the moment awaiting improvement to allow return by ref
                    // to be transformed into return by scope.
                    if (0 && !tf->isref)
                    {
                        StorageClass stc = fparam->storageClass & (STCref | STCout);
                        error(loc, "parameter %s is 'return %s' but function does not return by ref",
                            fparam->ident ? fparam->ident->toChars() : "",
                            stcToChars(stc));
                        errors = true;
                    }
                }
                else
                {
                    fparam->storageClass |= STCscope;        // 'return' implies 'scope'
                    if (tf->isref)
                    {
                    }
                    else if (!tf->isref && tf->next && !tf->next->hasPointers())
                    {
                        error(loc, "parameter %s is 'return' but function does not return any indirections",
                            fparam->ident ? fparam->ident->toChars() : "");
                        errors = true;
                    }
                }
            }

            if (fparam->storageClass & (STCref | STClazy))
            {
            }
            else if (fparam->storageClass & STCout)
            {
                if (unsigned char m = fparam->type->mod & (MODimmutable | MODconst | MODwild))
                {
                    error(loc, "cannot have %s out parameter of type %s", MODtoChars(m), t->toChars());
                    errors = true;
                }
                else
                {
                    Type *tv = t;
                    while (tv->ty == Tsarray)
                        tv = tv->nextOf()->toBasetype();
                    if (tv->ty == Tstruct && ((TypeStruct *)tv)->sym->noDefaultCtor)
                    {
                        error(loc, "cannot have out parameter of type %s because the default construction is disabled",
                            fparam->type->toChars());
                        errors = true;
                    }
                }
            }

            if (fparam->storageClass & STCscope && !fparam->type->hasPointers() && fparam->type->ty != Ttuple)
            {
                fparam->storageClass &= ~STCscope;
                if (!(fparam->storageClass & STCref))
                    fparam->storageClass &= ~STCreturn;
            }

            if (t->hasWild())
            {
                wildparams |= 1;
                //if (tf->next && !wildreturn)
                //    error(loc, "inout on parameter means inout must be on return type as well (if from D1 code, replace with 'ref')");
            }

            if (fparam->defaultArg)
            {
                Expression *e = fparam->defaultArg;
                if (fparam->storageClass & (STCref | STCout))
                {
                    e = ::semantic(e, argsc);
                    e = resolveProperties(argsc, e);
                }
                else
                {
                    e = inferType(e, fparam->type);
                    Initializer *iz = new ExpInitializer(e->loc, e);
                    iz = ::semantic(iz, argsc, fparam->type, INITnointerpret);
                    e = initializerToExpression(iz);
                }
                if (e->op == TOKfunction)               // see Bugzilla 4820
                {
                    FuncExp *fe = (FuncExp *)e;
                    // Replace function literal with a function symbol,
                    // since default arg expression must be copied when used
                    // and copying the literal itself is wrong.
                    e = new VarExp(e->loc, fe->fd, false);
                    e = new AddrExp(e->loc, e);
                    e = ::semantic(e, argsc);
                }
                e = e->implicitCastTo(argsc, fparam->type);

                // default arg must be an lvalue
                if (fparam->storageClass & (STCout | STCref))
                    e = e->toLvalue(argsc, e);

                fparam->defaultArg = e;
                if (e->op == TOKerror)
                    errors = true;
            }

            /* If fparam after semantic() turns out to be a tuple, the number of parameters may
             * change.
             */
            if (t->ty == Ttuple)
            {
                /* TypeFunction::parameter also is used as the storage of
                 * Parameter objects for FuncDeclaration. So we should copy
                 * the elements of TypeTuple::arguments to avoid unintended
                 * sharing of Parameter object among other functions.
                 */
                TypeTuple *tt = (TypeTuple *)t;
                if (tt->arguments && tt->arguments->dim)
                {
                    /* Propagate additional storage class from tuple parameters to their
                     * element-parameters.
                     * Make a copy, as original may be referenced elsewhere.
                     */
                    size_t tdim = tt->arguments->dim;
                    Parameters *newparams = new Parameters();
                    newparams->setDim(tdim);
                    for (size_t j = 0; j < tdim; j++)
                    {
                        Parameter *narg = (*tt->arguments)[j];

                        // Bugzilla 12744: If the storage classes of narg
                        // conflict with the ones in fparam, it's ignored.
                        StorageClass stc  = fparam->storageClass | narg->storageClass;
                        StorageClass stc1 = fparam->storageClass & (STCref | STCout | STClazy);
                        StorageClass stc2 =   narg->storageClass & (STCref | STCout | STClazy);
                        if (stc1 && stc2 && stc1 != stc2)
                        {
                            OutBuffer buf1;  stcToBuffer(&buf1, stc1 | ((stc1 & STCref) ? (fparam->storageClass & STCauto) : 0));
                            OutBuffer buf2;  stcToBuffer(&buf2, stc2);

                            error(loc, "incompatible parameter storage classes '%s' and '%s'",
                                      buf1.peekString(), buf2.peekString());
                            errors = true;
                            stc = stc1 | (stc & ~(STCref | STCout | STClazy));
                        }

                        (*newparams)[j] = new Parameter(
                                stc, narg->type, narg->ident, narg->defaultArg);
                    }
                    fparam->type = new TypeTuple(newparams);
                }
                fparam->storageClass = 0;

                /* Reset number of parameters, and back up one to do this fparam again,
                 * now that it is a tuple
                 */
                dim = Parameter::dim(tf->parameters);
                i--;
                continue;
            }

            /* Resolve "auto ref" storage class to be either ref or value,
             * based on the argument matching the parameter
             */
            if (fparam->storageClass & STCauto)
            {
                if (fargs && i < fargs->dim && (fparam->storageClass & STCref))
                {
                    Expression *farg = (*fargs)[i];
                    if (farg->isLvalue())
                        ;                               // ref parameter
                    else
                        fparam->storageClass &= ~STCref;        // value parameter
                    fparam->storageClass &= ~STCauto;    // Bugzilla 14656
                    fparam->storageClass |= STCautoref;
                }
                else
                {
                    error(loc, "'auto' can only be used as part of 'auto ref' for template function parameters");
                    errors = true;
                }
            }

            // Remove redundant storage classes for type, they are already applied
            fparam->storageClass &= ~(STC_TYPECTOR | STCin);
        }
        argsc->pop();
    }
    if (tf->isWild())
        wildparams |= 2;

    if (wildreturn && !wildparams)
    {
        error(loc, "inout on return means inout must be on a parameter as well for %s", toChars());
        errors = true;
    }
    tf->iswild = wildparams;

    if (tf->inuse)
    {
        error(loc, "recursive type");
        tf->inuse = 0;
        errors = true;
    }

    if (tf->isproperty && (tf->varargs || Parameter::dim(tf->parameters) > 2))
    {
        error(loc, "properties can only have zero, one, or two parameter");
        errors = true;
    }

    if (tf->varargs == 1 && tf->linkage != LINKd && Parameter::dim(tf->parameters) == 0)
    {
        error(loc, "variadic functions with non-D linkage must have at least one parameter");
        errors = true;
    }

    if (errors)
        return terror;

    if (tf->next)
        tf->deco = tf->merge()->deco;

    /* Don't return merge(), because arg identifiers and default args
     * can be different
     * even though the types match
     */
    return tf;
}

bool TypeFunction::checkRetType(Loc loc)
{
    Type *tb = next->toBasetype();
    if (tb->ty == Tfunction)
    {
        error(loc, "functions cannot return a function");
        next = Type::terror;
    }
    if (tb->ty == Ttuple)
    {
        error(loc, "functions cannot return a tuple");
        next = Type::terror;
    }
    if (!isref && (tb->ty == Tstruct || tb->ty == Tsarray))
    {
        Type *tb2 = tb->baseElemOf();
        if (tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members)
        {
            error(loc, "functions cannot return opaque type %s by value", tb->toChars());
            next = Type::terror;
        }
    }
    if (tb->ty == Terror)
        return true;

    return false;
}

/* Determine purity level based on mutability of t
 * and whether it is a 'ref' type or not.
 */
static PURE purityOfType(bool isref, Type *t)
{
    if (isref)
    {
        if (t->mod & MODimmutable)
            return PUREstrong;
        if (t->mod & (MODconst | MODwild))
            return PUREconst;
        return PUREweak;
    }

    t = t->baseElemOf();

    if (!t->hasPointers() || t->mod & MODimmutable)
        return PUREstrong;

    /* Accept immutable(T)[] and immutable(T)* as being strongly pure
     */
    if (t->ty == Tarray || t->ty == Tpointer)
    {
        Type *tn = t->nextOf()->toBasetype();
        if (tn->mod & MODimmutable)
            return PUREstrong;
        if (tn->mod & (MODconst | MODwild))
            return PUREconst;
    }

    /* The rest of this is too strict; fix later.
     * For example, the only pointer members of a struct may be immutable,
     * which would maintain strong purity.
     * (Just like for dynamic arrays and pointers above.)
     */
    if (t->mod & (MODconst | MODwild))
        return PUREconst;

    /* Should catch delegates and function pointers, and fold in their purity
     */
    return PUREweak;
}

/********************************************
 * Set 'purity' field of 'this'.
 * Do this lazily, as the parameter types might be forward referenced.
 */
void TypeFunction::purityLevel()
{
    TypeFunction *tf = this;
    if (tf->purity != PUREfwdref)
        return;

    purity = PUREstrong; // assume strong until something weakens it

    /* Evaluate what kind of purity based on the modifiers for the parameters
     */
    const size_t dim = Parameter::dim(tf->parameters);
    for (size_t i = 0; i < dim; i++)
    {
        Parameter *fparam = Parameter::getNth(tf->parameters, i);
        Type *t = fparam->type;
        if (!t)
            continue;

        if (fparam->storageClass & (STClazy | STCout))
        {
            purity = PUREweak;
            break;
        }
        switch (purityOfType((fparam->storageClass & STCref) != 0, t))
        {
            case PUREweak:
                purity = PUREweak;
                break;

            case PUREconst:
                purity = PUREconst;
                continue;

            case PUREstrong:
                continue;

            default:
                assert(0);
        }
        break;              // since PUREweak, no need to check further
    }

    if (purity > PUREweak && tf->nextOf())
    {
        /* Adjust purity based on mutability of return type.
         * https://issues.dlang.org/show_bug.cgi?id=15862
         */
        const PURE purity2 = purityOfType(tf->isref, tf->nextOf());
        if (purity2 < purity)
            purity = purity2;
    }
    tf->purity = purity;
}

/********************************
 * 'args' are being matched to function 'this'
 * Determine match level.
 * Input:
 *      flag    1       performing a partial ordering match
 * Returns:
 *      MATCHxxxx
 */

MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag)
{
    //printf("TypeFunction::callMatch() %s\n", toChars());
    MATCH match = MATCHexact;           // assume exact match
    unsigned char wildmatch = 0;

    if (tthis)
    {
        Type *t = tthis;
        if (t->toBasetype()->ty == Tpointer)
            t = t->toBasetype()->nextOf();      // change struct* to struct
        if (t->mod != mod)
        {
            if (MODimplicitConv(t->mod, mod))
                match = MATCHconst;
            else if ((mod & MODwild) && MODimplicitConv(t->mod, (mod & ~MODwild) | MODconst))
            {
                match = MATCHconst;
            }
            else
                return MATCHnomatch;
        }
        if (isWild())
        {
            if (t->isWild())
                wildmatch |= MODwild;
            else if (t->isConst())
                wildmatch |= MODconst;
            else if (t->isImmutable())
                wildmatch |= MODimmutable;
            else
                wildmatch |= MODmutable;
        }
    }

    size_t nparams = Parameter::dim(parameters);
    size_t nargs = args ? args->dim : 0;
    if (nparams == nargs)
        ;
    else if (nargs > nparams)
    {
        if (varargs == 0)
            goto Nomatch;               // too many args; no match
        match = MATCHconvert;           // match ... with a "conversion" match level
    }

    for (size_t u = 0; u < nargs; u++)
    {
        if (u >= nparams)
            break;
        Parameter *p = Parameter::getNth(parameters, u);
        Expression *arg = (*args)[u];
        assert(arg);
        Type *tprm = p->type;
        Type *targ = arg->type;

        if (!(p->storageClass & STClazy && tprm->ty == Tvoid && targ->ty != Tvoid))
        {
            bool isRef = (p->storageClass & (STCref | STCout)) != 0;
            wildmatch |= targ->deduceWild(tprm, isRef);
        }
    }
    if (wildmatch)
    {
        /* Calculate wild matching modifier
         */
        if (wildmatch & MODconst || wildmatch & (wildmatch - 1))
            wildmatch = MODconst;
        else if (wildmatch & MODimmutable)
            wildmatch = MODimmutable;
        else if (wildmatch & MODwild)
            wildmatch = MODwild;
        else
        {
            assert(wildmatch & MODmutable);
            wildmatch = MODmutable;
        }
    }

    for (size_t u = 0; u < nparams; u++)
    {
        MATCH m;

        Parameter *p = Parameter::getNth(parameters, u);
        assert(p);
        if (u >= nargs)
        {
            if (p->defaultArg)
                continue;
            goto L1;        // try typesafe variadics
        }
        {
            Expression *arg = (*args)[u];
            assert(arg);
            //printf("arg: %s, type: %s\n", arg->toChars(), arg->type->toChars());

            Type *targ = arg->type;
            Type *tprm = wildmatch ? p->type->substWildTo(wildmatch) : p->type;

            if (p->storageClass & STClazy && tprm->ty == Tvoid && targ->ty != Tvoid)
                m = MATCHconvert;
            else
            {
                //printf("%s of type %s implicitConvTo %s\n", arg->toChars(), targ->toChars(), tprm->toChars());
                if (flag)
                {
                    // for partial ordering, value is an irrelevant mockup, just look at the type
                    m = targ->implicitConvTo(tprm);
                }
                else
                    m = arg->implicitConvTo(tprm);
                //printf("match %d\n", m);
            }

            // Non-lvalues do not match ref or out parameters
            if (p->storageClass & (STCref | STCout))
            {
                // Bugzilla 13783: Don't use toBasetype() to handle enum types.
                Type *ta = targ;
                Type *tp = tprm;
                //printf("fparam[%d] ta = %s, tp = %s\n", u, ta->toChars(), tp->toChars());

                if (m && !arg->isLvalue())
                {
                    if (p->storageClass & STCout)
                        goto Nomatch;

                    if (arg->op == TOKstring && tp->ty == Tsarray)
                    {
                        if (ta->ty != Tsarray)
                        {
                            Type *tn = tp->nextOf()->castMod(ta->nextOf()->mod);
                            dinteger_t dim = ((StringExp *)arg)->len;
                            ta = tn->sarrayOf(dim);
                        }
                    }
                    else if (arg->op == TOKslice && tp->ty == Tsarray)
                    {
                        // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
                        if (ta->ty != Tsarray)
                        {
                            Type *tn = ta->nextOf();
                            dinteger_t dim = ((TypeSArray *)tp)->dim->toUInteger();
                            ta = tn->sarrayOf(dim);
                        }
                    }
                    else
                        goto Nomatch;
                }

                /* Find most derived alias this type being matched.
                 * Bugzilla 15674: Allow on both ref and out parameters.
                 */
                while (1)
                {
                    Type *tat = ta->toBasetype()->aliasthisOf();
                    if (!tat || !tat->implicitConvTo(tprm))
                        break;
                    ta = tat;
                }

                /* A ref variable should work like a head-const reference.
                 * e.g. disallows:
                 *  ref T      <- an lvalue of const(T) argument
                 *  ref T[dim] <- an lvalue of const(T[dim]) argument
                 */
                if (!ta->constConv(tp))
                    goto Nomatch;
            }
        }

        /* prefer matching the element type rather than the array
         * type when more arguments are present with T[]...
         */
        if (varargs == 2 && u + 1 == nparams && nargs > nparams)
            goto L1;

        //printf("\tm = %d\n", m);
        if (m == MATCHnomatch)                  // if no match
        {
          L1:
            if (varargs == 2 && u + 1 == nparams)       // if last varargs param
            {
                Type *tb = p->type->toBasetype();
                TypeSArray *tsa;
                dinteger_t sz;

                switch (tb->ty)
                {
                case Tsarray:
                    tsa = (TypeSArray *)tb;
                    sz = tsa->dim->toInteger();
                    if (sz != nargs - u)
                        goto Nomatch;
                    /* fall through */
                case Tarray:
                    {
                        TypeArray *ta = (TypeArray *)tb;
                        for (; u < nargs; u++)
                        {
                            Expression *arg = (*args)[u];
                            assert(arg);

                            /* If lazy array of delegates,
                             * convert arg(s) to delegate(s)
                             */
                            Type *tret = p->isLazyArray();
                            if (tret)
                            {
                                if (ta->next->equals(arg->type))
                                    m = MATCHexact;
                                else if (tret->toBasetype()->ty == Tvoid)
                                    m = MATCHconvert;
                                else
                                {
                                    m = arg->implicitConvTo(tret);
                                    if (m == MATCHnomatch)
                                        m = arg->implicitConvTo(ta->next);
                                }
                            }
                            else
                                m = arg->implicitConvTo(ta->next);

                            if (m == MATCHnomatch)
                                goto Nomatch;
                            if (m < match)
                                match = m;
                        }
                        goto Ldone;
                    }
                case Tclass:
                    // Should see if there's a constructor match?
                    // Or just leave it ambiguous?
                    goto Ldone;

                default:
                    goto Nomatch;
                }
            }
            goto Nomatch;
        }
        if (m < match)
            match = m;                  // pick worst match
    }

Ldone:
    //printf("match = %d\n", match);
    return match;

Nomatch:
    //printf("no match\n");
    return MATCHnomatch;
}

/********************************************
 * Return true if there are lazy parameters.
 */
bool TypeFunction::hasLazyParameters()
{
    size_t dim = Parameter::dim(parameters);
    for (size_t i = 0; i < dim; i++)
    {
        Parameter *fparam = Parameter::getNth(parameters, i);
        if (fparam->storageClass & STClazy)
            return true;
    }
    return false;
}

/***************************
 * Examine function signature for parameter p and see if
 * the value of p can 'escape' the scope of the function.
 * This is useful to minimize the needed annotations for the parameters.
 * Params:
 *  p = parameter to this function
 * Returns:
 *  true if escapes via assignment to global or through a parameter
 */

bool TypeFunction::parameterEscapes(Parameter *p)
{
    /* Scope parameters do not escape.
     * Allow 'lazy' to imply 'scope' -
     * lazy parameters can be passed along
     * as lazy parameters to the next function, but that isn't
     * escaping.
     */
    if (parameterStorageClass(p) & (STCscope | STClazy))
        return false;
    return true;
}

/************************************
 * Take the specified storage class for p,
 * and use the function signature to infer whether
 * STCscope and STCreturn should be OR'd in.
 * (This will not affect the name mangling.)
 * Params:
 *  p = one of the parameters to 'this'
 * Returns:
 *  storage class with STCscope or STCreturn OR'd in
 */
StorageClass TypeFunction::parameterStorageClass(Parameter *p)
{
    StorageClass stc = p->storageClass;
    if (!global.params.vsafe)
        return stc;

    if (stc & (STCscope | STCreturn | STClazy) || purity == PUREimpure)
        return stc;

    /* If haven't inferred the return type yet, can't infer storage classes
     */
    if (!nextOf())
        return stc;

    purityLevel();

    // See if p can escape via any of the other parameters
    if (purity == PUREweak)
    {
        const size_t dim = Parameter::dim(parameters);
        for (size_t i = 0; i < dim; i++)
        {
            Parameter *fparam = Parameter::getNth(parameters, i);
            Type *t = fparam->type;
            if (!t)
                continue;
            t = t->baseElemOf();
            if (t->isMutable() && t->hasPointers())
            {
                if (fparam->storageClass & (STCref | STCout))
                {
                }
                else if (t->ty == Tarray || t->ty == Tpointer)
                {
                    Type *tn = t->nextOf()->toBasetype();
                    if (!(tn->isMutable() && tn->hasPointers()))
                        continue;
                }
                return stc;
            }
        }
    }

    stc |= STCscope;

    /* Inferring STCreturn here has false positives
     * for pure functions, producing spurious error messages
     * about escaping references.
     * Give up on it for now.
     */
    return stc;
}

Expression *TypeFunction::defaultInit(Loc loc)
{
    error(loc, "function does not have a default initializer");
    return new ErrorExp();
}

Type *TypeFunction::addStorageClass(StorageClass stc)
{
    //printf("addStorageClass(%llx) %d\n", stc, (stc & STCscope) != 0);
    TypeFunction *t = Type::addStorageClass(stc)->toTypeFunction();
    if ((stc & STCpure && !t->purity) ||
        (stc & STCnothrow && !t->isnothrow) ||
        (stc & STCnogc && !t->isnogc) ||
        (stc & STCscope && !t->isscope) ||
        (stc & STCsafe && t->trust < TRUSTtrusted))
    {
        // Klunky to change these
        TypeFunction *tf = new TypeFunction(t->parameters, t->next, t->varargs, t->linkage, 0);
        tf->mod = t->mod;
        tf->fargs = fargs;
        tf->purity = t->purity;
        tf->isnothrow = t->isnothrow;
        tf->isnogc = t->isnogc;
        tf->isproperty = t->isproperty;
        tf->isref = t->isref;
        tf->isreturn = t->isreturn;
        tf->isscope = t->isscope;
        tf->isscopeinferred = t->isscopeinferred;
        tf->trust = t->trust;
        tf->iswild = t->iswild;

        if (stc & STCpure)
            tf->purity = PUREfwdref;
        if (stc & STCnothrow)
            tf->isnothrow = true;
        if (stc & STCnogc)
            tf->isnogc = true;
        if (stc & STCsafe)
            tf->trust = TRUSTsafe;
        if (stc & STCscope)
        {
            tf->isscope = true;
            if (stc & STCscopeinferred)
                tf->isscopeinferred = true;
        }

        tf->deco = tf->merge()->deco;
        t = tf;
    }
    return t;
}

/** For each active attribute (ref/const/nogc/etc) call fp with a void* for the
work param and a string representation of the attribute. */
int TypeFunction::attributesApply(void *param, int (*fp)(void *, const char *), TRUSTformat trustFormat)
{
    int res = 0;

    if (purity) res = fp(param, "pure");
    if (res) return res;

    if (isnothrow) res = fp(param, "nothrow");
    if (res) return res;

    if (isnogc) res = fp(param, "@nogc");
    if (res) return res;

    if (isproperty) res = fp(param, "@property");
    if (res) return res;

    if (isref) res = fp(param, "ref");
    if (res) return res;

    if (isreturn) res = fp(param, "return");
    if (res) return res;

    if (isscope && !isscopeinferred) res = fp(param, "scope");
    if (res) return res;

    TRUST trustAttrib = trust;

    if (trustAttrib == TRUSTdefault)
    {
        // Print out "@system" when trust equals TRUSTdefault (if desired).
        if (trustFormat == TRUSTformatSystem)
            trustAttrib = TRUSTsystem;
        else
            return res;  // avoid calling with an empty string
    }

    return fp(param, trustToChars(trustAttrib));
}

/***************************** TypeDelegate *****************************/

TypeDelegate::TypeDelegate(Type *t)
    : TypeNext(Tfunction, t)
{
    ty = Tdelegate;
}

TypeDelegate *TypeDelegate::create(Type *t)
{
    return new TypeDelegate(t);
}

const char *TypeDelegate::kind()
{
    return "delegate";
}

Type *TypeDelegate::syntaxCopy()
{
    Type *t = next->syntaxCopy();
    if (t == next)
        t = this;
    else
    {
        t = new TypeDelegate(t);
        t->mod = mod;
    }
    return t;
}

Type *TypeDelegate::semantic(Loc loc, Scope *sc)
{
    //printf("TypeDelegate::semantic() %s\n", toChars());
    if (deco)                   // if semantic() already run
    {
        //printf("already done\n");
        return this;
    }
    next = next->semantic(loc,sc);
    if (next->ty != Tfunction)
        return terror;

    /* In order to deal with Bugzilla 4028, perhaps default arguments should
     * be removed from next before the merge.
     */

    /* Don't return merge(), because arg identifiers and default args
     * can be different
     * even though the types match
     */
    deco = merge()->deco;
    return this;
}

Type *TypeDelegate::addStorageClass(StorageClass stc)
{
    TypeDelegate *t = (TypeDelegate*)Type::addStorageClass(stc);
    if (!global.params.vsafe)
        return t;

    /* The rest is meant to add 'scope' to a delegate declaration if it is of the form:
     *  alias dg_t = void* delegate();
     *  scope dg_t dg = ...;
     */
    if(stc & STCscope)
    {
        Type *n = t->next->addStorageClass(STCscope | STCscopeinferred);
        if (n != t->next)
        {
            t->next = n;
            t->deco = t->merge()->deco; // mangling supposed to not be changed due to STCscopeinferrred
        }
    }
    return t;
}

d_uns64 TypeDelegate::size(Loc)
{
    return Target::ptrsize * 2;
}

unsigned TypeDelegate::alignsize()
{
    return Target::ptrsize;
}

MATCH TypeDelegate::implicitConvTo(Type *to)
{
    //printf("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to);
    //printf("from: %s\n", toChars());
    //printf("to  : %s\n", to->toChars());
    if (this == to)
        return MATCHexact;
#if 1 // not allowing covariant conversions because it interferes with overriding
    if (to->ty == Tdelegate && this->nextOf()->covariant(to->nextOf()) == 1)
    {
        Type *tret = this->next->nextOf();
        Type *toret = ((TypeDelegate *)to)->next->nextOf();
        if (tret->ty == Tclass && toret->ty == Tclass)
        {
            /* Bugzilla 10219: Check covariant interface return with offset tweaking.
             * interface I {}
             * class C : Object, I {}
             * I delegate() dg = delegate C() {}    // should be error
             */
            int offset = 0;
            if (toret->isBaseOf(tret, &offset) && offset != 0)
                return MATCHnomatch;
        }
        return MATCHconvert;
    }
#endif
    return MATCHnomatch;
}

Expression *TypeDelegate::defaultInit(Loc loc)
{
    return new NullExp(loc, this);
}

bool TypeDelegate::isZeroInit(Loc)
{
    return true;
}

bool TypeDelegate::isBoolean()
{
    return true;
}

Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    if (ident == Id::ptr)
    {
        e = new DelegatePtrExp(e->loc, e);
        e = ::semantic(e, sc);
    }
    else if (ident == Id::funcptr)
    {
        if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
        {
            e->error("%s.funcptr cannot be used in @safe code", e->toChars());
            return new ErrorExp();
        }
        e = new DelegateFuncptrExp(e->loc, e);
        e = ::semantic(e, sc);
    }
    else
    {
        e = Type::dotExp(sc, e, ident, flag);
    }
    return e;
}

bool TypeDelegate::hasPointers()
{
    return true;
}



/***************************** TypeQualified *****************************/

TypeQualified::TypeQualified(TY ty, Loc loc)
    : Type(ty)
{
    this->loc = loc;
}

void TypeQualified::syntaxCopyHelper(TypeQualified *t)
{
    //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
    idents.setDim(t->idents.dim);
    for (size_t i = 0; i < idents.dim; i++)
    {
        RootObject *id = t->idents[i];
        if (id->dyncast() == DYNCAST_DSYMBOL)
        {
            TemplateInstance *ti = (TemplateInstance *)id;

            ti = (TemplateInstance *)ti->syntaxCopy(NULL);
            id = ti;
        }
        else if (id->dyncast() == DYNCAST_EXPRESSION)
        {
            Expression *e = (Expression *)id;
            e = e->syntaxCopy();
            id = e;
        }
        else if (id->dyncast() == DYNCAST_TYPE)
        {
            Type *tx = (Type *)id;
            tx = tx->syntaxCopy();
            id = tx;
        }
        idents[i] = id;
    }
}

void TypeQualified::addIdent(Identifier *ident)
{
    idents.push(ident);
}

void TypeQualified::addInst(TemplateInstance *inst)
{
    idents.push(inst);
}

void TypeQualified::addIndex(RootObject *e)
{
    idents.push(e);
}

d_uns64 TypeQualified::size(Loc)
{
    error(this->loc, "size of type %s is not known", toChars());
    return SIZE_INVALID;
}

/*************************************
 * Resolve a tuple index.
 */
void TypeQualified::resolveTupleIndex(Loc loc, Scope *sc, Dsymbol *s,
        Expression **pe, Type **pt, Dsymbol **ps, RootObject *oindex)
{
    *pt = NULL;
    *ps = NULL;
    *pe = NULL;

    TupleDeclaration *td = s->isTupleDeclaration();

    Expression *eindex = isExpression(oindex);
    Type *tindex = isType(oindex);
    Dsymbol *sindex = isDsymbol(oindex);

    if (!td)
    {
        // It's really an index expression
        if (tindex)
            eindex = new TypeExp(loc, tindex);
        else if (sindex)
            eindex = ::resolve(loc, sc, sindex, false);
        Expression *e = new IndexExp(loc, ::resolve(loc, sc, s, false), eindex);
        e = ::semantic(e, sc);
        resolveExp(e, pt, pe, ps);
        return;
    }

    // Convert oindex to Expression, then try to resolve to constant.
    if (tindex)
        tindex->resolve(loc, sc, &eindex, &tindex, &sindex);
    if (sindex)
        eindex = ::resolve(loc, sc, sindex, false);
    if (!eindex)
    {
        ::error(loc, "index is %s not an expression", oindex->toChars());
        *pt = Type::terror;
        return;
    }
    sc = sc->startCTFE();
    eindex = ::semantic(eindex, sc);
    sc = sc->endCTFE();

    eindex = eindex->ctfeInterpret();
    if (eindex->op == TOKerror)
    {
        *pt = Type::terror;
        return;
    }

    const uinteger_t d = eindex->toUInteger();
    if (d >= td->objects->dim)
    {
        ::error(loc, "tuple index %llu exceeds length %u", (ulonglong)d, (unsigned)td->objects->dim);
        *pt = Type::terror;
        return;
    }

    RootObject *o = (*td->objects)[(size_t)d];
    *pt = isType(o);
    *ps = isDsymbol(o);
    *pe = isExpression(o);

    if (*pt)
        *pt = (*pt)->semantic(loc, sc);
    if (*pe)
        resolveExp(*pe, pt, pe, ps);
}

/*************************************
 * Takes an array of Identifiers and figures out if
 * it represents a Type or an Expression.
 * Output:
 *      if expression, *pe is set
 *      if type, *pt is set
 */
void TypeQualified::resolveHelper(Loc loc, Scope *sc,
        Dsymbol *s, Dsymbol *,
        Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
{
    *pe = NULL;
    *pt = NULL;
    *ps = NULL;
    if (s)
    {
        //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
        Declaration *d = s->isDeclaration();
        if (d && (d->storage_class & STCtemplateparameter))
            s = s->toAlias();
        else
            s->checkDeprecated(loc, sc);            // check for deprecated aliases

        s = s->toAlias();
        //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
        for (size_t i = 0; i < idents.dim; i++)
        {
            RootObject *id = idents[i];

            if (id->dyncast() == DYNCAST_EXPRESSION ||
                id->dyncast() == DYNCAST_TYPE)
            {
                Type *tx;
                Expression *ex;
                Dsymbol *sx;
                resolveTupleIndex(loc, sc, s, &ex, &tx, &sx, id);
                if (sx)
                {
                    s = sx->toAlias();
                    continue;
                }
                if (tx)
                    ex = new TypeExp(loc, tx);
                assert(ex);

                ex = typeToExpressionHelper(this, ex, i + 1);
                ex = ::semantic(ex, sc);
                resolveExp(ex, pt, pe, ps);
                return;
            }

            Type *t = s->getType();     // type symbol, type alias, or type tuple?
            unsigned errorsave = global.errors;
            Dsymbol *sm = s->searchX(loc, sc, id);
            if (sm && !(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, sm))
            {
                ::deprecation(loc, "%s is not visible from module %s", sm->toPrettyChars(), sc->_module->toChars());
                // sm = NULL;
            }
            if (global.errors != errorsave)
            {
                *pt = Type::terror;
                return;
            }
            //printf("\t3: s = %p %s %s, sm = %p\n", s, s->kind(), s->toChars(), sm);
            if (intypeid && !t && sm && sm->needThis())
                goto L3;
            if (VarDeclaration *v = s->isVarDeclaration())
            {
                if (v->storage_class & (STCconst | STCimmutable | STCmanifest) ||
                    v->type->isConst() || v->type->isImmutable())
                {
                    // Bugzilla 13087: this.field is not constant always
                    if (!v->isThisDeclaration())
                        goto L3;
                }
            }
            if (!sm)
            {
                if (!t)
                {
                    if (s->isDeclaration())         // var, func, or tuple declaration?
                    {
                        t = s->isDeclaration()->type;
                        if (!t && s->isTupleDeclaration())  // expression tuple?
                            goto L3;
                    }
                    else if (s->isTemplateInstance() ||
                             s->isImport() || s->isPackage() || s->isModule())
                    {
                        goto L3;
                    }
                }
                if (t)
                {
                    sm = t->toDsymbol(sc);
                    if (sm && id->dyncast() == DYNCAST_IDENTIFIER)
                    {
                        sm = sm->search(loc, (Identifier *)id);
                        if (sm)
                            goto L2;
                    }
                L3:
                    Expression *e;
                    VarDeclaration *v = s->isVarDeclaration();
                    FuncDeclaration *f = s->isFuncDeclaration();
                    if (intypeid || (!v && !f))
                        e = ::resolve(loc, sc, s, true);
                    else
                        e = new VarExp(loc, s->isDeclaration(), true);

                    e = typeToExpressionHelper(this, e, i);
                    e = ::semantic(e, sc);
                    resolveExp(e, pt, pe, ps);
                    return;
                }
                else
                {
                    if (id->dyncast() == DYNCAST_DSYMBOL)
                    {
                        // searchX already handles errors for template instances
                        assert(global.errors);
                    }
                    else
                    {
                        assert(id->dyncast() == DYNCAST_IDENTIFIER);
                        sm = s->search_correct((Identifier *)id);
                        if (sm)
                            error(loc, "identifier '%s' of '%s' is not defined, did you mean %s '%s'?",
                                  id->toChars(), toChars(), sm->kind(), sm->toChars());
                        else
                            error(loc, "identifier '%s' of '%s' is not defined", id->toChars(), toChars());
                    }
                    *pe = new ErrorExp();
                }
                return;
            }
        L2:
            s = sm->toAlias();
        }

        if (EnumMember *em = s->isEnumMember())
        {
            // It's not a type, it's an expression
            *pe = em->getVarExp(loc, sc);
            return;
        }
        if (VarDeclaration *v = s->isVarDeclaration())
        {
            /* This is mostly same with DsymbolExp::semantic(), but we cannot use it
             * because some variables used in type context need to prevent lowering
             * to a literal or contextful expression. For example:
             *
             *  enum a = 1; alias b = a;
             *  template X(alias e){ alias v = e; }  alias x = X!(1);
             *  struct S { int v; alias w = v; }
             *      // TypeIdentifier 'a', 'e', and 'v' should be TOKvar,
             *      // because getDsymbol() need to work in AliasDeclaration::semantic().
             */
            if (!v->type ||
                (!v->type->deco && v->inuse))
            {
                if (v->inuse)   // Bugzilla 9494
                    error(loc, "circular reference to %s '%s'", v->kind(), v->toPrettyChars());
                else
                    error(loc, "forward reference to %s '%s'", v->kind(), v->toPrettyChars());
                *pt = Type::terror;
                return;
            }
            if (v->type->ty == Terror)
                *pt = Type::terror;
            else
                *pe = new VarExp(loc, v);
            return;
        }
        if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
        {
            //printf("'%s' is a function literal\n", fld->toChars());
            *pe = new FuncExp(loc, fld);
            *pe = ::semantic(*pe, sc);
            return;
        }
L1:
        Type *t = s->getType();
        if (!t)
        {
            // If the symbol is an import, try looking inside the import
            if (Import *si = s->isImport())
            {
                s = si->search(loc, s->ident);
                if (s && s != si)
                    goto L1;
                s = si;
            }
            *ps = s;
            return;
        }
        if (t->ty == Tinstance && t != this && !t->deco)
        {
            if (!((TypeInstance *)t)->tempinst->errors)
                error(loc, "forward reference to '%s'", t->toChars());
            *pt = Type::terror;
            return;
        }

        if (t->ty == Ttuple)
            *pt = t;
        else
            *pt = t->merge();
    }
    if (!s)
    {
        /* Look for what user might have intended
         */
        const char *p = mutableOf()->unSharedOf()->toChars();
        Identifier *id = Identifier::idPool(p, strlen(p));
        if (const char *n = importHint(p))
            error(loc, "`%s` is not defined, perhaps `import %s;` ?", p, n);
        else if (Dsymbol *s2 = sc->search_correct(id))
            error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2->kind(), s2->toChars());
        else if (const char *q = Scope::search_correct_C(id))
            error(loc, "undefined identifier `%s`, did you mean `%s`?", p, q);
        else
            error(loc, "undefined identifier `%s`", p);

        *pt = Type::terror;
    }
}

/***************************** TypeIdentifier *****************************/

TypeIdentifier::TypeIdentifier(Loc loc, Identifier *ident)
    : TypeQualified(Tident, loc)
{
    this->ident = ident;
}

const char *TypeIdentifier::kind()
{
    return "identifier";
}

Type *TypeIdentifier::syntaxCopy()
{
    TypeIdentifier *t = new TypeIdentifier(loc, ident);
    t->syntaxCopyHelper(this);
    t->mod = mod;
    return t;
}

/*************************************
 * Takes an array of Identifiers and figures out if
 * it represents a Type or an Expression.
 * Output:
 *      if expression, *pe is set
 *      if type, *pt is set
 */

void TypeIdentifier::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
{
    //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars());

    if ((ident->equals(Id::_super) || ident->equals(Id::This)) && !hasThis(sc))
    {
        AggregateDeclaration *ad = sc->getStructClassScope();
        if (ad)
        {
            ClassDeclaration *cd = ad->isClassDeclaration();
            if (cd)
            {
                if (ident->equals(Id::This))
                    ident = cd->ident;
                else if (cd->baseClass && ident->equals(Id::_super))
                    ident = cd->baseClass->ident;
            }
            else
            {
                StructDeclaration *sd = ad->isStructDeclaration();
                if (sd && ident->equals(Id::This))
                    ident = sd->ident;
            }
        }
    }
    if (ident == Id::ctfe)
    {
        error(loc, "variable __ctfe cannot be read at compile time");
        *pe = NULL;
        *ps = NULL;
        *pt = Type::terror;
        return;
    }

    Dsymbol *scopesym;
    Dsymbol *s = sc->search(loc, ident, &scopesym);
    resolveHelper(loc, sc, s, scopesym, pe, pt, ps, intypeid);
    if (*pt)
        (*pt) = (*pt)->addMod(mod);
}

/*****************************************
 * See if type resolves to a symbol, if so,
 * return that symbol.
 */

Dsymbol *TypeIdentifier::toDsymbol(Scope *sc)
{
    //printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
    if (!sc)
        return NULL;

    Type *t;
    Expression *e;
    Dsymbol *s;

    resolve(loc, sc, &e, &t, &s);
    if (t && t->ty != Tident)
        s = t->toDsymbol(sc);
    if (e)
        s = getDsymbol(e);

    return s;
}

Type *TypeIdentifier::semantic(Loc loc, Scope *sc)
{
    Type *t;
    Expression *e;
    Dsymbol *s;

    //printf("TypeIdentifier::semantic(%s)\n", toChars());
    resolve(loc, sc, &e, &t, &s);
    if (t)
    {
        //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco);
        t = t->addMod(mod);
    }
    else
    {
        if (s)
        {
            s->error(loc, "is used as a type");
            //halt();
        }
        else
            error(loc, "%s is used as a type", toChars());
        t = terror;
    }
    //t->print();
    return t;
}

/***************************** TypeInstance *****************************/

TypeInstance::TypeInstance(Loc loc, TemplateInstance *tempinst)
    : TypeQualified(Tinstance, loc)
{
    this->tempinst = tempinst;
}

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

Type *TypeInstance::syntaxCopy()
{
    //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
    TypeInstance *t = new TypeInstance(loc, (TemplateInstance *)tempinst->syntaxCopy(NULL));
    t->syntaxCopyHelper(this);
    t->mod = mod;
    return t;
}

void TypeInstance::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
{
    // Note close similarity to TypeIdentifier::resolve()
    *pe = NULL;
    *pt = NULL;
    *ps = NULL;
    //printf("TypeInstance::resolve(sc = %p, tempinst = '%s')\n", sc, tempinst->toChars());
    tempinst->semantic(sc);
    if (!global.gag && tempinst->errors)
    {
        *pt = terror;
        return;
    }

    resolveHelper(loc, sc, tempinst, NULL, pe, pt, ps, intypeid);
    if (*pt)
        *pt = (*pt)->addMod(mod);
    //if (*pt) printf("pt = '%s'\n", (*pt)->toChars());
}

Type *TypeInstance::semantic(Loc loc, Scope *sc)
{
    Type *t;
    Expression *e;
    Dsymbol *s;

    //printf("TypeInstance::semantic(%p, %s)\n", this, toChars());
    {
        unsigned errors = global.errors;
        resolve(loc, sc, &e, &t, &s);
        // if we had an error evaluating the symbol, suppress further errors
        if (!t && errors != global.errors)
            return terror;
    }

    if (!t)
    {
        if (!e && s && s->errors)
        {
            // if there was an error evaluating the symbol, it might actually
            // be a type. Avoid misleading error messages.
            error(loc, "%s had previous errors", toChars());
        }
        else
            error(loc, "%s is used as a type", toChars());
        t = terror;
    }
    return t;
}

Dsymbol *TypeInstance::toDsymbol(Scope *sc)
{
    Type *t;
    Expression *e;
    Dsymbol *s;

    //printf("TypeInstance::semantic(%s)\n", toChars());
    resolve(loc, sc, &e, &t, &s);
    if (t && t->ty != Tinstance)
        s = t->toDsymbol(sc);

    return s;
}


/***************************** TypeTypeof *****************************/

TypeTypeof::TypeTypeof(Loc loc, Expression *exp)
        : TypeQualified(Ttypeof, loc)
{
    this->exp = exp;
    inuse = 0;
}

const char *TypeTypeof::kind()
{
    return "typeof";
}

Type *TypeTypeof::syntaxCopy()
{
    //printf("TypeTypeof::syntaxCopy() %s\n", toChars());
    TypeTypeof *t = new TypeTypeof(loc, exp->syntaxCopy());
    t->syntaxCopyHelper(this);
    t->mod = mod;
    return t;
}

Dsymbol *TypeTypeof::toDsymbol(Scope *sc)
{
    //printf("TypeTypeof::toDsymbol('%s')\n", toChars());
    Expression *e;
    Type *t;
    Dsymbol *s;
    resolve(loc, sc, &e, &t, &s);

    return s;
}

void TypeTypeof::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
{
    *pe = NULL;
    *pt = NULL;
    *ps = NULL;

    //printf("TypeTypeof::resolve(sc = %p, idents = '%s')\n", sc, toChars());
    //static int nest; if (++nest == 50) *(char*)0=0;
    if (inuse)
    {
        inuse = 2;
        error(loc, "circular typeof definition");
    Lerr:
        *pt = Type::terror;
        inuse--;
        return;
    }
    inuse++;

    Type *t;
    {
        /* Currently we cannot evalute 'exp' in speculative context, because
         * the type implementation may leak to the final execution. Consider:
         *
         * struct S(T) {
         *   string toString() const { return "x"; }
         * }
         * void main() {
         *   alias X = typeof(S!int());
         *   assert(typeid(X).xtoString(null) == "x");
         * }
         */
        Scope *sc2 = sc->push();
        sc2->intypeof = 1;
        Expression *exp2 = ::semantic(exp, sc2);
        exp2 = resolvePropertiesOnly(sc2, exp2);
        sc2->pop();

        if (exp2->op == TOKerror)
        {
            if (!global.gag)
                exp = exp2;
            goto Lerr;
        }
        exp = exp2;

        if (exp->op == TOKtype ||
            exp->op == TOKscope)
        {
            if (exp->checkType())
                goto Lerr;

            /* Today, 'typeof(func)' returns void if func is a
             * function template (TemplateExp), or
             * template lambda (FuncExp).
             * It's actually used in Phobos as an idiom, to branch code for
             * template functions.
             */
        }
        if (FuncDeclaration *f = exp->op == TOKvar    ? ((   VarExp *)exp)->var->isFuncDeclaration()
                               : exp->op == TOKdotvar ? ((DotVarExp *)exp)->var->isFuncDeclaration() : NULL)
        {
            if (f->checkForwardRef(loc))
                goto Lerr;
        }
        if (FuncDeclaration *f = isFuncAddress(exp))
        {
            if (f->checkForwardRef(loc))
                goto Lerr;
        }

        t = exp->type;
        if (!t)
        {
            error(loc, "expression (%s) has no type", exp->toChars());
            goto Lerr;
        }
        if (t->ty == Ttypeof)
        {
            error(loc, "forward reference to %s", toChars());
            goto Lerr;
        }
    }
    if (idents.dim == 0)
        *pt = t;
    else
    {
        if (Dsymbol *s = t->toDsymbol(sc))
            resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid);
        else
        {
            Expression *e = typeToExpressionHelper(this, new TypeExp(loc, t));
            e = ::semantic(e, sc);
            resolveExp(e, pt, pe, ps);
        }
    }
    if (*pt)
        (*pt) = (*pt)->addMod(mod);
    inuse--;
    return;
}

Type *TypeTypeof::semantic(Loc loc, Scope *sc)
{
    //printf("TypeTypeof::semantic() %s\n", toChars());

    Expression *e;
    Type *t;
    Dsymbol *s;
    resolve(loc, sc, &e, &t, &s);
    if (s && (t = s->getType()) != NULL)
        t = t->addMod(mod);
    if (!t)
    {
        error(loc, "%s is used as a type", toChars());
        t = Type::terror;
    }
    return t;
}

d_uns64 TypeTypeof::size(Loc loc)
{
    if (exp->type)
        return exp->type->size(loc);
    else
        return TypeQualified::size(loc);
}



/***************************** TypeReturn *****************************/

TypeReturn::TypeReturn(Loc loc)
        : TypeQualified(Treturn, loc)
{
}

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

Type *TypeReturn::syntaxCopy()
{
    TypeReturn *t = new TypeReturn(loc);
    t->syntaxCopyHelper(this);
    t->mod = mod;
    return t;
}

Dsymbol *TypeReturn::toDsymbol(Scope *sc)
{
    Expression *e;
    Type *t;
    Dsymbol *s;
    resolve(loc, sc, &e, &t, &s);

    return s;
}

void TypeReturn::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
{
    *pe = NULL;
    *pt = NULL;
    *ps = NULL;

    //printf("TypeReturn::resolve(sc = %p, idents = '%s')\n", sc, toChars());
    Type *t;
    {
        FuncDeclaration *func = sc->func;
        if (!func)
        {
            error(loc, "typeof(return) must be inside function");
            goto Lerr;
        }
        if (func->fes)
            func = func->fes->func;

        t = func->type->nextOf();
        if (!t)
        {
            error(loc, "cannot use typeof(return) inside function %s with inferred return type", sc->func->toChars());
            goto Lerr;
        }
    }
    if (idents.dim == 0)
        *pt = t;
    else
    {
        if (Dsymbol *s = t->toDsymbol(sc))
            resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid);
        else
        {
            Expression *e = typeToExpressionHelper(this, new TypeExp(loc, t));
            e = ::semantic(e, sc);
            resolveExp(e, pt, pe, ps);
        }
    }
    if (*pt)
        (*pt) = (*pt)->addMod(mod);
    return;

Lerr:
    *pt = Type::terror;
    return;
}

Type *TypeReturn::semantic(Loc loc, Scope *sc)
{
    //printf("TypeReturn::semantic() %s\n", toChars());

    Expression *e;
    Type *t;
    Dsymbol *s;
    resolve(loc, sc, &e, &t, &s);
    if (s && (t = s->getType()) != NULL)
        t = t->addMod(mod);
    if (!t)
    {
        error(loc, "%s is used as a type", toChars());
        t = Type::terror;
    }
    return t;
}

/***************************** TypeEnum *****************************/

TypeEnum::TypeEnum(EnumDeclaration *sym)
        : Type(Tenum)
{
    this->sym = sym;
}

const char *TypeEnum::kind()
{
    return "enum";
}

Type *TypeEnum::syntaxCopy()
{
    return this;
}

Type *TypeEnum::semantic(Loc, Scope *)
{
    //printf("TypeEnum::semantic() %s\n", toChars());
    if (deco)
        return this;
    return merge();
}

d_uns64 TypeEnum::size(Loc loc)
{
    return sym->getMemtype(loc)->size(loc);
}

unsigned TypeEnum::alignsize()
{
    Type *t = sym->getMemtype(Loc());
    if (t->ty == Terror)
        return 4;
    return t->alignsize();
}

Dsymbol *TypeEnum::toDsymbol(Scope *)
{
    return sym;
}

Type *TypeEnum::toBasetype()
{
    if (!sym->members && !sym->memtype)
        return this;
    Type *tb = sym->getMemtype(Loc())->toBasetype();
    return tb->castMod(mod);         // retain modifier bits from 'this'
}

Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    // Bugzilla 14010
    if (ident == Id::_mangleof)
        return getProperty(e->loc, ident, flag & 1);

    if (sym->_scope)
        sym->semantic(sym->_scope);
    if (!sym->members)
    {
        if (sym->isSpecial())
        {
            /* Special enums forward to the base type
             */
            e = sym->memtype->dotExp(sc, e, ident, flag);
        }
        else if (!(flag & 1))
        {
            sym->error("is forward referenced when looking for '%s'", ident->toChars());
            e = new ErrorExp();
        }
        else
            e = NULL;
        return e;
    }

    Dsymbol *s = sym->search(e->loc, ident);
    if (!s)
    {
        if (ident == Id::max ||
            ident == Id::min ||
            ident == Id::_init)
        {
            return getProperty(e->loc, ident, flag & 1);
        }
        Expression *res = sym->getMemtype(Loc())->dotExp(sc, e, ident, 1);
        if (!(flag & 1) && !res)
        {
            if (Dsymbol *ns = sym->search_correct(ident))
                e->error("no property '%s' for type '%s'. Did you mean '%s.%s' ?",
                    ident->toChars(), toChars(), toChars(), ns->toChars());
            else
                e->error("no property '%s' for type '%s'",
                    ident->toChars(), toChars());

            return new ErrorExp();
        }
        return res;
    }
    EnumMember *m = s->isEnumMember();
    return m->getVarExp(e->loc, sc);
}

Expression *TypeEnum::getProperty(Loc loc, Identifier *ident, int flag)
{
    Expression *e;
    if (ident == Id::max || ident == Id::min)
    {
        return sym->getMaxMinValue(loc, ident);
    }
    else if (ident == Id::_init)
    {
        e = defaultInitLiteral(loc);
    }
    else if (ident == Id::stringof)
    {
        const char *s = toChars();
        e = new StringExp(loc, const_cast<char *>(s), strlen(s));
        Scope sc;
        e = ::semantic(e, &sc);
    }
    else if (ident == Id::_mangleof)
    {
        e = Type::getProperty(loc, ident, flag);
    }
    else
    {
        e = toBasetype()->getProperty(loc, ident, flag);
    }
    return e;
}

bool TypeEnum::isintegral()
{
    return sym->getMemtype(Loc())->isintegral();
}

bool TypeEnum::isfloating()
{
    return sym->getMemtype(Loc())->isfloating();
}

bool TypeEnum::isreal()
{
    return sym->getMemtype(Loc())->isreal();
}

bool TypeEnum::isimaginary()
{
    return sym->getMemtype(Loc())->isimaginary();
}

bool TypeEnum::iscomplex()
{
    return sym->getMemtype(Loc())->iscomplex();
}

bool TypeEnum::isunsigned()
{
    return sym->getMemtype(Loc())->isunsigned();
}

bool TypeEnum::isscalar()
{
    return sym->getMemtype(Loc())->isscalar();
}

bool TypeEnum::isString()
{
    return sym->getMemtype(Loc())->isString();
}

bool TypeEnum::isAssignable()
{
    return sym->getMemtype(Loc())->isAssignable();
}

bool TypeEnum::isBoolean()
{
    return sym->getMemtype(Loc())->isBoolean();
}

bool TypeEnum::needsDestruction()
{
    return sym->getMemtype(Loc())->needsDestruction();
}

bool TypeEnum::needsNested()
{
    return sym->getMemtype(Loc())->needsNested();
}

MATCH TypeEnum::implicitConvTo(Type *to)
{
    MATCH m;

    //printf("TypeEnum::implicitConvTo()\n");
    if (ty == to->ty && sym == ((TypeEnum *)to)->sym)
        m = (mod == to->mod) ? MATCHexact : MATCHconst;
    else if (sym->getMemtype(Loc())->implicitConvTo(to))
        m = MATCHconvert;       // match with conversions
    else
        m = MATCHnomatch;       // no match
    return m;
}

MATCH TypeEnum::constConv(Type *to)
{
    if (equals(to))
        return MATCHexact;
    if (ty == to->ty && sym == ((TypeEnum *)to)->sym &&
        MODimplicitConv(mod, to->mod))
        return MATCHconst;
    return MATCHnomatch;
}


Expression *TypeEnum::defaultInit(Loc loc)
{
    // Initialize to first member of enum
    Expression *e = sym->getDefaultValue(loc);
    e = e->copy();
    e->loc = loc;
    e->type = this;     // to deal with const, immutable, etc., variants
    return e;
}

bool TypeEnum::isZeroInit(Loc loc)
{
    return sym->getDefaultValue(loc)->isBool(false);
}

bool TypeEnum::hasPointers()
{
    return sym->getMemtype(Loc())->hasPointers();
}

bool TypeEnum::hasVoidInitPointers()
{
    return sym->getMemtype(Loc())->hasVoidInitPointers();
}

Type *TypeEnum::nextOf()
{
    return sym->getMemtype(Loc())->nextOf();
}

/***************************** TypeStruct *****************************/

TypeStruct::TypeStruct(StructDeclaration *sym)
        : Type(Tstruct)
{
    this->sym = sym;
    this->att = RECfwdref;
    this->cppmangle = CPPMANGLEdefault;
}

TypeStruct *TypeStruct::create(StructDeclaration *sym)
{
    return new TypeStruct(sym);
}

const char *TypeStruct::kind()
{
    return "struct";
}

Type *TypeStruct::syntaxCopy()
{
    return this;
}

Type *TypeStruct::semantic(Loc, Scope *sc)
{
    //printf("TypeStruct::semantic('%s')\n", sym->toChars());
    if (deco)
    {
        if (sc && sc->cppmangle != CPPMANGLEdefault)
        {
            if (this->cppmangle == CPPMANGLEdefault)
                this->cppmangle = sc->cppmangle;
            else
                assert(this->cppmangle == sc->cppmangle);
        }
        return this;
    }

    /* Don't semantic for sym because it should be deferred until
     * sizeof needed or its members accessed.
     */
    // instead, parent should be set correctly
    assert(sym->parent);

    if (sym->type->ty == Terror)
        return Type::terror;
    if (sc)
        this->cppmangle = sc->cppmangle;
    return merge();
}

d_uns64 TypeStruct::size(Loc loc)
{
    return sym->size(loc);
}

unsigned TypeStruct::alignsize()
{
    sym->size(Loc());               // give error for forward references
    return sym->alignsize;
}

Dsymbol *TypeStruct::toDsymbol(Scope *)
{
    return sym;
}

static Dsymbol *searchSymStruct(Scope *sc, Dsymbol *sym, Expression *e, Identifier *ident)
{
    int flags = sc->flags & SCOPEignoresymbolvisibility ? IgnoreSymbolVisibility : 0;
    Dsymbol *sold = NULL;
    if (global.params.bug10378 || global.params.check10378)
    {
        sold = sym->search(e->loc, ident, flags);
        if (!global.params.check10378)
            return sold;
    }

    Dsymbol *s = sym->search(e->loc, ident, flags | SearchLocalsOnly);
    if (global.params.check10378)
    {
        Dsymbol *snew = s;
        if (sold != snew)
            Scope::deprecation10378(e->loc, sold, snew);
        if (global.params.bug10378)
            s = sold;
    }
    return s;
}

Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    Dsymbol *s;

    assert(e->op != TOKdot);

    // Bugzilla 14010
    if (ident == Id::_mangleof)
        return getProperty(e->loc, ident, flag & 1);

    /* If e.tupleof
     */
    if (ident == Id::_tupleof)
    {
        /* Create a TupleExp out of the fields of the struct e:
         * (e.field0, e.field1, e.field2, ...)
         */
        e = ::semantic(e, sc);  // do this before turning on noaccesscheck

        sym->size(e->loc);      // do semantic of type

        Expression *e0 = NULL;
        Expression *ev = e->op == TOKtype ? NULL : e;
        if (ev)
            ev = extractSideEffect(sc, "__tup", &e0, ev);

        Expressions *exps = new Expressions;
        exps->reserve(sym->fields.dim);
        for (size_t i = 0; i < sym->fields.dim; i++)
        {
            VarDeclaration *v = sym->fields[i];
            Expression *ex;
            if (ev)
                ex = new DotVarExp(e->loc, ev, v);
            else
            {
                ex = new VarExp(e->loc, v);
                ex->type = ex->type->addMod(e->type->mod);
            }
            exps->push(ex);
        }

        e = new TupleExp(e->loc, e0, exps);
        Scope *sc2 = sc->push();
        sc2->flags = sc->flags | SCOPEnoaccesscheck;
        e = ::semantic(e, sc2);
        sc2->pop();
        return e;
    }

    s = searchSymStruct(sc, sym, e, ident);
L1:
    if (!s)
    {
        return noMember(sc, e, ident, flag);
    }
    if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, s))
    {
        ::deprecation(e->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toPrettyChars());
        // return noMember(sc, e, ident, flag);
    }
    if (!s->isFuncDeclaration())        // because of overloading
        s->checkDeprecated(e->loc, sc);
    s = s->toAlias();

    EnumMember *em = s->isEnumMember();
    if (em)
    {
        return em->getVarExp(e->loc, sc);
    }

    if (VarDeclaration *v = s->isVarDeclaration())
    {
        if (!v->type ||
            (!v->type->deco && v->inuse))
        {
            if (v->inuse) // Bugzilla 9494
                e->error("circular reference to %s '%s'", v->kind(), v->toPrettyChars());
            else
                e->error("forward reference to %s '%s'", v->kind(), v->toPrettyChars());
            return new ErrorExp();
        }
        if (v->type->ty == Terror)
            return new ErrorExp();

        if ((v->storage_class & STCmanifest) && v->_init)
        {
            if (v->inuse)
            {
                e->error("circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
                return new ErrorExp();
            }
            checkAccess(e->loc, sc, NULL, v);
            Expression *ve = new VarExp(e->loc, v);
            ve = ::semantic(ve, sc);
            return ve;
        }
    }

    if (Type *t = s->getType())
    {
        return ::semantic(new TypeExp(e->loc, t), sc);
    }

    TemplateMixin *tm = s->isTemplateMixin();
    if (tm)
    {
        Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm));
        de->type = e->type;
        return de;
    }

    TemplateDeclaration *td = s->isTemplateDeclaration();
    if (td)
    {
        if (e->op == TOKtype)
            e = new TemplateExp(e->loc, td);
        else
            e = new DotTemplateExp(e->loc, e, td);
        e = ::semantic(e, sc);
        return e;
    }

    TemplateInstance *ti = s->isTemplateInstance();
    if (ti)
    {
        if (!ti->semanticRun)
        {
            ti->semantic(sc);
            if (!ti->inst || ti->errors)    // if template failed to expand
                return new ErrorExp();
        }
        s = ti->inst->toAlias();
        if (!s->isTemplateInstance())
            goto L1;
        if (e->op == TOKtype)
            e = new ScopeExp(e->loc, ti);
        else
            e = new DotExp(e->loc, e, new ScopeExp(e->loc, ti));
        return ::semantic(e, sc);
    }

    if (s->isImport() || s->isModule() || s->isPackage())
    {
        e = ::resolve(e->loc, sc, s, false);
        return e;
    }

    OverloadSet *o = s->isOverloadSet();
    if (o)
    {
        OverExp *oe = new OverExp(e->loc, o);
        if (e->op == TOKtype)
            return oe;
        return new DotExp(e->loc, e, oe);
    }

    Declaration *d = s->isDeclaration();
    if (!d)
    {
        e->error("%s.%s is not a declaration", e->toChars(), ident->toChars());
        return new ErrorExp();
    }

    if (e->op == TOKtype)
    {
        /* It's:
         *    Struct.d
         */
        if (TupleDeclaration *tup = d->isTupleDeclaration())
        {
            e = new TupleExp(e->loc, tup);
            e = ::semantic(e, sc);
            return e;
        }
        if (d->needThis() && sc->intypeof != 1)
        {
            /* Rewrite as:
             *  this.d
             */
            if (hasThis(sc))
            {
                e = new DotVarExp(e->loc, new ThisExp(e->loc), d);
                e = ::semantic(e, sc);
                return e;
            }
        }
        if (d->semanticRun == PASSinit && d->_scope)
            d->semantic(d->_scope);
        checkAccess(e->loc, sc, e, d);
        VarExp *ve = new VarExp(e->loc, d);
        if (d->isVarDeclaration() && d->needThis())
            ve->type = d->type->addMod(e->type->mod);
        return ve;
    }

    bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField();
    if (d->isDataseg() || (unreal && d->isField()))
    {
        // (e, d)
        checkAccess(e->loc, sc, e, d);
        Expression *ve = new VarExp(e->loc, d);
        e = unreal ? ve : new CommaExp(e->loc, e, ve);
        e = ::semantic(e, sc);
        return e;
    }

    e = new DotVarExp(e->loc, e, d);
    e = ::semantic(e, sc);
    return e;
}

structalign_t TypeStruct::alignment()
{
    if (sym->alignment == 0)
        sym->size(sym->loc);
    return sym->alignment;
}

Expression *TypeStruct::defaultInit(Loc)
{
    Declaration *d = new SymbolDeclaration(sym->loc, sym);
    assert(d);
    d->type = this;
    d->storage_class |= STCrvalue;      // Bugzilla 14398
    return new VarExp(sym->loc, d);
}

/***************************************
 * Use when we prefer the default initializer to be a literal,
 * rather than a global immutable variable.
 */
Expression *TypeStruct::defaultInitLiteral(Loc loc)
{
    sym->size(loc);
    if (sym->sizeok != SIZEOKdone)
        return new ErrorExp();
    Expressions *structelems = new Expressions();
    structelems->setDim(sym->fields.dim - sym->isNested());
    unsigned offset = 0;
    for (size_t j = 0; j < structelems->dim; j++)
    {
        VarDeclaration *vd = sym->fields[j];
        Expression *e;
        if (vd->inuse)
        {
            error(loc, "circular reference to '%s'", vd->toPrettyChars());
            return new ErrorExp();
        }
        if (vd->offset < offset || vd->type->size() == 0)
            e = NULL;
        else if (vd->_init)
        {
            if (vd->_init->isVoidInitializer())
                e = NULL;
            else
                e = vd->getConstInitializer(false);
        }
        else
            e = vd->type->defaultInitLiteral(loc);
        if (e && e->op == TOKerror)
            return e;
        if (e)
            offset = vd->offset + (unsigned)vd->type->size();
        (*structelems)[j] = e;
    }
    StructLiteralExp *structinit = new StructLiteralExp(loc, (StructDeclaration *)sym, structelems);

    /* Copy from the initializer symbol for larger symbols,
     * otherwise the literals expressed as code get excessively large.
     */
    if (size(loc) > Target::ptrsize * 4U && !needsNested())
        structinit->useStaticInit = true;

    structinit->type = this;
    return structinit;
}


bool TypeStruct::isZeroInit(Loc)
{
    return sym->zeroInit != 0;
}

bool TypeStruct::isBoolean()
{
    return false;
}

bool TypeStruct::needsDestruction()
{
    return sym->dtor != NULL;
}

bool TypeStruct::needsNested()
{
    if (sym->isNested())
        return true;

    for (size_t i = 0; i < sym->fields.dim; i++)
    {
        VarDeclaration *v = sym->fields[i];
        if (!v->isDataseg() && v->type->needsNested())
            return true;
    }
    return false;
}

bool TypeStruct::isAssignable()
{
    bool assignable = true;
    unsigned offset = ~0;  // dead-store initialize to prevent spurious warning

    /* If any of the fields are const or immutable,
     * then one cannot assign this struct.
     */
    for (size_t i = 0; i < sym->fields.dim; i++)
    {
        VarDeclaration *v = sym->fields[i];
        //printf("%s [%d] v = (%s) %s, v->offset = %d, v->parent = %s", sym->toChars(), i, v->kind(), v->toChars(), v->offset, v->parent->kind());
        if (i == 0)
            ;
        else if (v->offset == offset)
        {
            /* If any fields of anonymous union are assignable,
             * then regard union as assignable.
             * This is to support unsafe things like Rebindable templates.
             */
            if (assignable)
                continue;
        }
        else
        {
            if (!assignable)
                return false;
        }
        assignable = v->type->isMutable() && v->type->isAssignable();
        offset = v->offset;
        //printf(" -> assignable = %d\n", assignable);
    }

    return assignable;
}

bool TypeStruct::hasPointers()
{
    // Probably should cache this information in sym rather than recompute
    StructDeclaration *s = sym;

    sym->size(Loc());               // give error for forward references
    for (size_t i = 0; i < s->fields.dim; i++)
    {
        Declaration *d = s->fields[i];
        if (d->storage_class & STCref || d->hasPointers())
            return true;
    }
    return false;
}

bool TypeStruct::hasVoidInitPointers()
{
    // Probably should cache this information in sym rather than recompute
    StructDeclaration *s = sym;

    sym->size(Loc()); // give error for forward references
    for (size_t i = 0; i < s->fields.dim; i++)
    {
        VarDeclaration *v = s->fields[i];
        if (v->_init && v->_init->isVoidInitializer() && v->type->hasPointers())
            return true;
        if (!v->_init && v->type->hasVoidInitPointers())
            return true;
    }
    return false;
}

MATCH TypeStruct::implicitConvTo(Type *to)
{   MATCH m;

    //printf("TypeStruct::implicitConvTo(%s => %s)\n", toChars(), to->toChars());

    if (ty == to->ty && sym == ((TypeStruct *)to)->sym)
    {
        m = MATCHexact;         // exact match
        if (mod != to->mod)
        {
            m = MATCHconst;
            if (MODimplicitConv(mod, to->mod))
                ;
            else
            {
                /* Check all the fields. If they can all be converted,
                 * allow the conversion.
                 */
                unsigned offset = ~0;   // dead-store to prevent spurious warning
                for (size_t i = 0; i < sym->fields.dim; i++)
                {
                    VarDeclaration *v = sym->fields[i];
                    if (i == 0)
                        ;
                    else if (v->offset == offset)
                    {
                        if (m > MATCHnomatch)
                            continue;
                    }
                    else
                    {
                        if (m <= MATCHnomatch)
                            return m;
                    }

                    // 'from' type
                    Type *tvf = v->type->addMod(mod);

                    // 'to' type
                    Type *tv = v->type->addMod(to->mod);

                    // field match
                    MATCH mf = tvf->implicitConvTo(tv);
                    //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), mf);

                    if (mf <= MATCHnomatch)
                        return mf;
                    if (mf < m)         // if field match is worse
                        m = mf;
                    offset = v->offset;
                }
            }
        }
    }
    else if (sym->aliasthis && !(att & RECtracing))
    {
        att = (AliasThisRec)(att | RECtracing);
        m = aliasthisOf()->implicitConvTo(to);
        att = (AliasThisRec)(att & ~RECtracing);
    }
    else
        m = MATCHnomatch;       // no match
    return m;
}

MATCH TypeStruct::constConv(Type *to)
{
    if (equals(to))
        return MATCHexact;
    if (ty == to->ty && sym == ((TypeStruct *)to)->sym &&
        MODimplicitConv(mod, to->mod))
        return MATCHconst;
    return MATCHnomatch;
}

unsigned char TypeStruct::deduceWild(Type *t, bool isRef)
{
    if (ty == t->ty && sym == ((TypeStruct *)t)->sym)
        return Type::deduceWild(t, isRef);

    unsigned char wm = 0;

    if (t->hasWild() && sym->aliasthis && !(att & RECtracing))
    {
        att = (AliasThisRec)(att | RECtracing);
        wm = aliasthisOf()->deduceWild(t, isRef);
        att = (AliasThisRec)(att & ~RECtracing);
    }

    return wm;
}

Type *TypeStruct::toHeadMutable()
{
    return this;
}


/***************************** TypeClass *****************************/

TypeClass::TypeClass(ClassDeclaration *sym)
        : Type(Tclass)
{
    this->sym = sym;
    this->att = RECfwdref;
    this->cppmangle = CPPMANGLEdefault;
}

const char *TypeClass::kind()
{
    return "class";
}

Type *TypeClass::syntaxCopy()
{
    return this;
}

Type *TypeClass::semantic(Loc, Scope *sc)
{
    //printf("TypeClass::semantic(%s)\n", sym->toChars());
    if (deco)
    {
        if (sc && sc->cppmangle != CPPMANGLEdefault)
        {
            if (this->cppmangle == CPPMANGLEdefault)
                this->cppmangle = sc->cppmangle;
            else
                assert(this->cppmangle == sc->cppmangle);
        }
        return this;
    }

    /* Don't semantic for sym because it should be deferred until
     * sizeof needed or its members accessed.
     */
    // instead, parent should be set correctly
    assert(sym->parent);

    if (sym->type->ty == Terror)
        return Type::terror;
    if (sc)
        this->cppmangle = sc->cppmangle;
    return merge();
}

d_uns64 TypeClass::size(Loc)
{
    return Target::ptrsize;
}

Dsymbol *TypeClass::toDsymbol(Scope *)
{
    return sym;
}

static Dsymbol *searchSymClass(Scope *sc, Dsymbol *sym, Expression *e, Identifier *ident)
{
    int flags = sc->flags & SCOPEignoresymbolvisibility ? IgnoreSymbolVisibility : 0;
    Dsymbol *sold = NULL;
    if (global.params.bug10378 || global.params.check10378)
    {
        sold = sym->search(e->loc, ident, flags | IgnoreSymbolVisibility);
        if (!global.params.check10378)
            return sold;
    }

    Dsymbol *s = sym->search(e->loc, ident, flags | SearchLocalsOnly);
    if (!s && !(flags & IgnoreSymbolVisibility))
    {
        s = sym->search(e->loc, ident, flags | SearchLocalsOnly | IgnoreSymbolVisibility);
        if (s && !(flags & IgnoreErrors))
            ::deprecation(e->loc, "%s is not visible from class %s", s->toPrettyChars(), sym->toChars());
    }
    if (global.params.check10378)
    {
        Dsymbol *snew = s;
        if (sold != snew)
            Scope::deprecation10378(e->loc, sold, snew);
        if (global.params.bug10378)
            s = sold;
    }
    return s;
}

Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
{
    Dsymbol *s;
    assert(e->op != TOKdot);

    // Bugzilla 12543
    if (ident == Id::__sizeof || ident == Id::__xalignof || ident == Id::_mangleof)
    {
        return Type::getProperty(e->loc, ident, 0);
    }

    /* If e.tupleof
     */
    if (ident == Id::_tupleof)
    {
        /* Create a TupleExp
         */
        e = ::semantic(e, sc);  // do this before turning on noaccesscheck

        sym->size(e->loc); // do semantic of type

        Expression *e0 = NULL;
        Expression *ev = e->op == TOKtype ? NULL : e;
        if (ev)
            ev = extractSideEffect(sc, "__tup", &e0, ev);

        Expressions *exps = new Expressions;
        exps->reserve(sym->fields.dim);
        for (size_t i = 0; i < sym->fields.dim; i++)
        {
            VarDeclaration *v = sym->fields[i];
            // Don't include hidden 'this' pointer
            if (v->isThisDeclaration())
                continue;
            Expression *ex;
            if (ev)
                ex = new DotVarExp(e->loc, ev, v);
            else
            {
                ex = new VarExp(e->loc, v);
                ex->type = ex->type->addMod(e->type->mod);
            }
            exps->push(ex);
        }

        e = new TupleExp(e->loc, e0, exps);
        Scope *sc2 = sc->push();
        sc2->flags = sc->flags | SCOPEnoaccesscheck;
        e = ::semantic(e, sc2);
        sc2->pop();
        return e;
    }

    s = searchSymClass(sc, sym, e, ident);
L1:
    if (!s)
    {
        // See if it's 'this' class or a base class
        if (sym->ident == ident)
        {
            if (e->op == TOKtype)
                return Type::getProperty(e->loc, ident, 0);
            e = new DotTypeExp(e->loc, e, sym);
            e = ::semantic(e, sc);
            return e;
        }
        if (ClassDeclaration *cbase = sym->searchBase(ident))
        {
            if (e->op == TOKtype)
                return Type::getProperty(e->loc, ident, 0);
            if (InterfaceDeclaration *ifbase = cbase->isInterfaceDeclaration())
                e = new CastExp(e->loc, e, ifbase->type);
            else
                e = new DotTypeExp(e->loc, e, cbase);
            e = ::semantic(e, sc);
            return e;
        }

        if (ident == Id::classinfo)
        {
            if (!Type::typeinfoclass)
            {
                error(e->loc, "`object.TypeInfo_Class` could not be found, but is implicitly used");
                return new ErrorExp();
            }

            Type *t = Type::typeinfoclass->type;
            if (e->op == TOKtype || e->op == TOKdottype)
            {
                /* For type.classinfo, we know the classinfo
                 * at compile time.
                 */
                if (!sym->vclassinfo)
                    sym->vclassinfo = new TypeInfoClassDeclaration(sym->type);
                e = new VarExp(e->loc, sym->vclassinfo);
                e = e->addressOf();
                e->type = t;    // do this so we don't get redundant dereference
            }
            else
            {
                /* For class objects, the classinfo reference is the first
                 * entry in the vtbl[]
                 */
                e = new PtrExp(e->loc, e);
                e->type = t->pointerTo();
                if (sym->isInterfaceDeclaration())
                {
                    if (sym->isCPPinterface())
                    {
                        /* C++ interface vtbl[]s are different in that the
                         * first entry is always pointer to the first virtual
                         * function, not classinfo.
                         * We can't get a .classinfo for it.
                         */
                        error(e->loc, "no .classinfo for C++ interface objects");
                    }
                    /* For an interface, the first entry in the vtbl[]
                     * is actually a pointer to an instance of struct Interface.
                     * The first member of Interface is the .classinfo,
                     * so add an extra pointer indirection.
                     */
                    e->type = e->type->pointerTo();
                    e = new PtrExp(e->loc, e);
                    e->type = t->pointerTo();
                }
                e = new PtrExp(e->loc, e, t);
            }
            return e;
        }

        if (ident == Id::__vptr)
        {
            /* The pointer to the vtbl[]
             * *cast(immutable(void*)**)e
             */
            e = e->castTo(sc, tvoidptr->immutableOf()->pointerTo()->pointerTo());
            e = new PtrExp(e->loc, e);
            e = ::semantic(e, sc);
            return e;
        }

        if (ident == Id::__monitor)
        {
            /* The handle to the monitor (call it a void*)
             * *(cast(void**)e + 1)
             */
            e = e->castTo(sc, tvoidptr->pointerTo());
            e = new AddExp(e->loc, e, new IntegerExp(1));
            e = new PtrExp(e->loc, e);
            e = ::semantic(e, sc);
            return e;
        }

        if (ident == Id::outer && sym->vthis)
        {
            if (sym->vthis->_scope)
                sym->vthis->semantic(NULL);

            if (ClassDeclaration *cdp = sym->toParent2()->isClassDeclaration())
            {
                DotVarExp *dve = new DotVarExp(e->loc, e, sym->vthis);
                dve->type = cdp->type->addMod(e->type->mod);
                return dve;
            }

            /* Bugzilla 15839: Find closest parent class through nested functions.
             */
            for (Dsymbol *p = sym->toParent2(); p; p = p->toParent2())
            {
                FuncDeclaration *fd = p->isFuncDeclaration();
                if (!fd)
                    break;
                if (fd->isNested())
                    continue;
                AggregateDeclaration *ad = fd->isThis();
                if (!ad)
                    break;
                if (ad->isClassDeclaration())
                {
                    ThisExp *ve = new ThisExp(e->loc);

                    ve->var = fd->vthis;
                    const bool nestedError = fd->vthis->checkNestedReference(sc, e->loc);
                    assert(!nestedError);

                    ve->type = fd->vthis->type->addMod(e->type->mod);
                    return ve;
                }
                break;
            }

            // Continue to show enclosing function's frame (stack or closure).
            DotVarExp *dve = new DotVarExp(e->loc, e, sym->vthis);
            dve->type = sym->vthis->type->addMod(e->type->mod);
            return dve;
        }

        return noMember(sc, e, ident, flag & 1);
    }
    if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, s))
    {
        ::deprecation(e->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toPrettyChars());
        // return noMember(sc, e, ident, flag);
    }
    if (!s->isFuncDeclaration())        // because of overloading
        s->checkDeprecated(e->loc, sc);
    s = s->toAlias();

    EnumMember *em = s->isEnumMember();
    if (em)
    {
        return em->getVarExp(e->loc, sc);
    }

    if (VarDeclaration *v = s->isVarDeclaration())
    {
        if (!v->type ||
            (!v->type->deco && v->inuse))
        {
            if (v->inuse) // Bugzilla 9494
                e->error("circular reference to %s '%s'", v->kind(), v->toPrettyChars());
            else
                e->error("forward reference to %s '%s'", v->kind(), v->toPrettyChars());
            return new ErrorExp();
        }
        if (v->type->ty == Terror)
            return new ErrorExp();

        if ((v->storage_class & STCmanifest) && v->_init)
        {
            if (v->inuse)
            {
                e->error("circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
                return new ErrorExp();
            }
            checkAccess(e->loc, sc, NULL, v);
            Expression *ve = new VarExp(e->loc, v);
            ve = ::semantic(ve, sc);
            return ve;
        }
    }

    if (Type *t = s->getType())
    {
        return ::semantic(new TypeExp(e->loc, t), sc);
    }

    TemplateMixin *tm = s->isTemplateMixin();
    if (tm)
    {
        Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm));
        de->type = e->type;
        return de;
    }

    TemplateDeclaration *td = s->isTemplateDeclaration();
    if (td)
    {
        if (e->op == TOKtype)
            e = new TemplateExp(e->loc, td);
        else
            e = new DotTemplateExp(e->loc, e, td);
        e = ::semantic(e, sc);
        return e;
    }

    TemplateInstance *ti = s->isTemplateInstance();
    if (ti)
    {
        if (!ti->semanticRun)
        {
            ti->semantic(sc);
            if (!ti->inst || ti->errors)    // if template failed to expand
                return new ErrorExp();
        }
        s = ti->inst->toAlias();
        if (!s->isTemplateInstance())
            goto L1;
        if (e->op == TOKtype)
            e = new ScopeExp(e->loc, ti);
        else
            e = new DotExp(e->loc, e, new ScopeExp(e->loc, ti));
        return ::semantic(e, sc);
    }

    if (s->isImport() || s->isModule() || s->isPackage())
    {
        e = ::resolve(e->loc, sc, s, false);
        return e;
    }

    OverloadSet *o = s->isOverloadSet();
    if (o)
    {
        OverExp *oe = new OverExp(e->loc, o);
        if (e->op == TOKtype)
            return oe;
        return new DotExp(e->loc, e, oe);
    }

    Declaration *d = s->isDeclaration();
    if (!d)
    {
        e->error("%s.%s is not a declaration", e->toChars(), ident->toChars());
        return new ErrorExp();
    }

    if (e->op == TOKtype)
    {
        /* It's:
         *    Class.d
         */
        if (TupleDeclaration *tup = d->isTupleDeclaration())
        {
            e = new TupleExp(e->loc, tup);
            e = ::semantic(e, sc);
            return e;
        }
        if (d->needThis() && sc->intypeof != 1)
        {
            /* Rewrite as:
             *  this.d
             */
            if (hasThis(sc))
            {
                // This is almost same as getRightThis() in expression.c
                Expression *e1 = new ThisExp(e->loc);
                e1 = ::semantic(e1, sc);
            L2:
                Type *t = e1->type->toBasetype();
                ClassDeclaration *cd = e->type->isClassHandle();
                ClassDeclaration *tcd = t->isClassHandle();
                if (cd && tcd && (tcd == cd || cd->isBaseOf(tcd, NULL)))
                {
                    e = new DotTypeExp(e1->loc, e1, cd);
                    e = new DotVarExp(e->loc, e, d);
                    e = ::semantic(e, sc);
                    return e;
                }
                if (tcd && tcd->isNested())
                {   /* e1 is the 'this' pointer for an inner class: tcd.
                     * Rewrite it as the 'this' pointer for the outer class.
                     */

                    e1 = new DotVarExp(e->loc, e1, tcd->vthis);
                    e1->type = tcd->vthis->type;
                    e1->type = e1->type->addMod(t->mod);
                    // Do not call checkNestedRef()
                    //e1 = ::semantic(e1, sc);

                    // Skip up over nested functions, and get the enclosing
                    // class type.
                    int n = 0;
                    for (s = tcd->toParent();
                         s && s->isFuncDeclaration();
                         s = s->toParent())
                    {   FuncDeclaration *f = s->isFuncDeclaration();
                        if (f->vthis)
                        {
                            //printf("rewriting e1 to %s's this\n", f->toChars());
                            n++;
                            e1 = new VarExp(e->loc, f->vthis);
                        }
                        else
                        {
                            e = new VarExp(e->loc, d);
                            return e;
                        }
                    }
                    if (s && s->isClassDeclaration())
                    {   e1->type = s->isClassDeclaration()->type;
                        e1->type = e1->type->addMod(t->mod);
                        if (n > 1)
                            e1 = ::semantic(e1, sc);
                    }
                    else
                        e1 = ::semantic(e1, sc);
                    goto L2;
                }
            }
        }
        //printf("e = %s, d = %s\n", e->toChars(), d->toChars());
        if (d->semanticRun == PASSinit && d->_scope)
            d->semantic(d->_scope);
        checkAccess(e->loc, sc, e, d);
        VarExp *ve = new VarExp(e->loc, d);
        if (d->isVarDeclaration() && d->needThis())
            ve->type = d->type->addMod(e->type->mod);
        return ve;
    }

    bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField();
    if (d->isDataseg() || (unreal && d->isField()))
    {
        // (e, d)
        checkAccess(e->loc, sc, e, d);
        Expression *ve = new VarExp(e->loc, d);
        e = unreal ? ve : new CommaExp(e->loc, e, ve);
        e = ::semantic(e, sc);
        return e;
    }

    e = new DotVarExp(e->loc, e, d);
    e = ::semantic(e, sc);
    return e;
}

ClassDeclaration *TypeClass::isClassHandle()
{
    return sym;
}

bool TypeClass::isscope()
{
    return sym->isscope;
}

bool TypeClass::isBaseOf(Type *t, int *poffset)
{
    if (t && t->ty == Tclass)
    {
        ClassDeclaration *cd = ((TypeClass *)t)->sym;
        if (sym->isBaseOf(cd, poffset))
            return true;
    }
    return false;
}

MATCH TypeClass::implicitConvTo(Type *to)
{
    //printf("TypeClass::implicitConvTo(to = '%s') %s\n", to->toChars(), toChars());
    MATCH m = constConv(to);
    if (m > MATCHnomatch)
        return m;

    ClassDeclaration *cdto = to->isClassHandle();
    if (cdto)
    {
        //printf("TypeClass::implicitConvTo(to = '%s') %s, isbase = %d %d\n", to->toChars(), toChars(), cdto->isBaseInfoComplete(), sym->isBaseInfoComplete());
        if (cdto->_scope && !cdto->isBaseInfoComplete())
            cdto->semantic(NULL);
        if (sym->_scope && !sym->isBaseInfoComplete())
            sym->semantic(NULL);
        if (cdto->isBaseOf(sym, NULL) && MODimplicitConv(mod, to->mod))
        {
            //printf("'to' is base\n");
            return MATCHconvert;
        }
    }

    m = MATCHnomatch;
    if (sym->aliasthis && !(att & RECtracing))
    {
        att = (AliasThisRec)(att | RECtracing);
        m = aliasthisOf()->implicitConvTo(to);
        att = (AliasThisRec)(att & ~RECtracing);
    }

    return m;
}

MATCH TypeClass::constConv(Type *to)
{
    if (equals(to))
        return MATCHexact;
    if (ty == to->ty && sym == ((TypeClass *)to)->sym &&
        MODimplicitConv(mod, to->mod))
        return MATCHconst;

    /* Conversion derived to const(base)
     */
    int offset = 0;
    if (to->isBaseOf(this, &offset) && offset == 0 &&
        MODimplicitConv(mod, to->mod))
    {
        // Disallow:
        //  derived to base
        //  inout(derived) to inout(base)
        if (!to->isMutable() && !to->isWild())
            return MATCHconvert;
    }

    return MATCHnomatch;
}

unsigned char TypeClass::deduceWild(Type *t, bool isRef)
{
    ClassDeclaration *cd = t->isClassHandle();
    if (cd && (sym == cd || cd->isBaseOf(sym, NULL)))
        return Type::deduceWild(t, isRef);

    unsigned char wm = 0;

    if (t->hasWild() && sym->aliasthis && !(att & RECtracing))
    {
        att = (AliasThisRec)(att | RECtracing);
        wm = aliasthisOf()->deduceWild(t, isRef);
        att = (AliasThisRec)(att & ~RECtracing);
    }

    return wm;
}

Type *TypeClass::toHeadMutable()
{
    return this;
}

Expression *TypeClass::defaultInit(Loc loc)
{
    return new NullExp(loc, this);
}

bool TypeClass::isZeroInit(Loc)
{
    return true;
}

bool TypeClass::isBoolean()
{
    return true;
}

bool TypeClass::hasPointers()
{
    return true;
}

/***************************** TypeTuple *****************************/

TypeTuple::TypeTuple(Parameters *arguments)
    : Type(Ttuple)
{
    //printf("TypeTuple(this = %p)\n", this);
    this->arguments = arguments;
    //printf("TypeTuple() %p, %s\n", this, toChars());
}

/****************
 * Form TypeTuple from the types of the expressions.
 * Assume exps[] is already tuple expanded.
 */

TypeTuple::TypeTuple(Expressions *exps)
    : Type(Ttuple)
{
    Parameters *arguments = new Parameters;
    if (exps)
    {
        arguments->setDim(exps->dim);
        for (size_t i = 0; i < exps->dim; i++)
        {   Expression *e = (*exps)[i];
            if (e->type->ty == Ttuple)
                e->error("cannot form tuple of tuples");
            Parameter *arg = new Parameter(STCundefined, e->type, NULL, NULL);
            (*arguments)[i] = arg;
        }
    }
    this->arguments = arguments;
    //printf("TypeTuple() %p, %s\n", this, toChars());
}

TypeTuple *TypeTuple::create(Parameters *arguments)
{
    return new TypeTuple(arguments);
}

/*******************************************
 * Type tuple with 0, 1 or 2 types in it.
 */
TypeTuple::TypeTuple()
    : Type(Ttuple)
{
    arguments = new Parameters();
}

TypeTuple::TypeTuple(Type *t1)
    : Type(Ttuple)
{
    arguments = new Parameters();
    arguments->push(new Parameter(0, t1, NULL, NULL));
}

TypeTuple::TypeTuple(Type *t1, Type *t2)
    : Type(Ttuple)
{
    arguments = new Parameters();
    arguments->push(new Parameter(0, t1, NULL, NULL));
    arguments->push(new Parameter(0, t2, NULL, NULL));
}

const char *TypeTuple::kind()
{
    return "tuple";
}

Type *TypeTuple::syntaxCopy()
{
    Parameters *args = Parameter::arraySyntaxCopy(arguments);
    Type *t = new TypeTuple(args);
    t->mod = mod;
    return t;
}

Type *TypeTuple::semantic(Loc, Scope *)
{
    //printf("TypeTuple::semantic(this = %p)\n", this);
    //printf("TypeTuple::semantic() %p, %s\n", this, toChars());
    if (!deco)
        deco = merge()->deco;

    /* Don't return merge(), because a tuple with one type has the
     * same deco as that type.
     */
    return this;
}

bool TypeTuple::equals(RootObject *o)
{
    Type *t = (Type *)o;
    //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars());
    if (this == t)
        return true;
    if (t->ty == Ttuple)
    {
        TypeTuple *tt = (TypeTuple *)t;
        if (arguments->dim == tt->arguments->dim)
        {
            for (size_t i = 0; i < tt->arguments->dim; i++)
            {
                Parameter *arg1 = (*arguments)[i];
                Parameter *arg2 = (*tt->arguments)[i];
                if (!arg1->type->equals(arg2->type))
                    return false;
            }
            return true;
        }
    }
    return false;
}

Expression *TypeTuple::getProperty(Loc loc, Identifier *ident, int flag)
{
    Expression *e;

    if (ident == Id::length)
    {
        e = new IntegerExp(loc, arguments->dim, Type::tsize_t);
    }
    else if (ident == Id::_init)
    {
        e = defaultInitLiteral(loc);
    }
    else if (flag)
    {
        e = NULL;
    }
    else
    {
        error(loc, "no property '%s' for tuple '%s'", ident->toChars(), toChars());
        e = new ErrorExp();
    }
    return e;
}

Expression *TypeTuple::defaultInit(Loc loc)
{
    Expressions *exps = new Expressions();
    exps->setDim(arguments->dim);
    for (size_t i = 0; i < arguments->dim; i++)
    {
        Parameter *p = (*arguments)[i];
        assert(p->type);
        Expression *e = p->type->defaultInitLiteral(loc);
        if (e->op == TOKerror)
            return e;
        (*exps)[i] = e;
    }
    return new TupleExp(loc, exps);
}

/***************************** TypeSlice *****************************/

/* This is so we can slice a TypeTuple */

TypeSlice::TypeSlice(Type *next, Expression *lwr, Expression *upr)
    : TypeNext(Tslice, next)
{
    //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars());
    this->lwr = lwr;
    this->upr = upr;
}

const char *TypeSlice::kind()
{
    return "slice";
}

Type *TypeSlice::syntaxCopy()
{
    Type *t = new TypeSlice(next->syntaxCopy(), lwr->syntaxCopy(), upr->syntaxCopy());
    t->mod = mod;
    return t;
}

Type *TypeSlice::semantic(Loc loc, Scope *sc)
{
    //printf("TypeSlice::semantic() %s\n", toChars());
    Type *tn = next->semantic(loc, sc);
    //printf("next: %s\n", tn->toChars());

    Type *tbn = tn->toBasetype();
    if (tbn->ty != Ttuple)
    {
        error(loc, "can only slice tuple types, not %s", tbn->toChars());
        return Type::terror;
    }
    TypeTuple *tt = (TypeTuple *)tbn;

    lwr = semanticLength(sc, tbn, lwr);
    lwr = lwr->ctfeInterpret();
    uinteger_t i1 = lwr->toUInteger();

    upr = semanticLength(sc, tbn, upr);
    upr = upr->ctfeInterpret();
    uinteger_t i2 = upr->toUInteger();

    if (!(i1 <= i2 && i2 <= tt->arguments->dim))
    {
        error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, tt->arguments->dim);
        return Type::terror;
    }

    next = tn;
    transitive();

    Parameters *args = new Parameters;
    args->reserve((size_t)(i2 - i1));
    for (size_t i = (size_t)i1; i < (size_t)i2; i++)
    {
        Parameter *arg = (*tt->arguments)[i];
        args->push(arg);
    }
    Type *t = new TypeTuple(args);
    return t->semantic(loc, sc);
}

void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
{
    next->resolve(loc, sc, pe, pt, ps, intypeid);
    if (*pe)
    {
        // It's really a slice expression
        if (Dsymbol *s = getDsymbol(*pe))
            *pe = new DsymbolExp(loc, s);
        *pe = new ArrayExp(loc, *pe, new IntervalExp(loc, lwr, upr));
    }
    else if (*ps)
    {
        Dsymbol *s = *ps;
        TupleDeclaration *td = s->isTupleDeclaration();
        if (td)
        {
            /* It's a slice of a TupleDeclaration
             */
            ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td);
            sym->parent = sc->scopesym;
            sc = sc->push(sym);
            sc = sc->startCTFE();
            lwr = ::semantic(lwr, sc);
            upr = ::semantic(upr, sc);
            sc = sc->endCTFE();
            sc = sc->pop();

            lwr = lwr->ctfeInterpret();
            upr = upr->ctfeInterpret();
            uinteger_t i1 = lwr->toUInteger();
            uinteger_t i2 = upr->toUInteger();

            if (!(i1 <= i2 && i2 <= td->objects->dim))
            {
                error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim);
                *ps = NULL;
                *pt = Type::terror;
                return;
            }

            if (i1 == 0 && i2 == td->objects->dim)
            {
                *ps = td;
                return;
            }

            /* Create a new TupleDeclaration which
             * is a slice [i1..i2] out of the old one.
             */
            Objects *objects = new Objects;
            objects->setDim((size_t)(i2 - i1));
            for (size_t i = 0; i < objects->dim; i++)
            {
                (*objects)[i] = (*td->objects)[(size_t)i1 + i];
            }

            TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects);
            *ps = tds;
        }
        else
            goto Ldefault;
    }
    else
    {
        if ((*pt)->ty != Terror)
            next = *pt;     // prevent re-running semantic() on 'next'
     Ldefault:
        Type::resolve(loc, sc, pe, pt, ps, intypeid);
    }
}

/***************************** TypeNull *****************************/

TypeNull::TypeNull()
        : Type(Tnull)
{
}

const char *TypeNull::kind()
{
    return "null";
}

Type *TypeNull::syntaxCopy()
{
    // No semantic analysis done, no need to copy
    return this;
}

MATCH TypeNull::implicitConvTo(Type *to)
{
    //printf("TypeNull::implicitConvTo(this=%p, to=%p)\n", this, to);
    //printf("from: %s\n", toChars());
    //printf("to  : %s\n", to->toChars());
    MATCH m = Type::implicitConvTo(to);
    if (m != MATCHnomatch)
        return m;

    // NULL implicitly converts to any pointer type or dynamic array
    //if (type->ty == Tpointer && type->nextOf()->ty == Tvoid)
    {
        Type *tb = to->toBasetype();
        if (tb->ty == Tnull ||
            tb->ty == Tpointer || tb->ty == Tarray ||
            tb->ty == Taarray  || tb->ty == Tclass ||
            tb->ty == Tdelegate)
            return MATCHconst;
    }

    return MATCHnomatch;
}

bool TypeNull::isBoolean()
{
    return true;
}

d_uns64 TypeNull::size(Loc loc)
{
    return tvoidptr->size(loc);
}

Expression *TypeNull::defaultInit(Loc)
{
    return new NullExp(Loc(), Type::tnull);
}

/***************************** Parameter *****************************/

Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
{
    this->type = type;
    this->ident = ident;
    this->storageClass = storageClass;
    this->defaultArg = defaultArg;
}

Parameter *Parameter::create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
{
    return new Parameter(storageClass, type, ident, defaultArg);
}

Parameter *Parameter::syntaxCopy()
{
    return new Parameter(storageClass,
        type ? type->syntaxCopy() : NULL,
        ident,
        defaultArg ? defaultArg->syntaxCopy() : NULL);
}

Parameters *Parameter::arraySyntaxCopy(Parameters *parameters)
{
    Parameters *params = NULL;
    if (parameters)
    {
        params = new Parameters();
        params->setDim(parameters->dim);
        for (size_t i = 0; i < params->dim; i++)
            (*params)[i] = (*parameters)[i]->syntaxCopy();
    }
    return params;
}

/****************************************************
 * Determine if parameter is a lazy array of delegates.
 * If so, return the return type of those delegates.
 * If not, return NULL.
 *
 * Returns T if the type is one of the following forms:
 *      T delegate()[]
 *      T delegate()[dim]
 */

Type *Parameter::isLazyArray()
{
    Type *tb = type->toBasetype();
    if (tb->ty == Tsarray || tb->ty == Tarray)
    {
        Type *tel = ((TypeArray *)tb)->next->toBasetype();
        if (tel->ty == Tdelegate)
        {
            TypeDelegate *td = (TypeDelegate *)tel;
            TypeFunction *tf = td->next->toTypeFunction();

            if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
            {
                return tf->next;    // return type of delegate
            }
        }
    }
    return NULL;
}

/***************************************
 * Determine number of arguments, folding in tuples.
 */

static int dimDg(void *ctx, size_t, Parameter *)
{
    ++*(size_t *)ctx;
    return 0;
}

size_t Parameter::dim(Parameters *parameters)
{
    size_t n = 0;
    Parameter_foreach(parameters, &dimDg, &n);
    return n;
}

/***************************************
 * Get nth Parameter, folding in tuples.
 * Returns:
 *      Parameter*      nth Parameter
 *      NULL            not found, *pn gets incremented by the number
 *                      of Parameters
 */

struct GetNthParamCtx
{
    size_t nth;
    Parameter *param;
};

static int getNthParamDg(void *ctx, size_t n, Parameter *p)
{
    GetNthParamCtx *c = (GetNthParamCtx *)ctx;
    if (n == c->nth)
    {
        c->param = p;
        return 1;
    }
    return 0;
}

Parameter *Parameter::getNth(Parameters *parameters, size_t nth, size_t *)
{
    GetNthParamCtx ctx = { nth, NULL };
    int res = Parameter_foreach(parameters, &getNthParamDg, &ctx);
    return res ? ctx.param : NULL;
}

/***************************************
 * Expands tuples in args in depth first order. Calls
 * dg(void *ctx, size_t argidx, Parameter *arg) for each Parameter.
 * If dg returns !=0, stops and returns that value else returns 0.
 * Use this function to avoid the O(N + N^2/2) complexity of
 * calculating dim and calling N times getNth.
 */

int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn)
{
    assert(dg);
    if (!parameters)
        return 0;

    size_t n = pn ? *pn : 0; // take over index
    int result = 0;
    for (size_t i = 0; i < parameters->dim; i++)
    {
        Parameter *p = (*parameters)[i];
        Type *t = p->type->toBasetype();

        if (t->ty == Ttuple)
        {
            TypeTuple *tu = (TypeTuple *)t;
            result = Parameter_foreach(tu->arguments, dg, ctx, &n);
        }
        else
            result = dg(ctx, n++, p);

        if (result)
            break;
    }

    if (pn)
        *pn = n; // update index
    return result;
}


const char *Parameter::toChars()
{
    return ident ? ident->toChars() : "__anonymous_param";
}

/*********************************
 * Compute covariance of parameters `this` and `p`
 * as determined by the storage classes of both.
 * Params:
 *  p = Parameter to compare with
 * Returns:
 *  true = `this` can be used in place of `p`
 *  false = nope
 */
bool Parameter::isCovariant(bool returnByRef, const Parameter *p) const
{
    const StorageClass stc = STCref | STCin | STCout | STClazy;
    if ((this->storageClass & stc) != (p->storageClass & stc))
        return false;

    return isCovariantScope(returnByRef, this->storageClass, p->storageClass);
}

bool Parameter::isCovariantScope(bool returnByRef, StorageClass from, StorageClass to)
{
    if (from == to)
        return true;

    struct SR
    {
        /* Classification of 'scope-return-ref' possibilities
        */
        enum
        {
            SRNone,
            SRScope,
            SRReturnScope,
            SRRef,
            SRReturnRef,
            SRRefScope,
            SRReturnRef_Scope,
            SRRef_ReturnScope,
            SRMAX,
        };

        /* Shrinking the representation is necessary because StorageClass is so wide
         * Params:
         *   returnByRef = true if the function returns by ref
         *   stc = storage class of parameter
         */
        static unsigned buildSR(bool returnByRef, StorageClass stc)
        {
            unsigned result;
            StorageClass stc2 = stc & (STCref | STCscope | STCreturn);
            if (stc2 == 0)
                result = SRNone;
            else if (stc2 == STCref)
                result = SRRef;
            else if (stc2 == STCscope)
                result = SRScope;
            else if (stc2 == (STCscope | STCreturn))
                result = SRReturnScope;
            else if (stc2 == (STCref | STCreturn))
                result = SRReturnRef;
            else if (stc2 == (STCscope | STCref))
                result = SRRefScope;
            else if (stc2 == (STCscope | STCref | STCreturn))
                result = returnByRef ? SRReturnRef_Scope : SRRef_ReturnScope;
            else
                assert(0);
            return result;
        }

        static void covariantInit(bool covariant[SRMAX][SRMAX])
        {
            /* Initialize covariant[][] with this:

                 From\To           n   rs  s
                 None              X
                 ReturnScope       X   X
                 Scope             X   X   X

                 From\To           r   rr  rs  rr-s r-rs
                 Ref               X   X
                 ReturnRef             X
                 RefScope          X   X   X   X    X
                 ReturnRef-Scope       X       X
                 Ref-ReturnScope   X   X            X
            */
            for (int i = 0; i < SRMAX; i++)
            {
                covariant[i][i] = true;
                covariant[SRRefScope][i] = true;
            }
            covariant[SRReturnScope][SRNone]        = true;
            covariant[SRScope      ][SRNone]        = true;
            covariant[SRScope      ][SRReturnScope] = true;

            covariant[SRRef            ][SRReturnRef] = true;
            covariant[SRReturnRef_Scope][SRReturnRef] = true;
            covariant[SRRef_ReturnScope][SRRef      ] = true;
            covariant[SRRef_ReturnScope][SRReturnRef] = true;
        }
    };

    /* result is true if the 'from' can be used as a 'to'
     */

    if ((from ^ to) & STCref)               // differing in 'ref' means no covariance
        return false;

    static bool covariant[SR::SRMAX][SR::SRMAX];
    static bool init = false;
    if (!init)
    {
        SR::covariantInit(covariant);
        init = true;
    }

    return covariant[SR::buildSR(returnByRef, from)][SR::buildSR(returnByRef, to)];
}
