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

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

#include "mars.h"
#include "module.h"
#include "parse.h"
#include "scope.h"
#include "identifier.h"
#include "id.h"
#include "import.h"
#include "dsymbol.h"
#include "expression.h"
#include "lexer.h"
#include "attrib.h"

AggregateDeclaration *Module::moduleinfo;

Module *Module::rootModule;
DsymbolTable *Module::modules;
Modules Module::amodules;

Dsymbols Module::deferred;  // deferred Dsymbol's needing semantic() run on them
Dsymbols Module::deferred2; // deferred Dsymbol's needing semantic2() run on them
Dsymbols Module::deferred3; // deferred Dsymbol's needing semantic3() run on them
unsigned Module::dprogress;

const char *lookForSourceFile(const char **path, const char *filename);
StringExp *semanticString(Scope *sc, Expression *exp, const char *s);

void Module::_init()
{
    modules = new DsymbolTable();
}

Module::Module(const char *filename, Identifier *ident, int doDocComment, int doHdrGen)
        : Package(ident)
{
    const char *srcfilename;

//    printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars());
    this->arg = filename;
    md = NULL;
    errors = 0;
    numlines = 0;
    members = NULL;
    isDocFile = 0;
    isPackageFile = false;
    needmoduleinfo = 0;
    selfimports = 0;
    rootimports = 0;
    insearch = 0;
    searchCacheIdent = NULL;
    searchCacheSymbol = NULL;
    searchCacheFlags = 0;
    decldefs = NULL;
    sictor = NULL;
    sctor = NULL;
    sdtor = NULL;
    ssharedctor = NULL;
    sshareddtor = NULL;
    stest = NULL;
    sfilename = NULL;
    importedFrom = NULL;
    srcfile = NULL;
    srcfilePath = NULL;
    docfile = NULL;

    debuglevel = 0;
    debugids = NULL;
    debugidsNot = NULL;
    versionlevel = 0;
    versionids = NULL;
    versionidsNot = NULL;

    macrotable = NULL;
    escapetable = NULL;
    doppelganger = 0;
    cov = NULL;
    covb = NULL;

    nameoffset = 0;
    namelen = 0;

    srcfilename = FileName::defaultExt(filename, global.mars_ext);

    if (global.run_noext && global.params.run &&
        !FileName::ext(filename) &&
        FileName::exists(srcfilename) == 0 &&
        FileName::exists(filename) == 1)
    {
        FileName::free(srcfilename);
        srcfilename = FileName::removeExt(filename);    // just does a mem.strdup(filename)
    }
    else if (!FileName::equalsExt(srcfilename, global.mars_ext) &&
        !FileName::equalsExt(srcfilename, global.hdr_ext) &&
        !FileName::equalsExt(srcfilename, "dd"))
    {
        error("source file name '%s' must have .%s extension", srcfilename, global.mars_ext);
        fatal();
    }
    srcfile = new File(srcfilename);
    if (!FileName::absolute(srcfilename))
        srcfilePath = getcwd(NULL, 0);

    objfile = setOutfile(global.params.objname, global.params.objdir, filename, global.obj_ext);

    if (doDocComment)
        setDocfile();

    if (doHdrGen)
        hdrfile = setOutfile(global.params.hdrname, global.params.hdrdir, arg, global.hdr_ext);

    //objfile = new File(objfilename);
}

Module *Module::create(const char *filename, Identifier *ident, int doDocComment, int doHdrGen)
{
    return new Module(filename, ident, doDocComment, doHdrGen);
}

void Module::setDocfile()
{
    docfile = setOutfile(global.params.docname, global.params.docdir, arg, global.doc_ext);
}

/*********************************************
 * Combines things into output file name for .html and .di files.
 * Input:
 *      name    Command line name given for the file, NULL if none
 *      dir     Command line directory given for the file, NULL if none
 *      arg     Name of the source file
 *      ext     File name extension to use if 'name' is NULL
 *      global.params.preservePaths     get output path from arg
 *      srcfile Input file - output file name must not match input file
 */

File *Module::setOutfile(const char *name, const char *dir, const char *arg, const char *ext)
{
    const char *docfilename;

    if (name)
    {
        docfilename = name;
    }
    else
    {
        const char *argdoc;
        if (global.params.preservePaths)
            argdoc = arg;
        else
            argdoc = FileName::name(arg);

        // If argdoc doesn't have an absolute path, make it relative to dir
        if (!FileName::absolute(argdoc))
        {   //FileName::ensurePathExists(dir);
            argdoc = FileName::combine(dir, argdoc);
        }
        docfilename = FileName::forceExt(argdoc, ext);
    }

    if (FileName::equals(docfilename, srcfile->name->str))
    {
        error("source file and output file have same name '%s'", srcfile->name->str);
        fatal();
    }

    return new File(docfilename);
}

void Module::deleteObjFile()
{
    if (global.params.obj)
        objfile->remove();
    if (docfile)
        docfile->remove();
}

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

static void checkModFileAlias(OutBuffer *buf, OutBuffer *dotmods,
                              Array<const char *> *ms, size_t msdim, const char *p)
{
    /* Check and replace the contents of buf[] with
     * an alias string from global.params.modFileAliasStrings[]
     */
    dotmods->writestring(p);
    for (size_t j = msdim; j--;)
    {
        const char *m = (*ms)[j];
        const char *q = strchr(m, '=');
        assert(q);
        if (dotmods->offset == (size_t)(q - m) && memcmp(dotmods->peekString(), m, q - m) == 0)
        {
            buf->reset();
            size_t qlen = strlen(q + 1);
            if (qlen && (q[qlen] == '/' || q[qlen] == '\\'))
                --qlen;             // remove trailing separator
            buf->write(q + 1, qlen);
            break;                  // last matching entry in ms[] wins
        }
    }
    dotmods->writeByte('.');
}

Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
{
    //printf("Module::load(ident = '%s')\n", ident->toChars());

    // Build module filename by turning:
    //  foo.bar.baz
    // into:
    //  foo\bar\baz
    const char *filename = ident->toChars();
    if (packages && packages->dim)
    {
        OutBuffer buf;
        OutBuffer dotmods;
        Array<const char *> *ms = global.params.modFileAliasStrings;
        const size_t msdim = ms ? ms->dim : 0;

        for (size_t i = 0; i < packages->dim; i++)
        {
            Identifier *pid = (*packages)[i];
            const char *p = pid->toChars();
            buf.writestring(p);
            if (msdim)
                checkModFileAlias(&buf, &dotmods, ms, msdim, p);
#if _WIN32
            buf.writeByte('\\');
#else
            buf.writeByte('/');
#endif
        }
        buf.writestring(filename);
        if (msdim)
            checkModFileAlias(&buf, &dotmods, ms, msdim, filename);
        buf.writeByte(0);
        filename = (char *)buf.extractData();
    }

    Module *m = new Module(filename, ident, 0, 0);
    m->loc = loc;

    /* Look for the source file
     */
    const char *path;
    const char *result = lookForSourceFile(&path, filename);
    if (result)
    {
        m->srcfile = new File(result);
        if (path)
            m->srcfilePath = path;
        else if (!FileName::absolute(result))
            m->srcfilePath = getcwd(NULL, 0);
    }

    if (!m->read(loc))
        return NULL;

    if (global.params.verbose)
    {
        OutBuffer buf;
        if (packages)
        {
            for (size_t i = 0; i < packages->dim; i++)
            {
                Identifier *pid = (*packages)[i];
                buf.writestring(pid->toChars());
                buf.writeByte('.');
            }
        }
        buf.printf("%s\t(%s)", ident->toChars(), m->srcfile->toChars());
        message("import    %s", buf.peekString());
    }

    m = m->parse();

    Compiler::loadModule(m);

    return m;
}

bool Module::read(Loc loc)
{
    //printf("Module::read('%s') file '%s'\n", toChars(), srcfile->toChars());
    if (srcfile->read())
    {
        if (!strcmp(srcfile->toChars(), "object.d"))
        {
            ::error(loc, "cannot find source code for runtime library file 'object.d'");
            errorSupplemental(loc, "dmd might not be correctly installed. Run 'dmd -man' for installation instructions.");
            const char *dmdConfFile = global.inifilename ? FileName::canonicalName(global.inifilename) : NULL;
            errorSupplemental(loc, "config file: %s", dmdConfFile ? dmdConfFile : "not found");
        }
        else
        {
            // if module is not named 'package' but we're trying to read 'package.d', we're looking for a package module
            bool isPackageMod = (strcmp(toChars(), "package") != 0) &&
                                (strcmp(srcfile->name->name(), "package.d") == 0 || (strcmp(srcfile->name->name(), "package.di") == 0));

            if (isPackageMod)
                ::error(loc, "importing package '%s' requires a 'package.d' file which cannot be found in '%s'",
                    toChars(), srcfile->toChars());
            else
                error(loc, "is in file '%s' which cannot be read", srcfile->toChars());
        }

        if (!global.gag)
        {
            /* Print path
             */
            if (global.path)
            {
                for (size_t i = 0; i < global.path->dim; i++)
                {
                    const char *p = (*global.path)[i];
                    fprintf(stderr, "import path[%llu] = %s\n", (ulonglong)i, p);
                }
            }
            else
                fprintf(stderr, "Specify path to file '%s' with -I switch\n", srcfile->toChars());
            fatal();
        }
        return false;
    }
    return true;
}

Module *Module::parse()
{
    //printf("Module::parse(srcfile='%s') this=%p\n", srcfile->name->toChars(), this);

    const char *srcname = srcfile->name->toChars();
    //printf("Module::parse(srcname = '%s')\n", srcname);

    isPackageFile = (strcmp(srcfile->name->name(), "package.d") == 0 ||
                     strcmp(srcfile->name->name(), "package.di") == 0);

    utf8_t *buf = (utf8_t *)srcfile->buffer;
    size_t buflen = srcfile->len;

    if (buflen >= 2)
    {
        /* Convert all non-UTF-8 formats to UTF-8.
         * BOM : http://www.unicode.org/faq/utf_bom.html
         * 00 00 FE FF  UTF-32BE, big-endian
         * FF FE 00 00  UTF-32LE, little-endian
         * FE FF        UTF-16BE, big-endian
         * FF FE        UTF-16LE, little-endian
         * EF BB BF     UTF-8
         */

        unsigned le;
        unsigned bom = 1;                // assume there's a BOM
        if (buf[0] == 0xFF && buf[1] == 0xFE)
        {
            if (buflen >= 4 && buf[2] == 0 && buf[3] == 0)
            {   // UTF-32LE
                le = 1;

            Lutf32:
                OutBuffer dbuf;
                unsigned *pu = (unsigned *)(buf);
                unsigned *pumax = &pu[buflen / 4];

                if (buflen & 3)
                {   error("odd length of UTF-32 char source %u", buflen);
                    fatal();
                }

                dbuf.reserve(buflen / 4);
                for (pu += bom; pu < pumax; pu++)
                {   unsigned u;

                    u = le ? Port::readlongLE(pu) : Port::readlongBE(pu);
                    if (u & ~0x7F)
                    {
                        if (u > 0x10FFFF)
                        {   error("UTF-32 value %08x greater than 0x10FFFF", u);
                            fatal();
                        }
                        dbuf.writeUTF8(u);
                    }
                    else
                        dbuf.writeByte(u);
                }
                dbuf.writeByte(0);              // add 0 as sentinel for scanner
                buflen = dbuf.offset - 1;       // don't include sentinel in count
                buf = (utf8_t *) dbuf.extractData();
            }
            else
            {   // UTF-16LE (X86)
                // Convert it to UTF-8
                le = 1;

            Lutf16:
                OutBuffer dbuf;
                unsigned short *pu = (unsigned short *)(buf);
                unsigned short *pumax = &pu[buflen / 2];

                if (buflen & 1)
                {   error("odd length of UTF-16 char source %u", buflen);
                    fatal();
                }

                dbuf.reserve(buflen / 2);
                for (pu += bom; pu < pumax; pu++)
                {   unsigned u;

                    u = le ? Port::readwordLE(pu) : Port::readwordBE(pu);
                    if (u & ~0x7F)
                    {   if (u >= 0xD800 && u <= 0xDBFF)
                        {   unsigned u2;

                            if (++pu > pumax)
                            {   error("surrogate UTF-16 high value %04x at EOF", u);
                                fatal();
                            }
                            u2 = le ? Port::readwordLE(pu) : Port::readwordBE(pu);
                            if (u2 < 0xDC00 || u2 > 0xDFFF)
                            {   error("surrogate UTF-16 low value %04x out of range", u2);
                                fatal();
                            }
                            u = (u - 0xD7C0) << 10;
                            u |= (u2 - 0xDC00);
                        }
                        else if (u >= 0xDC00 && u <= 0xDFFF)
                        {   error("unpaired surrogate UTF-16 value %04x", u);
                            fatal();
                        }
                        else if (u == 0xFFFE || u == 0xFFFF)
                        {   error("illegal UTF-16 value %04x", u);
                            fatal();
                        }
                        dbuf.writeUTF8(u);
                    }
                    else
                        dbuf.writeByte(u);
                }
                dbuf.writeByte(0);              // add 0 as sentinel for scanner
                buflen = dbuf.offset - 1;       // don't include sentinel in count
                buf = (utf8_t *) dbuf.extractData();
            }
        }
        else if (buf[0] == 0xFE && buf[1] == 0xFF)
        {   // UTF-16BE
            le = 0;
            goto Lutf16;
        }
        else if (buflen >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0xFE && buf[3] == 0xFF)
        {   // UTF-32BE
            le = 0;
            goto Lutf32;
        }
        else if (buflen >= 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF)
        {   // UTF-8

            buf += 3;
            buflen -= 3;
        }
        else
        {
            /* There is no BOM. Make use of Arcane Jill's insight that
             * the first char of D source must be ASCII to
             * figure out the encoding.
             */

            bom = 0;
            if (buflen >= 4)
            {   if (buf[1] == 0 && buf[2] == 0 && buf[3] == 0)
                {   // UTF-32LE
                    le = 1;
                    goto Lutf32;
                }
                else if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0)
                {   // UTF-32BE
                    le = 0;
                    goto Lutf32;
                }
            }
            if (buflen >= 2)
            {
                if (buf[1] == 0)
                {   // UTF-16LE
                    le = 1;
                    goto Lutf16;
                }
                else if (buf[0] == 0)
                {   // UTF-16BE
                    le = 0;
                    goto Lutf16;
                }
            }

            // It's UTF-8
            if (buf[0] >= 0x80)
            {   error("source file must start with BOM or ASCII character, not \\x%02X", buf[0]);
                fatal();
            }
        }
    }

    /* If it starts with the string "Ddoc", then it's a documentation
     * source file.
     */
    if (buflen >= 4 && memcmp(buf, "Ddoc", 4) == 0)
    {
        comment = buf + 4;
        isDocFile = 1;
        if (!docfile)
            setDocfile();
        return this;
    }
    {
        Parser p(this, buf, buflen, docfile != NULL);
        p.nextToken();
        members = p.parseModule();
        md = p.md;
        numlines = p.scanloc.linnum;
        if (p.errors)
            ++global.errors;
    }

    if (srcfile->ref == 0)
        ::free(srcfile->buffer);
    srcfile->buffer = NULL;
    srcfile->len = 0;

    /* The symbol table into which the module is to be inserted.
     */
    DsymbolTable *dst;

    if (md)
    {
        /* A ModuleDeclaration, md, was provided.
         * The ModuleDeclaration sets the packages this module appears in, and
         * the name of this module.
         */
        this->ident = md->id;
        Package *ppack = NULL;
        dst = Package::resolve(md->packages, &this->parent, &ppack);
        assert(dst);

        Module *m = ppack ? ppack->isModule() : NULL;
        if (m && (strcmp(m->srcfile->name->name(), "package.d") != 0 &&
                  strcmp(m->srcfile->name->name(), "package.di") != 0))
        {
            ::error(md->loc, "package name '%s' conflicts with usage as a module name in file %s",
                ppack->toPrettyChars(), m->srcfile->toChars());
        }
    }
    else
    {
        /* The name of the module is set to the source file name.
         * There are no packages.
         */
        dst = modules;          // and so this module goes into global module symbol table

        /* Check to see if module name is a valid identifier
         */
        if (!Identifier::isValidIdentifier(this->ident->toChars()))
            error("has non-identifier characters in filename, use module declaration instead");
    }

    // Insert module into the symbol table
    Dsymbol *s = this;
    if (isPackageFile)
    {
        /* If the source tree is as follows:
         *     pkg/
         *     +- package.d
         *     +- common.d
         * the 'pkg' will be incorporated to the internal package tree in two ways:
         *     import pkg;
         * and:
         *     import pkg.common;
         *
         * If both are used in one compilation, 'pkg' as a module (== pkg/package.d)
         * and a package name 'pkg' will conflict each other.
         *
         * To avoid the conflict:
         * 1. If preceding package name insertion had occurred by Package::resolve,
         *    later package.d loading will change Package::isPkgMod to PKGmodule and set Package::mod.
         * 2. Otherwise, 'package.d' wrapped by 'Package' is inserted to the internal tree in here.
         */
        Package *p = new Package(ident);
        p->parent = this->parent;
        p->isPkgMod = PKGmodule;
        p->mod = this;
        p->tag = this->tag; // reuse the same package tag
        p->symtab = new DsymbolTable();
        s = p;
    }
    if (!dst->insert(s))
    {
        /* It conflicts with a name that is already in the symbol table.
         * Figure out what went wrong, and issue error message.
         */
        Dsymbol *prev = dst->lookup(ident);
        assert(prev);
        if (Module *mprev = prev->isModule())
        {
            if (FileName::compare(srcname, mprev->srcfile->toChars()) != 0)
                error(loc, "from file %s conflicts with another module %s from file %s",
                    srcname, mprev->toChars(), mprev->srcfile->toChars());
            else if (isRoot() && mprev->isRoot())
                error(loc, "from file %s is specified twice on the command line",
                    srcname);
            else
                error(loc, "from file %s must be imported with 'import %s;'",
                    srcname, toPrettyChars());

            // Bugzilla 14446: Return previously parsed module to avoid AST duplication ICE.
            return mprev;
        }
        else if (Package *pkg = prev->isPackage())
        {
            if (pkg->isPkgMod == PKGunknown && isPackageFile)
            {
                /* If the previous inserted Package is not yet determined as package.d,
                 * link it to the actual module.
                 */
                pkg->isPkgMod = PKGmodule;
                pkg->mod = this;
                pkg->tag = this->tag; // reuse the same package tag
            }
            else
                error(md ? md->loc : loc, "from file %s conflicts with package name %s",
                    srcname, pkg->toChars());
        }
        else
            assert(global.errors);
    }
    else
    {
        // Add to global array of all modules
        amodules.push(this);
    }
    return this;
}

void Module::importAll(Scope *)
{
    //printf("+Module::importAll(this = %p, '%s'): parent = %p\n", this, toChars(), parent);

    if (_scope)
        return;                 // already done

    if (isDocFile)
    {
        error("is a Ddoc file, cannot import it");
        return;
    }

    /* Note that modules get their own scope, from scratch.
     * This is so regardless of where in the syntax a module
     * gets imported, it is unaffected by context.
     * Ignore prevsc.
     */
    Scope *sc = Scope::createGlobal(this);      // create root scope

    if (md && md->msg)
      md->msg = semanticString(sc, md->msg, "deprecation message");

    // Add import of "object", even for the "object" module.
    // If it isn't there, some compiler rewrites, like
    //    classinst == classinst -> .object.opEquals(classinst, classinst)
    // would fail inside object.d.
    if (members->dim == 0 || ((*members)[0])->ident != Id::object)
    {
        Import *im = new Import(Loc(), NULL, Id::object, NULL, 0);
        members->shift(im);
    }

    if (!symtab)
    {
        // Add all symbols into module's symbol table
        symtab = new DsymbolTable();
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            s->addMember(sc, sc->scopesym);
        }
    }
    // anything else should be run after addMember, so version/debug symbols are defined

    /* Set scope for the symbols so that if we forward reference
     * a symbol, it can possibly be resolved on the spot.
     * If this works out well, it can be extended to all modules
     * before any semantic() on any of them.
     */
    setScope(sc);               // remember module scope for semantic
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->setScope(sc);
    }

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

    sc = sc->pop();
    sc->pop();          // 2 pops because Scope::createGlobal() created 2
}

void Module::semantic(Scope *)
{
    if (semanticRun != PASSinit)
        return;

    //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
    semanticRun = PASSsemantic;

    // Note that modules get their own scope, from scratch.
    // This is so regardless of where in the syntax a module
    // gets imported, it is unaffected by context.
    Scope *sc = _scope;                  // see if already got one from importAll()
    if (!sc)
    {
        Scope::createGlobal(this);      // create root scope
    }

    //printf("Module = %p, linkage = %d\n", sc->scopesym, sc->linkage);

    // Pass 1 semantic routines: do public side of the definition
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];

        //printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars());
        s->semantic(sc);
        runDeferredSemantic();
    }

    if (userAttribDecl)
    {
        userAttribDecl->semantic(sc);
    }

    if (!_scope)
    {
        sc = sc->pop();
        sc->pop();              // 2 pops because Scope::createGlobal() created 2
    }
    semanticRun = PASSsemanticdone;
    //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
}

void Module::semantic2(Scope*)
{
    //printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent);
    if (semanticRun != PASSsemanticdone)       // semantic() not completed yet - could be recursive call
        return;
    semanticRun = PASSsemantic2;

    // Note that modules get their own scope, from scratch.
    // This is so regardless of where in the syntax a module
    // gets imported, it is unaffected by context.
    Scope *sc = Scope::createGlobal(this);      // create root scope
    //printf("Module = %p\n", sc.scopesym);

    // Pass 2 semantic routines: do initializers and function bodies
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        s->semantic2(sc);
    }

    if (userAttribDecl)
    {
        userAttribDecl->semantic2(sc);
    }

    sc = sc->pop();
    sc->pop();
    semanticRun = PASSsemantic2done;
    //printf("-Module::semantic2('%s'): parent = %p\n", toChars(), parent);
}

void Module::semantic3(Scope*)
{
    //printf("Module::semantic3('%s'): parent = %p\n", toChars(), parent);
    if (semanticRun != PASSsemantic2done)
        return;
    semanticRun = PASSsemantic3;

    // Note that modules get their own scope, from scratch.
    // This is so regardless of where in the syntax a module
    // gets imported, it is unaffected by context.
    Scope *sc = Scope::createGlobal(this);      // create root scope
    //printf("Module = %p\n", sc.scopesym);

    // Pass 3 semantic routines: do initializers and function bodies
    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];
        //printf("Module %s: %s.semantic3()\n", toChars(), s->toChars());
        s->semantic3(sc);

        runDeferredSemantic2();
    }

    if (userAttribDecl)
    {
        userAttribDecl->semantic3(sc);
    }

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

/**********************************
 * Determine if we need to generate an instance of ModuleInfo
 * for this Module.
 */

int Module::needModuleInfo()
{
    //printf("needModuleInfo() %s, %d, %d\n", toChars(), needmoduleinfo, global.params.cov);
    return needmoduleinfo || global.params.cov;
}

Dsymbol *Module::search(const Loc &loc, Identifier *ident, int flags)
{
    /* Since modules can be circularly referenced,
     * need to stop infinite recursive searches.
     * This is done with the cache.
     */

    //printf("%s Module::search('%s', flags = x%x) insearch = %d\n", toChars(), ident->toChars(), flags, insearch);
    if (insearch)
        return NULL;

    /* Qualified module searches always search their imports,
     * even if SearchLocalsOnly
     */
    if (!(flags & SearchUnqualifiedModule))
        flags &= ~(SearchUnqualifiedModule | SearchLocalsOnly);

    if (searchCacheIdent == ident && searchCacheFlags == flags)
    {
        //printf("%s Module::search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n",
        //        toChars(), ident->toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol->toChars() : "null");
        return searchCacheSymbol;
    }

    unsigned int errors = global.errors;

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

    if (errors == global.errors)
    {
        // Bugzilla 10752: We can cache the result only when it does not cause
        // access error so the side-effect should be reproduced in later search.
        searchCacheIdent = ident;
        searchCacheSymbol = s;
        searchCacheFlags = flags;
    }
    return s;
}

bool Module::isPackageAccessible(Package *p, Prot protection, int flags)
{
    if (insearch) // don't follow import cycles
        return false;
    if (flags & IgnorePrivateImports)
        protection = Prot(PROTpublic); // only consider public imports
    insearch = true;
    bool r = ScopeDsymbol::isPackageAccessible(p, protection);
    insearch = false;
    return r;
}

Dsymbol *Module::symtabInsert(Dsymbol *s)
{
    searchCacheIdent = NULL;       // symbol is inserted, so invalidate cache
    return Package::symtabInsert(s);
}

void Module::clearCache()
{
    for (size_t i = 0; i < amodules.dim; i++)
    {
        Module *m = amodules[i];
        m->searchCacheIdent = NULL;
    }
}

/*******************************************
 * Can't run semantic on s now, try again later.
 */

void Module::addDeferredSemantic(Dsymbol *s)
{
    // Don't add it if it is already there
    for (size_t i = 0; i < deferred.dim; i++)
    {
        Dsymbol *sd = deferred[i];

        if (sd == s)
            return;
    }

    //printf("Module::addDeferredSemantic('%s')\n", s->toChars());
    deferred.push(s);
}

void Module::addDeferredSemantic2(Dsymbol *s)
{
    //printf("Module::addDeferredSemantic2('%s')\n", s->toChars());
    deferred2.push(s);
}

void Module::addDeferredSemantic3(Dsymbol *s)
{
    //printf("Module::addDeferredSemantic3('%s')\n", s->toChars());
    deferred3.push(s);
}

/******************************************
 * Run semantic() on deferred symbols.
 */

void Module::runDeferredSemantic()
{
    if (dprogress == 0)
        return;

    static int nested;
    if (nested)
        return;
    //if (deferred.dim) printf("+Module::runDeferredSemantic(), len = %d\n", deferred.dim);
    nested++;

    size_t len;
    do
    {
        dprogress = 0;
        len = deferred.dim;
        if (!len)
            break;

        Dsymbol **todo;
        Dsymbol **todoalloc = NULL;
        Dsymbol *tmp;
        if (len == 1)
        {
            todo = &tmp;
        }
        else
        {
            todo = (Dsymbol **)mem.xmalloc(len * sizeof(Dsymbol *));
            todoalloc = todo;
        }
        memcpy(todo, deferred.tdata(), len * sizeof(Dsymbol *));
        deferred.setDim(0);

        for (size_t i = 0; i < len; i++)
        {
            Dsymbol *s = todo[i];

            s->semantic(NULL);
            //printf("deferred: %s, parent = %s\n", s->toChars(), s->parent->toChars());
        }
        //printf("\tdeferred.dim = %d, len = %d, dprogress = %d\n", deferred.dim, len, dprogress);
        if (todoalloc)
            free(todoalloc);
    } while (deferred.dim < len || dprogress);  // while making progress
    nested--;
    //printf("-Module::runDeferredSemantic(), len = %d\n", deferred.dim);
}

void Module::runDeferredSemantic2()
{
    Module::runDeferredSemantic();

    Dsymbols *a = &Module::deferred2;
    for (size_t i = 0; i < a->dim; i++)
    {
        Dsymbol *s = (*a)[i];
        //printf("[%d] %s semantic2a\n", i, s->toPrettyChars());
        s->semantic2(NULL);

        if (global.errors)
            break;
    }
    a->setDim(0);
}

void Module::runDeferredSemantic3()
{
    Module::runDeferredSemantic2();

    Dsymbols *a = &Module::deferred3;
    for (size_t i = 0; i < a->dim; i++)
    {
        Dsymbol *s = (*a)[i];
        //printf("[%d] %s semantic3a\n", i, s->toPrettyChars());

        s->semantic3(NULL);

        if (global.errors)
            break;
    }
    a->setDim(0);
}

/************************************
 * Recursively look at every module this module imports,
 * return true if it imports m.
 * Can be used to detect circular imports.
 */

int Module::imports(Module *m)
{
    //printf("%s Module::imports(%s)\n", toChars(), m->toChars());
    for (size_t i = 0; i < aimports.dim; i++)
    {
        Module *mi = aimports[i];
        if (mi == m)
            return true;
        if (!mi->insearch)
        {
            mi->insearch = 1;
            int r = mi->imports(m);
            if (r)
                return r;
        }
    }
    return false;
}

/*************************************
 * Return true if module imports itself.
 */

bool Module::selfImports()
{
    //printf("Module::selfImports() %s\n", toChars());
    if (selfimports == 0)
    {
        for (size_t i = 0; i < amodules.dim; i++)
            amodules[i]->insearch = 0;

        selfimports = imports(this) + 1;

        for (size_t i = 0; i < amodules.dim; i++)
            amodules[i]->insearch = 0;
    }
    return selfimports == 2;
}

/*************************************
 * Return true if module imports root module.
 */

bool Module::rootImports()
{
    //printf("Module::rootImports() %s\n", toChars());
    if (rootimports == 0)
    {
        for (size_t i = 0; i < amodules.dim; i++)
            amodules[i]->insearch = 0;

        rootimports = 1;
        for (size_t i = 0; i < amodules.dim; ++i)
        {
            Module *m = amodules[i];
            if (m->isRoot() && imports(m))
            {
                rootimports = 2;
                break;
            }
        }

        for (size_t i = 0; i < amodules.dim; i++)
            amodules[i]->insearch = 0;
    }
    return rootimports == 2;
}

bool Module::isCoreModule(Identifier *ident)
{
    return this->ident == ident && parent && parent->ident == Id::core && !parent->parent;
}

/* =========================== ModuleDeclaration ===================== */

ModuleDeclaration::ModuleDeclaration(Loc loc, Identifiers *packages, Identifier *id)
{
    this->loc = loc;
    this->packages = packages;
    this->id = id;
    this->isdeprecated = false;
    this->msg = NULL;
}

const char *ModuleDeclaration::toChars()
{
    OutBuffer buf;

    if (packages && packages->dim)
    {
        for (size_t i = 0; i < packages->dim; i++)
        {
            Identifier *pid = (*packages)[i];
            buf.writestring(pid->toChars());
            buf.writeByte('.');
        }
    }
    buf.writestring(id->toChars());
    return buf.extractString();
}

/* =========================== Package ===================== */

Package::Package(Identifier *ident)
        : ScopeDsymbol(ident)
{
    this->isPkgMod = PKGunknown;
    this->mod = NULL;
    static unsigned packageTag = 0;
    this->tag = packageTag++;
}


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

Module *Package::isPackageMod()
{
    if (isPkgMod == PKGmodule)
    {
        return mod;
    }
    return NULL;
}

/**
 * Checks if pkg is a sub-package of this
 *
 * For example, if this qualifies to 'a1.a2' and pkg - to 'a1.a2.a3',
 * this function returns 'true'. If it is other way around or qualified
 * package paths conflict function returns 'false'.
 *
 * Params:
 *  pkg = possible subpackage
 *
 * Returns:
 *  see description
 */
bool Package::isAncestorPackageOf(const Package * const pkg) const
{
    if (this == pkg)
        return true;
    if (!pkg || !pkg->parent)
        return false;
    return isAncestorPackageOf(pkg->parent->isPackage());
}

void Package::semantic(Scope *)
{
    if (semanticRun < PASSsemanticdone)
        semanticRun = PASSsemanticdone;
}

/****************************************************
 * Input:
 *      packages[]      the pkg1.pkg2 of pkg1.pkg2.mod
 * Returns:
 *      the symbol table that mod should be inserted into
 * Output:
 *      *pparent        the rightmost package, i.e. pkg2, or NULL if no packages
 *      *ppkg           the leftmost package, i.e. pkg1, or NULL if no packages
 */

DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package **ppkg)
{
    DsymbolTable *dst = Module::modules;
    Dsymbol *parent = NULL;

    //printf("Package::resolve()\n");
    if (ppkg)
        *ppkg = NULL;

    if (packages)
    {
        for (size_t i = 0; i < packages->dim; i++)
        {
            Identifier *pid = (*packages)[i];
            Package *pkg;
            Dsymbol *p = dst->lookup(pid);
            if (!p)
            {
                pkg = new Package(pid);
                dst->insert(pkg);
                pkg->parent = parent;
                pkg->symtab = new DsymbolTable();
            }
            else
            {
                pkg = p->isPackage();
                assert(pkg);
                // It might already be a module, not a package, but that needs
                // to be checked at a higher level, where a nice error message
                // can be generated.
                // dot net needs modules and packages with same name

                // But we still need a symbol table for it
                if (!pkg->symtab)
                    pkg->symtab = new DsymbolTable();
            }
            parent = pkg;
            dst = pkg->symtab;
            if (ppkg && !*ppkg)
                *ppkg = pkg;
            if (pkg->isModule())
            {
                // Return the module so that a nice error message can be generated
                if (ppkg)
                    *ppkg = (Package *)p;
                break;
            }
        }
    }
    if (pparent)
        *pparent = parent;
    return dst;
}

Dsymbol *Package::search(const Loc &loc, Identifier *ident, int flags)
{
    //printf("%s Package::search('%s', flags = x%x)\n", toChars(), ident->toChars(), flags);
    flags &= ~SearchLocalsOnly;  // searching an import is always transitive
    if (!isModule() && mod)
    {
        // Prefer full package name.
        Dsymbol *s = symtab ? symtab->lookup(ident) : NULL;
        if (s)
            return s;
        //printf("[%s] through pkdmod: %s\n", loc.toChars(), toChars());
        return mod->search(loc, ident, flags);
    }

    return ScopeDsymbol::search(loc, ident, flags);
}

/* ===========================  ===================== */

/********************************************
 * Look for the source file if it's different from filename.
 * Look for .di, .d, directory, and along global.path.
 * Does not open the file.
 * Output:
 *      path            the path where the file was found if it was not the current directory
 * Input:
 *      filename        as supplied by the user
 *      global.path
 * Returns:
 *      NULL if it's not different from filename.
 */

const char *lookForSourceFile(const char **path, const char *filename)
{
    /* Search along global.path for .di file, then .d file.
     */
    *path = NULL;

    const char *sdi = FileName::forceExt(filename, global.hdr_ext);
    if (FileName::exists(sdi) == 1)
        return sdi;

    const char *sd  = FileName::forceExt(filename, global.mars_ext);
    if (FileName::exists(sd) == 1)
        return sd;

    if (FileName::exists(filename) == 2)
    {
        /* The filename exists and it's a directory.
         * Therefore, the result should be: filename/package.d
         * iff filename/package.d is a file
         */
        const char *ni = FileName::combine(filename, "package.di");
        if (FileName::exists(ni) == 1)
            return ni;
        FileName::free(ni);
        const char *n = FileName::combine(filename, "package.d");
        if (FileName::exists(n) == 1)
            return n;
        FileName::free(n);
    }

    if (FileName::absolute(filename))
        return NULL;

    if (!global.path)
        return NULL;

    for (size_t i = 0; i < global.path->dim; i++)
    {
        const char *p = (*global.path)[i];

        const char *n = FileName::combine(p, sdi);
        if (FileName::exists(n) == 1)
        {
            *path = p;
            return n;
        }
        FileName::free(n);

        n = FileName::combine(p, sd);
        if (FileName::exists(n) == 1)
        {
            *path = p;
            return n;
        }
        FileName::free(n);

        const char *b = FileName::removeExt(filename);
        n = FileName::combine(p, b);
        FileName::free(b);
        if (FileName::exists(n) == 2)
        {
            const char *n2i = FileName::combine(n, "package.di");
            if (FileName::exists(n2i) == 1)
                return n2i;
            FileName::free(n2i);
            const char *n2 = FileName::combine(n, "package.d");
            if (FileName::exists(n2) == 1)
            {
                *path = p;
                return n2;
            }
            FileName::free(n2);
        }
        FileName::free(n);
    }
    return NULL;
}
