
/* Compiler implementation of the D programming language
 * Copyright (C) 1999-2021 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/attrib.c
 */

#include "root/dsystem.h"               // memcmp()
#include "root/rmem.h"

#include "mars.h"
#include "init.h"
#include "declaration.h"
#include "attrib.h"
#include "cond.h"
#include "scope.h"
#include "id.h"
#include "expression.h"
#include "dsymbol.h"
#include "aggregate.h"
#include "module.h"
#include "parse.h"
#include "target.h"
#include "template.h"
#include "utf.h"
#include "mtype.h"

bool definitelyValueParameter(Expression *e);
Dsymbols *makeTupleForeachStaticDecl(Scope *sc, ForeachStatement *fs, Dsymbols *dbody, bool needExpansion);

/********************************* AttribDeclaration ****************************/

AttribDeclaration::AttribDeclaration(Dsymbols *decl)
        : Dsymbol()
{
    this->decl = decl;
}

Dsymbols *AttribDeclaration::include(Scope *)
{
    if (errors)
        return NULL;

    return decl;
}

int AttribDeclaration::apply(Dsymbol_apply_ft_t fp, void *param)
{
    Dsymbols *d = include(_scope);

    if (d)
    {
        for (size_t i = 0; i < d->length; i++)
        {
            Dsymbol *s = (*d)[i];
            if (s)
            {
                if (s->apply(fp, param))
                    return 1;
            }
        }
    }
    return 0;
}

/****************************************
 * Create a new scope if one or more given attributes
 * are different from the sc's.
 * If the returned scope != sc, the caller should pop
 * the scope after it used.
 */
Scope *AttribDeclaration::createNewScope(Scope *sc,
        StorageClass stc, LINK linkage, CPPMANGLE cppmangle, Prot protection,
        int explicitProtection, AlignDeclaration *aligndecl, PINLINE inlining)
{
    Scope *sc2 = sc;
    if (stc != sc->stc ||
        linkage != sc->linkage ||
        cppmangle != sc->cppmangle ||
        explicitProtection != sc->explicitProtection ||
        !(protection == sc->protection) ||
        aligndecl != sc->aligndecl ||
        inlining != sc->inlining)
    {
        // create new one for changes
        sc2 = sc->copy();
        sc2->stc = stc;
        sc2->linkage = linkage;
        sc2->cppmangle = cppmangle;
        sc2->protection = protection;
        sc2->explicitProtection = explicitProtection;
        sc2->aligndecl = aligndecl;
        sc2->inlining = inlining;
    }
    return sc2;
}

/****************************************
 * A hook point to supply scope for members.
 * addMember, setScope, importAll, semantic, semantic2 and semantic3 will use this.
 */
Scope *AttribDeclaration::newScope(Scope *sc)
{
    return sc;
}

void AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sds)
{
    Dsymbols *d = include(sc);

    if (d)
    {
        Scope *sc2 = newScope(sc);

        for (size_t i = 0; i < d->length; i++)
        {
            Dsymbol *s = (*d)[i];
            //printf("\taddMember %s to %s\n", s->toChars(), sds->toChars());
            s->addMember(sc2, sds);
        }

        if (sc2 != sc)
            sc2->pop();
    }
}

void AttribDeclaration::setScope(Scope *sc)
{
    Dsymbols *d = include(sc);

    //printf("\tAttribDeclaration::setScope '%s', d = %p\n",toChars(), d);
    if (d)
    {
        Scope *sc2 = newScope(sc);

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

        if (sc2 != sc)
            sc2->pop();
    }
}

void AttribDeclaration::importAll(Scope *sc)
{
    Dsymbols *d = include(sc);

    //printf("\tAttribDeclaration::importAll '%s', d = %p\n", toChars(), d);
    if (d)
    {
        Scope *sc2 = newScope(sc);

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

        if (sc2 != sc)
            sc2->pop();
    }
}

void AttribDeclaration::addComment(const utf8_t *comment)
{
    //printf("AttribDeclaration::addComment %s\n", comment);
    if (comment)
    {
        Dsymbols *d = include(NULL);

        if (d)
        {
            for (size_t i = 0; i < d->length; i++)
            {
                Dsymbol *s = (*d)[i];
                //printf("AttribDeclaration::addComment %s\n", s->toChars());
                s->addComment(comment);
            }
        }
    }
}

void AttribDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
{
    Dsymbols *d = include(NULL);

    if (d)
    {
        for (size_t i = 0; i < d->length; i++)
        {
            Dsymbol *s = (*d)[i];
            s->setFieldOffset(ad, poffset, isunion);
        }
    }
}

bool AttribDeclaration::hasPointers()
{
    Dsymbols *d = include(NULL);

    if (d)
    {
        for (size_t i = 0; i < d->length; i++)
        {
            Dsymbol *s = (*d)[i];
            if (s->hasPointers())
                return true;
        }
    }
    return false;
}

bool AttribDeclaration::hasStaticCtorOrDtor()
{
    Dsymbols *d = include(NULL);

    if (d)
    {
        for (size_t i = 0; i < d->length; i++)
        {
            Dsymbol *s = (*d)[i];
            if (s->hasStaticCtorOrDtor())
                return true;
        }
    }
    return false;
}

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

bool AttribDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
{
    Dsymbols *d = include(NULL);

    return Dsymbol::oneMembers(d, ps, ident);
}

void AttribDeclaration::checkCtorConstInit()
{
    Dsymbols *d = include(NULL);

    if (d)
    {
        for (size_t i = 0; i < d->length; i++)
        {
            Dsymbol *s = (*d)[i];
            s->checkCtorConstInit();
        }
    }
}

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

void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses)
{
    Dsymbols *d = include(NULL);

    if (d)
    {
        for (size_t i = 0; i < d->length; i++)
        {
            Dsymbol *s = (*d)[i];
            s->addLocalClass(aclasses);
        }
    }
}

/************************* StorageClassDeclaration ****************************/

StorageClassDeclaration::StorageClassDeclaration(StorageClass stc, Dsymbols *decl)
        : AttribDeclaration(decl)
{
    this->stc = stc;
}

Dsymbol *StorageClassDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    return new StorageClassDeclaration(stc, Dsymbol::arraySyntaxCopy(decl));
}

bool StorageClassDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
{
    bool t = Dsymbol::oneMembers(decl, ps, ident);
    if (t && *ps)
    {
        /* This is to deal with the following case:
         * struct Tick {
         *   template to(T) { const T to() { ... } }
         * }
         * For eponymous function templates, the 'const' needs to get attached to 'to'
         * before the semantic analysis of 'to', so that template overloading based on the
         * 'this' pointer can be successful.
         */

        FuncDeclaration *fd = (*ps)->isFuncDeclaration();
        if (fd)
        {
            /* Use storage_class2 instead of storage_class otherwise when we do .di generation
             * we'll wind up with 'const const' rather than 'const'.
             */
            /* Don't think we need to worry about mutually exclusive storage classes here
             */
            fd->storage_class2 |= stc;
        }
    }
    return t;
}

void StorageClassDeclaration::addMember(Scope *sc, ScopeDsymbol *sds)
{
    Dsymbols *d = include(sc);
    if (d)
    {
        Scope *sc2 = newScope(sc);
        for (size_t i = 0; i < d->length; i++)
        {
            Dsymbol *s = (*d)[i];
            //printf("\taddMember %s to %s\n", s->toChars(), sds->toChars());
            // STClocal needs to be attached before the member is added to the scope (because it influences the parent symbol)
            if (Declaration *decl = s->isDeclaration())
            {
                decl->storage_class |= stc & STClocal;
                if (StorageClassDeclaration *sdecl = s->isStorageClassDeclaration())
                {
                    sdecl->stc |= stc & STClocal;
                }
            }
            s->addMember(sc2, sds);
        }
        if (sc2 != sc)
            sc2->pop();
    }
}

Scope *StorageClassDeclaration::newScope(Scope *sc)
{
    StorageClass scstc = sc->stc;

    /* These sets of storage classes are mutually exclusive,
     * so choose the innermost or most recent one.
     */
    if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest))
        scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest);
    if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared))
        scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared);
    if (stc & (STCconst | STCimmutable | STCmanifest))
        scstc &= ~(STCconst | STCimmutable | STCmanifest);
    if (stc & (STCgshared | STCshared | STCtls))
        scstc &= ~(STCgshared | STCshared | STCtls);
    if (stc & (STCsafe | STCtrusted | STCsystem))
        scstc &= ~(STCsafe | STCtrusted | STCsystem);
    scstc |= stc;
    //printf("scstc = x%llx\n", scstc);

    return createNewScope(sc, scstc, sc->linkage, sc->cppmangle,
        sc->protection, sc->explicitProtection, sc->aligndecl,
        sc->inlining);
}

/********************************* DeprecatedDeclaration ****************************/

DeprecatedDeclaration::DeprecatedDeclaration(Expression *msg, Dsymbols *decl)
        : StorageClassDeclaration(STCdeprecated, decl)
{
    this->msg = msg;
    this->msgstr = NULL;
}

Dsymbol *DeprecatedDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    return new DeprecatedDeclaration(msg->syntaxCopy(), Dsymbol::arraySyntaxCopy(decl));
}

/**
 * Provides a new scope with `STCdeprecated` and `Scope.depdecl` set
 *
 * Calls `StorageClassDeclaration.newScope` (as it must be called or copied
 * in any function overriding `newScope`), then set the `Scope`'s depdecl.
 *
 * Returns:
 *   Always a new scope, to use for this `DeprecatedDeclaration`'s members.
 */
Scope *DeprecatedDeclaration::newScope(Scope *sc)
{
    Scope *scx = StorageClassDeclaration::newScope(sc);
    // The enclosing scope is deprecated as well
    if (scx == sc)
        scx = sc->push();
    scx->depdecl = this;
    return scx;
}

void DeprecatedDeclaration::setScope(Scope *sc)
{
    //printf("DeprecatedDeclaration::setScope() %p\n", this);
    if (decl)
        Dsymbol::setScope(sc); // for forward reference
    return AttribDeclaration::setScope(sc);
}

const char *DeprecatedDeclaration::getMessage()
{
    if (Scope *sc = _scope)
    {
        _scope = NULL;

        sc = sc->startCTFE();
        msg = expressionSemantic(msg, sc);
        msg = resolveProperties(sc, msg);
        sc = sc->endCTFE();
        msg = msg->ctfeInterpret();

        if (StringExp *se = msg->toStringExp())
            msgstr = (char *)se->string;
        else
            msg->error("compile time constant expected, not `%s`", msg->toChars());
    }
    return msgstr;
}

/********************************* LinkDeclaration ****************************/

LinkDeclaration::LinkDeclaration(LINK p, Dsymbols *decl)
        : AttribDeclaration(decl)
{
    //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl);
    linkage = (p == LINKsystem) ? target.systemLinkage() : p;
}

LinkDeclaration *LinkDeclaration::create(LINK p, Dsymbols *decl)
{
    return new LinkDeclaration(p, decl);
}

Dsymbol *LinkDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    return new LinkDeclaration(linkage, Dsymbol::arraySyntaxCopy(decl));
}

Scope *LinkDeclaration::newScope(Scope *sc)
{
    return createNewScope(sc, sc->stc, this->linkage, sc->cppmangle,
        sc->protection, sc->explicitProtection, sc->aligndecl,
        sc->inlining);
}

const char *LinkDeclaration::toChars()
{
    return "extern ()";
}

/********************************* CPPMangleDeclaration ****************************/

CPPMangleDeclaration::CPPMangleDeclaration(CPPMANGLE p, Dsymbols *decl)
        : AttribDeclaration(decl)
{
    //printf("CPPMangleDeclaration(cppmangle = %d, decl = %p)\n", p, decl);
    cppmangle = p;
}

Dsymbol *CPPMangleDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    return new CPPMangleDeclaration(cppmangle, Dsymbol::arraySyntaxCopy(decl));
}

Scope *CPPMangleDeclaration::newScope(Scope *sc)
{
    return createNewScope(sc, sc->stc, LINKcpp, this->cppmangle,
        sc->protection, sc->explicitProtection, sc->aligndecl,
        sc->inlining);
}

const char *CPPMangleDeclaration::toChars()
{
    return "extern ()";
}

/********************************* ProtDeclaration ****************************/

/**
 * Params:
 *  loc = source location of attribute token
 *  p = protection attribute data
 *  decl = declarations which are affected by this protection attribute
 */
ProtDeclaration::ProtDeclaration(Loc loc, Prot p, Dsymbols *decl)
        : AttribDeclaration(decl)
{
    this->loc = loc;
    this->protection = p;
    this->pkg_identifiers = NULL;
    //printf("decl = %p\n", decl);
}

/**
 * Params:
 *  loc = source location of attribute token
 *  pkg_identifiers = list of identifiers for a qualified package name
 *  decl = declarations which are affected by this protection attribute
 */
ProtDeclaration::ProtDeclaration(Loc loc, Identifiers* pkg_identifiers, Dsymbols *decl)
        : AttribDeclaration(decl)
{
    this->loc = loc;
    this->protection.kind = Prot::package_;
    this->protection.pkg  = NULL;
    this->pkg_identifiers = pkg_identifiers;
}

Dsymbol *ProtDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    if (protection.kind == Prot::package_)
        return new ProtDeclaration(this->loc, pkg_identifiers, Dsymbol::arraySyntaxCopy(decl));
    else
        return new ProtDeclaration(this->loc, protection, Dsymbol::arraySyntaxCopy(decl));
}

Scope *ProtDeclaration::newScope(Scope *sc)
{
    if (pkg_identifiers)
        dsymbolSemantic(this, sc);
    return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle,
        this->protection, 1, sc->aligndecl,
        sc->inlining);
}

void ProtDeclaration::addMember(Scope *sc, ScopeDsymbol *sds)
{
    if (pkg_identifiers)
    {
        Dsymbol* tmp;
        Package::resolve(pkg_identifiers, &tmp, NULL);
        protection.pkg = tmp ? tmp->isPackage() : NULL;
        pkg_identifiers = NULL;
    }

    if (protection.kind == Prot::package_ && protection.pkg && sc->_module)
    {
        Module *m = sc->_module;

        // While isAncestorPackageOf does an equality check, the fix for issue 17441 adds a check to see if
        // each package's .isModule() properites are equal.
        //
        // Properties generated from `package(foo)` i.e. protection.pkg have .isModule() == null.
        // This breaks package declarations of the package in question if they are declared in
        // the same package.d file, which _do_ have a module associated with them, and hence a non-null
        // isModule()
        if (!m->isPackage() || !protection.pkg->ident->equals(m->isPackage()->ident))
        {
            Package* pkg = m->parent ? m->parent->isPackage() : NULL;
            if (!pkg || !protection.pkg->isAncestorPackageOf(pkg))
                error("does not bind to one of ancestor packages of module `%s`",
                      m->toPrettyChars(true));
        }
    }

    return AttribDeclaration::addMember(sc, sds);
}

const char *ProtDeclaration::kind() const
{
    return "protection attribute";
}

const char *ProtDeclaration::toPrettyChars(bool)
{
    assert(protection.kind > Prot::undefined);

    OutBuffer buf;
    buf.writeByte('\'');
    protectionToBuffer(&buf, protection);
    buf.writeByte('\'');
    return buf.extractChars();
}

/********************************* AlignDeclaration ****************************/

AlignDeclaration::AlignDeclaration(Loc loc, Expression *ealign, Dsymbols *decl)
        : AttribDeclaration(decl)
{
    this->loc = loc;
    this->ealign = ealign;
    this->salign = 0;
}

Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    return new AlignDeclaration(loc,
        ealign ? ealign->syntaxCopy() : NULL,
        Dsymbol::arraySyntaxCopy(decl));
}

Scope *AlignDeclaration::newScope(Scope *sc)
{
    return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle,
        sc->protection, sc->explicitProtection, this,
        sc->inlining);
}

structalign_t AlignDeclaration::getAlignment(Scope *sc)
{
    if (salign != 0)
        return salign;

    if (!ealign)
        return salign = STRUCTALIGN_DEFAULT;

    sc = sc->startCTFE();
    ealign = expressionSemantic(ealign, sc);
    ealign = resolveProperties(sc, ealign);
    sc = sc->endCTFE();
    ealign = ealign->ctfeInterpret();

    if (ealign->op == TOKerror)
        return salign = STRUCTALIGN_DEFAULT;

    Type *tb = ealign->type->toBasetype();
    sinteger_t n = ealign->toInteger();

    if (n < 1 || n & (n - 1) || STRUCTALIGN_DEFAULT < n || !tb->isintegral())
    {
        ::error(loc, "alignment must be an integer positive power of 2, not %s", ealign->toChars());
        return salign = STRUCTALIGN_DEFAULT;
    }

    return salign = (structalign_t)n;
}

/********************************* AnonDeclaration ****************************/

AnonDeclaration::AnonDeclaration(Loc loc, bool isunion, Dsymbols *decl)
        : AttribDeclaration(decl)
{
    this->loc = loc;
    this->isunion = isunion;
    this->sem = 0;
    this->anonoffset = 0;
    this->anonstructsize = 0;
    this->anonalignsize = 0;
}

Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    return new AnonDeclaration(loc, isunion, Dsymbol::arraySyntaxCopy(decl));
}

void AnonDeclaration::setScope(Scope *sc)
{
    //printf("AnonDeclaration::setScope() %p\n", this);
    if (decl)
        Dsymbol::setScope(sc);
    AttribDeclaration::setScope(sc);
}

void AnonDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
{
    //printf("\tAnonDeclaration::setFieldOffset %s %p\n", isunion ? "union" : "struct", this);

    if (decl)
    {
        /* This works by treating an AnonDeclaration as an aggregate 'member',
         * so in order to place that member we need to compute the member's
         * size and alignment.
         */

        size_t fieldstart = ad->fields.length;

        /* Hackishly hijack ad's structsize and alignsize fields
         * for use in our fake anon aggregate member.
         */
        unsigned savestructsize = ad->structsize;
        unsigned savealignsize  = ad->alignsize;
        ad->structsize = 0;
        ad->alignsize = 0;

        unsigned offset = 0;
        for (size_t i = 0; i < decl->length; i++)
        {
            Dsymbol *s = (*decl)[i];
            s->setFieldOffset(ad, &offset, this->isunion);
            if (this->isunion)
                offset = 0;
        }

        /* Bugzilla 13613: If the fields in this->members had been already
         * added in ad->fields, just update *poffset for the subsequent
         * field offset calculation.
         */
        if (fieldstart == ad->fields.length)
        {
            ad->structsize = savestructsize;
            ad->alignsize  = savealignsize;
            *poffset = ad->structsize;
            return;
        }

        anonstructsize = ad->structsize;
        anonalignsize  = ad->alignsize;
        ad->structsize = savestructsize;
        ad->alignsize  = savealignsize;

        // 0 sized structs are set to 1 byte
        // TODO: is this corect hebavior?
        if (anonstructsize == 0)
        {
            anonstructsize = 1;
            anonalignsize = 1;
        }

        assert(_scope);
        structalign_t alignment = _scope->alignment();

        /* Given the anon 'member's size and alignment,
         * go ahead and place it.
         */
        anonoffset = AggregateDeclaration::placeField(
                poffset,
                anonstructsize, anonalignsize, alignment,
                &ad->structsize, &ad->alignsize,
                isunion);

        // Add to the anon fields the base offset of this anonymous aggregate
        //printf("anon fields, anonoffset = %d\n", anonoffset);
        for (size_t i = fieldstart; i < ad->fields.length; i++)
        {
            VarDeclaration *v = ad->fields[i];
            //printf("\t[%d] %s %d\n", i, v->toChars(), v->offset);
            v->offset += anonoffset;
        }
    }
}

const char *AnonDeclaration::kind() const
{
    return (isunion ? "anonymous union" : "anonymous struct");
}

/********************************* PragmaDeclaration ****************************/

PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Dsymbols *decl)
        : AttribDeclaration(decl)
{
    this->loc = loc;
    this->ident = ident;
    this->args = args;
}

Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s)
{
    //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars());
    assert(!s);
    return new PragmaDeclaration(loc, ident,
        Expression::arraySyntaxCopy(args),
        Dsymbol::arraySyntaxCopy(decl));
}

Scope *PragmaDeclaration::newScope(Scope *sc)
{
    if (ident == Id::Pinline)
    {
        PINLINE inlining = PINLINEdefault;
        if (!args || args->length == 0)
            inlining = PINLINEdefault;
        else if (args->length != 1)
        {
            error("one boolean expression expected for pragma(inline), not %d", args->length);
            args->setDim(1);
            (*args)[0] = new ErrorExp();
        }
        else
        {
            Expression *e = (*args)[0];

            if (e->op != TOKint64 || !e->type->equals(Type::tbool))
            {
                if (e->op != TOKerror)
                {
                    error("pragma(inline, true or false) expected, not %s", e->toChars());
                    (*args)[0] = new ErrorExp();
                }
            }
            else if (e->isBool(true))
                inlining = PINLINEalways;
            else if (e->isBool(false))
                inlining = PINLINEnever;
        }

        return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle,
            sc->protection, sc->explicitProtection, sc->aligndecl,
            inlining);
    }
    if (ident == Id::printf || ident == Id::scanf)
    {
        Scope *sc2 = sc->push();

        if (ident == Id::printf)
            // Override previous setting, never let both be set
            sc2->flags = (sc2->flags & ~SCOPEscanf) | SCOPEprintf;
        else
            sc2->flags = (sc2->flags & ~SCOPEprintf) | SCOPEscanf;

        return sc2;
    }
    return sc;
}

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

/********************************* ConditionalDeclaration ****************************/

ConditionalDeclaration::ConditionalDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl)
        : AttribDeclaration(decl)
{
    //printf("ConditionalDeclaration::ConditionalDeclaration()\n");
    this->condition = condition;
    this->elsedecl = elsedecl;
}

Dsymbol *ConditionalDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    return new ConditionalDeclaration(condition->syntaxCopy(),
        Dsymbol::arraySyntaxCopy(decl),
        Dsymbol::arraySyntaxCopy(elsedecl));
}

bool ConditionalDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
{
    //printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition->inc);
    if (condition->inc)
    {
        Dsymbols *d = condition->include(NULL) ? decl : elsedecl;
        return Dsymbol::oneMembers(d, ps, ident);
    }
    else
    {
        bool res = (Dsymbol::oneMembers(    decl, ps, ident) && *ps == NULL &&
                    Dsymbol::oneMembers(elsedecl, ps, ident) && *ps == NULL);
        *ps = NULL;
        return res;
    }
}

// Decide if 'then' or 'else' code should be included

Dsymbols *ConditionalDeclaration::include(Scope *sc)
{
    //printf("ConditionalDeclaration::include(sc = %p) _scope = %p\n", sc, _scope);

    if (errors)
        return NULL;

    assert(condition);
    return condition->include(_scope ? _scope : sc) ? decl : elsedecl;
}

void ConditionalDeclaration::setScope(Scope *sc)
{
    Dsymbols *d = include(sc);

    //printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d);
    if (d)
    {
       for (size_t i = 0; i < d->length; i++)
       {
           Dsymbol *s = (*d)[i];
           s->setScope(sc);
       }
    }
}

void ConditionalDeclaration::addComment(const utf8_t *comment)
{
    /* Because addComment is called by the parser, if we called
     * include() it would define a version before it was used.
     * But it's no problem to drill down to both decl and elsedecl,
     * so that's the workaround.
     */

    if (comment)
    {
        Dsymbols *d = decl;

        for (int j = 0; j < 2; j++)
        {
            if (d)
            {
                for (size_t i = 0; i < d->length; i++)
                {
                    Dsymbol *s = (*d)[i];
                    //printf("ConditionalDeclaration::addComment %s\n", s->toChars());
                    s->addComment(comment);
                }
            }
            d = elsedecl;
        }
    }
}

/***************************** StaticIfDeclaration ****************************/

StaticIfDeclaration::StaticIfDeclaration(Condition *condition,
        Dsymbols *decl, Dsymbols *elsedecl)
        : ConditionalDeclaration(condition, decl, elsedecl)
{
    //printf("StaticIfDeclaration::StaticIfDeclaration()\n");
    scopesym = NULL;
    addisdone = false;
    onStack = false;
}

Dsymbol *StaticIfDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    return new StaticIfDeclaration(condition->syntaxCopy(),
        Dsymbol::arraySyntaxCopy(decl),
        Dsymbol::arraySyntaxCopy(elsedecl));
}

/****************************************
 * Different from other AttribDeclaration subclasses, include() call requires
 * the completion of addMember and setScope phases.
 */
Dsymbols *StaticIfDeclaration::include(Scope *sc)
{
    //printf("StaticIfDeclaration::include(sc = %p) _scope = %p\n", sc, _scope);

    if (errors || onStack)
        return NULL;
    onStack = true;
    Dsymbols *d;

    if (condition->inc == 0)
    {
        assert(scopesym);   // addMember is already done
        assert(_scope);      // setScope is already done

        d = ConditionalDeclaration::include(_scope);

        if (d && !addisdone)
        {
            // Add members lazily.
            for (size_t i = 0; i < d->length; i++)
            {
                Dsymbol *s = (*d)[i];
                s->addMember(_scope, scopesym);
            }

            // Set the member scopes lazily.
            for (size_t i = 0; i < d->length; i++)
            {
                Dsymbol *s = (*d)[i];
                s->setScope(_scope);
            }

            addisdone = true;
        }
        onStack = false;
        return d;
    }
    else
    {
        d = ConditionalDeclaration::include(sc);
        onStack = false;
        return d;
    }
}

void StaticIfDeclaration::addMember(Scope *, ScopeDsymbol *sds)
{
    //printf("StaticIfDeclaration::addMember() '%s'\n", toChars());
    /* This is deferred until the condition evaluated later (by the include() call),
     * so that expressions in the condition can refer to declarations
     * in the same scope, such as:
     *
     * template Foo(int i)
     * {
     *     const int j = i + 1;
     *     static if (j == 3)
     *         const int k;
     * }
     */
    this->scopesym = sds;
}

void StaticIfDeclaration::importAll(Scope *)
{
    // do not evaluate condition before semantic pass
}

void StaticIfDeclaration::setScope(Scope *sc)
{
    // do not evaluate condition before semantic pass

    // But do set the scope, in case we need it for forward referencing
    Dsymbol::setScope(sc);
}

const char *StaticIfDeclaration::kind() const
{
    return "static if";
}

/***************************** StaticForeachDeclaration ***********************/

/* Static foreach at declaration scope, like:
 *     static foreach (i; [0, 1, 2]){ }
 */

StaticForeachDeclaration::StaticForeachDeclaration(StaticForeach *sfe, Dsymbols *decl)
        : AttribDeclaration(decl)
{
    this->sfe = sfe;
    this->scopesym = NULL;
    this->onStack = false;
    this->cached = false;
    this->cache = NULL;
}

Dsymbol *StaticForeachDeclaration::syntaxCopy(Dsymbol *s)
{
    assert(!s);
    return new StaticForeachDeclaration(
        sfe->syntaxCopy(),
        Dsymbol::arraySyntaxCopy(decl));
}

bool StaticForeachDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
{
    // Required to support IFTI on a template that contains a
    // `static foreach` declaration.  `super.oneMember` calls
    // include with a `null` scope.  As `static foreach` requires
    // the scope for expansion, `oneMember` can only return a
    // precise result once `static foreach` has been expanded.
    if (cached)
    {
        return AttribDeclaration::oneMember(ps, ident);
    }
    *ps = NULL; // a `static foreach` declaration may in general expand to multiple symbols
    return false;
}

Dsymbols *StaticForeachDeclaration::include(Scope *)
{
    if (errors || onStack)
        return NULL;
    if (cached)
    {
        assert(!onStack);
        return cache;
    }
    onStack = true;

    if (_scope)
    {
        staticForeachPrepare(sfe, _scope); // lower static foreach aggregate
    }
    if (!staticForeachReady(sfe))
    {
        onStack = false;
        return NULL; // TODO: ok?
    }

    // expand static foreach
    Dsymbols *d = makeTupleForeachStaticDecl(_scope, sfe->aggrfe, decl, sfe->needExpansion);
    if (d) // process generated declarations
    {
        // Add members lazily.
        for (size_t i = 0; i < d->length; i++)
        {
            Dsymbol *s = (*d)[i];
            s->addMember(_scope, scopesym);
        }
        // Set the member scopes lazily.
        for (size_t i = 0; i < d->length; i++)
        {
            Dsymbol *s = (*d)[i];
            s->setScope(_scope);
        }
    }
    onStack = false;
    cached = true;
    cache = d;
    return d;
}

void StaticForeachDeclaration::addMember(Scope *, ScopeDsymbol *sds)
{
    // used only for caching the enclosing symbol
    this->scopesym = sds;
}

void StaticForeachDeclaration::addComment(const utf8_t *)
{
    // do nothing
    // change this to give semantics to documentation comments on static foreach declarations
}

void StaticForeachDeclaration::setScope(Scope *sc)
{
    // do not evaluate condition before semantic pass
    // But do set the scope, in case we need it for forward referencing
    Dsymbol::setScope(sc);
}

void StaticForeachDeclaration::importAll(Scope *)
{
    // do not evaluate aggregate before semantic pass
}

const char *StaticForeachDeclaration::kind() const
{
    return "static foreach";
}

/***********************************************************
 * Collection of declarations that stores foreach index variables in a
 * local symbol table.  Other symbols declared within are forwarded to
 * another scope, like:
 *
 *      static foreach (i; 0 .. 10) // loop variables for different indices do not conflict.
 *      { // this body is expanded into 10 ForwardingAttribDeclarations, where `i` has storage class STClocal
 *          mixin("enum x" ~ to!string(i) ~ " = i"); // ok, can access current loop variable
 *      }
 *
 *      static foreach (i; 0.. 10)
 *      {
 *          pragma(msg, mixin("x" ~ to!string(i))); // ok, all 10 symbols are visible as they were forwarded to the global scope
 *      }
 *
 *      static assert (!is(typeof(i))); // loop index variable is not visible outside of the static foreach loop
 *
 * A StaticForeachDeclaration generates one
 * ForwardingAttribDeclaration for each expansion of its body.  The
 * AST of the ForwardingAttribDeclaration contains both the `static
 * foreach` variables and the respective copy of the `static foreach`
 * body.  The functionality is achieved by using a
 * ForwardingScopeDsymbol as the parent symbol for the generated
 * declarations.
 */

ForwardingAttribDeclaration::ForwardingAttribDeclaration(Dsymbols *decl)
        : AttribDeclaration(decl)
{
    sym = new ForwardingScopeDsymbol(NULL);
    sym->symtab = new DsymbolTable();
}

/**************************************
 * Use the ForwardingScopeDsymbol as the parent symbol for members.
 */
Scope *ForwardingAttribDeclaration::newScope(Scope *sc)
{
    return sc->push(sym);
}

/***************************************
 * Lazily initializes the scope to forward to.
 */
void ForwardingAttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sds)
{
    parent = sym->parent = sym->forward = sds;
    return AttribDeclaration::addMember(sc, sym);
}

/***************************** CompileDeclaration *****************************/

// These are mixin declarations, like mixin("int x");

CompileDeclaration::CompileDeclaration(Loc loc, Expressions *exps)
    : AttribDeclaration(NULL)
{
    //printf("CompileDeclaration(loc = %d)\n", loc.linnum);
    this->loc = loc;
    this->exps = exps;
    this->scopesym = NULL;
    this->compiled = false;
}

Dsymbol *CompileDeclaration::syntaxCopy(Dsymbol *)
{
    //printf("CompileDeclaration::syntaxCopy('%s')\n", toChars());
    return new CompileDeclaration(loc, Expression::arraySyntaxCopy(exps));
}

void CompileDeclaration::addMember(Scope *, ScopeDsymbol *sds)
{
    //printf("CompileDeclaration::addMember(sc = %p, sds = %p, memnum = %d)\n", sc, sds, memnum);
    this->scopesym = sds;
}

void CompileDeclaration::setScope(Scope *sc)
{
    Dsymbol::setScope(sc);
}

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

/***************************** UserAttributeDeclaration *****************************/

UserAttributeDeclaration::UserAttributeDeclaration(Expressions *atts, Dsymbols *decl)
        : AttribDeclaration(decl)
{
    //printf("UserAttributeDeclaration()\n");
    this->atts = atts;
}

Dsymbol *UserAttributeDeclaration::syntaxCopy(Dsymbol *s)
{
    //printf("UserAttributeDeclaration::syntaxCopy('%s')\n", toChars());
    assert(!s);
    return new UserAttributeDeclaration(
        Expression::arraySyntaxCopy(this->atts),
        Dsymbol::arraySyntaxCopy(decl));
}

Scope *UserAttributeDeclaration::newScope(Scope *sc)
{
    Scope *sc2 = sc;
    if (atts && atts->length)
    {
        // create new one for changes
        sc2 = sc->copy();
        sc2->userAttribDecl = this;
    }
    return sc2;
}

void UserAttributeDeclaration::setScope(Scope *sc)
{
    //printf("UserAttributeDeclaration::setScope() %p\n", this);
    if (decl)
        Dsymbol::setScope(sc);  // for forward reference of UDAs

    return AttribDeclaration::setScope(sc);
}

void udaExpressionEval(Scope *sc, Expressions *exps)
{
    for (size_t i = 0; i < exps->length; i++)
    {
        Expression *e = (*exps)[i];
        if (e)
        {
            e = expressionSemantic(e, sc);
            if (definitelyValueParameter(e))
                e = e->ctfeInterpret();
            if (e->op == TOKtuple)
            {
                TupleExp *te = (TupleExp *)e;
                udaExpressionEval(sc, te->exps);
            }
            (*exps)[i] = e;
        }
    }
}

Expressions *UserAttributeDeclaration::concat(Expressions *udas1, Expressions *udas2)
{
    Expressions *udas;
    if (!udas1 || udas1->length == 0)
        udas = udas2;
    else if (!udas2 || udas2->length == 0)
        udas = udas1;
    else
    {
        /* Create a new tuple that combines them
         * (do not append to left operand, as this is a copy-on-write operation)
         */
        udas = new Expressions();
        udas->push(new TupleExp(Loc(), udas1));
        udas->push(new TupleExp(Loc(), udas2));
    }
    return udas;
}

Expressions *UserAttributeDeclaration::getAttributes()
{
    if (Scope *sc = _scope)
    {
        _scope = NULL;
        arrayExpressionSemantic(atts, sc);
    }

    Expressions *exps = new Expressions();
    if (userAttribDecl)
        exps->push(new TupleExp(Loc(), userAttribDecl->getAttributes()));
    if (atts && atts->length)
        exps->push(new TupleExp(Loc(), atts));

    return exps;
}

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