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

#include "root/dsystem.h"

#include "mars.h"
#include "init.h"
#include "declaration.h"
#include "attrib.h"
#include "expression.h"
#include "scope.h"
#include "mtype.h"
#include "aggregate.h"
#include "identifier.h"
#include "id.h"
#include "module.h"
#include "statement.h"
#include "template.h"
#include "hdrgen.h"
#include "target.h"
#include "parse.h"
#include "root/rmem.h"
#include "visitor.h"
#include "objc.h"

Expression *addInvariant(Loc loc, Scope *sc, AggregateDeclaration *ad, VarDeclaration *vthis, bool direct);
bool checkReturnEscape(Scope *sc, Expression *e, bool gag);
bool checkReturnEscapeRef(Scope *sc, Expression *e, bool gag);
bool checkNestedRef(Dsymbol *s, Dsymbol *p);
Statement *semantic(Statement *s, Scope *sc);
void semantic(Catch *c, Scope *sc);
Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
Expression *semantic(Expression *e, Scope *sc);
int blockExit(Statement *s, FuncDeclaration *func, bool mustNotThrow);
TypeIdentifier *getThrowable();

RET retStyle(TypeFunction *tf);
void MODtoBuffer(OutBuffer *buf, MOD mod);
char *MODtoChars(MOD mod);
bool MODimplicitConv(MOD modfrom, MOD modto);
MATCH MODmethodConv(MOD modfrom, MOD modto);
void allocFieldinit(Scope *sc, size_t dim);
void freeFieldinit(Scope *sc);
Objc *objc();


/* A visitor to walk entire statements and provides ability to replace any sub-statements.
 */
class StatementRewriteWalker : public Visitor
{
    /* Point the currently visited statement.
     * By using replaceCurrent() method, you can replace AST during walking.
     */
    Statement **ps;
public:
    void visitStmt(Statement *&s) { ps = &s; s->accept(this); }
    void replaceCurrent(Statement *s) { *ps = s; }

    void visit(ErrorStatement *) {  }
    void visit(PeelStatement *s)
    {
        if (s->s)
            visitStmt(s->s);
    }
    void visit(ExpStatement *) {  }
    void visit(DtorExpStatement *) {  }
    void visit(CompileStatement *) {  }
    void visit(CompoundStatement *s)
    {
        if (s->statements && s->statements->dim)
        {
            for (size_t i = 0; i < s->statements->dim; i++)
            {
                if ((*s->statements)[i])
                    visitStmt((*s->statements)[i]);
            }
        }
    }
    void visit(CompoundDeclarationStatement *s) { visit((CompoundStatement *)s); }
    void visit(UnrolledLoopStatement *s)
    {
        if (s->statements && s->statements->dim)
        {
            for (size_t i = 0; i < s->statements->dim; i++)
            {
                if ((*s->statements)[i])
                    visitStmt((*s->statements)[i]);
            }
        }
    }
    void visit(ScopeStatement *s)
    {
        if (s->statement)
            visitStmt(s->statement);
    }
    void visit(WhileStatement *s)
    {
        if (s->_body)
            visitStmt(s->_body);
    }
    void visit(DoStatement *s)
    {
        if (s->_body)
            visitStmt(s->_body);
    }
    void visit(ForStatement *s)
    {
        if (s->_init)
            visitStmt(s->_init);
        if (s->_body)
            visitStmt(s->_body);
    }
    void visit(ForeachStatement *s)
    {
        if (s->_body)
            visitStmt(s->_body);
    }
    void visit(ForeachRangeStatement *s)
    {
        if (s->_body)
            visitStmt(s->_body);
    }
    void visit(IfStatement *s)
    {
        if (s->ifbody)
            visitStmt(s->ifbody);
        if (s->elsebody)
            visitStmt(s->elsebody);
    }
    void visit(ConditionalStatement *) {  }
    void visit(PragmaStatement *) {  }
    void visit(StaticAssertStatement *) {  }
    void visit(SwitchStatement *s)
    {
        if (s->_body)
            visitStmt(s->_body);
    }
    void visit(CaseStatement *s)
    {
        if (s->statement)
            visitStmt(s->statement);
    }
    void visit(CaseRangeStatement *s)
    {
        if (s->statement)
            visitStmt(s->statement);
    }
    void visit(DefaultStatement *s)
    {
        if (s->statement)
            visitStmt(s->statement);
    }
    void visit(GotoDefaultStatement *) {  }
    void visit(GotoCaseStatement *) {  }
    void visit(SwitchErrorStatement *) {  }
    void visit(ReturnStatement *) {  }
    void visit(BreakStatement *) {  }
    void visit(ContinueStatement *) {  }
    void visit(SynchronizedStatement *s)
    {
        if (s->_body)
            visitStmt(s->_body);
    }
    void visit(WithStatement *s)
    {
        if (s->_body)
            visitStmt(s->_body);
    }
    void visit(TryCatchStatement *s)
    {
        if (s->_body)
            visitStmt(s->_body);
        if (s->catches && s->catches->dim)
        {
            for (size_t i = 0; i < s->catches->dim; i++)
            {
                Catch *c = (*s->catches)[i];
                if (c && c->handler)
                    visitStmt(c->handler);
            }
        }
    }
    void visit(TryFinallyStatement *s)
    {
        if (s->_body)
            visitStmt(s->_body);
        if (s->finalbody)
            visitStmt(s->finalbody);
    }
    void visit(OnScopeStatement *) {  }
    void visit(ThrowStatement *) {  }
    void visit(DebugStatement *s)
    {
        if (s->statement)
            visitStmt(s->statement);
    }
    void visit(GotoStatement *) {  }
    void visit(LabelStatement *s)
    {
        if (s->statement)
            visitStmt(s->statement);
    }
    void visit(AsmStatement *) {  }
    void visit(ImportStatement *) {  }
};

/* Tweak all return statements and dtor call for nrvo_var, for correct NRVO.
 */
class NrvoWalker : public StatementRewriteWalker
{
public:
    FuncDeclaration *fd;
    Scope *sc;

    void visit(ReturnStatement *s)
    {
        // See if all returns are instead to be replaced with a goto returnLabel;
        if (fd->returnLabel)
        {
            /* Rewrite:
             *  return exp;
             * as:
             *  vresult = exp; goto Lresult;
             */
            GotoStatement *gs = new GotoStatement(s->loc, Id::returnLabel);
            gs->label = fd->returnLabel;

            Statement *s1 = gs;
            if (s->exp)
                s1 = new CompoundStatement(s->loc, new ExpStatement(s->loc, s->exp), gs);

            replaceCurrent(s1);
        }
    }
    void visit(TryFinallyStatement *s)
    {
        DtorExpStatement *des;
        if (fd->nrvo_can &&
            s->finalbody && (des = s->finalbody->isDtorExpStatement()) != NULL &&
            fd->nrvo_var == des->var)
        {
            if (!(global.params.useExceptions && ClassDeclaration::throwable))
            {
                /* Don't need to call destructor at all, since it is nrvo
                 */
                replaceCurrent(s->_body);
                s->_body->accept(this);
                return;
            }

            /* Normally local variable dtors are called regardless exceptions.
             * But for nrvo_var, its dtor should be called only when exception is thrown.
             *
             * Rewrite:
             *      try { s->body; } finally { nrvo_var->edtor; }
             *      // equivalent with:
             *      //    s->body; scope(exit) nrvo_var->edtor;
             * as:
             *      try { s->body; } catch(Throwable __o) { nrvo_var->edtor; throw __o; }
             *      // equivalent with:
             *      //    s->body; scope(failure) nrvo_var->edtor;
             */
            Statement *sexception = new DtorExpStatement(Loc(), fd->nrvo_var->edtor, fd->nrvo_var);
            Identifier *id = Identifier::generateId("__o");

            Statement *handler = new PeelStatement(sexception);
            if (blockExit(sexception, fd, false) & BEfallthru)
            {
                ThrowStatement *ts = new ThrowStatement(Loc(), new IdentifierExp(Loc(), id));
                ts->internalThrow = true;
                handler = new CompoundStatement(Loc(), handler, ts);
            }

            Catches *catches = new Catches();
            Catch *ctch = new Catch(Loc(), getThrowable(), id, handler);
            ctch->internalCatch = true;
            ::semantic(ctch, sc);     // Run semantic to resolve identifier '__o'
            catches->push(ctch);

            Statement *s2 = new TryCatchStatement(Loc(), s->_body, catches);
            replaceCurrent(s2);
            s2->accept(this);
        }
        else
            StatementRewriteWalker::visit(s);
    }
};

/********************************* FuncDeclaration ****************************/

FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type)
    : Declaration(id)
{
    //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
    //printf("storage_class = x%x\n", storage_class);
    this->storage_class = storage_class;
    this->type = type;
    if (type)
    {
        // Normalize storage_class, because function-type related attributes
        // are already set in the 'type' in parsing phase.
        this->storage_class &= ~(STC_TYPECTOR | STC_FUNCATTR);
    }
    this->loc = loc;
    this->endloc = endloc;
    fthrows = NULL;
    frequire = NULL;
    fdrequire = NULL;
    fdensure = NULL;
    mangleString = NULL;
    outId = NULL;
    vresult = NULL;
    returnLabel = NULL;
    fensure = NULL;
    fbody = NULL;
    localsymtab = NULL;
    vthis = NULL;
    v_arguments = NULL;
    v_argptr = NULL;
    parameters = NULL;
    labtab = NULL;
    overnext = NULL;
    overnext0 = NULL;
    vtblIndex = -1;
    hasReturnExp = 0;
    naked = false;
    generated = false;
    inlineStatusExp = ILSuninitialized;
    inlineStatusStmt = ILSuninitialized;
    inlining = PINLINEdefault;
    inlineNest = 0;
    ctfeCode = NULL;
    isArrayOp = 0;
    semantic3Errors = false;
    fes = NULL;
    interfaceVirtual = NULL;
    introducing = 0;
    tintro = NULL;
    /* The type given for "infer the return type" is a TypeFunction with
     * NULL for the return type.
     */
    inferRetType = (type && type->nextOf() == NULL);
    storage_class2 = 0;
    hasReturnExp = 0;
    nrvo_can = 1;
    nrvo_var = NULL;
    shidden = NULL;
    builtin = BUILTINunknown;
    tookAddressOf = 0;
    requiresClosure = false;
    inlinedNestedCallees = NULL;
    flags = 0;
    returns = NULL;
    gotos = NULL;
    selector = NULL;
}

FuncDeclaration *FuncDeclaration::create(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type)
{
    return new FuncDeclaration(loc, endloc, id, storage_class, type);
}

Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
{
    //printf("FuncDeclaration::syntaxCopy('%s')\n", toChars());
    FuncDeclaration *f =
        s ? (FuncDeclaration *)s
          : new FuncDeclaration(loc, endloc, ident, storage_class, type->syntaxCopy());
    f->outId = outId;
    f->frequire = frequire ? frequire->syntaxCopy() : NULL;
    f->fensure  = fensure  ? fensure->syntaxCopy()  : NULL;
    f->fbody    = fbody    ? fbody->syntaxCopy()    : NULL;
    assert(!fthrows); // deprecated
    return f;
}

/**********************************
 * Decide if attributes for this function can be inferred from examining
 * the function body.
 * Returns:
 *  true if can
 */
static bool canInferAttributes(FuncDeclaration *fd, Scope *sc)
{
    if (!fd->fbody)
        return false;

    if (fd->isVirtualMethod())
        return false;               // since they may be overridden

    if (sc->func &&
        /********** this is for backwards compatibility for the moment ********/
        (!fd->isMember() || (sc->func->isSafeBypassingInference() && !fd->isInstantiated())))
        return true;

    if (fd->isFuncLiteralDeclaration() ||               // externs are not possible with literals
        (fd->storage_class & STCinference) ||           // do attribute inference
        (fd->inferRetType && !fd->isCtorDeclaration()))
        return true;

    if (fd->isInstantiated())
    {
        TemplateInstance *ti = fd->parent->isTemplateInstance();
        if (ti == NULL || ti->isTemplateMixin() || ti->tempdecl->ident == fd->ident)
            return true;
    }

    return false;
}

/*****************************************
 * Initialize for inferring the attributes of this function.
 */
static void initInferAttributes(FuncDeclaration *fd)
{
    //printf("initInferAttributes() for %s\n", toPrettyChars());
    TypeFunction *tf = fd->type->toTypeFunction();
    if (tf->purity == PUREimpure) // purity not specified
        fd->flags |= FUNCFLAGpurityInprocess;

    if (tf->trust == TRUSTdefault)
        fd->flags |= FUNCFLAGsafetyInprocess;

    if (!tf->isnothrow)
        fd->flags |= FUNCFLAGnothrowInprocess;

    if (!tf->isnogc)
        fd->flags |= FUNCFLAGnogcInprocess;

    if (!fd->isVirtual() || fd->introducing)
        fd->flags |= FUNCFLAGreturnInprocess;

    // Initialize for inferring STCscope
    if (global.params.vsafe)
        fd->flags |= FUNCFLAGinferScope;
}

// Do the semantic analysis on the external interface to the function.

void FuncDeclaration::semantic(Scope *sc)
{
    TypeFunction *f;
    AggregateDeclaration *ad;
    InterfaceDeclaration *id;

    if (semanticRun != PASSinit && isFuncLiteralDeclaration())
    {
        /* Member functions that have return types that are
         * forward references can have semantic() run more than
         * once on them.
         * See test\interface2.d, test20
         */
        return;
    }

    if (semanticRun >= PASSsemanticdone)
        return;
    assert(semanticRun <= PASSsemantic);
    semanticRun = PASSsemantic;

    if (_scope)
    {
        sc = _scope;
        _scope = NULL;
    }

    if (!sc || errors)
        return;

    parent = sc->parent;
    Dsymbol *parent = toParent();

    foverrides.setDim(0);       // reset in case semantic() is being retried for this function

    storage_class |= sc->stc & ~STCref;
    ad = isThis();
    // Don't nest structs b/c of generated methods which should not access the outer scopes.
    // https://issues.dlang.org/show_bug.cgi?id=16627
    if (ad && !generated)
    {
        storage_class |= ad->storage_class & (STC_TYPECTOR | STCsynchronized);
        ad->makeNested();
    }
    if (sc->func)
        storage_class |= sc->func->storage_class & STCdisable;
    // Remove prefix storage classes silently.
    if ((storage_class & STC_TYPECTOR) && !(ad || isNested()))
        storage_class &= ~STC_TYPECTOR;

    //printf("function storage_class = x%llx, sc->stc = x%llx, %x\n", storage_class, sc->stc, Declaration::isFinal());

    FuncLiteralDeclaration *fld = isFuncLiteralDeclaration();
    if (fld && fld->treq)
    {
        Type *treq = fld->treq;
        assert(treq->nextOf()->ty == Tfunction);
        if (treq->ty == Tdelegate)
            fld->tok = TOKdelegate;
        else if (treq->ty == Tpointer && treq->nextOf()->ty == Tfunction)
            fld->tok = TOKfunction;
        else
            assert(0);
        linkage = treq->nextOf()->toTypeFunction()->linkage;
    }
    else
        linkage = sc->linkage;
    inlining = sc->inlining;
    protection = sc->protection;
    userAttribDecl = sc->userAttribDecl;

    if (!originalType)
        originalType = type->syntaxCopy();
    if (type->ty != Tfunction)
    {
        if (type->ty != Terror)
        {
            error("%s must be a function instead of %s", toChars(), type->toChars());
            type = Type::terror;
        }
        errors = true;
        return;
    }
    if (!type->deco)
    {
        sc = sc->push();
        sc->stc |= storage_class & (STCdisable | STCdeprecated);  // forward to function type
        TypeFunction *tf = type->toTypeFunction();

        if (sc->func)
        {
            /* If the nesting parent is pure without inference,
             * then this function defaults to pure too.
             *
             *  auto foo() pure {
             *    auto bar() {}     // become a weak purity funciton
             *    class C {         // nested class
             *      auto baz() {}   // become a weak purity funciton
             *    }
             *
             *    static auto boo() {}   // typed as impure
             *    // Even though, boo cannot call any impure functions.
             *    // See also Expression::checkPurity().
             *  }
             */
            if (tf->purity == PUREimpure && (isNested() || isThis()))
            {
                FuncDeclaration *fd = NULL;
                for (Dsymbol *p = toParent2(); p; p = p->toParent2())
                {
                    if (AggregateDeclaration *adx = p->isAggregateDeclaration())
                    {
                        if (adx->isNested())
                            continue;
                        break;
                    }
                    if ((fd = p->isFuncDeclaration()) != NULL)
                        break;
                }

                /* If the parent's purity is inferred, then this function's purity needs
                 * to be inferred first.
                 */
                if (fd && fd->isPureBypassingInference() >= PUREweak &&
                    !isInstantiated())
                {
                    tf->purity = PUREfwdref;            // default to pure
                }
            }
        }

        if (tf->isref)      sc->stc |= STCref;
        if (tf->isscope)    sc->stc |= STCscope;
        if (tf->isnothrow)  sc->stc |= STCnothrow;
        if (tf->isnogc)     sc->stc |= STCnogc;
        if (tf->isproperty) sc->stc |= STCproperty;
        if (tf->purity == PUREfwdref)   sc->stc |= STCpure;
        if (tf->trust != TRUSTdefault)
            sc->stc &= ~(STCsafe | STCsystem | STCtrusted);
        if (tf->trust == TRUSTsafe)     sc->stc |= STCsafe;
        if (tf->trust == TRUSTsystem)   sc->stc |= STCsystem;
        if (tf->trust == TRUSTtrusted)  sc->stc |= STCtrusted;

        if (isCtorDeclaration())
        {
            sc->flags |= SCOPEctor;

            Type *tret = ad->handleType();
            assert(tret);
            tret = tret->addStorageClass(storage_class | sc->stc);
            tret = tret->addMod(type->mod);
            tf->next = tret;

            if (ad->isStructDeclaration())
                sc->stc |= STCref;
        }

        // 'return' on a non-static class member function implies 'scope' as well
        if (ad && ad->isClassDeclaration() && (tf->isreturn || sc->stc & STCreturn) && !(sc->stc & STCstatic))
            sc->stc |= STCscope;

        // If 'this' has no pointers, remove 'scope' as it has no meaning
        if (sc->stc & STCscope && ad && ad->isStructDeclaration() && !ad->type->hasPointers())
        {
            sc->stc &= ~STCscope;
            tf->isscope = false;
        }

        sc->linkage = linkage;

        if (!tf->isNaked() && !(isThis() || isNested()))
        {
            OutBuffer buf;
            MODtoBuffer(&buf, tf->mod);
            error("without 'this' cannot be %s", buf.peekString());
            tf->mod = 0;    // remove qualifiers
        }

        /* Apply const, immutable, wild and shared storage class
         * to the function type. Do this before type semantic.
         */
        StorageClass stc = storage_class;
        if (type->isImmutable())
            stc |= STCimmutable;
        if (type->isConst())
            stc |= STCconst;
        if (type->isShared() || storage_class & STCsynchronized)
            stc |= STCshared;
        if (type->isWild())
            stc |= STCwild;
        switch (stc & STC_TYPECTOR)
        {
            case STCimmutable:
            case STCimmutable | STCconst:
            case STCimmutable | STCwild:
            case STCimmutable | STCwild | STCconst:
            case STCimmutable | STCshared:
            case STCimmutable | STCshared | STCconst:
            case STCimmutable | STCshared | STCwild:
            case STCimmutable | STCshared | STCwild | STCconst:
                // Don't use immutableOf(), as that will do a merge()
                type = type->makeImmutable();
                break;

            case STCconst:
                type = type->makeConst();
                break;

            case STCwild:
                type = type->makeWild();
                break;

            case STCwild | STCconst:
                type = type->makeWildConst();
                break;

            case STCshared:
                type = type->makeShared();
                break;

            case STCshared | STCconst:
                type = type->makeSharedConst();
                break;

            case STCshared | STCwild:
                type = type->makeSharedWild();
                break;

            case STCshared | STCwild | STCconst:
                type = type->makeSharedWildConst();
                break;

            case 0:
                break;

            default:
                assert(0);
        }

        type = type->semantic(loc, sc);
        sc = sc->pop();
    }
    if (type->ty != Tfunction)
    {
        if (type->ty != Terror)
        {
            error("%s must be a function instead of %s", toChars(), type->toChars());
            type = Type::terror;
        }
        errors = true;
        return;
    }
    else
    {
        // Merge back function attributes into 'originalType'.
        // It's used for mangling, ddoc, and json output.
        TypeFunction *tfo = originalType->toTypeFunction();
        TypeFunction *tfx = type->toTypeFunction();
        tfo->mod        = tfx->mod;
        tfo->isscope    = tfx->isscope;
        tfo->isscopeinferred = tfx->isscopeinferred;
        tfo->isref      = tfx->isref;
        tfo->isnothrow  = tfx->isnothrow;
        tfo->isnogc     = tfx->isnogc;
        tfo->isproperty = tfx->isproperty;
        tfo->purity     = tfx->purity;
        tfo->trust      = tfx->trust;

        storage_class &= ~(STC_TYPECTOR | STC_FUNCATTR);
    }

    f = (TypeFunction *)type;

    if ((storage_class & STCauto) && !f->isref && !inferRetType)
        error("storage class 'auto' has no effect if return type is not inferred");
    /* Functions can only be 'scope' if they have a 'this'
     */
    if (f->isscope && !isNested() && !ad)
    {
        error("functions cannot be scope");
    }

    if (f->isreturn && !needThis() && !isNested())
    {
        /* Non-static nested functions have a hidden 'this' pointer to which
         * the 'return' applies
         */
        error("static member has no 'this' to which 'return' can apply");
    }

    if (isAbstract() && !isVirtual())
    {
        const char *sfunc;
        if (isStatic())
            sfunc = "static";
        else if (protection.kind == PROTprivate || protection.kind == PROTpackage)
            sfunc = protectionToChars(protection.kind);
        else
            sfunc = "non-virtual";
        error("%s functions cannot be abstract", sfunc);
    }

    if (isOverride() && !isVirtual())
    {
        PROTKIND kind = prot().kind;
        if ((kind == PROTprivate || kind == PROTpackage) && isMember())
            error("%s method is not virtual and cannot override", protectionToChars(kind));
        else
            error("cannot override a non-virtual function");
    }

    if (isAbstract() && isFinalFunc())
        error("cannot be both final and abstract");

    id = parent->isInterfaceDeclaration();
    if (id)
    {
        storage_class |= STCabstract;

        if (isCtorDeclaration() ||
            isPostBlitDeclaration() ||
            isDtorDeclaration() ||
            isInvariantDeclaration() ||
            isNewDeclaration() || isDelete())
            error("constructors, destructors, postblits, invariants, new and delete functions are not allowed in interface %s", id->toChars());
        if (fbody && isVirtual())
            error("function body only allowed in final functions in interface %s", id->toChars());
    }

    if (UnionDeclaration *ud = parent->isUnionDeclaration())
    {
        if (isPostBlitDeclaration() ||
            isDtorDeclaration() ||
            isInvariantDeclaration())
            error("destructors, postblits and invariants are not allowed in union %s", ud->toChars());
    }

    /* Contracts can only appear without a body when they are virtual interface functions
     */
    if (!fbody && (fensure || frequire) && !(id && isVirtual()))
        error("in and out contracts require function body");

    if (parent->isStructDeclaration())
    {
        if (isCtorDeclaration())
        {
            goto Ldone;
        }
    }

    if (ClassDeclaration *cd = parent->isClassDeclaration())
    {
        if (isCtorDeclaration())
        {
            goto Ldone;
        }

        if (storage_class & STCabstract)
            cd->isabstract = ABSyes;

        // if static function, do not put in vtbl[]
        if (!isVirtual())
        {
            //printf("\tnot virtual\n");
            goto Ldone;
        }
        // Suppress further errors if the return type is an error
        if (type->nextOf() == Type::terror)
            goto Ldone;

        bool may_override = false;
        for (size_t i = 0; i < cd->baseclasses->dim; i++)
        {
            BaseClass *b = (*cd->baseclasses)[i];
            ClassDeclaration *cbd = b->type->toBasetype()->isClassHandle();
            if (!cbd)
                continue;
            for (size_t j = 0; j < cbd->vtbl.dim; j++)
            {
                FuncDeclaration *f2 = cbd->vtbl[j]->isFuncDeclaration();
                if (!f2 || f2->ident != ident)
                    continue;
                if (cbd->parent && cbd->parent->isTemplateInstance())
                {
                    if (!f2->functionSemantic())
                        goto Ldone;
                }
                may_override = true;
            }
        }
        if (may_override && type->nextOf() == NULL)
        {
            /* If same name function exists in base class but 'this' is auto return,
             * cannot find index of base class's vtbl[] to override.
             */
            error("return type inference is not supported if may override base class function");
        }

        /* Find index of existing function in base class's vtbl[] to override
         * (the index will be the same as in cd's current vtbl[])
         */
        int vi = cd->baseClass ? findVtblIndex((Dsymbols*)&cd->baseClass->vtbl, (int)cd->baseClass->vtbl.dim)
                               : -1;

        bool doesoverride = false;
        switch (vi)
        {
            case -1:
        Lintro:
                /* Didn't find one, so
                 * This is an 'introducing' function which gets a new
                 * slot in the vtbl[].
                 */

                // Verify this doesn't override previous final function
                if (cd->baseClass)
                {
                    Dsymbol *s = cd->baseClass->search(loc, ident);
                    if (s)
                    {
                        FuncDeclaration *f2 = s->isFuncDeclaration();
                        if (f2)
                        {
                            f2 = f2->overloadExactMatch(type);
                            if (f2 && f2->isFinalFunc() && f2->prot().kind != PROTprivate)
                                error("cannot override final function %s", f2->toPrettyChars());
                        }
                    }
                }

                /* These quirky conditions mimic what VC++ appears to do
                 */
                if (global.params.mscoff && cd->isCPPclass() &&
                    cd->baseClass && cd->baseClass->vtbl.dim)
                {
                    /* if overriding an interface function, then this is not
                     * introducing and don't put it in the class vtbl[]
                     */
                    interfaceVirtual = overrideInterface();
                    if (interfaceVirtual)
                    {
                        //printf("\tinterface function %s\n", toChars());
                        cd->vtblFinal.push(this);
                        goto Linterfaces;
                    }
                }

                if (isFinalFunc())
                {
                    // Don't check here, as it may override an interface function
                    //if (isOverride())
                        //error("is marked as override, but does not override any function");
                    cd->vtblFinal.push(this);
                }
                else
                {
                    //printf("\tintroducing function %s\n", toChars());
                    introducing = 1;
                    if (cd->isCPPclass() && Target::reverseCppOverloads)
                    {
                        // with dmc, overloaded functions are grouped and in reverse order
                        vtblIndex = (int)cd->vtbl.dim;
                        for (int i = 0; i < (int)cd->vtbl.dim; i++)
                        {
                            if (cd->vtbl[i]->ident == ident && cd->vtbl[i]->parent == parent)
                            {
                                vtblIndex = (int)i;
                                break;
                            }
                        }
                        // shift all existing functions back
                        for (int i = (int)cd->vtbl.dim; i > vtblIndex; i--)
                        {
                            FuncDeclaration *fd = cd->vtbl[i-1]->isFuncDeclaration();
                            assert(fd);
                            fd->vtblIndex++;
                        }
                        cd->vtbl.insert(vtblIndex, this);
                    }
                    else
                    {
                        // Append to end of vtbl[]
                        vi = (int)cd->vtbl.dim;
                        cd->vtbl.push(this);
                        vtblIndex = vi;
                    }
                }
                break;

            case -2:
                // can't determine because of forward references
                errors = true;
                return;

            default:
            {
                FuncDeclaration *fdv = cd->baseClass->vtbl[vi]->isFuncDeclaration();
                FuncDeclaration *fdc = cd->vtbl[vi]->isFuncDeclaration();
                // This function is covariant with fdv

                if (fdc == this)
                {
                    doesoverride = true;
                    break;
                }

                if (fdc->toParent() == parent)
                {
                    //printf("vi = %d,\tthis = %p %s %s @ [%s]\n\tfdc  = %p %s %s @ [%s]\n\tfdv  = %p %s %s @ [%s]\n",
                    //        vi, this, this->toChars(), this->type->toChars(), this->loc.toChars(),
                    //            fdc,  fdc ->toChars(), fdc ->type->toChars(), fdc ->loc.toChars(),
                    //            fdv,  fdv ->toChars(), fdv ->type->toChars(), fdv ->loc.toChars());

                    // fdc overrides fdv exactly, then this introduces new function.
                    if (fdc->type->mod == fdv->type->mod && this->type->mod != fdv->type->mod)
                        goto Lintro;
                }

                // This function overrides fdv
                if (fdv->isFinalFunc())
                    error("cannot override final function %s", fdv->toPrettyChars());

                if (!isOverride())
                {
                    if (fdv->isFuture())
                    {
                        ::deprecation(loc, "@future base class method %s is being overridden by %s; rename the latter",
                            fdv->toPrettyChars(), toPrettyChars());
                        // Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[]
                        goto Lintro;
                    }
                    else
                    {
                        int vi2 = findVtblIndex(&cd->baseClass->vtbl, (int)cd->baseClass->vtbl.dim, false);
                        if (vi2 < 0)
                            // https://issues.dlang.org/show_bug.cgi?id=17349
                            ::deprecation(loc, "cannot implicitly override base class method `%s` with `%s`; add `override` attribute",
                                fdv->toPrettyChars(), toPrettyChars());
                        else
                            ::error(loc, "implicitly overriding base class method %s with %s deprecated; add 'override' attribute",
                                fdv->toPrettyChars(), toPrettyChars());
                    }
                }

                doesoverride = true;
                if (fdc->toParent() == parent)
                {
                    // If both are mixins, or both are not, then error.
                    // If either is not, the one that is not overrides the other.
                    bool thismixin = this->parent->isClassDeclaration() != NULL;
                    bool fdcmixin = fdc->parent->isClassDeclaration() != NULL;
                    if (thismixin == fdcmixin)
                    {
                        error("multiple overrides of same function");
                    }
                    else if (!thismixin)    // fdc overrides fdv
                    {
                        // this doesn't override any function
                        break;
                    }
                }
                cd->vtbl[vi] = this;
                vtblIndex = vi;

                /* Remember which functions this overrides
                 */
                foverrides.push(fdv);

                /* This works by whenever this function is called,
                 * it actually returns tintro, which gets dynamically
                 * cast to type. But we know that tintro is a base
                 * of type, so we could optimize it by not doing a
                 * dynamic cast, but just subtracting the isBaseOf()
                 * offset if the value is != null.
                 */

                if (fdv->tintro)
                    tintro = fdv->tintro;
                else if (!type->equals(fdv->type))
                {
                    /* Only need to have a tintro if the vptr
                     * offsets differ
                     */
                    int offset;
                    if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
                    {
                        tintro = fdv->type;
                    }
                }
                break;
            }
        }

        /* Go through all the interface bases.
         * If this function is covariant with any members of those interface
         * functions, set the tintro.
         */
    Linterfaces:
        for (size_t i = 0; i < cd->interfaces.length; i++)
        {
            BaseClass *b = cd->interfaces.ptr[i];
            vi = findVtblIndex((Dsymbols *)&b->sym->vtbl, (int)b->sym->vtbl.dim);
            switch (vi)
            {
                case -1:
                    break;

                case -2:
                    // can't determine because of forward references
                    errors = true;
                    return;

                default:
                {
                    FuncDeclaration *fdv = (FuncDeclaration *)b->sym->vtbl[vi];
                    Type *ti = NULL;

                    /* Remember which functions this overrides
                     */
                    foverrides.push(fdv);

                    /* Should we really require 'override' when implementing
                     * an interface function?
                     */
                    //if (!isOverride())
                        //warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars());

                    if (fdv->tintro)
                        ti = fdv->tintro;
                    else if (!type->equals(fdv->type))
                    {
                        /* Only need to have a tintro if the vptr
                         * offsets differ
                         */
                        int offset;
                        if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
                        {
                            ti = fdv->type;
                        }
                    }
                    if (ti)
                    {
                        if (tintro)
                        {
                            if (!tintro->nextOf()->equals(ti->nextOf()) &&
                                !tintro->nextOf()->isBaseOf(ti->nextOf(), NULL) &&
                                !ti->nextOf()->isBaseOf(tintro->nextOf(), NULL))
                            {
                                error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
                            }
                        }
                        tintro = ti;
                    }
                    goto L2;
                }
            }
        }

        if (!doesoverride && isOverride() && (type->nextOf() || !may_override))
        {
            BaseClass *bc = NULL;
            Dsymbol *s = NULL;
            for (size_t i = 0; i < cd->baseclasses->dim; i++)
            {
                bc = (*cd->baseclasses)[i];
                s = bc->sym->search_correct(ident);
                if (s) break;
            }

            if (s)
                error("does not override any function, did you mean to override '%s%s'?",
                    bc->sym->isCPPclass() ? "extern (C++) " : "", s->toPrettyChars());
            else
                error("does not override any function");
        }

    L2: ;

        /* Go through all the interface bases.
         * Disallow overriding any final functions in the interface(s).
         */
        for (size_t i = 0; i < cd->interfaces.length; i++)
        {
            BaseClass *b = cd->interfaces.ptr[i];
            if (b->sym)
            {
                Dsymbol *s = search_function(b->sym, ident);
                if (s)
                {
                    FuncDeclaration *f2 = s->isFuncDeclaration();
                    if (f2)
                    {
                        f2 = f2->overloadExactMatch(type);
                        if (f2 && f2->isFinalFunc() && f2->prot().kind != PROTprivate)
                            error("cannot override final function %s.%s", b->sym->toChars(), f2->toPrettyChars());
                    }
                }
            }
        }

        if (isOverride())
        {
            if (storage_class & STCdisable)
                deprecation("overridden functions cannot be annotated @disable");
            if (isDeprecated())
                deprecation("deprecated functions cannot be annotated @disable");
        }
    }
    else if (isOverride() && !parent->isTemplateInstance())
        error("override only applies to class member functions");

    // Reflect this->type to f because it could be changed by findVtblIndex
    f = type->toTypeFunction();

    /* Do not allow template instances to add virtual functions
     * to a class.
     */
    if (isVirtual())
    {
        TemplateInstance *ti = parent->isTemplateInstance();
        if (ti)
        {
            // Take care of nested templates
            while (1)
            {
                TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
                if (!ti2)
                    break;
                ti = ti2;
            }

            // If it's a member template
            ClassDeclaration *cd = ti->tempdecl->isClassMember();
            if (cd)
            {
                error("cannot use template to add virtual function to class '%s'", cd->toChars());
            }
        }
    }

    if (isMain())
        checkDmain();       // Check main() parameters and return type

Ldone:
    /* Purity and safety can be inferred for some functions by examining
     * the function body.
     */
    if (canInferAttributes(this, sc))
        initInferAttributes(this);

    Module::dprogress++;
    semanticRun = PASSsemanticdone;

    /* Save scope for possible later use (if we need the
     * function internals)
     */
    _scope = sc->copy();
    _scope->setNoFree();

    static bool printedMain = false;  // semantic might run more than once
    if (global.params.verbose && !printedMain)
    {
        const char *type = isMain() ? "main" : isWinMain() ? "winmain" : isDllMain() ? "dllmain" : (const char *)NULL;
        Module *mod = sc->_module;

        if (type && mod)
        {
            printedMain = true;
            const char *name = mod->srcfile->toChars();
            const char *path = FileName::searchPath(global.path, name, true);
            message("entry     %-10s\t%s", type, path ? path : name);
        }
    }

    if (fbody && isMain() && sc->_module->isRoot())
        Compiler::genCmain(sc);

    assert(type->ty != Terror || errors);
}

void FuncDeclaration::semantic2(Scope *sc)
{
    if (semanticRun >= PASSsemantic2done)
        return;
    assert(semanticRun <= PASSsemantic2);
    semanticRun = PASSsemantic2;

    objc()->setSelector(this, sc);
    objc()->validateSelector(this);

    if (parent->isClassDeclaration())
    {
        objc()->checkLinkage(this);
    }
}

/****************************************************
 * Determine whether an 'out' contract is declared inside
 * the given function or any of its overrides.
 * Params:
 *      fd = the function to search
 * Returns:
 *      true    found an 'out' contract
 *      false   didn't find one
 */
static bool needsFensure(FuncDeclaration *fd)
{
    if (fd->fensure)
        return true;

    for (size_t i = 0; i < fd->foverrides.dim; i++)
    {
        FuncDeclaration *fdv = fd->foverrides[i];

        if (fdv->fensure)
            return true;

        if (needsFensure(fdv))
            return true;
    }
    return false;
}

/****************************************************
 * Rewrite contracts as nested functions, then call them. Doing it as nested
 * functions means that overriding functions can call them.
 * Params:
 *      fd = the function to rewrite contracts for
 */
static void buildEnsureRequire(FuncDeclaration *fdx)
{
    if (!fdx->isVirtual())
        return;

    TypeFunction *f = (TypeFunction *)fdx->type;

    if (fdx->frequire)
    {
        /*   in { ... }
         * becomes:
         *   void __require() { ... }
         *   __require();
         */
        Loc loc = fdx->frequire->loc;
        TypeFunction *tf = new TypeFunction(NULL, Type::tvoid, 0, LINKd);
        tf->isnothrow = f->isnothrow;
        tf->isnogc = f->isnogc;
        tf->purity = f->purity;
        tf->trust = f->trust;
        FuncDeclaration *fd = new FuncDeclaration(loc, loc,
                                                  Id::require, STCundefined, tf);
        fd->fbody = fdx->frequire;
        Statement *s1 = new ExpStatement(loc, fd);
        Expression *e = new CallExp(loc, new VarExp(loc, fd, false), (Expressions *)NULL);
        Statement *s2 = new ExpStatement(loc, e);
        fdx->frequire = new CompoundStatement(loc, s1, s2);
        fdx->fdrequire = fd;
    }

    if (!fdx->outId && f->nextOf() && f->nextOf()->toBasetype()->ty != Tvoid)
        fdx->outId = Id::result; // provide a default

    if (fdx->fensure)
    {
        /*   out (result) { ... }
         * becomes:
         *   void __ensure(ref tret result) { ... }
         *   __ensure(result);
         */
        Loc loc = fdx->fensure->loc;
        Parameters *fparams = new Parameters();
        Parameter *p = NULL;
        if (fdx->outId)
        {
            p = new Parameter(STCref | STCconst, f->nextOf(), fdx->outId, NULL);
            fparams->push(p);
        }
        TypeFunction *tf = new TypeFunction(fparams, Type::tvoid, 0, LINKd);
        tf->isnothrow = f->isnothrow;
        tf->isnogc = f->isnogc;
        tf->purity = f->purity;
        tf->trust = f->trust;
        FuncDeclaration *fd = new FuncDeclaration(loc, loc,
                                                  Id::ensure, STCundefined, tf);
        fd->fbody = fdx->fensure;
        Statement *s1 = new ExpStatement(loc, fd);
        Expression *eresult = NULL;
        if (fdx->outId)
            eresult = new IdentifierExp(loc, fdx->outId);
        Expression *e = new CallExp(loc, new VarExp(loc, fd, false), eresult);
        Statement *s2 = new ExpStatement(loc, e);
        fdx->fensure = new CompoundStatement(loc, s1, s2);
        fdx->fdensure = fd;
    }
}

/* Determine if function should add `return 0;`
 */
static bool addReturn0(FuncDeclaration *funcdecl)
{
    TypeFunction *f = (TypeFunction *)funcdecl->type;

    return f->next->ty == Tvoid &&
        (funcdecl->isMain() || (global.params.betterC && funcdecl->isCMain()));
}

// Do the semantic analysis on the internals of the function.

void FuncDeclaration::semantic3(Scope *sc)
{
    VarDeclaration *_arguments = NULL;

    if (!parent)
    {
        if (global.errors)
            return;
        //printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
        assert(0);
    }
    if (errors || isError(parent))
    {
        errors = true;
        return;
    }
    //printf("FuncDeclaration::semantic3('%s.%s', %p, sc = %p, loc = %s)\n", parent->toChars(), toChars(), this, sc, loc.toChars());
    //fflush(stdout);
    //printf("storage class = x%x %x\n", sc->stc, storage_class);
    //{ static int x; if (++x == 2) *(char*)0=0; }
    //printf("\tlinkage = %d\n", sc->linkage);

    if (ident == Id::assign && !inuse)
    {
        if (storage_class & STCinference)
        {
            /* Bugzilla 15044: For generated opAssign function, any errors
             * from its body need to be gagged.
             */
            unsigned oldErrors = global.startGagging();
            ++inuse;
            semantic3(sc);
            --inuse;
            if (global.endGagging(oldErrors))   // if errors happened
            {
                // Disable generated opAssign, because some members forbid identity assignment.
                storage_class |= STCdisable;
                fbody = NULL;   // remove fbody which contains the error
                semantic3Errors = false;
            }
            return;
        }
    }

    //printf(" sc->incontract = %d\n", (sc->flags & SCOPEcontract));
    if (semanticRun >= PASSsemantic3)
        return;
    semanticRun = PASSsemantic3;
    semantic3Errors = false;

    if (!type || type->ty != Tfunction)
        return;
    TypeFunction *f = (TypeFunction *)type;
    if (!inferRetType && f->next->ty == Terror)
        return;

    if (!fbody && inferRetType && !f->next)
    {
        error("has no function body with return type inference");
        return;
    }

    unsigned oldErrors = global.errors;

    if (frequire)
    {
        for (size_t i = 0; i < foverrides.dim; i++)
        {
            FuncDeclaration *fdv = foverrides[i];

            if (fdv->fbody && !fdv->frequire)
            {
                error("cannot have an in contract when overriden function %s does not have an in contract", fdv->toPrettyChars());
                break;
            }
        }
    }

    // Remember whether we need to generate an 'out' contract.
    bool needEnsure = needsFensure(this);

    if (fbody || frequire || needEnsure)
    {
        /* Symbol table into which we place parameters and nested functions,
         * solely to diagnose name collisions.
         */
        localsymtab = new DsymbolTable();

        // Establish function scope
        ScopeDsymbol *ss = new ScopeDsymbol();
        // find enclosing scope symbol, might skip symbol-less CTFE and/or FuncExp scopes
        for (Scope *scx = sc; ; scx = scx->enclosing)
        {
            if (scx->scopesym)
            {
                ss->parent = scx->scopesym;
                break;
            }
        }
        ss->loc = loc;
        ss->endlinnum = endloc.linnum;
        Scope *sc2 = sc->push(ss);
        sc2->func = this;
        sc2->parent = this;
        sc2->callSuper = 0;
        sc2->sbreak = NULL;
        sc2->scontinue = NULL;
        sc2->sw = NULL;
        sc2->fes = fes;
        sc2->linkage = LINKd;
        sc2->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCabstract |
                        STCdeprecated | STCoverride |
                        STC_TYPECTOR | STCfinal | STCtls | STCgshared | STCref | STCreturn |
                        STCproperty | STCnothrow | STCpure | STCsafe | STCtrusted | STCsystem);
        sc2->protection = Prot(PROTpublic);
        sc2->explicitProtection = 0;
        sc2->aligndecl = NULL;
        if (this->ident != Id::require && this->ident != Id::ensure)
            sc2->flags = sc->flags & ~SCOPEcontract;
        sc2->flags &= ~SCOPEcompile;
        sc2->tf = NULL;
        sc2->os = NULL;
        sc2->noctor = 0;
        sc2->userAttribDecl = NULL;
        if (sc2->intypeof == 1) sc2->intypeof = 2;
        sc2->fieldinit = NULL;
        sc2->fieldinit_dim = 0;

        /* Note: When a lambda is defined immediately under aggregate member
         * scope, it should be contextless due to prevent interior pointers.
         * e.g.
         *      // dg points 'this' - it's interior pointer
         *      class C { int x; void delegate() dg = (){ this.x = 1; }; }
         *
         * However, lambdas could be used inside typeof, in order to check
         * some expressions varidity at compile time. For such case the lambda
         * body can access aggregate instance members.
         * e.g.
         *      class C { int x; static assert(is(typeof({ this.x = 1; }))); }
         *
         * To properly accept it, mark these lambdas as member functions.
         */
        if (FuncLiteralDeclaration *fld = isFuncLiteralDeclaration())
        {
            if (AggregateDeclaration *ad = isMember2())
            {
                if (!sc->intypeof)
                {
                    if (fld->tok == TOKdelegate)
                        error("cannot be %s members", ad->kind());
                    else
                        fld->tok = TOKfunction;
                }
                else
                {
                    if (fld->tok != TOKfunction)
                        fld->tok = TOKdelegate;
                }
            }
        }

        // Declare 'this'
        AggregateDeclaration *ad = isThis();
        vthis = declareThis(sc2, ad);
        //printf("[%s] ad = %p vthis = %p\n", loc.toChars(), ad, vthis);
        //if (vthis) printf("\tvthis->type = %s\n", vthis->type->toChars());

        // Declare hidden variable _arguments[] and _argptr
        if (f->varargs == 1)
        {
            if (f->linkage == LINKd)
            {
                // Variadic arguments depend on Typeinfo being defined
                if (!global.params.useTypeInfo || !Type::dtypeinfo || !Type::typeinfotypelist)
                {
                    if (!global.params.useTypeInfo)
                        error("D-style variadic functions cannot be used with -betterC");
                    else if (!Type::typeinfotypelist)
                        error("`object.TypeInfo_Tuple` could not be found, but is implicitly used in D-style variadic functions");
                    else
                        error("`object.TypeInfo` could not be found, but is implicitly used in D-style variadic functions");
                    fatal();
                }

                // Declare _arguments[]
                v_arguments = new VarDeclaration(Loc(), Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
                v_arguments->storage_class |= STCtemp | STCparameter;
                v_arguments->semantic(sc2);
                sc2->insert(v_arguments);
                v_arguments->parent = this;

                //Type *t = Type::typeinfo->type->constOf()->arrayOf();
                Type *t = Type::dtypeinfo->type->arrayOf();
                _arguments = new VarDeclaration(Loc(), t, Id::_arguments, NULL);
                _arguments->storage_class |= STCtemp;
                _arguments->semantic(sc2);
                sc2->insert(_arguments);
                _arguments->parent = this;
            }
            if (f->linkage == LINKd || (f->parameters && Parameter::dim(f->parameters)))
            {
                // Declare _argptr
                Type *t = Type::tvalist;
                v_argptr = new VarDeclaration(Loc(), t, Id::_argptr, NULL);
                v_argptr->storage_class |= STCtemp;
                v_argptr->semantic(sc2);
                sc2->insert(v_argptr);
                v_argptr->parent = this;
            }
        }

        /* Declare all the function parameters as variables
         * and install them in parameters[]
         */
        size_t nparams = Parameter::dim(f->parameters);
        if (nparams)
        {
            /* parameters[] has all the tuples removed, as the back end
             * doesn't know about tuples
             */
            parameters = new VarDeclarations();
            parameters->reserve(nparams);
            for (size_t i = 0; i < nparams; i++)
            {
                Parameter *fparam = Parameter::getNth(f->parameters, i);
                Identifier *id = fparam->ident;
                StorageClass stc = 0;
                if (!id)
                {
                    /* Generate identifier for un-named parameter,
                     * because we need it later on.
                     */
                    fparam->ident = id = Identifier::generateId("_param_", i);
                    stc |= STCtemp;
                }
                Type *vtype = fparam->type;
                VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL);
                //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars());
                stc |= STCparameter;
                if (f->varargs == 2 && i + 1 == nparams)
                    stc |= STCvariadic;
                if (flags & FUNCFLAGinferScope && !(fparam->storageClass & STCscope))
                    stc |= STCmaybescope;
                stc |= fparam->storageClass & (STCin | STCout | STCref | STCreturn | STCscope | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
                v->storage_class = stc;
                v->semantic(sc2);
                if (!sc2->insert(v))
                    error("parameter %s.%s is already defined", toChars(), v->toChars());
                else
                    parameters->push(v);
                localsymtab->insert(v);
                v->parent = this;
            }
        }

        // Declare the tuple symbols and put them in the symbol table,
        // but not in parameters[].
        if (f->parameters)
        {
            for (size_t i = 0; i < f->parameters->dim; i++)
            {
                Parameter *fparam = (*f->parameters)[i];

                if (!fparam->ident)
                    continue;                   // never used, so ignore
                if (fparam->type->ty == Ttuple)
                {
                    TypeTuple *t = (TypeTuple *)fparam->type;
                    size_t dim = Parameter::dim(t->arguments);
                    Objects *exps = new Objects();
                    exps->setDim(dim);
                    for (size_t j = 0; j < dim; j++)
                    {
                        Parameter *narg = Parameter::getNth(t->arguments, j);
                        assert(narg->ident);
                        VarDeclaration *v = sc2->search(Loc(), narg->ident, NULL)->isVarDeclaration();
                        assert(v);
                        Expression *e = new VarExp(v->loc, v);
                        (*exps)[j] = e;
                    }
                    assert(fparam->ident);
                    TupleDeclaration *v = new TupleDeclaration(loc, fparam->ident, exps);
                    //printf("declaring tuple %s\n", v->toChars());
                    v->isexp = true;
                    if (!sc2->insert(v))
                        error("parameter %s.%s is already defined", toChars(), v->toChars());
                    localsymtab->insert(v);
                    v->parent = this;
                }
            }
        }

        // Precondition invariant
        Statement *fpreinv = NULL;
        if (addPreInvariant())
        {
            Expression *e = addInvariant(loc, sc, ad, vthis, isDtorDeclaration() != NULL);
            if (e)
                fpreinv = new ExpStatement(Loc(), e);
        }

        // Postcondition invariant
        Statement *fpostinv = NULL;
        if (addPostInvariant())
        {
            Expression *e = addInvariant(loc, sc, ad, vthis, isCtorDeclaration() != NULL);
            if (e)
                fpostinv = new ExpStatement(Loc(), e);
        }

        // Pre/Postcondition contract
        if (!fbody)
            buildEnsureRequire(this);

        Scope *scout = NULL;
        if (needEnsure || addPostInvariant())
        {
            if ((needEnsure && global.params.useOut) || fpostinv)
            {
                returnLabel = new LabelDsymbol(Id::returnLabel);
            }

            // scope of out contract (need for vresult->semantic)
            ScopeDsymbol *sym = new ScopeDsymbol();
            sym->parent = sc2->scopesym;
            sym->loc = loc;
            sym->endlinnum = endloc.linnum;
            scout = sc2->push(sym);
        }

        if (fbody)
        {
            ScopeDsymbol *sym = new ScopeDsymbol();
            sym->parent = sc2->scopesym;
            sym->loc = loc;
            sym->endlinnum = endloc.linnum;
            sc2 = sc2->push(sym);

            AggregateDeclaration *ad2 = isMember2();

            /* If this is a class constructor
             */
            if (ad2 && isCtorDeclaration())
            {
                allocFieldinit(sc2, ad2->fields.dim);
                for (size_t i = 0; i < ad2->fields.dim; i++)
                {
                    VarDeclaration *v = ad2->fields[i];
                    v->ctorinit = 0;
                }
            }

            if (!inferRetType && retStyle(f) != RETstack)
                nrvo_can = 0;

            bool inferRef = (f->isref && (storage_class & STCauto));

            fbody = ::semantic(fbody, sc2);
            if (!fbody)
                fbody = new CompoundStatement(Loc(), new Statements());

            if (naked)
            {
                fpreinv = NULL;         // can't accommodate with no stack frame
                fpostinv = NULL;
            }

            assert(type == f ||
                   (type->ty == Tfunction &&
                    f->purity == PUREimpure &&
                    ((TypeFunction *)type)->purity >= PUREfwdref));
            f = (TypeFunction *)type;

            if (inferRetType)
            {
                // If no return type inferred yet, then infer a void
                if (!f->next)
                    f->next = Type::tvoid;
                if (f->checkRetType(loc))
                    fbody = new ErrorStatement();
            }
            if (global.params.vcomplex && f->next != NULL)
                f->next->checkComplexTransition(loc);

            if (returns && !fbody->isErrorStatement())
            {
                for (size_t i = 0; i < returns->dim; )
                {
                    Expression *exp = (*returns)[i]->exp;
                    if (exp->op == TOKvar && ((VarExp *)exp)->var == vresult)
                    {
                        if (addReturn0(this))
                            exp->type = Type::tint32;
                        else
                            exp->type = f->next;
                        // Remove `return vresult;` from returns
                        returns->remove(i);
                        continue;
                    }
                    if (inferRef && f->isref && !exp->type->constConv(f->next))     // Bugzilla 13336
                        f->isref = false;
                    i++;
                }
            }
            if (f->isref)   // Function returns a reference
            {
                if (storage_class & STCauto)
                    storage_class &= ~STCauto;
            }
            if (retStyle(f) != RETstack)
                nrvo_can = 0;

            if (fbody->isErrorStatement())
                ;
            else if (isStaticCtorDeclaration())
            {
                /* It's a static constructor. Ensure that all
                 * ctor consts were initialized.
                 */
                ScopeDsymbol *pd = toParent()->isScopeDsymbol();
                for (size_t i = 0; i < pd->members->dim; i++)
                {
                    Dsymbol *s = (*pd->members)[i];
                    s->checkCtorConstInit();
                }
            }
            else if (ad2 && isCtorDeclaration())
            {
                ClassDeclaration *cd = ad2->isClassDeclaration();

                // Verify that all the ctorinit fields got initialized
                if (!(sc2->callSuper & CSXthis_ctor))
                {
                    for (size_t i = 0; i < ad2->fields.dim; i++)
                    {
                        VarDeclaration *v = ad2->fields[i];
                        if (v->isThisDeclaration())
                            continue;
                        if (v->ctorinit == 0)
                        {
                            /* Current bugs in the flow analysis:
                             * 1. union members should not produce error messages even if
                             *    not assigned to
                             * 2. structs should recognize delegating opAssign calls as well
                             *    as delegating calls to other constructors
                             */
                            if (v->isCtorinit() && !v->type->isMutable() && cd)
                                error("missing initializer for %s field %s", MODtoChars(v->type->mod), v->toChars());
                            else if (v->storage_class & STCnodefaultctor)
                                ::error(loc, "field %s must be initialized in constructor", v->toChars());
                            else if (v->type->needsNested())
                                ::error(loc, "field %s must be initialized in constructor, because it is nested struct", v->toChars());
                        }
                        else
                        {
                            bool mustInit = (v->storage_class & STCnodefaultctor ||
                                             v->type->needsNested());
                            if (mustInit && !(sc2->fieldinit[i] & CSXthis_ctor))
                            {
                                error("field %s must be initialized but skipped", v->toChars());
                            }
                        }
                    }
                }
                freeFieldinit(sc2);

                if (cd &&
                    !(sc2->callSuper & CSXany_ctor) &&
                    cd->baseClass && cd->baseClass->ctor)
                {
                    sc2->callSuper = 0;

                    // Insert implicit super() at start of fbody
                    FuncDeclaration *fd = resolveFuncCall(Loc(), sc2, cd->baseClass->ctor, NULL, vthis->type, NULL, 1);
                    if (!fd)
                    {
                        error("no match for implicit super() call in constructor");
                    }
                    else if (fd->storage_class & STCdisable)
                    {
                        error("cannot call super() implicitly because it is annotated with @disable");
                    }
                    else
                    {
                        Expression *e1 = new SuperExp(Loc());
                        Expression *e = new CallExp(Loc(), e1);
                        e = ::semantic(e, sc2);

                        Statement *s = new ExpStatement(Loc(), e);
                        fbody = new CompoundStatement(Loc(), s, fbody);
                    }
                }
                //printf("callSuper = x%x\n", sc2->callSuper);
            }

            /* https://issues.dlang.org/show_bug.cgi?id=17502
             * Wait until after the return type has been inferred before
             * generating the contracts for this function, and merging contracts
             * from overrides.
             *
             * https://issues.dlang.org/show_bug.cgi?id=17893
             * However should take care to generate this before inferered
             * function attributes are applied, such as 'nothrow'.
             *
             * This was originally at the end of the first semantic pass, but
             * required a fix-up to be done here for the '__result' variable
             * type of __ensure() inside auto functions, but this didn't work
             * if the out parameter was implicit.
             */
            buildEnsureRequire(this);

            int blockexit = BEnone;
            if (!fbody->isErrorStatement())
            {
                // Check for errors related to 'nothrow'.
                unsigned int nothrowErrors = global.errors;
                blockexit = blockExit(fbody, this, f->isnothrow);
                if (f->isnothrow && (global.errors != nothrowErrors))
                    ::error(loc, "nothrow %s '%s' may throw", kind(), toPrettyChars());
                if (flags & FUNCFLAGnothrowInprocess)
                {
                    if (type == f) f = (TypeFunction *)f->copy();
                    f->isnothrow = !(blockexit & BEthrow);
                }
            }

            if (fbody->isErrorStatement())
                ;
            else if (ad2 && isCtorDeclaration())
            {
                /* Append:
                 *  return this;
                 * to function body
                 */
                if (blockexit & BEfallthru)
                {
                    Statement *s = new ReturnStatement(loc, NULL);
                    s = ::semantic(s, sc2);
                    fbody = new CompoundStatement(loc, fbody, s);
                    hasReturnExp |= (hasReturnExp & 1 ? 16 : 1);
                }
            }
            else if (fes)
            {
                // For foreach(){} body, append a return 0;
                if (blockexit & BEfallthru)
                {
                    Expression *e = new IntegerExp(0);
                    Statement *s = new ReturnStatement(Loc(), e);
                    fbody = new CompoundStatement(Loc(), fbody, s);
                    hasReturnExp |= (hasReturnExp & 1 ? 16 : 1);
                }
                assert(!returnLabel);
            }
            else
            {
                const bool inlineAsm = (hasReturnExp & 8) != 0;
                if ((blockexit & BEfallthru) && f->next->ty != Tvoid && !inlineAsm)
                {
                    Expression *e;
                    if (!hasReturnExp)
                        error("has no return statement, but is expected to return a value of type %s", f->next->toChars());
                    else
                        error("no return exp; or assert(0); at end of function");
                    if (global.params.useAssert &&
                        !global.params.useInline)
                    {
                        /* Add an assert(0, msg); where the missing return
                         * should be.
                         */
                        e = new AssertExp(
                              endloc,
                              new IntegerExp(0),
                              new StringExp(loc, const_cast<char *>("missing return expression"))
                            );
                    }
                    else
                        e = new HaltExp(endloc);
                    e = new CommaExp(Loc(), e, f->next->defaultInit());
                    e = ::semantic(e, sc2);
                    Statement *s = new ExpStatement(Loc(), e);
                    fbody = new CompoundStatement(Loc(), fbody, s);
                }
            }

            if (returns)
            {
                bool implicit0 = addReturn0(this);
                Type *tret = implicit0 ? Type::tint32 : f->next;
                assert(tret->ty != Tvoid);
                if (vresult || returnLabel)
                    buildResultVar(scout ? scout : sc2, tret);

                /* Cannot move this loop into NrvoWalker, because
                 * returns[i] may be in the nested delegate for foreach-body.
                 */
                for (size_t i = 0; i < returns->dim; i++)
                {
                    ReturnStatement *rs = (*returns)[i];
                    Expression *exp = rs->exp;
                    if (exp->op == TOKerror)
                        continue;
                    if (tret->ty == Terror)
                    {
                        // Bugzilla 13702
                        exp = checkGC(sc2, exp);
                        continue;
                    }

                    if (!exp->implicitConvTo(tret) &&
                        parametersIntersect(exp->type))
                    {
                        if (exp->type->immutableOf()->implicitConvTo(tret))
                            exp = exp->castTo(sc2, exp->type->immutableOf());
                        else if (exp->type->wildOf()->implicitConvTo(tret))
                            exp = exp->castTo(sc2, exp->type->wildOf());
                    }
                    exp = exp->implicitCastTo(sc2, tret);

                    if (f->isref)
                    {
                        // Function returns a reference
                        exp = exp->toLvalue(sc2, exp);
                        checkReturnEscapeRef(sc2, exp, false);
                    }
                    else
                    {
                        exp = exp->optimize(WANTvalue);

                        /* Bugzilla 10789:
                         * If NRVO is not possible, all returned lvalues should call their postblits.
                         */
                        if (!nrvo_can)
                            exp = doCopyOrMove(sc2, exp);

                        if (tret->hasPointers())
                            checkReturnEscape(sc2, exp, false);
                    }

                    exp = checkGC(sc2, exp);

                    if (vresult)
                    {
                        // Create: return vresult = exp;
                        exp = new BlitExp(rs->loc, vresult, exp);
                        exp->type = vresult->type;

                        if (rs->caseDim)
                            exp = Expression::combine(exp, new IntegerExp(rs->caseDim));
                    }
                    else if (tintro && !tret->equals(tintro->nextOf()))
                    {
                        exp = exp->implicitCastTo(sc2, tintro->nextOf());
                    }
                    rs->exp = exp;
                }
            }
            if (nrvo_var || returnLabel)
            {
                NrvoWalker nw;
                nw.fd = this;
                nw.sc = sc2;
                nw.visitStmt(fbody);
            }

            sc2 = sc2->pop();
        }

        frequire = mergeFrequire(frequire);
        fensure = mergeFensure(fensure, outId);

        Statement *freq = frequire;
        Statement *fens = fensure;

        /* Do the semantic analysis on the [in] preconditions and
         * [out] postconditions.
         */
        if (freq)
        {
            /* frequire is composed of the [in] contracts
             */
            ScopeDsymbol *sym = new ScopeDsymbol();
            sym->parent = sc2->scopesym;
            sym->loc = loc;
            sym->endlinnum = endloc.linnum;
            sc2 = sc2->push(sym);
            sc2->flags = (sc2->flags & ~SCOPEcontract) | SCOPErequire;

            // BUG: need to error if accessing out parameters
            // BUG: need to treat parameters as const
            // BUG: need to disallow returns and throws
            // BUG: verify that all in and ref parameters are read
            freq = ::semantic(freq, sc2);
            blockExit(freq, this, false);

            sc2 = sc2->pop();

            if (!global.params.useIn)
                freq = NULL;
        }

        if (fens)
        {
            /* fensure is composed of the [out] contracts
             */
            if (f->next->ty == Tvoid && outId)
                error("void functions have no result");

            sc2 = scout;    //push
            sc2->flags = (sc2->flags & ~SCOPEcontract) | SCOPEensure;

            // BUG: need to treat parameters as const
            // BUG: need to disallow returns and throws
            if (fensure && f->next->ty != Tvoid)
                buildResultVar(scout, f->next);

            fens = ::semantic(fens, sc2);
            blockExit(fens, this, false);

            sc2 = sc2->pop();

            if (!global.params.useOut)
                fens = NULL;
        }

        if (fbody && fbody->isErrorStatement())
            ;
        else
        {
            Statements *a = new Statements();

            // Merge in initialization of 'out' parameters
            if (parameters)
            {
                for (size_t i = 0; i < parameters->dim; i++)
                {
                    VarDeclaration *v = (*parameters)[i];
                    if (v->storage_class & STCout)
                    {
                        assert(v->_init);
                        ExpInitializer *ie = v->_init->isExpInitializer();
                        assert(ie);
                        if (ie->exp->op == TOKconstruct)
                            ie->exp->op = TOKassign; // construction occured in parameter processing
                        a->push(new ExpStatement(Loc(), ie->exp));
                    }
                }
            }

            if (v_argptr)
            {
                // Handled in FuncDeclaration::toObjFile
                v_argptr->_init = new VoidInitializer(loc);
            }

            if (_arguments)
            {
                /* Advance to elements[] member of TypeInfo_Tuple with:
                 *  _arguments = v_arguments.elements;
                 */
                Expression *e = new VarExp(Loc(), v_arguments);
                e = new DotIdExp(Loc(), e, Id::elements);
                e = new ConstructExp(Loc(), _arguments, e);
                e = ::semantic(e, sc2);

                _arguments->_init = new ExpInitializer(Loc(), e);
                DeclarationExp *de = new DeclarationExp(Loc(), _arguments);
                a->push(new ExpStatement(Loc(), de));
            }

            // Merge contracts together with body into one compound statement

            if (freq || fpreinv)
            {
                if (!freq)
                    freq = fpreinv;
                else if (fpreinv)
                    freq = new CompoundStatement(Loc(), freq, fpreinv);

                a->push(freq);
            }

            if (fbody)
                a->push(fbody);

            if (fens || fpostinv)
            {
                if (!fens)
                    fens = fpostinv;
                else if (fpostinv)
                    fens = new CompoundStatement(Loc(), fpostinv, fens);

                LabelStatement *ls = new LabelStatement(Loc(), Id::returnLabel, fens);
                returnLabel->statement = ls;
                a->push(returnLabel->statement);

                if (f->next->ty != Tvoid && vresult)
                {
                    // Create: return vresult;
                    Expression *e = new VarExp(Loc(), vresult);
                    if (tintro)
                    {
                        e = e->implicitCastTo(sc, tintro->nextOf());
                        e = ::semantic(e, sc);
                    }
                    ReturnStatement *s = new ReturnStatement(Loc(), e);
                    a->push(s);
                }
            }
            if (addReturn0(this))
            {
                // Add a return 0; statement
                Statement *s = new ReturnStatement(Loc(), new IntegerExp(0));
                a->push(s);
            }

            Statement *sbody = new CompoundStatement(Loc(), a);
            /* Append destructor calls for parameters as finally blocks.
             */
            if (parameters)
            {
                for (size_t i = 0; i < parameters->dim; i++)
                {
                    VarDeclaration *v = (*parameters)[i];

                    if (v->storage_class & (STCref | STCout | STClazy))
                        continue;

                    if (v->needsScopeDtor())
                    {
                        // same with ExpStatement.scopeCode()
                        Statement *s = new DtorExpStatement(Loc(), v->edtor, v);
                        v->storage_class |= STCnodtor;

                        s = ::semantic(s, sc2);

                        bool isnothrow = f->isnothrow & !(flags & FUNCFLAGnothrowInprocess);
                        int blockexit = blockExit(s, this, isnothrow);
                        if (f->isnothrow && isnothrow && blockexit & BEthrow)
                            ::error(loc, "nothrow %s '%s' may throw", kind(), toPrettyChars());
                        if (flags & FUNCFLAGnothrowInprocess && blockexit & BEthrow)
                            f->isnothrow = false;
                        if (blockExit(sbody, this, f->isnothrow) == BEfallthru)
                            sbody = new CompoundStatement(Loc(), sbody, s);
                        else
                            sbody = new TryFinallyStatement(Loc(), sbody, s);
                    }
                }
            }
            // from this point on all possible 'throwers' are checked
            flags &= ~FUNCFLAGnothrowInprocess;

            if (isSynchronized())
            {
                /* Wrap the entire function body in a synchronized statement
                 */
                ClassDeclaration *cd = isThis() ? isThis()->isClassDeclaration() : parent->isClassDeclaration();

                if (cd)
                {
                    if (!global.params.is64bit &&
                        global.params.isWindows &&
                        !isStatic() && !sbody->usesEH() && !global.params.trace)
                    {
                        /* The back end uses the "jmonitor" hack for syncing;
                         * no need to do the sync at this level.
                         */
                    }
                    else
                    {
                        Expression *vsync;
                        if (isStatic())
                        {
                            // The monitor is in the ClassInfo
                            vsync = new DotIdExp(loc, resolve(loc, sc2, cd, false), Id::classinfo);
                        }
                        else
                        {
                            // 'this' is the monitor
                            vsync = new VarExp(loc, vthis);
                        }
                        sbody = new PeelStatement(sbody);       // don't redo semantic()
                        sbody = new SynchronizedStatement(loc, vsync, sbody);
                        sbody = ::semantic(sbody, sc2);
                    }
                }
                else
                {
                    error("synchronized function %s must be a member of a class", toChars());
                }
            }

            // If declaration has no body, don't set sbody to prevent incorrect codegen.
            InterfaceDeclaration *id = parent->isInterfaceDeclaration();
            if (fbody || (id && (fdensure || fdrequire) && isVirtual()))
                fbody = sbody;
        }

        // Fix up forward-referenced gotos
        if (gotos)
        {
            for (size_t i = 0; i < gotos->dim; ++i)
            {
                (*gotos)[i]->checkLabel();
            }
        }

        if (naked && (fensure || frequire))
            error("naked assembly functions with contracts are not supported");

        sc2->callSuper = 0;
        sc2->pop();
    }

    if (checkClosure())
    {
        // We should be setting errors here instead of relying on the global error count.
        //errors = true;
    }

    /* If function survived being marked as impure, then it is pure
     */
    if (flags & FUNCFLAGpurityInprocess)
    {
        flags &= ~FUNCFLAGpurityInprocess;
        if (type == f)
            f = (TypeFunction *)f->copy();
        f->purity = PUREfwdref;
    }

    if (flags & FUNCFLAGsafetyInprocess)
    {
        flags &= ~FUNCFLAGsafetyInprocess;
        if (type == f)
            f = (TypeFunction *)f->copy();
        f->trust = TRUSTsafe;
    }

    if (flags & FUNCFLAGnogcInprocess)
    {
        flags &= ~FUNCFLAGnogcInprocess;
        if (type == f)
            f = (TypeFunction *)f->copy();
        f->isnogc = true;
    }

    if (flags & FUNCFLAGreturnInprocess)
    {
        flags &= ~FUNCFLAGreturnInprocess;
        if (storage_class & STCreturn)
        {
            if (type == f)
                f = (TypeFunction *)f->copy();
            f->isreturn = true;
        }
    }

    flags &= ~FUNCFLAGinferScope;

    // Infer STCscope
    if (parameters)
    {
        size_t nfparams = Parameter::dim(f->parameters);
        assert(nfparams == parameters->dim);
        for (size_t u = 0; u < parameters->dim; u++)
        {
            VarDeclaration *v = (*parameters)[u];
            if (v->storage_class & STCmaybescope)
            {
                //printf("Inferring scope for %s\n", v->toChars());
                Parameter *p = Parameter::getNth(f->parameters, u);
                v->storage_class &= ~STCmaybescope;
                v->storage_class |= STCscope | STCscopeinferred;
                p->storageClass |= STCscope | STCscopeinferred;
                assert(!(p->storageClass & STCmaybescope));
            }
        }
    }

    if (vthis && vthis->storage_class & STCmaybescope)
    {
        vthis->storage_class &= ~STCmaybescope;
        vthis->storage_class |= STCscope | STCscopeinferred;
        f->isscope = true;
        f->isscopeinferred = true;
    }

    // reset deco to apply inference result to mangled name
    if (f != type)
        f->deco = NULL;

    // Do semantic type AFTER pure/nothrow inference.
    if (!f->deco && ident != Id::xopEquals && ident != Id::xopCmp)
    {
        sc = sc->push();
        if (isCtorDeclaration()) // Bugzilla #15665
            sc->flags |= SCOPEctor;
        sc->stc = 0;
        sc->linkage = linkage;  // Bugzilla 8496
        type = f->semantic(loc, sc);
        sc = sc->pop();
    }

    /* If this function had instantiated with gagging, error reproduction will be
     * done by TemplateInstance::semantic.
     * Otherwise, error gagging should be temporarily ungagged by functionSemantic3.
     */
    semanticRun = PASSsemantic3done;
    semantic3Errors = (global.errors != oldErrors) || (fbody && fbody->isErrorStatement());
    if (type->ty == Terror)
        errors = true;
    //printf("-FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
    //fflush(stdout);
}

/****************************************************
 * Resolve forward reference of function signature -
 * parameter types, return type, and attributes.
 * Returns false if any errors exist in the signature.
 */
bool FuncDeclaration::functionSemantic()
{
    if (!_scope)
        return !errors;

    if (!originalType)      // semantic not yet run
    {
        TemplateInstance *spec = isSpeculative();
        unsigned olderrs = global.errors;
        unsigned oldgag = global.gag;
        if (global.gag && !spec)
            global.gag = 0;
        semantic(_scope);
        global.gag = oldgag;
        if (spec && global.errors != olderrs)
            spec->errors = (global.errors - olderrs != 0);
        if (olderrs != global.errors)   // if errors compiling this function
            return false;
    }

    // if inferring return type, sematic3 needs to be run
    // - When the function body contains any errors, we cannot assume
    //   the inferred return type is valid.
    //   So, the body errors should become the function signature error.
    if (inferRetType && type && !type->nextOf())
        return functionSemantic3();

    TemplateInstance *ti;
    if (isInstantiated() && !isVirtualMethod() &&
        ((ti = parent->isTemplateInstance()) == NULL || ti->isTemplateMixin() || ti->tempdecl->ident == ident))
    {
        AggregateDeclaration *ad = isMember2();
        if (ad && ad->sizeok != SIZEOKdone)
        {
            /* Currently dmd cannot resolve forward references per methods,
             * then setting SIZOKfwd is too conservative and would break existing code.
             * So, just stop method attributes inference until ad->semantic() done.
             */
            //ad->sizeok = SIZEOKfwd;
        }
        else
            return functionSemantic3() || !errors;
    }

    if (storage_class & STCinference)
        return functionSemantic3() || !errors;

    return !errors;
}

/****************************************************
 * Resolve forward reference of function body.
 * Returns false if any errors exist in the body.
 */
bool FuncDeclaration::functionSemantic3()
{
    if (semanticRun < PASSsemantic3 && _scope)
    {
        /* Forward reference - we need to run semantic3 on this function.
         * If errors are gagged, and it's not part of a template instance,
         * we need to temporarily ungag errors.
         */
        TemplateInstance *spec = isSpeculative();
        unsigned olderrs = global.errors;
        unsigned oldgag = global.gag;
        if (global.gag && !spec)
            global.gag = 0;
        semantic3(_scope);
        global.gag = oldgag;

        // If it is a speculatively-instantiated template, and errors occur,
        // we need to mark the template as having errors.
        if (spec && global.errors != olderrs)
            spec->errors = (global.errors - olderrs != 0);
        if (olderrs != global.errors)   // if errors compiling this function
            return false;
    }

    return !errors && !semantic3Errors;
}

/****************************************************
 * Check that this function type is properly resolved.
 * If not, report "forward reference error" and return true.
 */
bool FuncDeclaration::checkForwardRef(Loc loc)
{
    if (!functionSemantic())
        return true;

    /* No deco means the functionSemantic() call could not resolve
     * forward referenes in the type of this function.
     */
    if (!type->deco)
    {
        bool inSemantic3 = (inferRetType && semanticRun >= PASSsemantic3);
        ::error(loc, "forward reference to %s'%s'",
            (inSemantic3 ? "inferred return type of function " : ""),
            toChars());
        return true;
    }
    return false;
}

VarDeclaration *FuncDeclaration::declareThis(Scope *sc, AggregateDeclaration *ad)
{
    if (ad)
    {
        VarDeclaration *v;
        {
            //printf("declareThis() %s\n", toChars());
            Type *thandle = ad->handleType();
            assert(thandle);
            thandle = thandle->addMod(type->mod);
            thandle = thandle->addStorageClass(storage_class);
            v = new ThisDeclaration(loc, thandle);
            v->storage_class |= STCparameter;
            if (thandle->ty == Tstruct)
            {
                v->storage_class |= STCref;

                // if member function is marked 'inout', then 'this' is 'return ref'
                if (type->ty == Tfunction && ((TypeFunction *)type)->iswild & 2)
                    v->storage_class |= STCreturn;
            }
            if (type->ty == Tfunction)
            {
                TypeFunction *tf = (TypeFunction *)type;
                if (tf->isreturn)
                    v->storage_class |= STCreturn;
                if (tf->isscope)
                    v->storage_class |= STCscope;
            }
            if (flags & FUNCFLAGinferScope && !(v->storage_class & STCscope))
                v->storage_class |= STCmaybescope;

            v->semantic(sc);
            if (!sc->insert(v))
                assert(0);
            v->parent = this;
            return v;
        }
    }
    else if (isNested())
    {
        /* The 'this' for a nested function is the link to the
         * enclosing function's stack frame.
         * Note that nested functions and member functions are disjoint.
         */
        VarDeclaration *v = new ThisDeclaration(loc, Type::tvoid->pointerTo());
        v->storage_class |= STCparameter;
        if (type->ty == Tfunction)
        {
            TypeFunction *tf = (TypeFunction *)type;
            if (tf->isreturn)
                v->storage_class |= STCreturn;
            if (tf->isscope)
                v->storage_class |= STCscope;
        }
        if (flags & FUNCFLAGinferScope && !(v->storage_class & STCscope))
            v->storage_class |= STCmaybescope;

        v->semantic(sc);
        if (!sc->insert(v))
            assert(0);
        v->parent = this;
        return v;
    }

    return NULL;
}

bool FuncDeclaration::equals(RootObject *o)
{
    if (this == o)
        return true;

    Dsymbol *s = isDsymbol(o);
    if (s)
    {
        FuncDeclaration *fd1 = this;
        FuncDeclaration *fd2 = s->isFuncDeclaration();
        if (!fd2)
            return false;

        FuncAliasDeclaration *fa1 = fd1->isFuncAliasDeclaration();
        FuncAliasDeclaration *fa2 = fd2->isFuncAliasDeclaration();
        if (fa1 && fa2)
        {
            return fa1->toAliasFunc()->equals(fa2->toAliasFunc()) &&
                   fa1->hasOverloads == fa2->hasOverloads;
        }

        if (fa1 && (fd1 = fa1->toAliasFunc())->isUnique() && !fa1->hasOverloads)
            fa1 = NULL;
        if (fa2 && (fd2 = fa2->toAliasFunc())->isUnique() && !fa2->hasOverloads)
            fa2 = NULL;
        if ((fa1 != NULL) != (fa2 != NULL))
            return false;

        return fd1->toParent()->equals(fd2->toParent()) &&
            fd1->ident->equals(fd2->ident) && fd1->type->equals(fd2->type);
    }
    return false;
}

/****************************************************
 * Declare result variable lazily.
 */

void FuncDeclaration::buildResultVar(Scope *sc, Type *tret)
{
    if (!vresult)
    {
        Loc loc = fensure ? fensure->loc : this->loc;

        /* If inferRetType is true, tret may not be a correct return type yet.
         * So, in here it may be a temporary type for vresult, and after
         * fbody->semantic() running, vresult->type might be modified.
         */
        vresult = new VarDeclaration(loc, tret, outId ? outId : Id::result, NULL);
        vresult->storage_class |= STCnodtor;

        if (outId == Id::result)
            vresult->storage_class |= STCtemp;
        if (!isVirtual())
            vresult->storage_class |= STCconst;
        vresult->storage_class |= STCresult;

        // set before the semantic() for checkNestedReference()
        vresult->parent = this;
    }

    if (sc && vresult->semanticRun == PASSinit)
    {
        TypeFunction *tf = type->toTypeFunction();
        if (tf->isref)
            vresult->storage_class |= STCref;
        vresult->type = tret;

        vresult->semantic(sc);

        if (!sc->insert(vresult))
            error("out result %s is already defined", vresult->toChars());
        assert(vresult->parent == this);
    }
}

/****************************************************
 * Merge into this function the 'in' contracts of all it overrides.
 * 'in's are OR'd together, i.e. only one of them needs to pass.
 */

Statement *FuncDeclaration::mergeFrequire(Statement *sf)
{
    /* If a base function and its override both have an IN contract, then
     * only one of them needs to succeed. This is done by generating:
     *
     * void derived.in() {
     *  try {
     *    base.in();
     *  }
     *  catch () {
     *    ... body of derived.in() ...
     *  }
     * }
     *
     * So if base.in() doesn't throw, derived.in() need not be executed, and the contract is valid.
     * If base.in() throws, then derived.in()'s body is executed.
     */

    /* Implementing this is done by having the overriding function call
     * nested functions (the fdrequire functions) nested inside the overridden
     * function. This requires that the stack layout of the calling function's
     * parameters and 'this' pointer be in the same place (as the nested
     * function refers to them).
     * This is easy for the parameters, as they are all on the stack in the same
     * place by definition, since it's an overriding function. The problem is
     * getting the 'this' pointer in the same place, since it is a local variable.
     * We did some hacks in the code generator to make this happen:
     *  1. always generate exception handler frame, or at least leave space for it
     *     in the frame (Windows 32 SEH only)
     *  2. always generate an EBP style frame
     *  3. since 'this' is passed in a register that is subsequently copied into
     *     a stack local, allocate that local immediately following the exception
     *     handler block, so it is always at the same offset from EBP.
     */
    for (size_t i = 0; i < foverrides.dim; i++)
    {
        FuncDeclaration *fdv = foverrides[i];

        /* The semantic pass on the contracts of the overridden functions must
         * be completed before code generation occurs.
         * https://issues.dlang.org/show_bug.cgi?id=3602
         */
        if (fdv->frequire && fdv->semanticRun != PASSsemantic3done)
        {
            assert(fdv->_scope);
            Scope *sc = fdv->_scope->push();
            sc->stc &= ~STCoverride;
            fdv->semantic3(sc);
            sc->pop();
        }

        sf = fdv->mergeFrequire(sf);
        if (sf && fdv->fdrequire)
        {
            //printf("fdv->frequire: %s\n", fdv->frequire->toChars());
            /* Make the call:
             *   try { __require(); }
             *   catch (Throwable) { frequire; }
             */
            Expression *eresult = NULL;
            Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdrequire, false), eresult);
            Statement *s2 = new ExpStatement(loc, e);

            Catch *c = new Catch(loc, getThrowable(), NULL, sf);
            c->internalCatch = true;
            Catches *catches = new Catches();
            catches->push(c);
            sf = new TryCatchStatement(loc, s2, catches);
        }
        else
            return NULL;
    }
    return sf;
}

/****************************************************
 * Merge into this function the 'out' contracts of all it overrides.
 * 'out's are AND'd together, i.e. all of them need to pass.
 */

Statement *FuncDeclaration::mergeFensure(Statement *sf, Identifier *oid)
{
    /* Same comments as for mergeFrequire(), except that we take care
     * of generating a consistent reference to the 'result' local by
     * explicitly passing 'result' to the nested function as a reference
     * argument.
     * This won't work for the 'this' parameter as it would require changing
     * the semantic code for the nested function so that it looks on the parameter
     * list for the 'this' pointer, something that would need an unknown amount
     * of tweaking of various parts of the compiler that I'd rather leave alone.
     */
    for (size_t i = 0; i < foverrides.dim; i++)
    {
        FuncDeclaration *fdv = foverrides[i];

        /* The semantic pass on the contracts of the overridden functions must
         * be completed before code generation occurs.
         * https://issues.dlang.org/show_bug.cgi?id=3602 and
         * https://issues.dlang.org/show_bug.cgi?id=5230
         */
        if (needsFensure(fdv) && fdv->semanticRun != PASSsemantic3done)
        {
            assert(fdv->_scope);
            Scope *sc = fdv->_scope->push();
            sc->stc &= ~STCoverride;
            fdv->semantic3(sc);
            sc->pop();
        }

        sf = fdv->mergeFensure(sf, oid);
        if (fdv->fdensure)
        {
            //printf("fdv->fensure: %s\n", fdv->fensure->toChars());
            // Make the call: __ensure(result)
            Expression *eresult = NULL;
            if (outId)
            {
                eresult = new IdentifierExp(loc, oid);

                Type *t1 = fdv->type->nextOf()->toBasetype();
                Type *t2 = this->type->nextOf()->toBasetype();
                if (t1->isBaseOf(t2, NULL))
                {
                    /* Making temporary reference variable is necessary
                     * in covariant return.
                     * See bugzilla 5204 and 10479.
                     */
                    ExpInitializer *ei = new ExpInitializer(Loc(), eresult);
                    VarDeclaration *v = new VarDeclaration(Loc(), t1, Identifier::generateId("__covres"), ei);
                    v->storage_class |= STCtemp;
                    DeclarationExp *de = new DeclarationExp(Loc(), v);
                    VarExp *ve = new VarExp(Loc(), v);
                    eresult = new CommaExp(Loc(), de, ve);
                }
            }
            Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdensure, false), eresult);
            Statement *s2 = new ExpStatement(loc, e);

            if (sf)
            {
                sf = new CompoundStatement(sf->loc, s2, sf);
            }
            else
                sf = s2;
        }
    }
    return sf;
}

/****************************************************
 * Determine if 'this' overrides fd.
 * Return !=0 if it does.
 */

int FuncDeclaration::overrides(FuncDeclaration *fd)
{   int result = 0;

    if (fd->ident == ident)
    {
        int cov = type->covariant(fd->type);
        if (cov)
        {   ClassDeclaration *cd1 = toParent()->isClassDeclaration();
            ClassDeclaration *cd2 = fd->toParent()->isClassDeclaration();

            if (cd1 && cd2 && cd2->isBaseOf(cd1, NULL))
                result = 1;
        }
    }
    return result;
}

/*************************************************
 * Find index of function in vtbl[0..dim] that
 * this function overrides.
 * Prefer an exact match to a covariant one.
 * Params:
 *      fix17349 = enable fix https://issues.dlang.org/show_bug.cgi?id=17349
 * Returns:
 *      -1      didn't find one
 *      -2      can't determine because of forward references
 */

int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim, bool fix17349)
{
    //printf("findVtblIndex() %s\n", toChars());
    FuncDeclaration *mismatch = NULL;
    StorageClass mismatchstc = 0;
    int mismatchvi = -1;
    int exactvi = -1;
    int bestvi = -1;
    for (int vi = 0; vi < dim; vi++)
    {
        FuncDeclaration *fdv = (*vtbl)[vi]->isFuncDeclaration();
        if (fdv && fdv->ident == ident)
        {
            if (type->equals(fdv->type))        // if exact match
            {
                if (fdv->parent->isClassDeclaration())
                {
                    if (fdv->isFuture())
                    {
                        bestvi = vi;
                        continue;           // keep looking
                    }
                    return vi;                  // no need to look further
                }

                if (exactvi >= 0)
                {
                    error("cannot determine overridden function");
                    return exactvi;
                }
                exactvi = vi;

                bestvi = vi;
                continue;
            }

            StorageClass stc = 0;
            int cov = type->covariant(fdv->type, &stc, fix17349);
            //printf("\tbaseclass cov = %d\n", cov);
            switch (cov)
            {
                case 0:         // types are distinct
                    break;

                case 1:
                    bestvi = vi;        // covariant, but not identical
                    break;              // keep looking for an exact match

                case 2:
                    mismatchvi = vi;
                    mismatchstc = stc;
                    mismatch = fdv;     // overrides, but is not covariant
                    break;              // keep looking for an exact match

                case 3:
                    return -2;  // forward references

                default:
                    assert(0);
            }
        }
    }
    if (bestvi == -1 && mismatch)
    {
        //type->print();
        //mismatch->type->print();
        //printf("%s %s\n", type->deco, mismatch->type->deco);
        //printf("stc = %llx\n", mismatchstc);
        if (mismatchstc)
        {   // Fix it by modifying the type to add the storage classes
            type = type->addStorageClass(mismatchstc);
            bestvi = mismatchvi;
        }
    }
    return bestvi;
}

/*********************************
 * If function a function in a base class,
 * return that base class.
 * Params:
 *  cd = class that function is in
 * Returns:
 *  base class if overriding, NULL if not
 */
BaseClass *FuncDeclaration::overrideInterface()
{
    ClassDeclaration *cd = parent->isClassDeclaration();
    for (size_t i = 0; i < cd->interfaces.length; i++)
    {
        BaseClass *b = cd->interfaces.ptr[i];
        int v = findVtblIndex((Dsymbols *)&b->sym->vtbl, (int)b->sym->vtbl.dim);
        if (v >= 0)
            return b;
    }
    return NULL;
}

/****************************************************
 * Overload this FuncDeclaration with the new one f.
 * Return true if successful; i.e. no conflict.
 */

bool FuncDeclaration::overloadInsert(Dsymbol *s)
{
    //printf("FuncDeclaration::overloadInsert(s = %s) this = %s\n", s->toChars(), toChars());
    assert(s != this);

    AliasDeclaration *ad = s->isAliasDeclaration();
    if (ad)
    {
        if (overnext)
            return overnext->overloadInsert(ad);
        if (!ad->aliassym && ad->type->ty != Tident && ad->type->ty != Tinstance)
        {
            //printf("\tad = '%s'\n", ad->type->toChars());
            return false;
        }
        overnext = ad;
        //printf("\ttrue: no conflict\n");
        return true;
    }
    TemplateDeclaration *td = s->isTemplateDeclaration();
    if (td)
    {
        if (!td->funcroot)
            td->funcroot = this;
        if (overnext)
            return overnext->overloadInsert(td);
        overnext = td;
        return true;
    }
    FuncDeclaration *fd = s->isFuncDeclaration();
    if (!fd)
        return false;

    if (overnext)
    {
        td = overnext->isTemplateDeclaration();
        if (td)
            fd->overloadInsert(td);
        else
            return overnext->overloadInsert(fd);
    }
    overnext = fd;
    //printf("\ttrue: no conflict\n");
    return true;
}

/***************************************************
 * Visit each overloaded function/template in turn, and call
 * (*fp)(param, s) on it.
 * Exit when no more, or (*fp)(param, f) returns nonzero.
 * Returns:
 *      ==0     continue
 *      !=0     done
 */

int overloadApply(Dsymbol *fstart, void *param, int (*fp)(void *, Dsymbol *))
{
    Dsymbol *d;
    Dsymbol *next;
    for (d = fstart; d; d = next)
    {
        if (OverDeclaration *od = d->isOverDeclaration())
        {
            if (od->hasOverloads)
            {
                if (int r = overloadApply(od->aliassym, param, fp))
                    return r;
            }
            else
            {
                if (int r = (*fp)(param, od->aliassym))
                    return r;
            }
            next = od->overnext;
        }
        else if (FuncAliasDeclaration *fa = d->isFuncAliasDeclaration())
        {
            if (fa->hasOverloads)
            {
                if (int r = overloadApply(fa->funcalias, param, fp))
                    return r;
            }
            else
            {
                FuncDeclaration *fd = fa->toAliasFunc();
                if (!fd)
                {
                    d->error("is aliased to a function");
                    break;
                }
                if (int r = (*fp)(param, fd))
                    return r;
            }
            next = fa->overnext;
        }
        else if (AliasDeclaration *ad = d->isAliasDeclaration())
        {
            next = ad->toAlias();
            if (next == ad)
                break;
            if (next == fstart)
                break;
        }
        else if (TemplateDeclaration *td = d->isTemplateDeclaration())
        {
            if (int r = (*fp)(param, td))
                return r;
            next = td->overnext;
        }
        else
        {
            FuncDeclaration *fd = d->isFuncDeclaration();
            if (!fd)
            {
                d->error("is aliased to a function");
                break;              // BUG: should print error message?
            }
            if (int r = (*fp)(param, fd))
                return r;
            next = fd->overnext;
        }
    }
    return 0;
}

/********************************************
 * If there are no overloads of function f, return that function,
 * otherwise return NULL.
 */

FuncDeclaration *FuncDeclaration::isUnique()
{
  struct ParamUnique
  {
    static int fp(void *param, Dsymbol *s)
    {
        FuncDeclaration *f = s->isFuncDeclaration();
        if (!f)
            return 0;
        FuncDeclaration **pf = (FuncDeclaration **)param;

        if (*pf)
        {
            *pf = NULL;
            return 1;               // ambiguous, done
        }
        else
        {
            *pf = f;
            return 0;
        }
    }
  };
    FuncDeclaration *result = NULL;
    overloadApply(this, &result, &ParamUnique::fp);
    return result;
}

/********************************************
 * Find function in overload list that exactly matches t.
 */

FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t)
{
  struct ParamExact
  {
    Type *t;            // type to match
    FuncDeclaration *f; // return value

    static int fp(void *param, Dsymbol *s)
    {
        FuncDeclaration *f = s->isFuncDeclaration();
        if (!f)
            return 0;
        ParamExact *p = (ParamExact *)param;
        Type *t = p->t;

        if (t->equals(f->type))
        {
            p->f = f;
            return 1;
        }

        /* Allow covariant matches, as long as the return type
         * is just a const conversion.
         * This allows things like pure functions to match with an impure function type.
         */
        if (t->ty == Tfunction)
        {   TypeFunction *tf = (TypeFunction *)f->type;
            if (tf->covariant(t) == 1 &&
                tf->nextOf()->implicitConvTo(t->nextOf()) >= MATCHconst)
            {
                p->f = f;
                return 1;
            }
        }
        return 0;
    }
  };
    ParamExact p;
    p.t = t;
    p.f = NULL;
    overloadApply(this, &p, &ParamExact::fp);
    return p.f;
}

void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod)
{
    bool bothMutable = ((lhsMod & rhsMod) == 0);
    bool sharedMismatch = ((lhsMod ^ rhsMod) & MODshared) != 0;
    bool sharedMismatchOnly = ((lhsMod ^ rhsMod) == MODshared);

    if (lhsMod & MODshared)
        buf->writestring("shared ");
    else if (sharedMismatch && !(lhsMod & MODimmutable))
        buf->writestring("non-shared ");

    if (bothMutable && sharedMismatchOnly)
    { }
    else if (lhsMod & MODimmutable)
        buf->writestring("immutable ");
    else if (lhsMod & MODconst)
        buf->writestring("const ");
    else if (lhsMod & MODwild)
        buf->writestring("inout ");
    else
        buf->writestring("mutable ");
}

/********************************************
 * Find function in overload list that matches to the 'this' modifier.
 * There's four result types.
 *
 * 1. If the 'tthis' matches only one candidate, it's an "exact match".
 *    Returns the function and 'hasOverloads' is set to false.
 *      eg. If 'tthis" is mutable and there's only one mutable method.
 * 2. If there's two or more match candidates, but a candidate function will be
 *    a "better match".
 *    Returns the better match function but 'hasOverloads' is set to true.
 *      eg. If 'tthis' is mutable, and there's both mutable and const methods,
 *          the mutable method will be a better match.
 * 3. If there's two or more match candidates, but there's no better match,
 *    Returns NULL and 'hasOverloads' is set to true to represent "ambiguous match".
 *      eg. If 'tthis' is mutable, and there's two or more mutable methods.
 * 4. If there's no candidates, it's "no match" and returns NULL with error report.
 *      e.g. If 'tthis' is const but there's no const methods.
 */
FuncDeclaration *FuncDeclaration::overloadModMatch(Loc loc, Type *tthis, bool &hasOverloads)
{
    //printf("FuncDeclaration::overloadModMatch('%s')\n", toChars());
    Match m;
    memset(&m, 0, sizeof(m));
    m.last = MATCHnomatch;

  struct ParamMod
  {
    Match *m;
    Type *tthis;

    static int fp(void *param, Dsymbol *s)
    {
        if (FuncDeclaration *fd = s->isFuncDeclaration())
            return ((ParamMod *)param)->fp(fd);
        return 0;
    }
    int fp(FuncDeclaration *f)
    {
        if (f == m->lastf)          // skip duplicates
            return 0;

        m->anyf = f;
        TypeFunction *tf = f->type->toTypeFunction();
        //printf("tf = %s\n", tf->toChars());

        MATCH match;
        if (tthis)   // non-static functions are preferred than static ones
        {
            if (f->needThis())
                match = f->isCtorDeclaration() ? MATCHexact : MODmethodConv(tthis->mod, tf->mod);
            else
                match = MATCHconst; // keep static funciton in overload candidates
        }
        else            // static functions are preferred than non-static ones
        {
            if (f->needThis())
                match = MATCHconvert;
            else
                match = MATCHexact;
        }
        if (match != MATCHnomatch)
        {
            if (match > m->last) goto LfIsBetter;
            if (match < m->last) goto LlastIsBetter;

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

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

        LlastIsBetter:
            //printf("\tlastbetter\n");
            m->count++; // count up
            return 0;

        LfIsBetter:
            //printf("\tisbetter\n");
            if (m->last <= MATCHconvert)
            {
                // clear last secondary matching
                m->nextf = NULL;
                m->count = 0;
            }
            m->last = match;
            m->lastf = f;
            m->count++;     // count up
            return 0;
        }
        return 0;
    }
  };
    ParamMod p;
    p.m = &m;
    p.tthis = tthis;
    overloadApply(this, &p, &ParamMod::fp);

    if (m.count == 1)       // exact match
    {
        hasOverloads = false;
    }
    else if (m.count > 1)   // better or ambiguous match
    {
        hasOverloads = true;
    }
    else                    // no match
    {
        hasOverloads = true;
        TypeFunction *tf = this->type->toTypeFunction();
        assert(tthis);
        assert(!MODimplicitConv(tthis->mod, tf->mod));  // modifier mismatch
        {
            OutBuffer thisBuf, funcBuf;
            MODMatchToBuffer(&thisBuf, tthis->mod, tf->mod);
            MODMatchToBuffer(&funcBuf, tf->mod, tthis->mod);
            ::error(loc, "%smethod %s is not callable using a %sobject",
                funcBuf.peekString(), this->toPrettyChars(), thisBuf.peekString());
        }
    }

    return m.lastf;
}

/********************************************
 * Returns true if function was declared
 * directly or indirectly in a unittest block
 */
bool FuncDeclaration::inUnittest()
{
    Dsymbol *f = this;
    do
    {
        if (f->isUnitTestDeclaration())
            return true;
        f = f->toParent();
    } while (f);

    return false;
}

/********************************************
 * find function template root in overload list
 */

TemplateDeclaration *FuncDeclaration::findTemplateDeclRoot()
{
    FuncDeclaration *f = this;
    while (f && f->overnext)
    {
        //printf("f->overnext = %p %s\n", f->overnext, f->overnext->toChars());
        TemplateDeclaration *td = f->overnext->isTemplateDeclaration();
        if (td)
            return td;
        f = f->overnext->isFuncDeclaration();
    }
    return NULL;
}

/*************************************
 * Determine partial specialization order of 'this' vs g.
 * This is very similar to TemplateDeclaration::leastAsSpecialized().
 * Returns:
 *      match   'this' is at least as specialized as g
 *      0       g is more specialized than 'this'
 */

MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
{
    /* This works by calling g() with f()'s parameters, and
     * if that is possible, then f() is at least as specialized
     * as g() is.
     */

    TypeFunction *tf = type->toTypeFunction();
    TypeFunction *tg = g->type->toTypeFunction();
    size_t nfparams = Parameter::dim(tf->parameters);

    /* If both functions have a 'this' pointer, and the mods are not
     * the same and g's is not const, then this is less specialized.
     */
    if (needThis() && g->needThis() && tf->mod != tg->mod)
    {
        if (isCtorDeclaration())
        {
            if (!MODimplicitConv(tg->mod, tf->mod))
                return MATCHnomatch;
        }
        else
        {
            if (!MODimplicitConv(tf->mod, tg->mod))
                return MATCHnomatch;
        }
    }

    /* Create a dummy array of arguments out of the parameters to f()
     */
    Expressions args;
    args.setDim(nfparams);
    for (size_t u = 0; u < nfparams; u++)
    {
        Parameter *p = Parameter::getNth(tf->parameters, u);
        Expression *e;
        if (p->storageClass & (STCref | STCout))
        {
            e = new IdentifierExp(Loc(), p->ident);
            e->type = p->type;
        }
        else
            e = p->type->defaultInitLiteral(Loc());
        args[u] = e;
    }

    MATCH m = (MATCH) tg->callMatch(NULL, &args, 1);
    if (m > MATCHnomatch)
    {
        /* A variadic parameter list is less specialized than a
         * non-variadic one.
         */
        if (tf->varargs && !tg->varargs)
            goto L1;    // less specialized

        return m;
    }
  L1:
    return MATCHnomatch;
}

/// Walk through candidate template overloads and print them in the diagnostics.
struct TemplateCandidateWalker
{
    Loc loc;
    int numToDisplay;  // max num of overloads to print (-v overrides this).

    /// Count template overloads.
    struct CountWalker
    {
        int numOverloads;

        static int fp(void *param, Dsymbol *)
        {
            CountWalker *p = (CountWalker *)param;
            ++(p->numOverloads);
            return 0;
        }
    };

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

        TemplateCandidateWalker *p = (TemplateCandidateWalker *)param;

        ::errorSupplemental(t->loc, "%s", t->toPrettyChars());

        if (!global.params.verbose && --(p->numToDisplay) == 0 && t->overnext)
        {
            // Too many overloads to sensibly display.
            // Just show count of remaining overloads.
            CountWalker cw;
            cw.numOverloads = 0;
            overloadApply(t->overnext, &cw, &CountWalker::fp);

            if (cw.numOverloads > 0)
                ::errorSupplemental(p->loc, "... (%d more, -v to show) ...", cw.numOverloads);

            return 1;  // stop iterating
        }

        return 0;
    }
};

/// Walk through candidate template overloads and print them in the diagnostics.
struct FuncCandidateWalker
{
    Loc loc;
    int numToDisplay;  // max num of overloads to print (-v overrides this).

    /// Count function overloads.
    struct CountWalker
    {
        int numOverloads;

        static int fp(void *param, Dsymbol *)
        {
            CountWalker *p = (CountWalker *)param;
            ++(p->numOverloads);
            return 0;
        }
    };

    static int fp(void *param, Dsymbol *s)
    {
        FuncDeclaration *fd = s->isFuncDeclaration();
        TemplateDeclaration *td = s->isTemplateDeclaration();
        if (fd)
        {
            if (fd->errors || fd->type->ty == Terror)
                return 0;

            TypeFunction *tf = (TypeFunction *)fd->type;

            ::errorSupplemental(fd->loc, "%s%s", fd->toPrettyChars(),
                parametersTypeToChars(tf->parameters, tf->varargs));
        }
        else
        {
            ::errorSupplemental(td->loc, "%s", td->toPrettyChars());
        }

        FuncCandidateWalker *p = (FuncCandidateWalker *)param;
        if (global.params.verbose || --(p->numToDisplay) != 0 || !fd)
            return 0;

        // Too many overloads to sensibly display.
        CountWalker cw;
        cw.numOverloads = 0;
        overloadApply(fd->overnext, &cw, &CountWalker::fp);

        if (cw.numOverloads > 0)
            ::errorSupplemental(p->loc, "... (%d more, -v to show) ...", cw.numOverloads);

        return 1;  // stop iterating
    }
};

/*******************************************
 * Given a symbol that could be either a FuncDeclaration or
 * a function template, resolve it to a function symbol.
 *      loc             instantiation location
 *      sc              instantiation scope
 *      tiargs          initial list of template arguments
 *      tthis           if !NULL, the 'this' pointer argument
 *      fargs           arguments to function
 *      flags           1: do not issue error message on no match, just return NULL
 *                      2: overloadResolve only
 */

FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s,
        Objects *tiargs, Type *tthis, Expressions *fargs, int flags)
{
    if (!s)
        return NULL;                    // no match

    if ((tiargs && arrayObjectIsError(tiargs)) ||
        (fargs  && arrayObjectIsError((Objects *)fargs)))
    {
        return NULL;
    }

    Match m;
    memset(&m, 0, sizeof(m));
    m.last = MATCHnomatch;

    functionResolve(&m, s, loc, sc, tiargs, tthis, fargs);

    if (m.last > MATCHnomatch && m.lastf)
    {
        if (m.count == 1)   // exactly one match
        {
            if (!(flags & 1))
                m.lastf->functionSemantic();
            return m.lastf;
        }
        if ((flags & 2) && !tthis && m.lastf->needThis())
        {
            return m.lastf;
        }
    }

    /* Failed to find a best match.
     * Do nothing or print error.
     */
    if (m.last <= MATCHnomatch)
    {
        // error was caused on matched function
        if (m.count == 1)
            return m.lastf;

        // if do not print error messages
        if (flags & 1)
            return NULL;    // no match
    }

    FuncDeclaration *fd = s->isFuncDeclaration();
    OverDeclaration *od = s->isOverDeclaration();
    TemplateDeclaration *td = s->isTemplateDeclaration();
    if (td && td->funcroot)
        s = fd = td->funcroot;

    OutBuffer tiargsBuf;
    arrayObjectsToBuffer(&tiargsBuf, tiargs);

    OutBuffer fargsBuf;
    fargsBuf.writeByte('(');
    argExpTypesToCBuffer(&fargsBuf, fargs);
    fargsBuf.writeByte(')');
    if (tthis)
        tthis->modToBuffer(&fargsBuf);

    const int numOverloadsDisplay = 5; // sensible number to display

    if (!m.lastf && !(flags & 1))   // no match
    {
        if (td && !fd)  // all of overloads are templates
        {
            ::error(loc, "%s %s.%s cannot deduce function from argument types !(%s)%s, candidates are:",
                    td->kind(), td->parent->toPrettyChars(), td->ident->toChars(),
                    tiargsBuf.peekString(), fargsBuf.peekString());

            // Display candidate templates (even if there are no multiple overloads)
            TemplateCandidateWalker tcw;
            tcw.loc = loc;
            tcw.numToDisplay = numOverloadsDisplay;
            overloadApply(td, &tcw, &TemplateCandidateWalker::fp);
        }
        else if (od)
        {
            ::error(loc, "none of the overloads of '%s' are callable using argument types !(%s)%s",
                od->ident->toChars(), tiargsBuf.peekString(), fargsBuf.peekString());
        }
        else
        {
            assert(fd);

            bool hasOverloads = fd->overnext != NULL;
            TypeFunction *tf = fd->type->toTypeFunction();
            if (tthis && !MODimplicitConv(tthis->mod, tf->mod)) // modifier mismatch
            {
                OutBuffer thisBuf, funcBuf;
                MODMatchToBuffer(&thisBuf, tthis->mod, tf->mod);
                MODMatchToBuffer(&funcBuf, tf->mod, tthis->mod);
                if (hasOverloads)
                    ::error(loc, "none of the overloads of '%s' are callable using a %sobject, candidates are:",
                        fd->ident->toChars(), thisBuf.peekString());
                else
                    ::error(loc, "%smethod %s is not callable using a %sobject",
                        funcBuf.peekString(), fd->toPrettyChars(), thisBuf.peekString());
            }
            else
            {
                //printf("tf = %s, args = %s\n", tf->deco, (*fargs)[0]->type->deco);
                if (hasOverloads)
                    ::error(loc, "none of the overloads of '%s' are callable using argument types %s, candidates are:",
                            fd->ident->toChars(), fargsBuf.peekString());
                else
                    fd->error(loc, "%s%s is not callable using argument types %s",
                        parametersTypeToChars(tf->parameters, tf->varargs),
                        tf->modToChars(),
                        fargsBuf.peekString());
            }

            // Display candidate functions
            if (hasOverloads)
            {
                FuncCandidateWalker fcw;
                fcw.loc = loc;
                fcw.numToDisplay = numOverloadsDisplay;
                overloadApply(fd, &fcw, &FuncCandidateWalker::fp);
            }
        }
    }
    else if (m.nextf)
    {
        TypeFunction *tf1 = m.lastf->type->toTypeFunction();
        TypeFunction *tf2 = m.nextf->type->toTypeFunction();
        const char *lastprms = parametersTypeToChars(tf1->parameters, tf1->varargs);
        const char *nextprms = parametersTypeToChars(tf2->parameters, tf2->varargs);
        ::error(loc, "%s.%s called with argument types %s matches both:\n"
                     "%s:     %s%s\nand:\n%s:     %s%s",
                s->parent->toPrettyChars(), s->ident->toChars(),
                fargsBuf.peekString(),
                m.lastf->loc.toChars(), m.lastf->toPrettyChars(), lastprms,
                m.nextf->loc.toChars(), m.nextf->toPrettyChars(), nextprms);
    }
    return NULL;
}

/********************************
 * Labels are in a separate scope, one per function.
 */

LabelDsymbol *FuncDeclaration::searchLabel(Identifier *ident)
{   Dsymbol *s;

    if (!labtab)
        labtab = new DsymbolTable();    // guess we need one

    s = labtab->lookup(ident);
    if (!s)
    {
        s = new LabelDsymbol(ident);
        labtab->insert(s);
    }
    return (LabelDsymbol *)s;
}

/*****************************************
 * Determine lexical level difference from 'this' to nested function 'fd'.
 * Error if this cannot call fd.
 * Returns:
 *      0       same level
 *      >0      decrease nesting by number
 *      -1      increase nesting by 1 (fd is nested within 'this')
 *      -2      error
 */

int FuncDeclaration::getLevel(Loc loc, Scope *sc, FuncDeclaration *fd)
{
    int level;
    Dsymbol *s;
    Dsymbol *fdparent;

    //printf("FuncDeclaration::getLevel(fd = '%s')\n", fd->toChars());
    fdparent = fd->toParent2();
    if (fdparent == this)
        return -1;
    s = this;
    level = 0;
    while (fd != s && fdparent != s->toParent2())
    {
        //printf("\ts = %s, '%s'\n", s->kind(), s->toChars());
        FuncDeclaration *thisfd = s->isFuncDeclaration();
        if (thisfd)
        {
            if (!thisfd->isNested() && !thisfd->vthis && !sc->intypeof)
                goto Lerr;
        }
        else
        {
            AggregateDeclaration *thiscd = s->isAggregateDeclaration();
            if (thiscd)
            {
                /* AggregateDeclaration::isNested returns true only when
                 * it has a hidden pointer.
                 * But, calling the function belongs unrelated lexical scope
                 * is still allowed inside typeof.
                 *
                 * struct Map(alias fun) {
                 *   typeof({ return fun(); }) RetType;
                 *   // No member function makes Map struct 'not nested'.
                 * }
                 */
                if (!thiscd->isNested() && !sc->intypeof)
                    goto Lerr;
            }
            else
                goto Lerr;
        }

        s = s->toParent2();
        assert(s);
        level++;
    }
    return level;

Lerr:
    // Don't give error if in template constraint
    if (!(sc->flags & SCOPEconstraint))
    {
        const char *xstatic = isStatic() ? "static " : "";
        // better diagnostics for static functions
        ::error(loc, "%s%s %s cannot access frame of function %s",
            xstatic, kind(), toPrettyChars(), fd->toPrettyChars());
        return -2;
    }
    return 1;
}

const char *FuncDeclaration::toPrettyChars(bool QualifyTypes)
{
    if (isMain())
        return "D main";
    else
        return Dsymbol::toPrettyChars(QualifyTypes);
}

/** for diagnostics, e.g. 'int foo(int x, int y) pure' */
const char *FuncDeclaration::toFullSignature()
{
    OutBuffer buf;
    functionToBufferWithIdent(type->toTypeFunction(), &buf, toChars());
    return buf.extractString();
}

bool FuncDeclaration::isMain()
{
    return ident == Id::main &&
        linkage != LINKc && !isMember() && !isNested();
}

bool FuncDeclaration::isCMain()
{
    return ident == Id::main &&
        linkage == LINKc && !isMember() && !isNested();
}

bool FuncDeclaration::isWinMain()
{
    //printf("FuncDeclaration::isWinMain() %s\n", toChars());
    return ident == Id::WinMain &&
        linkage != LINKc && !isMember();
}

bool FuncDeclaration::isDllMain()
{
    return ident == Id::DllMain &&
        linkage != LINKc && !isMember();
}

bool FuncDeclaration::isExport() const
{
    return protection.kind == PROTexport;
}

bool FuncDeclaration::isImportedSymbol() const
{
    //printf("isImportedSymbol()\n");
    //printf("protection = %d\n", protection);
    return (protection.kind == PROTexport) && !fbody;
}

// Determine if function goes into virtual function pointer table

bool FuncDeclaration::isVirtual()
{
    if (toAliasFunc() != this)
        return toAliasFunc()->isVirtual();

    Dsymbol *p = toParent();
    return isMember() &&
        !(isStatic() || protection.kind == PROTprivate || protection.kind == PROTpackage) &&
        p->isClassDeclaration() &&
        !(p->isInterfaceDeclaration() && isFinalFunc());
}

// Determine if a function is pedantically virtual

bool FuncDeclaration::isVirtualMethod()
{
    if (toAliasFunc() != this)
        return toAliasFunc()->isVirtualMethod();

    //printf("FuncDeclaration::isVirtualMethod() %s\n", toChars());
    if (!isVirtual())
        return false;
    // If it's a final method, and does not override anything, then it is not virtual
    if (isFinalFunc() && foverrides.dim == 0)
    {
        return false;
    }
    return true;
}

bool FuncDeclaration::isFinalFunc()
{
    if (toAliasFunc() != this)
        return toAliasFunc()->isFinalFunc();

    ClassDeclaration *cd;
    return isMember() &&
        (Declaration::isFinal() ||
         ((cd = toParent()->isClassDeclaration()) != NULL && cd->storage_class & STCfinal));
}

bool FuncDeclaration::isCodeseg() const
{
    return true;                // functions are always in the code segment
}

bool FuncDeclaration::isOverloadable()
{
    return true;                // functions can be overloaded
}

PURE FuncDeclaration::isPure()
{
    //printf("FuncDeclaration::isPure() '%s'\n", toChars());
    TypeFunction *tf = type->toTypeFunction();
    if (flags & FUNCFLAGpurityInprocess)
        setImpure();
    if (tf->purity == PUREfwdref)
        tf->purityLevel();
    PURE purity = tf->purity;
    if (purity > PUREweak && isNested())
        purity = PUREweak;
    if (purity > PUREweak && needThis())
    {
        // The attribute of the 'this' reference affects purity strength
        if (type->mod & MODimmutable)
            ;
        else if (type->mod & (MODconst | MODwild) && purity >= PUREconst)
            purity = PUREconst;
        else
            purity = PUREweak;
    }
    tf->purity = purity;
    // ^ This rely on the current situation that every FuncDeclaration has a
    //   unique TypeFunction.
    return purity;
}

PURE FuncDeclaration::isPureBypassingInference()
{
    if (flags & FUNCFLAGpurityInprocess)
        return PUREfwdref;
    else
        return isPure();
}

/**************************************
 * The function is doing something impure,
 * so mark it as impure.
 * If there's a purity error, return true.
 */
bool FuncDeclaration::setImpure()
{
    if (flags & FUNCFLAGpurityInprocess)
    {
        flags &= ~FUNCFLAGpurityInprocess;
        if (fes)
            fes->func->setImpure();
    }
    else if (isPure())
        return true;
    return false;
}

bool FuncDeclaration::isSafe()
{
    if (flags & FUNCFLAGsafetyInprocess)
        setUnsafe();
    return type->toTypeFunction()->trust == TRUSTsafe;
}

bool FuncDeclaration::isSafeBypassingInference()
{
    return !(flags & FUNCFLAGsafetyInprocess) && isSafe();
}

bool FuncDeclaration::isTrusted()
{
    if (flags & FUNCFLAGsafetyInprocess)
        setUnsafe();
    return type->toTypeFunction()->trust == TRUSTtrusted;
}

/**************************************
 * The function is doing something unsave,
 * so mark it as unsafe.
 * If there's a safe error, return true.
 */
bool FuncDeclaration::setUnsafe()
{
    if (flags & FUNCFLAGsafetyInprocess)
    {
        flags &= ~FUNCFLAGsafetyInprocess;
        type->toTypeFunction()->trust = TRUSTsystem;
        if (fes)
            fes->func->setUnsafe();
    }
    else if (isSafe())
        return true;
    return false;
}

bool FuncDeclaration::isNogc()
{
    if (flags & FUNCFLAGnogcInprocess)
        setGC();
    return type->toTypeFunction()->isnogc;
}

bool FuncDeclaration::isNogcBypassingInference()
{
    return !(flags & FUNCFLAGnogcInprocess) && isNogc();
}

/**************************************
 * The function is doing something that may allocate with the GC,
 * so mark it as not nogc (not no-how).
 * Returns:
 *      true if function is marked as @nogc, meaning a user error occurred
 */
bool FuncDeclaration::setGC()
{
    if (flags & FUNCFLAGnogcInprocess)
    {
        flags &= ~FUNCFLAGnogcInprocess;
        type->toTypeFunction()->isnogc = false;
        if (fes)
            fes->func->setGC();
    }
    else if (isNogc())
        return true;
    return false;
}

/**************************************
 * Returns an indirect type one step from t.
 */

Type *getIndirection(Type *t)
{
    t = t->baseElemOf();
    if (t->ty == Tarray || t->ty == Tpointer)
        return t->nextOf()->toBasetype();
    if (t->ty == Taarray || t->ty == Tclass)
        return t;
    if (t->ty == Tstruct)
        return t->hasPointers() ? t : NULL; // TODO

    // should consider TypeDelegate?
    return NULL;
}

/**************************************
 * Returns true if memory reachable through a reference B to a value of type tb,
 * which has been constructed with a reference A to a value of type ta
 * available, can alias memory reachable from A based on the types involved
 * (either directly or via any number of indirections).
 *
 * Note that this relation is not symmetric in the two arguments. For example,
 * a const(int) reference can point to a pre-existing int, but not the other
 * way round.
 */
bool traverseIndirections(Type *ta, Type *tb, void *p = NULL, bool reversePass = false)
{
    Type *source = ta;
    Type *target = tb;
    if (reversePass)
    {
        source = tb;
        target = ta;
    }

    if (source->constConv(target))
        return true;
    else if (target->ty == Tvoid && MODimplicitConv(source->mod, target->mod))
        return true;

    // No direct match, so try breaking up one of the types (starting with tb).
    Type *tbb = tb->toBasetype()->baseElemOf();
    if (tbb != tb)
        return traverseIndirections(ta, tbb, p, reversePass);

    // context date to detect circular look up
    struct Ctxt
    {
        Ctxt *prev;
        Type *type;
    };
    Ctxt *ctxt = (Ctxt *)p;

    if (tb->ty == Tclass || tb->ty == Tstruct)
    {
        for (Ctxt *c = ctxt; c; c = c->prev)
            if (tb == c->type) return false;
        Ctxt c;
        c.prev = ctxt;
        c.type = tb;

        AggregateDeclaration *sym = tb->toDsymbol(NULL)->isAggregateDeclaration();
        for (size_t i = 0; i < sym->fields.dim; i++)
        {
            VarDeclaration *v = sym->fields[i];
            Type *tprmi = v->type->addMod(tb->mod);
            //printf("\ttb = %s, tprmi = %s\n", tb->toChars(), tprmi->toChars());
            if (traverseIndirections(ta, tprmi, &c, reversePass))
                return true;
        }
    }
    else if (tb->ty == Tarray || tb->ty == Taarray || tb->ty == Tpointer)
    {
        Type *tind = tb->nextOf();
        if (traverseIndirections(ta, tind, ctxt, reversePass))
            return true;
    }
    else if (tb->hasPointers())
    {
        // FIXME: function pointer/delegate types should be considered.
        return true;
    }

    // Still no match, so try breaking up ta if we have note done so yet.
    if (!reversePass)
        return traverseIndirections(tb, ta, ctxt, true);

    return false;
}

/********************************************
 * Returns true if the function return value has no indirection
 * which comes from the parameters.
 */

bool FuncDeclaration::isolateReturn()
{
    TypeFunction *tf = type->toTypeFunction();
    assert(tf->next);

    Type *treti = tf->next;
    treti = tf->isref ? treti : getIndirection(treti);
    if (!treti)
        return true;    // target has no mutable indirection
    return parametersIntersect(treti);
}

/********************************************
 * Returns true if an object typed t can have indirections
 * which come from the parameters.
 */

bool FuncDeclaration::parametersIntersect(Type *t)
{
    assert(t);
    if (!isPureBypassingInference() || isNested())
        return false;

    TypeFunction *tf = type->toTypeFunction();

    //printf("parametersIntersect(%s) t = %s\n", tf->toChars(), t->toChars());

    size_t dim = Parameter::dim(tf->parameters);
    for (size_t i = 0; i < dim; i++)
    {
        Parameter *fparam = Parameter::getNth(tf->parameters, i);
        if (!fparam->type)
            continue;
        Type *tprmi = (fparam->storageClass & (STClazy | STCout | STCref))
                ? fparam->type : getIndirection(fparam->type);
        if (!tprmi)
            continue;   // there is no mutable indirection

        //printf("\t[%d] tprmi = %d %s\n", i, tprmi->ty, tprmi->toChars());
        if (traverseIndirections(tprmi, t))
            return false;
    }
    if (AggregateDeclaration *ad = isCtorDeclaration() ? NULL : isThis())
    {
        Type *tthis = ad->getType()->addMod(tf->mod);
        //printf("\ttthis = %s\n", tthis->toChars());
        if (traverseIndirections(tthis, t))
            return false;
    }

    return true;
}

/****************************************
 * Determine if function needs a static frame pointer.
 * Returns:
 *  `true` if function is really nested within other function.
 * Contracts:
 *  If isNested() returns true, isThis() should return false.
 */
bool FuncDeclaration::isNested()
{
    FuncDeclaration *f = toAliasFunc();
    //printf("\ttoParent2() = '%s'\n", f->toParent2()->toChars());
    return ((f->storage_class & STCstatic) == 0) &&
           (f->linkage == LINKd) &&
           (f->toParent2()->isFuncDeclaration() != NULL);
}

/****************************************
 * Determine if function is a non-static member function
 * that has an implicit 'this' expression.
 * Returns:
 *  The aggregate it is a member of, or null.
 * Contracts:
 *  If isThis() returns true, isNested() should return false.
 */
AggregateDeclaration *FuncDeclaration::isThis()
{
    //printf("+FuncDeclaration::isThis() '%s'\n", toChars());
    AggregateDeclaration *ad = (storage_class & STCstatic) ? NULL : isMember2();
    //printf("-FuncDeclaration::isThis() %p\n", ad);
    return ad;
}

bool FuncDeclaration::needThis()
{
    //printf("FuncDeclaration::needThis() '%s'\n", toChars());
    return toAliasFunc()->isThis() != NULL;
}

bool FuncDeclaration::addPreInvariant()
{
    AggregateDeclaration *ad = isThis();
    ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL;
    return (ad && !(cd && cd->isCPPclass()) &&
            global.params.useInvariants &&
            (protection.kind == PROTprotected || protection.kind == PROTpublic || protection.kind == PROTexport) &&
            !naked);
}

bool FuncDeclaration::addPostInvariant()
{
    AggregateDeclaration *ad = isThis();
    ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL;
    return (ad && !(cd && cd->isCPPclass()) &&
            ad->inv &&
            global.params.useInvariants &&
            (protection.kind == PROTprotected || protection.kind == PROTpublic || protection.kind == PROTexport) &&
            !naked);
}

/********************************************************
 * Generate Expression to call the invariant.
 * Input:
 *      ad      aggregate with the invariant
 *      vthis   variable with 'this'
 *      direct  call invariant directly
 * Returns:
 *      void expression that calls the invariant
 */
Expression *addInvariant(Loc loc, Scope *sc, AggregateDeclaration *ad, VarDeclaration *vthis, bool direct)
{
    Expression *e = NULL;
    if (direct)
    {
        // Call invariant directly only if it exists
        FuncDeclaration *inv = ad->inv;
        ClassDeclaration *cd = ad->isClassDeclaration();

        while (!inv && cd)
        {
            cd = cd->baseClass;
            if (!cd)
                break;
            inv = cd->inv;
        }
        if (inv)
        {
        #if 1
            // Workaround for bugzilla 13394: For the correct mangling,
            // run attribute inference on inv if needed.
            inv->functionSemantic();
        #endif

            //e = new DsymbolExp(Loc(), inv);
            //e = new CallExp(Loc(), e);
            //e = e->semantic(sc2);

            /* Bugzilla 13113: Currently virtual invariant calls completely
             * bypass attribute enforcement.
             * Change the behavior of pre-invariant call by following it.
             */
            e = new ThisExp(Loc());
            e->type = vthis->type;
            e = new DotVarExp(Loc(), e, inv, false);
            e->type = inv->type;
            e = new CallExp(Loc(), e);
            e->type = Type::tvoid;
        }
    }
    else
    {
    #if 1
        // Workaround for bugzilla 13394: For the correct mangling,
        // run attribute inference on inv if needed.
        if (ad->isStructDeclaration() && ad->inv)
            ad->inv->functionSemantic();
    #endif

        // Call invariant virtually
        Expression *v = new ThisExp(Loc());
        v->type = vthis->type;
        if (ad->isStructDeclaration())
            v = v->addressOf();
        e = new StringExp(Loc(), const_cast<char *>("null this"));
        e = new AssertExp(loc, v, e);
        e = semantic(e, sc);
    }
    return e;
}

/**********************************
 * Generate a FuncDeclaration for a runtime library function.
 */

FuncDeclaration *FuncDeclaration::genCfunc(Parameters *fparams, Type *treturn, const char *name, StorageClass stc)
{
    return genCfunc(fparams, treturn, Identifier::idPool(name), stc);
}

FuncDeclaration *FuncDeclaration::genCfunc(Parameters *fparams, Type *treturn, Identifier *id, StorageClass stc)
{
    FuncDeclaration *fd;
    TypeFunction *tf;
    Dsymbol *s;
    static DsymbolTable *st = NULL;

    //printf("genCfunc(name = '%s')\n", id->toChars());
    //printf("treturn\n\t"); treturn->print();

    // See if already in table
    if (!st)
        st = new DsymbolTable();
    s = st->lookup(id);
    if (s)
    {
        fd = s->isFuncDeclaration();
        assert(fd);
        assert(fd->type->nextOf()->equals(treturn));
    }
    else
    {
        tf = new TypeFunction(fparams, treturn, 0, LINKc, stc);
        fd = new FuncDeclaration(Loc(), Loc(), id, STCstatic, tf);
        fd->protection = Prot(PROTpublic);
        fd->linkage = LINKc;

        st->insert(fd);
    }
    return fd;
}

/******************
 * Check parameters and return type of D main() function.
 * Issue error messages.
 */
void FuncDeclaration::checkDmain()
{
    TypeFunction *tf = type->toTypeFunction();
    const size_t nparams = Parameter::dim(tf->parameters);
    bool argerr = false;
    if (nparams == 1)
    {
        Parameter *fparam0 = Parameter::getNth(tf->parameters, 0);
        Type *t = fparam0->type->toBasetype();
        if (t->ty != Tarray ||
            t->nextOf()->ty != Tarray ||
            t->nextOf()->nextOf()->ty != Tchar ||
            fparam0->storageClass & (STCout | STCref | STClazy))
        {
            argerr = true;
        }
    }

    if (!tf->nextOf())
        error("must return int or void");
    else if (tf->nextOf()->ty != Tint32 && tf->nextOf()->ty != Tvoid)
        error("must return int or void, not %s", tf->nextOf()->toChars());
    else if (tf->varargs || nparams >= 2 || argerr)
        error("parameters must be main() or main(string[] args)");
}

const char *FuncDeclaration::kind() const
{
    return generated ? "generated function" : "function";
}

/*********************************************
 * In the current function, we are calling 'this' function.
 * 1. Check to see if the current function can call 'this' function, issue error if not.
 * 2. If the current function is not the parent of 'this' function, then add
 *    the current function to the list of siblings of 'this' function.
 * 3. If the current function is a literal, and it's accessing an uplevel scope,
 *    then mark it as a delegate.
 * Returns true if error occurs.
 */
bool FuncDeclaration::checkNestedReference(Scope *sc, Loc loc)
{
    //printf("FuncDeclaration::checkNestedReference() %s\n", toPrettyChars());

    if (FuncLiteralDeclaration *fld = this->isFuncLiteralDeclaration())
    {
        if (fld->tok == TOKreserved)
        {
            fld->tok = TOKfunction;
            fld->vthis = NULL;
        }
    }

    if (!parent || parent == sc->parent)
        return false;
    if (ident == Id::require || ident == Id::ensure)
        return false;
    if (!isThis() && !isNested())
        return false;

    // The current function
    FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
    if (!fdthis)
        return false;   // out of function scope

    Dsymbol *p = toParent2();

    // Function literals from fdthis to p must be delegates
    checkNestedRef(fdthis, p);

    if (isNested())
    {
        // The function that this function is in
        FuncDeclaration *fdv = p->isFuncDeclaration();
        if (!fdv)
            return false;
        if (fdv == fdthis)
            return false;

        //printf("this = %s in [%s]\n", this->toChars(), this->loc.toChars());
        //printf("fdv = %s in [%s]\n", fdv->toChars(), fdv->loc.toChars());
        //printf("fdthis = %s in [%s]\n", fdthis->toChars(), fdthis->loc.toChars());

        // Add this function to the list of those which called us
        if (fdthis != this)
        {
            bool found = false;
            for (size_t i = 0; i < siblingCallers.dim; ++i)
            {
                if (siblingCallers[i] == fdthis)
                    found = true;
            }
            if (!found)
            {
                //printf("\tadding sibling %s\n", fdthis->toPrettyChars());
                if (!sc->intypeof && !(sc->flags & SCOPEcompile))
                    siblingCallers.push(fdthis);
            }
        }

        int lv = fdthis->getLevel(loc, sc, fdv);
        if (lv == -2)
            return true;    // error
        if (lv == -1)
            return false;   // downlevel call
        if (lv == 0)
            return false;   // same level call
        // Uplevel call
    }
    return false;
}

/* For all functions between outerFunc and f, mark them as needing
 * a closure.
 */
void markAsNeedingClosure(Dsymbol *f, FuncDeclaration *outerFunc)
{
    for (Dsymbol *sx = f; sx && sx != outerFunc; sx = sx->parent)
    {
        FuncDeclaration *fy = sx->isFuncDeclaration();
        if (fy && fy->closureVars.dim)
        {
            /* fy needs a closure if it has closureVars[],
             * because the frame pointer in the closure will be accessed.
             */
            fy->requiresClosure = true;
        }
    }
}


/* Given a nested function f inside a function outerFunc, check
 * if any sibling callers of f have escaped. If so, mark
 * all the enclosing functions as needing closures.
 * Return true if any closures were detected.
 * This is recursive: we need to check the callers of our siblings.
 * Note that nested functions can only call lexically earlier nested
 * functions, so loops are impossible.
 */
bool checkEscapingSiblings(FuncDeclaration *f, FuncDeclaration *outerFunc, void *p = NULL)
{
    struct PrevSibling
    {
        PrevSibling *p;
        FuncDeclaration *f;
    };

    PrevSibling ps;
    ps.p = (PrevSibling *)p;
    ps.f = f;

    //printf("checkEscapingSiblings(f = %s, outerfunc = %s)\n", f->toChars(), outerFunc->toChars());
    bool bAnyClosures = false;
    for (size_t i = 0; i < f->siblingCallers.dim; ++i)
    {
        FuncDeclaration *g = f->siblingCallers[i];
        if (g->isThis() || g->tookAddressOf)
        {
            markAsNeedingClosure(g, outerFunc);
            bAnyClosures = true;
        }

        PrevSibling *prev = (PrevSibling *)p;
        while (1)
        {
            if (!prev)
            {
                bAnyClosures |= checkEscapingSiblings(g, outerFunc, &ps);
                break;
            }
            if (prev->f == g)
                break;
            prev = prev->p;
        }
    }
    //printf("\t%d\n", bAnyClosures);
    return bAnyClosures;
}


/*******************************
 * Look at all the variables in this function that are referenced
 * by nested functions, and determine if a closure needs to be
 * created for them.
 */

bool FuncDeclaration::needsClosure()
{
    /* Need a closure for all the closureVars[] if any of the
     * closureVars[] are accessed by a
     * function that escapes the scope of this function.
     * We take the conservative approach and decide that a function needs
     * a closure if it:
     * 1) is a virtual function
     * 2) has its address taken
     * 3) has a parent that escapes
     * 4) calls another nested function that needs a closure
     *
     * Note that since a non-virtual function can be called by
     * a virtual one, if that non-virtual function accesses a closure
     * var, the closure still has to be taken. Hence, we check for isThis()
     * instead of isVirtual(). (thanks to David Friedman)
     *
     * When the function returns a local struct or class, `requiresClosure`
     * is already set to `true` upon entering this function when the
     * struct/class refers to a local variable and a closure is needed.
     */

    //printf("FuncDeclaration::needsClosure() %s\n", toChars());

    if (requiresClosure)
        goto Lyes;

    for (size_t i = 0; i < closureVars.dim; i++)
    {
        VarDeclaration *v = closureVars[i];
        //printf("\tv = %s\n", v->toChars());

        for (size_t j = 0; j < v->nestedrefs.dim; j++)
        {
            FuncDeclaration *f = v->nestedrefs[j];
            assert(f != this);

            //printf("\t\tf = %s, isVirtual=%d, isThis=%p, tookAddressOf=%d\n", f->toChars(), f->isVirtual(), f->isThis(), f->tookAddressOf);

            /* Look to see if f escapes. We consider all parents of f within
             * this, and also all siblings which call f; if any of them escape,
             * so does f.
             * Mark all affected functions as requiring closures.
             */
            for (Dsymbol *s = f; s && s != this; s = s->parent)
            {
                FuncDeclaration *fx = s->isFuncDeclaration();
                if (!fx)
                    continue;
                if (fx->isThis() || fx->tookAddressOf)
                {
                    //printf("\t\tfx = %s, isVirtual=%d, isThis=%p, tookAddressOf=%d\n", fx->toChars(), fx->isVirtual(), fx->isThis(), fx->tookAddressOf);

                    /* Mark as needing closure any functions between this and f
                     */
                    markAsNeedingClosure( (fx == f) ? fx->parent : fx, this);

                    requiresClosure = true;
                }

                /* We also need to check if any sibling functions that
                 * called us, have escaped. This is recursive: we need
                 * to check the callers of our siblings.
                 */
                if (checkEscapingSiblings(fx, this))
                    requiresClosure = true;

                /* Bugzilla 12406: Iterate all closureVars to mark all descendant
                 * nested functions that access to the closing context of this funciton.
                 */
            }
        }
    }
    if (requiresClosure)
        goto Lyes;

    return false;

Lyes:
    //printf("\tneeds closure\n");
    return true;
}

/***********************************************
 * Check that the function contains any closure.
 * If it's @nogc, report suitable errors.
 * This is mostly consistent with FuncDeclaration::needsClosure().
 *
 * Returns:
 *      true if any errors occur.
 */
bool FuncDeclaration::checkClosure()
{
    if (!needsClosure())
        return false;

    if (setGC())
    {
        error("is @nogc yet allocates closures with the GC");
        if (global.gag)     // need not report supplemental errors
            return true;
    }
    else
    {
        printGCUsage(loc, "using closure causes GC allocation");
        return false;
    }

    FuncDeclarations a;
    for (size_t i = 0; i < closureVars.dim; i++)
    {
        VarDeclaration *v = closureVars[i];

        for (size_t j = 0; j < v->nestedrefs.dim; j++)
        {
            FuncDeclaration *f = v->nestedrefs[j];
            assert(f != this);

            for (Dsymbol *s = f; s && s != this; s = s->parent)
            {
                FuncDeclaration *fx = s->isFuncDeclaration();
                if (!fx)
                    continue;
                if (fx->isThis() || fx->tookAddressOf)
                    goto Lfound;
                if (checkEscapingSiblings(fx, this))
                    goto Lfound;
            }
            continue;

        Lfound:
            for (size_t k = 0; ; k++)
            {
                if (k == a.dim)
                {
                    a.push(f);
                    ::errorSupplemental(f->loc, "%s closes over variable %s at %s",
                        f->toPrettyChars(), v->toChars(), v->loc.toChars());
                    break;
                }
                if (a[k] == f)
                    break;
            }
            continue;
        }
    }

    return true;
}

/***********************************************
 * Determine if function's variables are referenced by a function
 * nested within it.
 */

bool FuncDeclaration::hasNestedFrameRefs()
{
    if (closureVars.dim)
        return true;

    /* If a virtual function has contracts, assume its variables are referenced
     * by those contracts, even if they aren't. Because they might be referenced
     * by the overridden or overriding function's contracts.
     * This can happen because frequire and fensure are implemented as nested functions,
     * and they can be called directly by an overriding function and the overriding function's
     * context had better match, or Bugzilla 7335 will bite.
     */
    if (fdrequire || fdensure)
        return true;

    if (foverrides.dim && isVirtualMethod())
    {
        for (size_t i = 0; i < foverrides.dim; i++)
        {
            FuncDeclaration *fdv = foverrides[i];
            if (fdv->hasNestedFrameRefs())
                return true;
        }
    }

    return false;
}

/*********************************************
 * Return the function's parameter list, and whether
 * it is variadic or not.
 */

Parameters *FuncDeclaration::getParameters(int *pvarargs)
{
    Parameters *fparameters = NULL;
    int fvarargs = 0;

    if (type)
    {
        TypeFunction *fdtype = type->toTypeFunction();
        fparameters = fdtype->parameters;
        fvarargs = fdtype->varargs;
    }
    if (pvarargs)
        *pvarargs = fvarargs;
    return fparameters;
}


/****************************** FuncAliasDeclaration ************************/

// Used as a way to import a set of functions from another scope into this one.

FuncAliasDeclaration::FuncAliasDeclaration(Identifier *ident, FuncDeclaration *funcalias, bool hasOverloads)
    : FuncDeclaration(funcalias->loc, funcalias->endloc, ident,
        funcalias->storage_class, funcalias->type)
{
    assert(funcalias != this);
    this->funcalias = funcalias;

    this->hasOverloads = hasOverloads;
    if (hasOverloads)
    {
        if (FuncAliasDeclaration *fad = funcalias->isFuncAliasDeclaration())
            this->hasOverloads = fad->hasOverloads;
    }
    else
    {   // for internal use
        assert(!funcalias->isFuncAliasDeclaration());
        this->hasOverloads = false;
    }
    userAttribDecl = funcalias->userAttribDecl;
}

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

FuncDeclaration *FuncAliasDeclaration::toAliasFunc()
{
    return funcalias->toAliasFunc();
}


/****************************** FuncLiteralDeclaration ************************/

FuncLiteralDeclaration::FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type,
        TOK tok, ForeachStatement *fes, Identifier *id)
    : FuncDeclaration(loc, endloc, NULL, STCundefined, type)
{
    this->ident = id ? id : Id::empty;
    this->tok = tok;
    this->fes = fes;
    this->treq = NULL;
    this->deferToObj = false;
    //printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars());
}

Dsymbol *FuncLiteralDeclaration::syntaxCopy(Dsymbol *s)
{
    //printf("FuncLiteralDeclaration::syntaxCopy('%s')\n", toChars());
    assert(!s);
    FuncLiteralDeclaration *f = new FuncLiteralDeclaration(loc, endloc,
        type->syntaxCopy(), tok, fes, ident);
    f->treq = treq;     // don't need to copy
    return FuncDeclaration::syntaxCopy(f);
}

bool FuncLiteralDeclaration::isNested()
{
    //printf("FuncLiteralDeclaration::isNested() '%s'\n", toChars());
    return (tok != TOKfunction) && !isThis();
}

AggregateDeclaration *FuncLiteralDeclaration::isThis()
{
    //printf("FuncLiteralDeclaration::isThis() '%s'\n", toChars());
    return tok == TOKdelegate ? FuncDeclaration::isThis() : NULL;
}

bool FuncLiteralDeclaration::isVirtual()
{
    return false;
}

bool FuncLiteralDeclaration::addPreInvariant()
{
    return false;
}

bool FuncLiteralDeclaration::addPostInvariant()
{
    return false;
}

/*******************************
 * Modify all expression type of return statements to tret.
 *
 * On function literals, return type may be modified based on the context type
 * after its semantic3 is done, in FuncExp::implicitCastTo.
 *
 *  A function() dg = (){ return new B(); } // OK if is(B : A) == true
 *
 * If B to A conversion is convariant that requires offseet adjusting,
 * all return statements should be adjusted to return expressions typed A.
 */
void FuncLiteralDeclaration::modifyReturns(Scope *sc, Type *tret)
{
    class RetWalker : public StatementRewriteWalker
    {
    public:
        Scope *sc;
        Type *tret;
        FuncLiteralDeclaration *fld;

        void visit(ReturnStatement *s)
        {
            Expression *exp = s->exp;
            if (exp && !exp->type->equals(tret))
            {
                s->exp = exp->castTo(sc, tret);
            }
        }
    };

    if (semanticRun < PASSsemantic3done)
        return;

    if (fes)
        return;

    RetWalker w;
    w.sc = sc;
    w.tret = tret;
    w.fld = this;
    fbody->accept(&w);

    // Also update the inferred function type to match the new return type.
    // This is required so the code generator does not try to cast the
    // modified returns back to the original type.
    if (inferRetType && type->nextOf() != tret)
        type->toTypeFunction()->next = tret;
}

const char *FuncLiteralDeclaration::kind() const
{
    return (tok != TOKfunction) ? "delegate" : "function";
}

const char *FuncLiteralDeclaration::toPrettyChars(bool QualifyTypes)
{
    if (parent)
    {
        TemplateInstance *ti = parent->isTemplateInstance();
        if (ti)
            return ti->tempdecl->toPrettyChars(QualifyTypes);
    }
    return Dsymbol::toPrettyChars(QualifyTypes);
}

/********************************* CtorDeclaration ****************************/

CtorDeclaration::CtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Type *type)
    : FuncDeclaration(loc, endloc, Id::ctor, stc, type)
{
    //printf("CtorDeclaration(loc = %s) %s\n", loc.toChars(), toChars());
}

Dsymbol *CtorDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    CtorDeclaration *f = new CtorDeclaration(loc, endloc, storage_class, type->syntaxCopy());
    return FuncDeclaration::syntaxCopy(f);
}

void CtorDeclaration::semantic(Scope *sc)
{
    //printf("CtorDeclaration::semantic() %s\n", toChars());
    if (semanticRun >= PASSsemanticdone)
        return;
    if (_scope)
    {
        sc = _scope;
        _scope = NULL;
    }

    parent = sc->parent;
    Dsymbol *p = toParent2();
    AggregateDeclaration *ad = p->isAggregateDeclaration();
    if (!ad)
    {
        ::error(loc, "constructor can only be a member of aggregate, not %s %s",
            p->kind(), p->toChars());
        type = Type::terror;
        errors = true;
        return;
    }

    sc = sc->push();
    sc->stc &= ~STCstatic;              // not a static constructor
    sc->flags |= SCOPEctor;

    FuncDeclaration::semantic(sc);

    sc->pop();

    if (errors)
        return;

    TypeFunction *tf = type->toTypeFunction();

    /* See if it's the default constructor
     * But, template constructor should not become a default constructor.
     */
    if (ad && (!parent->isTemplateInstance() || parent->isTemplateMixin()))
    {
        const size_t dim = Parameter::dim(tf->parameters);

        if (StructDeclaration *sd = ad->isStructDeclaration())
        {
            if (dim == 0 && tf->varargs == 0) // empty default ctor w/o any varargs
            {
                if (fbody || !(storage_class & STCdisable) || dim)
                {
                    error("default constructor for structs only allowed "
                        "with @disable, no body, and no parameters");
                    storage_class |= STCdisable;
                    fbody = NULL;
                }
                sd->noDefaultCtor = true;
            }
            else if (dim == 0 && tf->varargs) // allow varargs only ctor
            {
            }
            else if (dim && Parameter::getNth(tf->parameters, 0)->defaultArg)
            {
                // if the first parameter has a default argument, then the rest does as well
                if (storage_class & STCdisable)
                {
                    deprecation("@disable'd constructor cannot have default "
                                "arguments for all parameters.");
                    deprecationSupplemental(loc, "Use @disable this(); if you want to disable default initialization.");
                }
                else
                    deprecation("all parameters have default arguments, "
                                "but structs cannot have default constructors.");
            }

        }
        else if (dim == 0 && tf->varargs == 0)
        {
            ad->defaultCtor = this;
        }
    }
}

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

const char *CtorDeclaration::toChars()
{
    return "this";
}

bool CtorDeclaration::isVirtual()
{
    return false;
}

bool CtorDeclaration::addPreInvariant()
{
    return false;
}

bool CtorDeclaration::addPostInvariant()
{
    return (isThis() && vthis && global.params.useInvariants);
}


/********************************* PostBlitDeclaration ****************************/

PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id)
    : FuncDeclaration(loc, endloc, id, stc, NULL)
{
}

Dsymbol *PostBlitDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    PostBlitDeclaration *dd = new PostBlitDeclaration(loc, endloc, storage_class, ident);
    return FuncDeclaration::syntaxCopy(dd);
}

void PostBlitDeclaration::semantic(Scope *sc)
{
    //printf("PostBlitDeclaration::semantic() %s\n", toChars());
    //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor);
    //printf("stc = x%llx\n", sc->stc);
    if (semanticRun >= PASSsemanticdone)
        return;
    if (_scope)
    {
        sc = _scope;
        _scope = NULL;
    }

    parent = sc->parent;
    Dsymbol *p = toParent2();
    StructDeclaration *ad = p->isStructDeclaration();
    if (!ad)
    {
        ::error(loc, "postblit can only be a member of struct/union, not %s %s",
            p->kind(), p->toChars());
        type = Type::terror;
        errors = true;
        return;
    }
    if (ident == Id::postblit && semanticRun < PASSsemantic)
        ad->postblits.push(this);
    if (!type)
        type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);

    sc = sc->push();
    sc->stc &= ~STCstatic;              // not static
    sc->linkage = LINKd;

    FuncDeclaration::semantic(sc);

    sc->pop();
}

bool PostBlitDeclaration::overloadInsert(Dsymbol *)
{
    return false;       // cannot overload postblits
}

bool PostBlitDeclaration::addPreInvariant()
{
    return false;
}

bool PostBlitDeclaration::addPostInvariant()
{
    return (isThis() && vthis && global.params.useInvariants);
}

bool PostBlitDeclaration::isVirtual()
{
    return false;
}

/********************************* DtorDeclaration ****************************/

DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc)
    : FuncDeclaration(loc, endloc, Id::dtor, STCundefined, NULL)
{
}

DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id)
    : FuncDeclaration(loc, endloc, id, stc, NULL)
{
}

Dsymbol *DtorDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    DtorDeclaration *dd = new DtorDeclaration(loc, endloc, storage_class, ident);
    return FuncDeclaration::syntaxCopy(dd);
}

void DtorDeclaration::semantic(Scope *sc)
{
    //printf("DtorDeclaration::semantic() %s\n", toChars());
    //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor);
    if (semanticRun >= PASSsemanticdone)
        return;
    if (_scope)
    {
        sc = _scope;
        _scope = NULL;
    }

    parent = sc->parent;
    Dsymbol *p = toParent2();
    AggregateDeclaration *ad = p->isAggregateDeclaration();
    if (!ad)
    {
        ::error(loc, "destructor can only be a member of aggregate, not %s %s",
            p->kind(), p->toChars());
        type = Type::terror;
        errors = true;
        return;
    }
    if (ident == Id::dtor && semanticRun < PASSsemantic)
        ad->dtors.push(this);
    if (!type)
        type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);

    sc = sc->push();
    sc->stc &= ~STCstatic;              // not a static destructor
    if (sc->linkage != LINKcpp)
        sc->linkage = LINKd;

    FuncDeclaration::semantic(sc);

    sc->pop();
}

bool DtorDeclaration::overloadInsert(Dsymbol *)
{
    return false;       // cannot overload destructors
}

bool DtorDeclaration::addPreInvariant()
{
    return (isThis() && vthis && global.params.useInvariants);
}

bool DtorDeclaration::addPostInvariant()
{
    return false;
}

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

const char *DtorDeclaration::toChars()
{
    return "~this";
}

bool DtorDeclaration::isVirtual()
{
    // false so that dtor's don't get put into the vtbl[]
    return false;
}

/********************************* StaticCtorDeclaration ****************************/

StaticCtorDeclaration::StaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc)
    : FuncDeclaration(loc, endloc,
      Identifier::generateId("_staticCtor"), STCstatic | stc, NULL)
{
}

StaticCtorDeclaration::StaticCtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc)
    : FuncDeclaration(loc, endloc,
      Identifier::generateId(name), STCstatic | stc, NULL)
{
}

Dsymbol *StaticCtorDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    StaticCtorDeclaration *scd = new StaticCtorDeclaration(loc, endloc, storage_class);
    return FuncDeclaration::syntaxCopy(scd);
}

void StaticCtorDeclaration::semantic(Scope *sc)
{
    //printf("StaticCtorDeclaration::semantic()\n");
    if (semanticRun >= PASSsemanticdone)
        return;
    if (_scope)
    {
        sc = _scope;
        _scope = NULL;
    }

    parent = sc->parent;
    Dsymbol *p = parent->pastMixin();
    if (!p->isScopeDsymbol())
    {
        const char *s = (isSharedStaticCtorDeclaration() ? "shared " : "");
        ::error(loc, "%sstatic constructor can only be member of module/aggregate/template, not %s %s",
            s, p->kind(), p->toChars());
        type = Type::terror;
        errors = true;
        return;
    }
    if (!type)
        type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);

    /* If the static ctor appears within a template instantiation,
     * it could get called multiple times by the module constructors
     * for different modules. Thus, protect it with a gate.
     */
    if (isInstantiated() && semanticRun < PASSsemantic)
    {
        /* Add this prefix to the function:
         *      static int gate;
         *      if (++gate != 1) return;
         * Note that this is not thread safe; should not have threads
         * during static construction.
         */
        VarDeclaration *v = new VarDeclaration(Loc(), Type::tint32, Id::gate, NULL);
        v->storage_class = STCtemp | (isSharedStaticCtorDeclaration() ? STCstatic : STCtls);
        Statements *sa = new Statements();
        Statement *s = new ExpStatement(Loc(), v);
        sa->push(s);
        Expression *e = new IdentifierExp(Loc(), v->ident);
        e = new AddAssignExp(Loc(), e, new IntegerExp(1));
        e = new EqualExp(TOKnotequal, Loc(), e, new IntegerExp(1));
        s = new IfStatement(Loc(), NULL, e, new ReturnStatement(Loc(), NULL), NULL, Loc());
        sa->push(s);
        if (fbody)
            sa->push(fbody);
        fbody = new CompoundStatement(Loc(), sa);
    }

    FuncDeclaration::semantic(sc);

    // We're going to need ModuleInfo
    Module *m = getModule();
    if (!m)
        m = sc->_module;
    if (m)
    {
        m->needmoduleinfo = 1;
        //printf("module1 %s needs moduleinfo\n", m->toChars());
    }
}

AggregateDeclaration *StaticCtorDeclaration::isThis()
{
    return NULL;
}

bool StaticCtorDeclaration::isVirtual()
{
    return false;
}

bool StaticCtorDeclaration::hasStaticCtorOrDtor()
{
    return true;
}

bool StaticCtorDeclaration::addPreInvariant()
{
    return false;
}

bool StaticCtorDeclaration::addPostInvariant()
{
    return false;
}

/********************************* SharedStaticCtorDeclaration ****************************/

SharedStaticCtorDeclaration::SharedStaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc)
    : StaticCtorDeclaration(loc, endloc, "_sharedStaticCtor", stc)
{
}

Dsymbol *SharedStaticCtorDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    SharedStaticCtorDeclaration *scd = new SharedStaticCtorDeclaration(loc, endloc, storage_class);
    return FuncDeclaration::syntaxCopy(scd);
}

/********************************* StaticDtorDeclaration ****************************/

StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc)
    : FuncDeclaration(loc, endloc,
      Identifier::generateId("_staticDtor"), STCstatic | stc, NULL)
{
    vgate = NULL;
}

StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc)
    : FuncDeclaration(loc, endloc,
      Identifier::generateId(name), STCstatic | stc, NULL)
{
    vgate = NULL;
}

Dsymbol *StaticDtorDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    StaticDtorDeclaration *sdd = new StaticDtorDeclaration(loc, endloc, storage_class);
    return FuncDeclaration::syntaxCopy(sdd);
}

void StaticDtorDeclaration::semantic(Scope *sc)
{
    if (semanticRun >= PASSsemanticdone)
        return;
    if (_scope)
    {
        sc = _scope;
        _scope = NULL;
    }

    parent = sc->parent;
    Dsymbol *p = parent->pastMixin();
    if (!p->isScopeDsymbol())
    {
        const char *s = (isSharedStaticDtorDeclaration() ? "shared " : "");
        ::error(loc, "%sstatic destructor can only be member of module/aggregate/template, not %s %s",
            s, p->kind(), p->toChars());
        type = Type::terror;
        errors = true;
        return;
    }
    if (!type)
        type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);

    /* If the static ctor appears within a template instantiation,
     * it could get called multiple times by the module constructors
     * for different modules. Thus, protect it with a gate.
     */
    if (isInstantiated() && semanticRun < PASSsemantic)
    {
        /* Add this prefix to the function:
         *      static int gate;
         *      if (--gate != 0) return;
         * Increment gate during constructor execution.
         * Note that this is not thread safe; should not have threads
         * during static destruction.
         */
        VarDeclaration *v = new VarDeclaration(Loc(), Type::tint32, Id::gate, NULL);
        v->storage_class = STCtemp | (isSharedStaticDtorDeclaration() ? STCstatic : STCtls);
        Statements *sa = new Statements();
        Statement *s = new ExpStatement(Loc(), v);
        sa->push(s);
        Expression *e = new IdentifierExp(Loc(), v->ident);
        e = new AddAssignExp(Loc(), e, new IntegerExp(-1));
        e = new EqualExp(TOKnotequal, Loc(), e, new IntegerExp(0));
        s = new IfStatement(Loc(), NULL, e, new ReturnStatement(Loc(), NULL), NULL, Loc());
        sa->push(s);
        if (fbody)
            sa->push(fbody);
        fbody = new CompoundStatement(Loc(), sa);
        vgate = v;
    }

    FuncDeclaration::semantic(sc);

    // We're going to need ModuleInfo
    Module *m = getModule();
    if (!m)
        m = sc->_module;
    if (m)
    {
        m->needmoduleinfo = 1;
        //printf("module2 %s needs moduleinfo\n", m->toChars());
    }
}

AggregateDeclaration *StaticDtorDeclaration::isThis()
{
    return NULL;
}

bool StaticDtorDeclaration::isVirtual()
{
    return false;
}

bool StaticDtorDeclaration::hasStaticCtorOrDtor()
{
    return true;
}

bool StaticDtorDeclaration::addPreInvariant()
{
    return false;
}

bool StaticDtorDeclaration::addPostInvariant()
{
    return false;
}

/********************************* SharedStaticDtorDeclaration ****************************/

SharedStaticDtorDeclaration::SharedStaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc)
    : StaticDtorDeclaration(loc, endloc, "_sharedStaticDtor", stc)
{
}

Dsymbol *SharedStaticDtorDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    SharedStaticDtorDeclaration *sdd = new SharedStaticDtorDeclaration(loc, endloc, storage_class);
    return FuncDeclaration::syntaxCopy(sdd);
}

/********************************* InvariantDeclaration ****************************/

InvariantDeclaration::InvariantDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id)
    : FuncDeclaration(loc, endloc,
                      id ? id : Identifier::generateId("__invariant"),
                      stc, NULL)
{
}

Dsymbol *InvariantDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    InvariantDeclaration *id = new InvariantDeclaration(loc, endloc, storage_class);
    return FuncDeclaration::syntaxCopy(id);
}

void InvariantDeclaration::semantic(Scope *sc)
{
    if (semanticRun >= PASSsemanticdone)
        return;
    if (_scope)
    {
        sc = _scope;
        _scope = NULL;
    }

    parent = sc->parent;
    Dsymbol *p = parent->pastMixin();
    AggregateDeclaration *ad = p->isAggregateDeclaration();
    if (!ad)
    {
        ::error(loc, "invariant can only be a member of aggregate, not %s %s",
            p->kind(), p->toChars());
        type = Type::terror;
        errors = true;
        return;
    }
    if (ident != Id::classInvariant &&
        semanticRun < PASSsemantic &&
        !ad->isUnionDeclaration()           // users are on their own with union fields
       )
        ad->invs.push(this);
    if (!type)
        type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);

    sc = sc->push();
    sc->stc &= ~STCstatic;              // not a static invariant
    sc->stc |= STCconst;                // invariant() is always const
    sc->flags = (sc->flags & ~SCOPEcontract) | SCOPEinvariant;
    sc->linkage = LINKd;

    FuncDeclaration::semantic(sc);

    sc->pop();
}

bool InvariantDeclaration::isVirtual()
{
    return false;
}

bool InvariantDeclaration::addPreInvariant()
{
    return false;
}

bool InvariantDeclaration::addPostInvariant()
{
    return false;
}

/********************************* UnitTestDeclaration ****************************/

/*******************************
 * Generate unique unittest function Id so we can have multiple
 * instances per module.
 */

static Identifier *unitTestId(Loc loc)
{
    OutBuffer buf;
    buf.printf("__unittestL%u_", loc.linnum);
    return Identifier::generateId(buf.peekString());
}

UnitTestDeclaration::UnitTestDeclaration(Loc loc, Loc endloc, StorageClass stc, char *codedoc)
    : FuncDeclaration(loc, endloc, unitTestId(loc), stc, NULL)
{
    this->codedoc = codedoc;
}

Dsymbol *UnitTestDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    UnitTestDeclaration *utd = new UnitTestDeclaration(loc, endloc, storage_class, codedoc);
    return FuncDeclaration::syntaxCopy(utd);
}

void UnitTestDeclaration::semantic(Scope *sc)
{
    if (semanticRun >= PASSsemanticdone)
        return;
    if (_scope)
    {
        sc = _scope;
        _scope = NULL;
    }

    protection = sc->protection;

    parent = sc->parent;
    Dsymbol *p = parent->pastMixin();
    if (!p->isScopeDsymbol())
    {
        ::error(loc, "unittest can only be a member of module/aggregate/template, not %s %s",
            p->kind(), p->toChars());
        type = Type::terror;
        errors = true;
        return;
    }

    if (global.params.useUnitTests)
    {
        if (!type)
            type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
        Scope *sc2 = sc->push();
        sc2->linkage = LINKd;
        FuncDeclaration::semantic(sc2);
        sc2->pop();
    }
}

AggregateDeclaration *UnitTestDeclaration::isThis()
{
    return NULL;
}

bool UnitTestDeclaration::isVirtual()
{
    return false;
}

bool UnitTestDeclaration::addPreInvariant()
{
    return false;
}

bool UnitTestDeclaration::addPostInvariant()
{
    return false;
}

/********************************* NewDeclaration ****************************/

NewDeclaration::NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *fparams, int varargs)
    : FuncDeclaration(loc, endloc, Id::classNew, STCstatic | stc, NULL)
{
    this->parameters = fparams;
    this->varargs = varargs;
}

Dsymbol *NewDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    NewDeclaration *f = new NewDeclaration(loc, endloc,
        storage_class, Parameter::arraySyntaxCopy(parameters), varargs);
    return FuncDeclaration::syntaxCopy(f);
}

void NewDeclaration::semantic(Scope *sc)
{
    //printf("NewDeclaration::semantic()\n");
    if (semanticRun >= PASSsemanticdone)
        return;
    if (_scope)
    {
        sc = _scope;
        _scope = NULL;
    }

    parent = sc->parent;
    Dsymbol *p = parent->pastMixin();
    if (!p->isAggregateDeclaration())
    {
        ::error(loc, "allocator can only be a member of aggregate, not %s %s",
            p->kind(), p->toChars());
        type = Type::terror;
        errors = true;
        return;
    }
    Type *tret = Type::tvoid->pointerTo();
    if (!type)
        type = new TypeFunction(parameters, tret, varargs, LINKd, storage_class);

    type = type->semantic(loc, sc);

    // Check that there is at least one argument of type size_t
    TypeFunction *tf = type->toTypeFunction();
    if (Parameter::dim(tf->parameters) < 1)
    {
        error("at least one argument of type size_t expected");
    }
    else
    {
        Parameter *fparam = Parameter::getNth(tf->parameters, 0);
        if (!fparam->type->equals(Type::tsize_t))
            error("first argument must be type size_t, not %s", fparam->type->toChars());
    }

    FuncDeclaration::semantic(sc);
}

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

bool NewDeclaration::isVirtual()
{
    return false;
}

bool NewDeclaration::addPreInvariant()
{
    return false;
}

bool NewDeclaration::addPostInvariant()
{
    return false;
}

/********************************* DeleteDeclaration ****************************/

DeleteDeclaration::DeleteDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *fparams)
    : FuncDeclaration(loc, endloc, Id::classDelete, STCstatic | stc, NULL)
{
    this->parameters = fparams;
}

Dsymbol *DeleteDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    DeleteDeclaration *f = new DeleteDeclaration(loc, endloc,
            storage_class, Parameter::arraySyntaxCopy(parameters));
    return FuncDeclaration::syntaxCopy(f);
}

void DeleteDeclaration::semantic(Scope *sc)
{
    //printf("DeleteDeclaration::semantic()\n");
    if (semanticRun >= PASSsemanticdone)
        return;
    if (_scope)
    {
        sc = _scope;
        _scope = NULL;
    }

    parent = sc->parent;
    Dsymbol *p = parent->pastMixin();
    if (!p->isAggregateDeclaration())
    {
        ::error(loc, "deallocator can only be a member of aggregate, not %s %s",
            p->kind(), p->toChars());
        type = Type::terror;
        errors = true;
        return;
    }
    if (!type)
        type = new TypeFunction(parameters, Type::tvoid, 0, LINKd, storage_class);

    type = type->semantic(loc, sc);

    // Check that there is only one argument of type void*
    TypeFunction *tf = type->toTypeFunction();
    if (Parameter::dim(tf->parameters) != 1)
    {
        error("one argument of type void* expected");
    }
    else
    {
        Parameter *fparam = Parameter::getNth(tf->parameters, 0);
        if (!fparam->type->equals(Type::tvoid->pointerTo()))
            error("one argument of type void* expected, not %s", fparam->type->toChars());
    }

    FuncDeclaration::semantic(sc);
}

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

bool DeleteDeclaration::isDelete()
{
    return true;
}

bool DeleteDeclaration::isVirtual()
{
    return false;
}

bool DeleteDeclaration::addPreInvariant()
{
    return false;
}

bool DeleteDeclaration::addPostInvariant()
{
    return false;
}
