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

#include "root/dsystem.h"               // mem{cpy|set}()
#include "root/root.h"
#include "root/rmem.h"

#include "errors.h"
#include "enum.h"
#include "init.h"
#include "attrib.h"
#include "declaration.h"
#include "aggregate.h"
#include "id.h"
#include "mtype.h"
#include "scope.h"
#include "module.h"
#include "expression.h"
#include "statement.h"
#include "template.h"
#include "target.h"
#include "objc.h"

bool symbolIsVisible(Dsymbol *origin, Dsymbol *s);
Objc *objc();


/********************************* ClassDeclaration ****************************/

ClassDeclaration *ClassDeclaration::object;
ClassDeclaration *ClassDeclaration::throwable;
ClassDeclaration *ClassDeclaration::exception;
ClassDeclaration *ClassDeclaration::errorException;
ClassDeclaration *ClassDeclaration::cpp_type_info_ptr;   // Object.__cpp_type_info_ptr

ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject)
    : AggregateDeclaration(loc, id ? id : Identifier::generateId("__anonclass"))
{
    static const char msg[] = "only object.d can define this reserved class name";

    if (baseclasses)
    {
        // Actually, this is a transfer
        this->baseclasses = baseclasses;
    }
    else
        this->baseclasses = new BaseClasses();

    this->members = members;

    baseClass = NULL;

    interfaces.length = 0;
    interfaces.ptr = NULL;

    vtblInterfaces = NULL;

    //printf("ClassDeclaration(%s), dim = %d\n", id->toChars(), this->baseclasses->dim);

    // For forward references
    type = new TypeClass(this);

    staticCtor = NULL;
    staticDtor = NULL;

    vtblsym = NULL;
    vclassinfo = NULL;

    if (id)
    {
        // Look for special class names

        if (id == Id::__sizeof || id == Id::__xalignof || id == Id::_mangleof)
            error("illegal class name");

        // BUG: What if this is the wrong TypeInfo, i.e. it is nested?
        if (id->toChars()[0] == 'T')
        {
            if (id == Id::TypeInfo)
            {
                if (!inObject)
                    error("%s", msg);
                Type::dtypeinfo = this;
            }

            if (id == Id::TypeInfo_Class)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfoclass = this;
            }

            if (id == Id::TypeInfo_Interface)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfointerface = this;
            }

            if (id == Id::TypeInfo_Struct)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfostruct = this;
            }

            if (id == Id::TypeInfo_Pointer)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfopointer = this;
            }

            if (id == Id::TypeInfo_Array)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfoarray = this;
            }

            if (id == Id::TypeInfo_StaticArray)
            {
                //if (!inObject)
                //    Type::typeinfostaticarray->error("%s", msg);
                Type::typeinfostaticarray = this;
            }

            if (id == Id::TypeInfo_AssociativeArray)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfoassociativearray = this;
            }

            if (id == Id::TypeInfo_Enum)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfoenum = this;
            }

            if (id == Id::TypeInfo_Function)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfofunction = this;
            }

            if (id == Id::TypeInfo_Delegate)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfodelegate = this;
            }

            if (id == Id::TypeInfo_Tuple)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfotypelist = this;
            }

            if (id == Id::TypeInfo_Const)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfoconst = this;
            }

            if (id == Id::TypeInfo_Invariant)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfoinvariant = this;
            }

            if (id == Id::TypeInfo_Shared)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfoshared = this;
            }

            if (id == Id::TypeInfo_Wild)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfowild = this;
            }

            if (id == Id::TypeInfo_Vector)
            {
                if (!inObject)
                    error("%s", msg);
                Type::typeinfovector = this;
            }
        }

        if (id == Id::Object)
        {
            if (!inObject)
                error("%s", msg);
            object = this;
        }

        if (id == Id::Throwable)
        {
            if (!inObject)
                error("%s", msg);
            throwable = this;
        }

        if (id == Id::Exception)
        {
            if (!inObject)
                error("%s", msg);
            exception = this;
        }

        if (id == Id::Error)
        {
            if (!inObject)
                error("%s", msg);
            errorException = this;
        }

        if (id == Id::cpp_type_info_ptr)
        {
            if (!inObject)
                error("%s", msg);
            cpp_type_info_ptr = this;
        }
    }

    com = false;
    isscope = false;
    isabstract = ABSfwdref;
    inuse = 0;
    baseok = BASEOKnone;
    cpp_type_info_ptr_sym = NULL;
}

ClassDeclaration *ClassDeclaration::create(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject)
{
    return new ClassDeclaration(loc, id, baseclasses, members, inObject);
}

Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s)
{
    //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars());
    ClassDeclaration *cd =
        s ? (ClassDeclaration *)s
          : new ClassDeclaration(loc, ident, NULL, NULL, false);

    cd->storage_class |= storage_class;

    cd->baseclasses->setDim(this->baseclasses->dim);
    for (size_t i = 0; i < cd->baseclasses->dim; i++)
    {
        BaseClass *b = (*this->baseclasses)[i];
        BaseClass *b2 = new BaseClass(b->type->syntaxCopy());
        (*cd->baseclasses)[i] = b2;
    }

    return ScopeDsymbol::syntaxCopy(cd);
}

Scope *ClassDeclaration::newScope(Scope *sc)
{
    Scope *sc2 = AggregateDeclaration::newScope(sc);
    if (isCOMclass())
    {
        if (global.params.isWindows)
            sc2->linkage = LINKwindows;
        else
        {
            /* This enables us to use COM objects under Linux and
             * work with things like XPCOM
             */
            sc2->linkage = LINKc;
        }
    }
    return sc2;
}

/* Bugzilla 12078, 12143 and 15733:
 * While resolving base classes and interfaces, a base may refer
 * the member of this derived class. In that time, if all bases of
 * this class can  be determined, we can go forward the semantc process
 * beyond the Lancestorsdone. To do the recursive semantic analysis,
 * temporarily set and unset `_scope` around exp().
 */
static Type *resolveBase(ClassDeclaration *cd, Scope *sc, Scope *&scx, Type *type)
{
    if (!scx)
    {
        scx = sc->copy();
        scx->setNoFree();
    }
    cd->_scope = scx;
    Type *t = type->semantic(cd->loc, sc);
    cd->_scope = NULL;
    return t;
}

static void resolveBase(ClassDeclaration *cd, Scope *sc, Scope *&scx, ClassDeclaration *sym)
{
    if (!scx)
    {
        scx = sc->copy();
        scx->setNoFree();
    }
    cd->_scope = scx;
    sym->semantic(NULL);
    cd->_scope = NULL;
}

static void badObjectDotD(ClassDeclaration *cd)
{
    cd->error("missing or corrupt object.d");
    fatal();
}

void ClassDeclaration::semantic(Scope *sc)
{
    //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
    //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : "");
    //printf("sc->stc = %x\n", sc->stc);

    //{ static int n;  if (++n == 20) *(char*)0=0; }

    if (semanticRun >= PASSsemanticdone)
        return;
    unsigned errors = global.errors;

    //printf("+ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);

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

    if (!parent)
    {
        assert(sc->parent);
        parent = sc->parent;
    }

    if (this->errors)
        type = Type::terror;
    type = type->semantic(loc, sc);

    if (type->ty == Tclass && ((TypeClass *)type)->sym != this)
    {
        TemplateInstance *ti = ((TypeClass *)type)->sym->isInstantiated();
        if (ti && isError(ti))
            ((TypeClass *)type)->sym = this;
    }

    // Ungag errors when not speculative
    Ungag ungag = ungagSpeculative();

    if (semanticRun == PASSinit)
    {
        protection = sc->protection;

        storage_class |= sc->stc;
        if (storage_class & STCdeprecated)
            isdeprecated = true;
        if (storage_class & STCauto)
            error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?");
        if (storage_class & STCscope)
            isscope = true;
        if (storage_class & STCabstract)
            isabstract = ABSyes;

        userAttribDecl = sc->userAttribDecl;

        if (sc->linkage == LINKcpp)
            classKind = ClassKind::cpp;
        if (sc->linkage == LINKobjc)
            objc()->setObjc(this);
    }
    else if (symtab && !scx)
    {
        return;
    }
    semanticRun = PASSsemantic;

    if (baseok < BASEOKdone)
    {
        baseok = BASEOKin;

        // Expand any tuples in baseclasses[]
        for (size_t i = 0; i < baseclasses->dim; )
        {
            BaseClass *b = (*baseclasses)[i];
            b->type = resolveBase(this, sc, scx, b->type);

            Type *tb = b->type->toBasetype();
            if (tb->ty == Ttuple)
            {
                TypeTuple *tup = (TypeTuple *)tb;
                baseclasses->remove(i);
                size_t dim = Parameter::dim(tup->arguments);
                for (size_t j = 0; j < dim; j++)
                {
                    Parameter *arg = Parameter::getNth(tup->arguments, j);
                    b = new BaseClass(arg->type);
                    baseclasses->insert(i + j, b);
                }
            }
            else
                i++;
        }

        if (baseok >= BASEOKdone)
        {
            //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun);
            if (semanticRun >= PASSsemanticdone)
                return;
            goto Lancestorsdone;
        }

        // See if there's a base class as first in baseclasses[]
        if (baseclasses->dim)
        {
            BaseClass *b = (*baseclasses)[0];
            Type *tb = b->type->toBasetype();
            TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL;
            if (!tc)
            {
                if (b->type != Type::terror)
                    error("base type must be class or interface, not %s", b->type->toChars());
                baseclasses->remove(0);
                goto L7;
            }

            if (tc->sym->isDeprecated())
            {
                if (!isDeprecated())
                {
                    // Deriving from deprecated class makes this one deprecated too
                    isdeprecated = true;

                    tc->checkDeprecated(loc, sc);
                }
            }

            if (tc->sym->isInterfaceDeclaration())
                goto L7;

            for (ClassDeclaration *cdb = tc->sym; cdb; cdb = cdb->baseClass)
            {
                if (cdb == this)
                {
                    error("circular inheritance");
                    baseclasses->remove(0);
                    goto L7;
                }
            }

            /* Bugzilla 11034: Essentially, class inheritance hierarchy
             * and instance size of each classes are orthogonal information.
             * Therefore, even if tc->sym->sizeof == SIZEOKnone,
             * we need to set baseClass field for class covariance check.
             */
            baseClass = tc->sym;
            b->sym = baseClass;

            if (tc->sym->baseok < BASEOKdone)
                resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference
            if (tc->sym->baseok < BASEOKdone)
            {
                //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars());
                if (tc->sym->_scope)
                    tc->sym->_scope->_module->addDeferredSemantic(tc->sym);
                baseok = BASEOKnone;
            }
         L7: ;
        }

        // Treat the remaining entries in baseclasses as interfaces
        // Check for errors, handle forward references
        for (size_t i = (baseClass ? 1 : 0); i < baseclasses->dim; )
        {
            BaseClass *b = (*baseclasses)[i];
            Type *tb = b->type->toBasetype();
            TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL;
            if (!tc || !tc->sym->isInterfaceDeclaration())
            {
                if (b->type != Type::terror)
                    error("base type must be interface, not %s", b->type->toChars());
                baseclasses->remove(i);
                continue;
            }

            // Check for duplicate interfaces
            for (size_t j = (baseClass ? 1 : 0); j < i; j++)
            {
                BaseClass *b2 = (*baseclasses)[j];
                if (b2->sym == tc->sym)
                {
                    error("inherits from duplicate interface %s", b2->sym->toChars());
                    baseclasses->remove(i);
                    continue;
                }
            }

            if (tc->sym->isDeprecated())
            {
                if (!isDeprecated())
                {
                    // Deriving from deprecated class makes this one deprecated too
                    isdeprecated = true;

                    tc->checkDeprecated(loc, sc);
                }
            }

            b->sym = tc->sym;

            if (tc->sym->baseok < BASEOKdone)
                resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference
            if (tc->sym->baseok < BASEOKdone)
            {
                //printf("\ttry later, forward reference of base %s\n", tc->sym->toChars());
                if (tc->sym->_scope)
                    tc->sym->_scope->_module->addDeferredSemantic(tc->sym);
                baseok = BASEOKnone;
            }
            i++;
        }
        if (baseok == BASEOKnone)
        {
            // Forward referencee of one or more bases, try again later
            _scope = scx ? scx : sc->copy();
            _scope->setNoFree();
            _scope->_module->addDeferredSemantic(this);
            //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
            return;
        }
        baseok = BASEOKdone;

        // If no base class, and this is not an Object, use Object as base class
        if (!baseClass && ident != Id::Object && !isCPPclass())
        {
            if (!object || object->errors)
                badObjectDotD(this);

            Type *t = object->type;
            t = t->semantic(loc, sc)->toBasetype();
            if (t->ty == Terror)
                badObjectDotD(this);
            assert(t->ty == Tclass);
            TypeClass *tc = (TypeClass *)t;

            BaseClass *b = new BaseClass(tc);
            baseclasses->shift(b);

            baseClass = tc->sym;
            assert(!baseClass->isInterfaceDeclaration());
            b->sym = baseClass;
        }
        if (baseClass)
        {
            if (baseClass->storage_class & STCfinal)
                error("cannot inherit from final class %s", baseClass->toChars());

            // Inherit properties from base class
            if (baseClass->isCOMclass())
                com = true;
            if (baseClass->isCPPclass())
                classKind = ClassKind::cpp;
            if (baseClass->isscope)
                isscope = true;
            enclosing = baseClass->enclosing;
            storage_class |= baseClass->storage_class & STC_TYPECTOR;
        }

        interfaces.length = baseclasses->dim - (baseClass ? 1 : 0);
        interfaces.ptr = baseclasses->tdata() + (baseClass ? 1 : 0);

        for (size_t i = 0; i < interfaces.length; i++)
        {
            BaseClass *b = interfaces.ptr[i];
            // If this is an interface, and it derives from a COM interface,
            // then this is a COM interface too.
            if (b->sym->isCOMinterface())
                com = true;
            if (isCPPclass() && !b->sym->isCPPinterface())
            {
                ::error(loc, "C++ class '%s' cannot implement D interface '%s'",
                    toPrettyChars(), b->sym->toPrettyChars());
            }
        }

        interfaceSemantic(sc);
    }
Lancestorsdone:
    //printf("\tClassDeclaration::semantic(%s) baseok = %d\n", toChars(), baseok);

    if (!members)               // if opaque declaration
    {
        semanticRun = PASSsemanticdone;
        return;
    }
    if (!symtab)
    {
        symtab = new DsymbolTable();

        /* Bugzilla 12152: The semantic analysis of base classes should be finished
         * before the members semantic analysis of this class, in order to determine
         * vtbl in this class. However if a base class refers the member of this class,
         * it can be resolved as a normal forward reference.
         * Call addMember() and setScope() to make this class members visible from the base classes.
         */
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            s->addMember(sc, this);
        }

        Scope *sc2 = newScope(sc);

        /* Set scope so if there are forward references, we still might be able to
         * resolve individual members like enums.
         */
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            //printf("[%d] setScope %s %s, sc2 = %p\n", i, s->kind(), s->toChars(), sc2);
            s->setScope(sc2);
        }

        sc2->pop();
    }

    for (size_t i = 0; i < baseclasses->dim; i++)
    {
        BaseClass *b = (*baseclasses)[i];
        Type *tb = b->type->toBasetype();
        assert(tb->ty == Tclass);
        TypeClass *tc = (TypeClass *)tb;

        if (tc->sym->semanticRun < PASSsemanticdone)
        {
            // Forward referencee of one or more bases, try again later
            _scope = scx ? scx : sc->copy();
            _scope->setNoFree();
            if (tc->sym->_scope)
                tc->sym->_scope->_module->addDeferredSemantic(tc->sym);
            _scope->_module->addDeferredSemantic(this);
            //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
            return;
        }
    }

    if (baseok == BASEOKdone)
    {
        baseok = BASEOKsemanticdone;

        // initialize vtbl
        if (baseClass)
        {
            if (isCPPclass() && baseClass->vtbl.dim == 0)
            {
                error("C++ base class %s needs at least one virtual function", baseClass->toChars());
            }

            // Copy vtbl[] from base class
            vtbl.setDim(baseClass->vtbl.dim);
            memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim);

            vthis = baseClass->vthis;
        }
        else
        {
            // No base class, so this is the root of the class hierarchy
            vtbl.setDim(0);
            if (vtblOffset())
                vtbl.push(this);            // leave room for classinfo as first member
        }

        /* If this is a nested class, add the hidden 'this'
         * member which is a pointer to the enclosing scope.
         */
        if (vthis)              // if inheriting from nested class
        {
            // Use the base class's 'this' member
            if (storage_class & STCstatic)
                error("static class cannot inherit from nested class %s", baseClass->toChars());
            if (toParent2() != baseClass->toParent2() &&
                (!toParent2() ||
                 !baseClass->toParent2()->getType() ||
                 !baseClass->toParent2()->getType()->isBaseOf(toParent2()->getType(), NULL)))
            {
                if (toParent2())
                {
                    error("is nested within %s, but super class %s is nested within %s",
                        toParent2()->toChars(),
                        baseClass->toChars(),
                        baseClass->toParent2()->toChars());
                }
                else
                {
                    error("is not nested, but super class %s is nested within %s",
                        baseClass->toChars(),
                        baseClass->toParent2()->toChars());
                }
                enclosing = NULL;
            }
        }
        else
            makeNested();
    }

    Scope *sc2 = newScope(sc);

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

    // Note that members.dim can grow due to tuple expansion during semantic()
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->semantic(sc2);
    }

    if (!determineFields())
    {
        assert(type == Type::terror);
        sc2->pop();
        return;
    }

    /* Following special member functions creation needs semantic analysis
     * completion of sub-structs in each field types.
     */
    for (size_t i = 0; i < fields.dim; i++)
    {
        VarDeclaration *v = fields[i];
        Type *tb = v->type->baseElemOf();
        if (tb->ty != Tstruct)
            continue;
        StructDeclaration *sd = ((TypeStruct *)tb)->sym;
        if (sd->semanticRun >= PASSsemanticdone)
            continue;

        sc2->pop();

        _scope = scx ? scx : sc->copy();
        _scope->setNoFree();
        _scope->_module->addDeferredSemantic(this);
        //printf("\tdeferring %s\n", toChars());
        return;
    }

    /* Look for special member functions.
     * They must be in this class, not in a base class.
     */

    // Can be in base class
    aggNew    =    (NewDeclaration *)search(Loc(), Id::classNew);
    aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete);

    // Look for the constructor
    ctor = searchCtor();

    if (!ctor && noDefaultCtor)
    {
        // A class object is always created by constructor, so this check is legitimate.
        for (size_t i = 0; i < fields.dim; i++)
        {
            VarDeclaration *v = fields[i];
            if (v->storage_class & STCnodefaultctor)
                ::error(v->loc, "field %s must be initialized in constructor", v->toChars());
        }
    }

    // If this class has no constructor, but base class has a default
    // ctor, create a constructor:
    //    this() { }
    if (!ctor && baseClass && baseClass->ctor)
    {
        FuncDeclaration *fd = resolveFuncCall(loc, sc2, baseClass->ctor, NULL, type, NULL, 1);
        if (!fd) // try shared base ctor instead
            fd = resolveFuncCall(loc, sc2, baseClass->ctor, NULL, type->sharedOf(), NULL, 1);
        if (fd && !fd->errors)
        {
            //printf("Creating default this(){} for class %s\n", toChars());
            TypeFunction *btf = fd->type->toTypeFunction();
            TypeFunction *tf = new TypeFunction(NULL, NULL, 0, LINKd, fd->storage_class);
            tf->mod = btf->mod;
            tf->purity = btf->purity;
            tf->isnothrow = btf->isnothrow;
            tf->isnogc = btf->isnogc;
            tf->trust = btf->trust;

            CtorDeclaration *ctor = new CtorDeclaration(loc, Loc(), 0, tf);
            ctor->fbody = new CompoundStatement(Loc(), new Statements());

            members->push(ctor);
            ctor->addMember(sc, this);
            ctor->semantic(sc2);

            this->ctor = ctor;
            defaultCtor = ctor;
        }
        else
        {
            error("cannot implicitly generate a default ctor when base class %s is missing a default ctor",
                baseClass->toPrettyChars());
        }
    }

    dtor = buildDtor(this, sc2);

    if (FuncDeclaration *f = hasIdentityOpAssign(this, sc2))
    {
        if (!(f->storage_class & STCdisable))
            error(f->loc, "identity assignment operator overload is illegal");
    }

    inv = buildInv(this, sc2);

    Module::dprogress++;
    semanticRun = PASSsemanticdone;
    //printf("-ClassDeclaration.semantic(%s), type = %p\n", toChars(), type);
    //members.print();

    sc2->pop();

    if (type->ty == Tclass && ((TypeClass *)type)->sym != this)
    {
        // https://issues.dlang.org/show_bug.cgi?id=17492
        ClassDeclaration *cd = ((TypeClass *)type)->sym;
        error("already exists at %s. Perhaps in another function with the same name?", cd->loc.toChars());
    }

    if (global.errors != errors)
    {
        // The type is no good.
        type = Type::terror;
        this->errors = true;
        if (deferred)
            deferred->errors = true;
    }

    // Verify fields of a synchronized class are not public
    if (storage_class & STCsynchronized)
    {
        for (size_t i = 0; i < fields.dim; i++)
        {
            VarDeclaration *vd = fields[i];
            if (!vd->isThisDeclaration() &&
                !vd->prot().isMoreRestrictiveThan(Prot(PROTpublic)))
            {
                vd->error("Field members of a synchronized class cannot be %s",
                    protectionToChars(vd->prot().kind));
            }
        }
    }

    if (deferred && !global.gag)
    {
        deferred->semantic2(sc);
        deferred->semantic3(sc);
    }
    //printf("-ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
}

/*********************************************
 * Determine if 'this' is a base class of cd.
 * This is used to detect circular inheritance only.
 */

bool ClassDeclaration::isBaseOf2(ClassDeclaration *cd)
{
    if (!cd)
        return false;
    //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
    for (size_t i = 0; i < cd->baseclasses->dim; i++)
    {
        BaseClass *b = (*cd->baseclasses)[i];
        if (b->sym == this || isBaseOf2(b->sym))
            return true;
    }
    return false;
}

/*******************************************
 * Determine if 'this' is a base class of cd.
 */

bool ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset)
{
    //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
    if (poffset)
        *poffset = 0;
    while (cd)
    {
        /* cd->baseClass might not be set if cd is forward referenced.
         */
        if (!cd->baseClass && cd->semanticRun < PASSsemanticdone && !cd->isInterfaceDeclaration())
        {
            cd->semantic(NULL);
            if (!cd->baseClass && cd->semanticRun < PASSsemanticdone)
                cd->error("base class is forward referenced by %s", toChars());
        }

        if (this == cd->baseClass)
            return true;

        cd = cd->baseClass;
    }
    return false;
}

/*********************************************
 * Determine if 'this' has complete base class information.
 * This is used to detect forward references in covariant overloads.
 */

bool ClassDeclaration::isBaseInfoComplete()
{
    return baseok >= BASEOKdone;
}

Dsymbol *ClassDeclaration::search(const Loc &loc, Identifier *ident, int flags)
{
    //printf("%s.ClassDeclaration::search('%s', flags=x%x)\n", toChars(), ident->toChars(), flags);

    //if (_scope) printf("%s baseok = %d\n", toChars(), baseok);
    if (_scope && baseok < BASEOKdone)
    {
        if (!inuse)
        {
            // must semantic on base class/interfaces
            ++inuse;
            semantic(NULL);
            --inuse;
        }
    }

    if (!members || !symtab)    // opaque or addMember is not yet done
    {
        error("is forward referenced when looking for '%s'", ident->toChars());
        //*(char*)0=0;
        return NULL;
    }

    Dsymbol *s = ScopeDsymbol::search(loc, ident, flags);

    // don't search imports of base classes
    if (flags & SearchImportsOnly)
        return s;

    if (!s)
    {
        // Search bases classes in depth-first, left to right order

        for (size_t i = 0; i < baseclasses->dim; i++)
        {
            BaseClass *b = (*baseclasses)[i];

            if (b->sym)
            {
                if (!b->sym->symtab)
                    error("base %s is forward referenced", b->sym->ident->toChars());
                else
                {
                    s = b->sym->search(loc, ident, flags);
                    if (!s)
                        continue;
                    else if (s == this) // happens if s is nested in this and derives from this
                        s = NULL;
                    else if (!(flags & IgnoreSymbolVisibility) && !(s->prot().kind == PROTprotected) && !symbolIsVisible(this, s))
                        s = NULL;
                    else
                        break;
                }
            }
        }
    }
    return s;
}

/************************************
 * Search base classes in depth-first, left-to-right order for
 * a class or interface named 'ident'.
 * Stops at first found. Does not look for additional matches.
 * Params:
 *  ident = identifier to search for
 * Returns:
 *  ClassDeclaration if found, null if not
 */
ClassDeclaration *ClassDeclaration::searchBase(Identifier *ident)
{
    for (size_t i = 0; i < baseclasses->dim; i++)
    {
        BaseClass *b = (*baseclasses)[i];
        ClassDeclaration *cdb = b->type->isClassHandle();
        if (!cdb)   // Bugzilla 10616
            return NULL;
        if (cdb->ident->equals(ident))
            return cdb;
        cdb = cdb->searchBase(ident);
        if (cdb)
            return cdb;
    }
    return NULL;
}

/****
 * Runs through the inheritance graph to set the BaseClass.offset fields.
 * Recursive in order to account for the size of the interface classes, if they are
 * more than just interfaces.
 * Params:
 *      cd = interface to look at
 *      baseOffset = offset of where cd will be placed
 * Returns:
 *      subset of instantiated size used by cd for interfaces
 */
static unsigned membersPlace(BaseClasses *vtblInterfaces, size_t &bi, ClassDeclaration *cd, unsigned baseOffset)
{
    //printf("    membersPlace(%s, %d)\n", cd->toChars(), baseOffset);
    unsigned offset = baseOffset;

    for (size_t i = 0; i < cd->interfaces.length; i++)
    {
        BaseClass *b = cd->interfaces.ptr[i];
        if (b->sym->sizeok != SIZEOKdone)
            b->sym->finalizeSize();
        assert(b->sym->sizeok == SIZEOKdone);

        if (!b->sym->alignsize)
            b->sym->alignsize = Target::ptrsize;
        cd->alignmember(b->sym->alignsize, b->sym->alignsize, &offset);
        assert(bi < vtblInterfaces->dim);
        BaseClass *bv = (*vtblInterfaces)[bi];
        if (b->sym->interfaces.length == 0)
        {
            //printf("\tvtblInterfaces[%d] b=%p b->sym = %s, offset = %d\n", bi, bv, bv->sym->toChars(), offset);
            bv->offset = offset;
            ++bi;
            // All the base interfaces down the left side share the same offset
            for (BaseClass *b2 = bv; b2->baseInterfaces.length; )
            {
                b2 = &b2->baseInterfaces.ptr[0];
                b2->offset = offset;
                //printf("\tvtblInterfaces[%d] b=%p   sym = %s, offset = %d\n", bi, b2, b2->sym->toChars(), b2->offset);
            }
        }
        membersPlace(vtblInterfaces, bi, b->sym, offset);
        //printf(" %s size = %d\n", b->sym->toChars(), b->sym->structsize);
        offset += b->sym->structsize;
        if (cd->alignsize < b->sym->alignsize)
            cd->alignsize = b->sym->alignsize;
    }
    return offset - baseOffset;
}

void ClassDeclaration::finalizeSize()
{
    assert(sizeok != SIZEOKdone);

    // Set the offsets of the fields and determine the size of the class
    if (baseClass)
    {
        assert(baseClass->sizeok == SIZEOKdone);

        alignsize = baseClass->alignsize;
        structsize = baseClass->structsize;
        if (isCPPclass() && global.params.isWindows)
            structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
    }
    else if (isInterfaceDeclaration())
    {
        if (interfaces.length == 0)
        {
            alignsize = Target::ptrsize;
            structsize = Target::ptrsize;      // allow room for __vptr
        }
    }
    else
    {
        alignsize = Target::ptrsize;
        structsize = Target::ptrsize;      // allow room for __vptr
        if (!isCPPclass())
            structsize += Target::ptrsize; // allow room for __monitor
    }

    //printf("finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
    size_t bi = 0;                  // index into vtblInterfaces[]

    // Add vptr's for any interfaces implemented by this class
    structsize += membersPlace(vtblInterfaces, bi, this, structsize);

    if (isInterfaceDeclaration())
    {
        sizeok = SIZEOKdone;
        return;
    }

    // FIXME: Currently setFieldOffset functions need to increase fields
    // to calculate each variable offsets. It can be improved later.
    fields.setDim(0);

    unsigned offset = structsize;
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->setFieldOffset(this, &offset, false);
    }

    sizeok = SIZEOKdone;

    // Calculate fields[i]->overlapped
    checkOverlappedFields();
}

/**********************************************************
 * fd is in the vtbl[] for this class.
 * Return 1 if function is hidden (not findable through search).
 */

int isf(void *param, Dsymbol *s)
{
    FuncDeclaration *fd = s->isFuncDeclaration();
    if (!fd)
        return 0;
    //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars());
    return (RootObject *)param == fd;
}

bool ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
{
    //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toPrettyChars());
    Dsymbol *s = search(Loc(), fd->ident, IgnoreAmbiguous | IgnoreErrors);
    if (!s)
    {
        //printf("not found\n");
        /* Because, due to a hack, if there are multiple definitions
         * of fd->ident, NULL is returned.
         */
        return false;
    }
    s = s->toAlias();
    OverloadSet *os = s->isOverloadSet();
    if (os)
    {
        for (size_t i = 0; i < os->a.dim; i++)
        {
            Dsymbol *s2 = os->a[i];
            FuncDeclaration *f2 = s2->isFuncDeclaration();
            if (f2 && overloadApply(f2, (void *)fd, &isf))
                return false;
        }
        return true;
    }
    else
    {
        FuncDeclaration *fdstart = s->isFuncDeclaration();
        //printf("%s fdstart = %p\n", s->kind(), fdstart);
        if (overloadApply(fdstart, (void *)fd, &isf))
            return false;

        return !fd->parent->isTemplateMixin();
    }
}

/****************
 * Find virtual function matching identifier and type.
 * Used to build virtual function tables for interface implementations.
 */

FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf)
{
    //printf("ClassDeclaration::findFunc(%s, %s) %s\n", ident->toChars(), tf->toChars(), toChars());
    FuncDeclaration *fdmatch = NULL;
    FuncDeclaration *fdambig = NULL;

    ClassDeclaration *cd = this;
    Dsymbols *vtbl = &cd->vtbl;
    while (1)
    {
        for (size_t i = 0; i < vtbl->dim; i++)
        {
            FuncDeclaration *fd = (*vtbl)[i]->isFuncDeclaration();
            if (!fd)
                continue;               // the first entry might be a ClassInfo

            //printf("\t[%d] = %s\n", i, fd->toChars());
            if (ident == fd->ident &&
                fd->type->covariant(tf) == 1)
            {
                //printf("fd->parent->isClassDeclaration() = %p\n", fd->parent->isClassDeclaration());
                if (!fdmatch)
                    goto Lfd;
                if (fd == fdmatch)
                    goto Lfdmatch;

                {
                // Function type matcing: exact > covariant
                MATCH m1 = tf->equals(fd     ->type) ? MATCHexact : MATCHnomatch;
                MATCH m2 = tf->equals(fdmatch->type) ? MATCHexact : MATCHnomatch;
                if (m1 > m2)
                    goto Lfd;
                else if (m1 < m2)
                    goto Lfdmatch;
                }

                {
                MATCH m1 = (tf->mod == fd     ->type->mod) ? MATCHexact : MATCHnomatch;
                MATCH m2 = (tf->mod == fdmatch->type->mod) ? MATCHexact : MATCHnomatch;
                if (m1 > m2)
                    goto Lfd;
                else if (m1 < m2)
                    goto Lfdmatch;
                }

                {
                // The way of definition: non-mixin > mixin
                MATCH m1 = fd     ->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch;
                MATCH m2 = fdmatch->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch;
                if (m1 > m2)
                    goto Lfd;
                else if (m1 < m2)
                    goto Lfdmatch;
                }

                fdambig = fd;
                //printf("Lambig fdambig = %s %s [%s]\n", fdambig->toChars(), fdambig->type->toChars(), fdambig->loc.toChars());
                continue;

            Lfd:
                fdmatch = fd;
                fdambig = NULL;
                //printf("Lfd fdmatch = %s %s [%s]\n", fdmatch->toChars(), fdmatch->type->toChars(), fdmatch->loc.toChars());
                continue;

            Lfdmatch:
                continue;
            }
            //else printf("\t\t%d\n", fd->type->covariant(tf));
        }
        if (!cd)
            break;
        vtbl = &cd->vtblFinal;
        cd = cd->baseClass;
    }

    if (fdambig)
        error("ambiguous virtual function %s", fdambig->toChars());
    return fdmatch;
}

void ClassDeclaration::interfaceSemantic(Scope *)
{
    vtblInterfaces = new BaseClasses();
    vtblInterfaces->reserve(interfaces.length);

    for (size_t i = 0; i < interfaces.length; i++)
    {
        BaseClass *b = interfaces.ptr[i];
        vtblInterfaces->push(b);
        b->copyBaseInterfaces(vtblInterfaces);
    }
}

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

bool ClassDeclaration::isCOMclass() const
{
    return com;
}

bool ClassDeclaration::isCOMinterface() const
{
    return false;
}

bool ClassDeclaration::isCPPclass() const
{
    return classKind == ClassKind::cpp;
}

bool ClassDeclaration::isCPPinterface() const
{
    return false;
}


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

bool ClassDeclaration::isAbstract()
{
    if (isabstract != ABSfwdref)
        return isabstract == ABSyes;

    /* Bugzilla 11169: Resolve forward references to all class member functions,
     * and determine whether this class is abstract.
     */
    struct SearchAbstract
    {
        static int fp(Dsymbol *s, void *)
        {
            FuncDeclaration *fd = s->isFuncDeclaration();
            if (!fd)
                return 0;
            if (fd->storage_class & STCstatic)
                return 0;

            if (fd->_scope)
                fd->semantic(NULL);

            if (fd->isAbstract())
                return 1;
            return 0;
        }
    };

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        if (s->apply(&SearchAbstract::fp, this))
        {
            isabstract = ABSyes;
            return true;
        }
    }

    /* Iterate inherited member functions and check their abstract attribute.
     */
    for (size_t i = 1; i < vtbl.dim; i++)
    {
        FuncDeclaration *fd = vtbl[i]->isFuncDeclaration();
        //if (fd) printf("\tvtbl[%d] = [%s] %s\n", i, fd->loc.toChars(), fd->toChars());
        if (!fd || fd->isAbstract())
        {
            isabstract = ABSyes;
            return true;
        }
    }

    isabstract = ABSno;
    return false;
}


/****************************************
 * Determine if slot 0 of the vtbl[] is reserved for something else.
 * For class objects, yes, this is where the classinfo ptr goes.
 * For COM interfaces, no.
 * For non-COM interfaces, yes, this is where the Interface ptr goes.
 * Returns:
 *      0       vtbl[0] is first virtual function pointer
 *      1       vtbl[0] is classinfo/interfaceinfo pointer
 */

int ClassDeclaration::vtblOffset() const
{
    return classKind == ClassKind::cpp ? 0 : 1;
}

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

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

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

void ClassDeclaration::addLocalClass(ClassDeclarations *aclasses)
{
    aclasses->push(this);
}

/********************************* InterfaceDeclaration ****************************/

InterfaceDeclaration::InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses)
    : ClassDeclaration(loc, id, baseclasses, NULL, false)
{
    if (id == Id::IUnknown)     // IUnknown is the root of all COM interfaces
    {
        com = true;
        classKind = ClassKind::cpp; // IUnknown is also a C++ interface
    }
}

Dsymbol *InterfaceDeclaration::syntaxCopy(Dsymbol *s)
{
    InterfaceDeclaration *id =
        s ? (InterfaceDeclaration *)s
          : new InterfaceDeclaration(loc, ident, NULL);
    return ClassDeclaration::syntaxCopy(id);
}

Scope *InterfaceDeclaration::newScope(Scope *sc)
{
    Scope *sc2 = ClassDeclaration::newScope(sc);
    if (com)
        sc2->linkage = LINKwindows;
    else if (classKind == ClassKind::cpp)
        sc2->linkage = LINKcpp;
    else if (classKind == ClassKind::objc)
        sc2->linkage = LINKobjc;
    return sc2;
}

void InterfaceDeclaration::semantic(Scope *sc)
{
    //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type);
    if (semanticRun >= PASSsemanticdone)
        return;
    unsigned errors = global.errors;

    //printf("+InterfaceDeclaration.semantic(%s), type = %p\n", toChars(), type);

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

    if (!parent)
    {
        assert(sc->parent && sc->func);
        parent = sc->parent;
    }
    assert(parent && !isAnonymous());

    if (this->errors)
        type = Type::terror;
    type = type->semantic(loc, sc);

    if (type->ty == Tclass && ((TypeClass *)type)->sym != this)
    {
        TemplateInstance *ti = ((TypeClass *)type)->sym->isInstantiated();
        if (ti && isError(ti))
            ((TypeClass *)type)->sym = this;
    }

    // Ungag errors when not speculative
    Ungag ungag = ungagSpeculative();

    if (semanticRun == PASSinit)
    {
        protection = sc->protection;

        storage_class |= sc->stc;
        if (storage_class & STCdeprecated)
            isdeprecated = true;

        userAttribDecl = sc->userAttribDecl;
    }
    else if (symtab)
    {
        if (sizeok == SIZEOKdone || !scx)
        {
            semanticRun = PASSsemanticdone;
            return;
        }
    }
    semanticRun = PASSsemantic;

    if (baseok < BASEOKdone)
    {
        baseok = BASEOKin;

        // Expand any tuples in baseclasses[]
        for (size_t i = 0; i < baseclasses->dim; )
        {
            BaseClass *b = (*baseclasses)[i];
            b->type = resolveBase(this, sc, scx, b->type);

            Type *tb = b->type->toBasetype();
            if (tb->ty == Ttuple)
            {
                TypeTuple *tup = (TypeTuple *)tb;
                baseclasses->remove(i);
                size_t dim = Parameter::dim(tup->arguments);
                for (size_t j = 0; j < dim; j++)
                {
                    Parameter *arg = Parameter::getNth(tup->arguments, j);
                    b = new BaseClass(arg->type);
                    baseclasses->insert(i + j, b);
                }
            }
            else
                i++;
        }

        if (baseok >= BASEOKdone)
        {
            //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun);
            if (semanticRun >= PASSsemanticdone)
                return;
            goto Lancestorsdone;
        }

        if (!baseclasses->dim && sc->linkage == LINKcpp)
            classKind = ClassKind::cpp;
        if (sc->linkage == LINKobjc)
            objc()->setObjc(this);

        // Check for errors, handle forward references
        for (size_t i = 0; i < baseclasses->dim; )
        {
            BaseClass *b = (*baseclasses)[i];
            Type *tb = b->type->toBasetype();
            TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL;
            if (!tc || !tc->sym->isInterfaceDeclaration())
            {
                if (b->type != Type::terror)
                    error("base type must be interface, not %s", b->type->toChars());
                baseclasses->remove(i);
                continue;
            }

            // Check for duplicate interfaces
            for (size_t j = 0; j < i; j++)
            {
                BaseClass *b2 = (*baseclasses)[j];
                if (b2->sym == tc->sym)
                {
                    error("inherits from duplicate interface %s", b2->sym->toChars());
                    baseclasses->remove(i);
                    continue;
                }
            }

            if (tc->sym == this || isBaseOf2(tc->sym))
            {
                error("circular inheritance of interface");
                baseclasses->remove(i);
                continue;
            }

            if (tc->sym->isDeprecated())
            {
                if (!isDeprecated())
                {
                    // Deriving from deprecated class makes this one deprecated too
                    isdeprecated = true;

                    tc->checkDeprecated(loc, sc);
                }
            }

            b->sym = tc->sym;

            if (tc->sym->baseok < BASEOKdone)
                resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference
            if (tc->sym->baseok < BASEOKdone)
            {
                //printf("\ttry later, forward reference of base %s\n", tc->sym->toChars());
                if (tc->sym->_scope)
                    tc->sym->_scope->_module->addDeferredSemantic(tc->sym);
                baseok = BASEOKnone;
            }
            i++;
        }
        if (baseok == BASEOKnone)
        {
            // Forward referencee of one or more bases, try again later
            _scope = scx ? scx : sc->copy();
            _scope->setNoFree();
            _scope->_module->addDeferredSemantic(this);
            return;
        }
        baseok = BASEOKdone;

        interfaces.length = baseclasses->dim;
        interfaces.ptr = baseclasses->tdata();

        for (size_t i = 0; i < interfaces.length; i++)
        {
            BaseClass *b = interfaces.ptr[i];
            // If this is an interface, and it derives from a COM interface,
            // then this is a COM interface too.
            if (b->sym->isCOMinterface())
                com = true;
            if (b->sym->isCPPinterface())
                classKind = ClassKind::cpp;
        }

        interfaceSemantic(sc);
    }
Lancestorsdone:

    if (!members)               // if opaque declaration
    {
        semanticRun = PASSsemanticdone;
        return;
    }
    if (!symtab)
        symtab = new DsymbolTable();

    for (size_t i = 0; i < baseclasses->dim; i++)
    {
        BaseClass *b = (*baseclasses)[i];
        Type *tb = b->type->toBasetype();
        assert(tb->ty == Tclass);
        TypeClass *tc = (TypeClass *)tb;

        if (tc->sym->semanticRun < PASSsemanticdone)
        {
            // Forward referencee of one or more bases, try again later
            _scope = scx ? scx : sc->copy();
            _scope->setNoFree();
            if (tc->sym->_scope)
                tc->sym->_scope->_module->addDeferredSemantic(tc->sym);
            _scope->_module->addDeferredSemantic(this);
            return;
        }
    }

    if (baseok == BASEOKdone)
    {
        baseok = BASEOKsemanticdone;

        // initialize vtbl
        if (vtblOffset())
            vtbl.push(this);                // leave room at vtbl[0] for classinfo

        // Cat together the vtbl[]'s from base interfaces
        for (size_t i = 0; i < interfaces.length; i++)
        {
            BaseClass *b = interfaces.ptr[i];

            // Skip if b has already appeared
            for (size_t k = 0; k < i; k++)
            {
                if (b == interfaces.ptr[k])
                    goto Lcontinue;
            }

            // Copy vtbl[] from base class
            if (b->sym->vtblOffset())
            {
                size_t d = b->sym->vtbl.dim;
                if (d > 1)
                {
                    vtbl.reserve(d - 1);
                    for (size_t j = 1; j < d; j++)
                        vtbl.push(b->sym->vtbl[j]);
                }
            }
            else
            {
                vtbl.append(&b->sym->vtbl);
            }

          Lcontinue:
            ;
        }
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->addMember(sc, this);
    }

    Scope *sc2 = newScope(sc);

    /* Set scope so if there are forward references, we still might be able to
     * resolve individual members like enums.
     */
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        //printf("setScope %s %s\n", s->kind(), s->toChars());
        s->setScope(sc2);
    }

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

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

    Module::dprogress++;
    semanticRun = PASSsemanticdone;
    //printf("-InterfaceDeclaration.semantic(%s), type = %p\n", toChars(), type);
    //members->print();

    sc2->pop();

    if (global.errors != errors)
    {
        // The type is no good.
        type = Type::terror;
    }

    assert(type->ty != Tclass || ((TypeClass *)type)->sym == this);
}

/*******************************************
 * Determine if 'this' is a base class of cd.
 * (Actually, if it is an interface supported by cd)
 * Output:
 *      *poffset        offset to start of class
 *                      OFFSET_RUNTIME  must determine offset at runtime
 * Returns:
 *      false   not a base
 *      true    is a base
 */

bool InterfaceDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset)
{
    //printf("%s.InterfaceDeclaration::isBaseOf(cd = '%s')\n", toChars(), cd->toChars());
    assert(!baseClass);
    for (size_t j = 0; j < cd->interfaces.length; j++)
    {
        BaseClass *b = cd->interfaces.ptr[j];

        //printf("\tX base %s\n", b->sym->toChars());
        if (this == b->sym)
        {
            //printf("\tfound at offset %d\n", b->offset);
            if (poffset)
            {
                // don't return incorrect offsets https://issues.dlang.org/show_bug.cgi?id=16980
                *poffset = cd->sizeok == SIZEOKdone ? b->offset : OFFSET_FWDREF;
            }
            //printf("\tfound at offset %d\n", b->offset);
            return true;
        }
        if (isBaseOf(b, poffset))
            return true;
    }

    if (cd->baseClass && isBaseOf(cd->baseClass, poffset))
        return true;

    if (poffset)
        *poffset = 0;
    return false;
}

bool InterfaceDeclaration::isBaseOf(BaseClass *bc, int *poffset)
{
    //printf("%s.InterfaceDeclaration::isBaseOf(bc = '%s')\n", toChars(), bc->sym->toChars());
    for (size_t j = 0; j < bc->baseInterfaces.length; j++)
    {
        BaseClass *b = &bc->baseInterfaces.ptr[j];

        //printf("\tY base %s\n", b->sym->toChars());
        if (this == b->sym)
        {
            //printf("\tfound at offset %d\n", b->offset);
            if (poffset)
            {
                *poffset = b->offset;
            }
            return true;
        }
        if (isBaseOf(b, poffset))
        {
            return true;
        }
    }
    if (poffset)
        *poffset = 0;
    return false;
}

/****************************************
 * Determine if slot 0 of the vtbl[] is reserved for something else.
 * For class objects, yes, this is where the ClassInfo ptr goes.
 * For COM interfaces, no.
 * For non-COM interfaces, yes, this is where the Interface ptr goes.
 */

int InterfaceDeclaration::vtblOffset() const
{
    if (isCOMinterface() || isCPPinterface())
        return 0;
    return 1;
}

bool InterfaceDeclaration::isCOMinterface() const
{
    return com;
}

bool InterfaceDeclaration::isCPPinterface() const
{
    return classKind == ClassKind::cpp;
}

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

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


/******************************** BaseClass *****************************/

BaseClass::BaseClass()
{
    this->type = NULL;
    this->sym = NULL;
    this->offset = 0;

    this->baseInterfaces.length = 0;
    this->baseInterfaces.ptr = NULL;
}

BaseClass::BaseClass(Type *type)
{
    //printf("BaseClass(this = %p, '%s')\n", this, type->toChars());
    this->type = type;
    this->sym = NULL;
    this->offset = 0;

    this->baseInterfaces.length = 0;
    this->baseInterfaces.ptr = NULL;
}

/****************************************
 * Fill in vtbl[] for base class based on member functions of class cd.
 * Input:
 *      vtbl            if !=NULL, fill it in
 *      newinstance     !=0 means all entries must be filled in by members
 *                      of cd, not members of any base classes of cd.
 * Returns:
 *      true if any entries were filled in by members of cd (not exclusively
 *      by base classes)
 */

bool BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance)
{
    bool result = false;

    //printf("BaseClass::fillVtbl(this='%s', cd='%s')\n", sym->toChars(), cd->toChars());
    if (vtbl)
        vtbl->setDim(sym->vtbl.dim);

    // first entry is ClassInfo reference
    for (size_t j = sym->vtblOffset(); j < sym->vtbl.dim; j++)
    {
        FuncDeclaration *ifd = sym->vtbl[j]->isFuncDeclaration();
        FuncDeclaration *fd;
        TypeFunction *tf;

        //printf("        vtbl[%d] is '%s'\n", j, ifd ? ifd->toChars() : "null");

        assert(ifd);
        // Find corresponding function in this class
        tf = ifd->type->toTypeFunction();
        fd = cd->findFunc(ifd->ident, tf);
        if (fd && !fd->isAbstract())
        {
            //printf("            found\n");
            // Check that calling conventions match
            if (fd->linkage != ifd->linkage)
                fd->error("linkage doesn't match interface function");

            // Check that it is current
            //printf("newinstance = %d fd->toParent() = %s ifd->toParent() = %s\n",
                //newinstance, fd->toParent()->toChars(), ifd->toParent()->toChars());
            if (newinstance && fd->toParent() != cd && ifd->toParent() == sym)
                cd->error("interface function '%s' is not implemented", ifd->toFullSignature());

            if (fd->toParent() == cd)
                result = true;
        }
        else
        {
            //printf("            not found %p\n", fd);
            // BUG: should mark this class as abstract?
            if (!cd->isAbstract())
                cd->error("interface function '%s' is not implemented", ifd->toFullSignature());

            fd = NULL;
        }
        if (vtbl)
            (*vtbl)[j] = fd;
    }

    return result;
}

void BaseClass::copyBaseInterfaces(BaseClasses *vtblInterfaces)
{
    //printf("+copyBaseInterfaces(), %s\n", sym->toChars());
//    if (baseInterfaces.length)
//      return;

    baseInterfaces.length = sym->interfaces.length;
    baseInterfaces.ptr = (BaseClass *)mem.xcalloc(baseInterfaces.length, sizeof(BaseClass));

    //printf("%s.copyBaseInterfaces()\n", sym->toChars());
    for (size_t i = 0; i < baseInterfaces.length; i++)
    {
        void *pb = &baseInterfaces.ptr[i];
        BaseClass *b2 = sym->interfaces.ptr[i];

        assert(b2->vtbl.dim == 0);      // should not be filled yet
        BaseClass *b = (BaseClass *)memcpy(pb, b2, sizeof(BaseClass));

        if (i)                          // single inheritance is i==0
            vtblInterfaces->push(b);    // only need for M.I.
        b->copyBaseInterfaces(vtblInterfaces);
    }
    //printf("-copyBaseInterfaces\n");
}
