Ejemplo n.º 1
0
    void visit(TypeFunction *t)
    {
        /*
         *  <function-type> ::= F [Y] <bare-function-type> E
         *  <bare-function-type> ::= <signature type>+
         *  # types are possible return type, then parameter types
         */

        /* ABI says:
            "The type of a non-static member function is considered to be different,
            for the purposes of substitution, from the type of a namespace-scope or
            static member function whose type appears similar. The types of two
            non-static member functions are considered to be different, for the
            purposes of substitution, if the functions are members of different
            classes. In other words, for the purposes of substitution, the class of
            which the function is a member is considered part of the type of
            function."

            BUG: Right now, types of functions are never merged, so our simplistic
            component matcher always finds them to be different.
            We should use Type::equals on these, and use different
            TypeFunctions for non-static member functions, and non-static
            member functions of different classes.
         */
        if (substitute(t))
            return;
        buf.writeByte('F');
        if (t->linkage == LINKc)
            buf.writeByte('Y');
        t->next->accept(this);
        argsCppMangle(t->parameters, t->varargs);
        buf.writeByte('E');
        store(t);
    }
Ejemplo n.º 2
0
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
    char *filename = ident->toChars();
    if (packages && packages->dim)
    {
        OutBuffer buf;

        for (size_t i = 0; i < packages->dim; i++)
        {   Identifier *pid = (*packages)[i];

            buf.writestring(pid->toChars());
#if _WIN32
            buf.writeByte('\\');
#else
            buf.writeByte('/');
#endif
        }
        buf.writestring(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 *result = lookForSourceFile(filename);
    if (result)
        m->srcfile = new File(result);

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

    if (global.params.verbose)
    {
        fprintf(global.stdmsg, "import    ");
        if (packages)
        {
            for (size_t i = 0; i < packages->dim; i++)
            {
                Identifier *pid = (*packages)[i];
                fprintf(global.stdmsg, "%s.", pid->toChars());
            }
        }
        fprintf(global.stdmsg, "%s\t(%s)\n", ident->toChars(), m->srcfile->toChars());
    }

    m->parse();

    Target::loadModule(m);

    return m;
}
Ejemplo n.º 3
0
    void cpp_mangle_name(Dsymbol *s)
    {
        Dsymbol *p = s->toParent();
        if (p && !p->isModule())
        {
            buf.writeByte('N');

            FuncDeclaration *fd = s->isFuncDeclaration();
            VarDeclaration *vd = s->isVarDeclaration();
            if (fd && fd->type->isConst())
            {
                buf.writeByte('K');
            }
            if (vd && !(vd->storage_class & (STCextern | STCgshared)))
            {
                s->error("C++ static non- __gshared non-extern variables not supported");
            }
            if (vd || fd)
            {
                prefix_name(p);
                source_name(s);
            }
            else
            {
                assert(0);
            }
            buf.writeByte('E');
        }
        else
            source_name(s);
    }
Ejemplo n.º 4
0
    void mangle_variable(VarDeclaration *d, bool is_temp_arg_ref)
    {

        if (!(d->storage_class & (STCextern | STCgshared)))
        {
            d->error("ICE: C++ static non- __gshared non-extern variables not supported");
            assert(0);
        }

        Dsymbol *p = d->toParent();
        if (p && !p->isModule()) //for example: char Namespace1::beta[6] should be mangled as "_ZN10Namespace14betaE"
        {
            buf.writestring(global.params.isOSX ? "__ZN" : "_ZN");      // "__Z" for OSX, "_Z" for other
            prefix_name(p);
            source_name(d);
            buf.writeByte('E');
        }
        else //char beta[6] should mangle as "beta"
        {
            if (!is_temp_arg_ref)
            {
                if (global.params.isOSX)
                    buf.writeByte('_');
                buf.writestring(d->ident->toChars());
            }
            else
            {
                buf.writestring(global.params.isOSX ? "__Z" : "_Z");
                source_name(d);
            }
        }
    }
Ejemplo n.º 5
0
Expression *BinExp::arrayOp(Scope *sc)
{
    //printf("BinExp::arrayOp() %s\n", toChars());

    Type *tb = type->toBasetype();
    assert(tb->ty == Tarray || tb->ty == Tsarray);
    if (tb->nextOf()->toBasetype()->ty == Tvoid)
    {
        error("Cannot perform array operations on void[] arrays");
        return new ErrorExp();
    }

    if (!isArrayOpValid(e2))
    {
        e2->error("invalid array operation %s (did you forget a [] ?)", toChars());
        return new ErrorExp();
    }

    Expressions *arguments = new Expressions();

    /* The expression to generate an array operation for is mangled
     * into a name to use as the array operation function name.
     * Mangle in the operands and operators in RPN order, and type.
     */
    OutBuffer buf;
    buf.writestring("_array");
    buildArrayIdent(&buf, arguments);
    buf.writeByte('_');

    /* Append deco of array element type
     */
#if DMDV2
    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco);
#else
    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco);
#endif

    buf.writeByte(0);
    char *name = buf.toChars();
    Identifier *ident = Lexer::idPool(name);

#if IN_LLVM
    ArrayOp **pOp = (ArrayOp **)_aaGet(&sc->module->arrayfuncs, ident);
#else
    ArrayOp **pOp = (ArrayOp **)_aaGet(&arrayfuncs, ident);
#endif
    ArrayOp *op = *pOp;

    if (!op)
        op = buildArrayOp(ident, this, sc, loc);

    *pOp = op;

    FuncDeclaration *fd = op->cFunc ? op->cFunc : op->dFunc;
    Expression *ec = new VarExp(loc, fd);
    Expression *e = new CallExp(loc, ec, arguments);

    return e->semantic(sc);
}
Ejemplo n.º 6
0
const char *ProtDeclaration::toPrettyChars(bool)
{
    assert(protection.kind > PROTundefined);

    OutBuffer buf;
    buf.writeByte('\'');
    protectionToBuffer(&buf, protection);
    buf.writeByte('\'');
    return buf.extractString();
}
Ejemplo n.º 7
0
 void writeBase36(size_t i)
 {
     if (i >= 36)
     {
         writeBase36(i / 36);
         i %= 36;
     }
     if (i < 10)
         buf.writeByte((char)(i + '0'));
     else if (i < 36)
         buf.writeByte((char)(i - 10 + 'A'));
     else
         assert(0);
 }
Ejemplo n.º 8
0
    void visit(TypePointer *t)
    {
        if (substitute(t)) return;
        if (t->isImmutable() || t->isShared())
        {
            visit((Type *)t);
        }
        if (t->isConst())
            buf.writeByte('K');
        buf.writeByte('P');
        t->next->accept(this);
        store(t);


    }
Ejemplo n.º 9
0
 void visit(TypeReference *t)
 {
     if (substitute(t)) return;
     buf.writeByte('R');
     t->next->accept(this);
     store(t);
 }
Ejemplo n.º 10
0
Archivo: json.c Proyecto: 1100110/dmd
void JsonOut::indent()
{
    if (buf->offset >= 1 &&
        buf->data[buf->offset - 1] == '\n')
        for (int i = 0; i < indentLevel; i++)
            buf->writeByte(' ');
}
Ejemplo n.º 11
0
char *cpp_mangle(Dsymbol *s)
{
    /*
     * <mangled-name> ::= _Z <encoding>
     * <encoding> ::= <function name> <bare-function-type>
     *         ::= <data name>
     *         ::= <special-name>
     */

    CppMangleState cms;
    memset(&cms, 0, sizeof(cms));
    cms.components.setDim(0);

    OutBuffer buf;
#if MACHOBJ
    buf.writestring("__Z");
#else
    buf.writestring("_Z");
#endif

    cpp_mangle_name(&buf, &cms, s);

    FuncDeclaration *fd = s->isFuncDeclaration();
    if (fd)
    {   // add <bare-function-type>
        TypeFunction *tf = (TypeFunction *)fd->type;
        assert(tf->ty == Tfunction);
        Parameter::argsCppMangle(&buf, &cms, tf->parameters, tf->varargs);
    }
    buf.writeByte(0);
    return (char *)buf.extractData();
}
Ejemplo n.º 12
0
 void visit(TypePointer *t)
 {
     if (substitute(t))
         return;
     buf.writeByte('P');
     t->next->accept(this);
     store(t);
 }
Ejemplo n.º 13
0
char *ModuleDeclaration::toChars()
{
    OutBuffer buf;

    if (packages && packages->dim)
    {
        for (size_t i = 0; i < packages->dim; i++)
        {   Identifier *pid = packages->tdata()[i];

            buf.writestring(pid->toChars());
            buf.writeByte('.');
        }
    }
    buf.writestring(id->toChars());
    buf.writeByte(0);
    return (char *)buf.extractData();
}
Ejemplo n.º 14
0
 int substitute(RootObject *p)
 {
     for (size_t i = 0; i < components.dim; i++)
     {
         if (p == components[i])
         {
             /* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
              */
             buf.writeByte('S');
             if (i)
                 writeBase36(i - 1);
             buf.writeByte('_');
             return 1;
         }
     }
     return 0;
 }
Ejemplo n.º 15
0
Archivo: mangle.c Proyecto: smunix/ldc
char *mangle(Declaration *sthis)
{
    OutBuffer buf;
    char *id;
    Dsymbol *s;

    //printf("::mangle(%s)\n", sthis->toChars());
    s = sthis;
    do
    {
        //printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent);
        if (s->ident)
        {
            FuncDeclaration *fd = s->isFuncDeclaration();
            if (s != sthis && fd)
            {
                id = mangle(fd);
                buf.prependstring(id);
                goto L1;
            }
            else
            {
                id = s->ident->toChars();
                int len = strlen(id);
                char tmp[sizeof(len) * 3 + 1];
                buf.prependstring(id);
                sprintf(tmp, "%d", len);
                buf.prependstring(tmp);
            }
        }
        else
            buf.prependstring("0");
        s = s->parent;
    } while (s);

//    buf.prependstring("_D");
L1:
    //printf("deco = '%s'\n", sthis->type->deco ? sthis->type->deco : "null");
    //printf("sthis->type = %s\n", sthis->type->toChars());
    FuncDeclaration *fd = sthis->isFuncDeclaration();
    if (fd && (fd->needThis() || fd->isNested()))
        buf.writeByte(Type::needThisPrefix());
    if (sthis->type->deco)
        buf.writestring(sthis->type->deco);
    else
    {
#ifdef DEBUG
        if (!fd->inferRetType)
            printf("%s\n", fd->toChars());
#endif
        assert(fd && fd->inferRetType);
    }

    id = buf.toChars();
    buf.data = NULL;
    return id;
}
Ejemplo n.º 16
0
    void argsCppMangle(Parameters *arguments, int varargs)
    {
        if (arguments)
            Parameter::foreach(arguments, &argsCppMangleDg, (void*)this);

        if (varargs)
            buf.writestring("z");
        else if (!arguments || !arguments->dim)
            buf.writeByte('v');            // encode ( ) arguments
    }
Ejemplo n.º 17
0
 void visit(TypeClass *t)
 {
     if (substitute(t)) return;
     if (t->isImmutable() || t->isShared())
     {
         visit((Type *)t);
     }
     
     buf.writeByte('P');
     if (t->isConst())
         buf.writeByte('K');
     if (!substitute(t->sym))
     {
         cpp_mangle_name(t->sym);
         store(t->sym);
     }
     if (t->isConst())
         store(NULL);
     store(t);
 }
Ejemplo n.º 18
0
 void visit(TypeClass *t)
 {
     if (substitute(t))
         return;
     buf.writeByte('P');
     if (!substitute(t->sym))
     {
         cpp_mangle_name(t->sym);
         store(t->sym);
     }
     store(t);
 }
Ejemplo n.º 19
0
    void mangle_function(FuncDeclaration *d)
    {
        /*
         * <mangled-name> ::= _Z <encoding>
         * <encoding> ::= <function name> <bare-function-type>
         *         ::= <data name>
         *         ::= <special-name>
         */
        TypeFunction *tf = (TypeFunction *)d->type;

        buf.writestring(global.params.isOSX ? "__Z" : "_Z");      // "__Z" for OSX, "_Z" for other
        Dsymbol *p = d->toParent();
        if (p && !p->isModule() && tf->linkage == LINKcpp)
        {
            buf.writeByte('N');
            if (d->type->isConst())
                buf.writeByte('K');
            prefix_name(p);
            if (d->isDtorDeclaration())
            {
                buf.writestring("D1");
            }
            else
            {
                source_name(d);
            }
            buf.writeByte('E');
        }
        else
        {
            source_name(d);
        }

        if (tf->linkage == LINKcpp) //Template args accept extern "C" symbols with special mangling
        {
            assert(tf->ty == Tfunction);
            argsCppMangle(tf->parameters, tf->varargs);
        }
    }
Ejemplo n.º 20
0
 void argsCppMangle(Parameters *arguments, int varargs)
 {
     size_t n = 0;
     if (arguments)
     {
         ArgsCppMangleCtx ctx = { this, 0 };
         Parameter::foreach(arguments, &argsCppMangleDg, &ctx);
         n = ctx.cnt;
     }
     if (varargs)
         buf.writestring("z");
     else if (!n)
         buf.writeByte('v');            // encode ( ) arguments
 }
Ejemplo n.º 21
0
 void visit(TypeEnum *t)
 {
     if (substitute(t))
         return;
     if (t->isConst())
         buf.writeByte('K');
     if (!substitute(t->sym))
     {
         cpp_mangle_name(t->sym);
         store(t->sym);
     }
     if (t->isConst())
         store(t);
 }
Ejemplo n.º 22
0
    void cpp_mangle_name(Dsymbol *s)
    {
        Dsymbol *p = s->toParent();
        bool dont_write_prefix = false;
        if (p && p->isTemplateInstance())
        {
            s = p;
            if (exist(p->isTemplateInstance()->tempdecl))
                dont_write_prefix = true;
            p = p->toParent();
        }

        if (p && !p->isModule())
        {
            buf.writeByte('N');
            if (!dont_write_prefix)
                prefix_name(p);
            source_name(s);
            buf.writeByte('E');
        }
        else
            source_name(s);
    }
Ejemplo n.º 23
0
 void visit(TypeSArray *t)
 {
     if (!substitute(t))
     store(t);
     if (t->isImmutable() || t->isShared())
     {
         visit((Type *)t);
     }
     if (t->isConst())
         buf.writeByte('K');
     buf.printf("A%llu_", t->dim ? t->dim->toInteger() : 0);
     t->next->accept(this);
     
 }
Ejemplo n.º 24
0
char *Loc::toChars()
{
    OutBuffer buf;

    if (filename)
    {
        buf.printf("%s", filename);
    }

    if (linnum)
        buf.printf("(%d)", linnum);
    buf.writeByte(0);
    return (char *)buf.extractData();
}
Ejemplo n.º 25
0
 void visit(TypeVector *t)
 {
     if (substitute(t)) return;
     store(t);
     if (t->isImmutable() || t->isShared())
     {
         visit((Type *)t);
     }
     if (t->isConst())
         buf.writeByte('K');
     assert(t->basetype && t->basetype->ty == Tsarray);
     assert(((TypeSArray *)t->basetype)->dim);
     //buf.printf("Dv%llu_", ((TypeSArray *)t->basetype)->dim->toInteger());// -- Gnu ABI v.4
     buf.writestring("U8__vector"); //-- Gnu ABI v.3
     t->basetype->nextOf()->accept(this);
     
 }
Ejemplo n.º 26
0
Archivo: json.c Proyecto: 1100110/dmd
void JsonOut::stringPart(const char *s)
{
    for (; *s; s++)
    {
        utf8_t c = (utf8_t) *s;
        switch (c)
        {
            case '\n':
                buf->writestring("\\n");
                break;

            case '\r':
                buf->writestring("\\r");
                break;

            case '\t':
                buf->writestring("\\t");
                break;

            case '\"':
                buf->writestring("\\\"");
                break;

            case '\\':
                buf->writestring("\\\\");
                break;

            case '\b':
                buf->writestring("\\b");
                break;

            case '\f':
                buf->writestring("\\f");
                break;

            default:
                if (c < 0x20)
                    buf->printf("\\u%04x", c);
                else
                    // Note that UTF-8 chars pass through here just fine
                    buf->writeByte(c);
                break;
        }
    }
}
Ejemplo n.º 27
0
Archivo: globals.c Proyecto: nrTQgc/ldc
char *Loc::toChars()
{
    OutBuffer buf;

    if (filename)
    {
        buf.printf("%s", filename);
    }

    if (linnum)
    {
        buf.printf("(%d", linnum);
        if (global.params.showColumns && charnum)
            buf.printf(",%d", charnum);
        buf.writeByte(')');
    }
    return buf.extractString();
}
Ejemplo n.º 28
0
Archivo: module.c Proyecto: smunix/ldc
void Module::parse()
#endif
{   char *srcname;
    unsigned char *buf;
    unsigned buflen;
    unsigned le;
    unsigned bom;

    //printf("Module::parse()\n");

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

    buf = srcfile->buffer;
    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
         */

        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 ? readlongLE(pu) : 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 = (unsigned char *) 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 ? readwordLE(pu) : 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 ? readwordLE(pu) : 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 = (unsigned char *) 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();
            }
        }
    }

#ifdef IN_GCC
    // dump utf-8 encoded source
    if (dump_source)
    {   // %% srcname could contain a path ...
        d_gcc_dump_source(srcname, "utf-8", buf, buflen);
    }
#endif

    /* 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;
        return;
    }
    if (isHtml)
    {
        OutBuffer *dbuf = new OutBuffer();
        Html h(srcname, buf, buflen);
        h.extractCode(dbuf);
        buf = dbuf->data;
        buflen = dbuf->offset;
#ifdef IN_GCC
        // dump extracted source
        if (dump_source)
            d_gcc_dump_source(srcname, "d.utf-8", buf, buflen);
#endif
    }
#if IN_LLVM
    Parser p(this, buf, buflen, gen_docs);
#else
    Parser p(this, buf, buflen, docfile != NULL);
#endif
    p.nextToken();
    members = p.parseModule();
    md = p.md;
    numlines = p.loc.linnum;

    DsymbolTable *dst;

    if (md)
    {   this->ident = md->id;
        dst = Package::resolve(md->packages, &this->parent, NULL);
    }
    else
    {
        dst = modules;

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

    // Update global list of modules
    if (!dst->insert(this))
    {
        Dsymbol *prev = dst->lookup(ident);
        assert(prev);
        Module *mprev = prev->isModule();
        if (mprev)
            error(loc, "from file %s conflicts with another module %s from file %s",
                srcname, mprev->toChars(), mprev->srcfile->toChars());
        else
        {
            Package *pkg = prev->isPackage();
            assert(pkg);
            error(loc, "from file %s conflicts with package name %s",
                srcname, pkg->toChars());
        }
    }
    else
    {
        amodules.push(this);
    }
}
Ejemplo n.º 29
0
Archivo: module.c Proyecto: smunix/ldc
Module *Module::load(Loc loc, Array *packages, Identifier *ident)
{   Module *m;
    char *filename;

    //printf("Module::load(ident = '%s')\n", ident->toChars());

    // Build module filename by turning:
    //  foo.bar.baz
    // into:
    //  foo\bar\baz
    filename = ident->toChars();
    if (packages && packages->dim)
    {
        OutBuffer buf;
        int i;

        for (i = 0; i < packages->dim; i++)
        {   Identifier *pid = (Identifier *)packages->data[i];

            buf.writestring(pid->toChars());
#if _WIN32
            buf.writeByte('\\');
#else
            buf.writeByte('/');
#endif
        }
        buf.writestring(filename);
        buf.writeByte(0);
        filename = (char *)buf.extractData();
    }

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

    /* Search along global.path for .di file, then .d file.
     */
    char *result = NULL;
    FileName *fdi = FileName::forceExt(filename, global.hdr_ext);
    FileName *fd  = FileName::forceExt(filename, global.mars_ext);
    char *sdi = fdi->toChars();
    char *sd  = fd->toChars();

    if (FileName::exists(sdi))
        result = sdi;
    else if (FileName::exists(sd))
        result = sd;
    else if (FileName::absolute(filename))
        ;
    else if (!global.path)
        ;
    else
    {
        for (size_t i = 0; i < global.path->dim; i++)
        {
            char *p = (char *)global.path->data[i];
            char *n = FileName::combine(p, sdi);
            if (FileName::exists(n))
            {   result = n;
                break;
            }
            mem.free(n);
            n = FileName::combine(p, sd);
            if (FileName::exists(n))
            {   result = n;
                break;
            }
            mem.free(n);
        }
    }
    if (result)
        m->srcfile = new File(result);

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

    m->read(loc);
    m->parse();

#ifdef IN_GCC
    d_gcc_magic_module(m);
#endif

    return m;
}
Ejemplo n.º 30
0
Archivo: glue.c Proyecto: Geod24/dnet
void obj_write_deferred(Library *library)
{
    for (int i = 0; i < obj_symbols_towrite.dim; i++)
    {	Dsymbol *s = (Dsymbol *)obj_symbols_towrite.data[i];
	Module *m = s->getModule();

	char *mname;
	if (m)
	{   mname = m->srcfile->toChars();
	    lastmname = mname;
	}
	else
	{
	    //mname = s->ident->toChars();
	    mname = lastmname;
	    assert(mname);
	}

	obj_start(mname);

	static int count;
	count++;		// sequence for generating names

	/* Create a module that's a doppelganger of m, with just
	 * enough to be able to create the moduleinfo.
	 */
	OutBuffer idbuf;
	idbuf.printf("%s.%d", m ? m->ident->toChars() : mname, count);
	char *idstr = idbuf.toChars();
	idbuf.data = NULL;
	Identifier *id = new Identifier(idstr, TOKidentifier);

	Module *md = new Module(mname, id, 0, 0);
	md->members = new Array();
	md->members->push(s);	// its only 'member' is s
	if (m)
	{
	    md->doppelganger = 1;	// identify this module as doppelganger
	    md->md = m->md;
	    md->aimports.push(m);	// it only 'imports' m
	    md->massert = m->massert;
	    md->marray = m->marray;
	}

	md->genobjfile(0);

	/* Set object file name to be source name with sequence number,
	 * as mangled symbol names get way too long.
	 */
	char *fname = FileName::removeExt(mname);
	OutBuffer namebuf;
	unsigned hash = 0;
	for (char *p = s->toChars(); *p; p++)
	    hash += *p;
	namebuf.printf("%s_%x_%x.%s", fname, count, hash, global.obj_ext);
	namebuf.writeByte(0);
	mem.free(fname);
	fname = (char *)namebuf.extractData();

	//printf("writing '%s'\n", fname);
	File *objfile = new File(fname);
	obj_end(library, objfile);
    }
    obj_symbols_towrite.dim = 0;
}