Esempio n. 1
0
Symbol *Dsymbol::toImport(Symbol *sym)
{
    char *id;
    char *n;
    Symbol *s;
    type *t;

    //printf("Dsymbol::toImport('%s')\n", sym->Sident);
    n = sym->Sident;
    id = (char *) alloca(6 + strlen(n) + 1 + sizeof(type_paramsize(sym->Stype))*3 + 1);
    if (sym->Stype->Tmangle == mTYman_std && tyfunc(sym->Stype->Tty))
    {
        if (config.exe == EX_WIN64)
            sprintf(id,"__imp_%s",n);
        else
        sprintf(id,"_imp__%s@%lu",n,(unsigned long)type_paramsize(sym->Stype));
    }
    else if (sym->Stype->Tmangle == mTYman_d)
        sprintf(id,"_imp_%s",n);
    else
        sprintf(id,"_imp__%s",n);
    t = type_alloc(TYnptr | mTYconst);
    t->Tnext = sym->Stype;
    t->Tnext->Tcount++;
    t->Tmangle = mTYman_c;
    t->Tcount++;
    s = symbol_calloc(id);
    s->Stype = t;
    s->Sclass = SCextern;
    s->Sfl = FLextern;
    slist_add(s);
    return s;
}
Esempio n. 2
0
/**************************************
 * Create a struct/union/class type.
 * Params:
 *      name = name of struct (this function makes its own copy of the string)
 * Returns:
 *      Tcount already incremented
 */
type *type_struct_class(const char *name, unsigned alignsize, unsigned structsize,
        type *arg1type, type *arg2type, bool isUnion, bool isClass, bool isPOD)
{
    Symbol *s = symbol_calloc(name);
    s->Sclass = SCstruct;
    s->Sstruct = struct_calloc();
    s->Sstruct->Salignsize = alignsize;
    s->Sstruct->Sstructalign = alignsize;
    s->Sstruct->Sstructsize = structsize;
    s->Sstruct->Sarg1type = arg1type;
    s->Sstruct->Sarg2type = arg2type;

    if (!isPOD)
        s->Sstruct->Sflags |= STRnotpod;
    if (isUnion)
        s->Sstruct->Sflags |= STRunion;
    if (isClass)
    {   s->Sstruct->Sflags |= STRclass;
        assert(!isUnion && isPOD);
    }

    type *t = type_alloc(TYstruct);
    t->Ttag = (Classsym *)s;            // structure tag name
    t->Tcount++;
    s->Stype = t;
    t->Tcount++;
    return t;
}
Esempio n. 3
0
Symbol *Dsymbol::toImport(Symbol *sym)
{
    char *id;
    char *n;
    Symbol *s;
    type *t;

    //printf("Dsymbol::toImport('%s')\n", sym->Sident);
    n = sym->Sident;
    id = (char *) alloca(6 + strlen(n) + 5 + 1);
    if (sym->Stype->Tmangle == mTYman_std)
    {
	sprintf(id,"_imp__%s@%d",n,type_paramsize(sym->Stype));
    }
    else if (sym->Stype->Tmangle == mTYman_d)
	sprintf(id,"_imp_%s",n);
    else
	sprintf(id,"_imp__%s",n);
    t = type_alloc(TYnptr | mTYconst);
    t->Tnext = sym->Stype;
    t->Tnext->Tcount++;
    t->Tmangle = mTYman_c;
    t->Tcount++;
    s = symbol_calloc(id);
    s->Stype = t;
    s->Sclass = SCextern;
    s->Sfl = FLextern;
    slist_add(s);
    return s;
}
Esempio n. 4
0
void Module::genhelpers(bool iscomdat)
{

    // If module assert
    for (int i = 0; i < 3; i++)
    {
        Symbol *ma;
        unsigned rt;
        unsigned bc;
        switch (i)
        {
            case 0:     ma = marray;    rt = RTLSYM_DARRAY;     bc = BCexit; break;
            case 1:     ma = massert;   rt = RTLSYM_DASSERT;    bc = BCexit; break;
            case 2:     ma = munittest; rt = RTLSYM_DUNITTEST;  bc = BCret;  break;
            default:    assert(0);
        }

        if (ma)
        {
            elem *elinnum;

            localgot = NULL;

            // Call dassert(filename, line)
            // Get sole parameter, linnum
            {
                Symbol *sp = symbol_calloc("linnum");
                sp->Stype = type_fake(TYint);
                sp->Stype->Tcount++;
                sp->Sclass = (config.exe == EX_WIN64) ? SCshadowreg : SCfastpar;

                FuncParamRegs fpr(TYjfunc);
                fpr.alloc(sp->Stype, sp->Stype->Tty, &sp->Spreg, &sp->Spreg2);

                sp->Sflags &= ~SFLspill;
                sp->Sfl = (sp->Sclass == SCshadowreg) ? FLpara : FLfast;
                cstate.CSpsymtab = &ma->Sfunc->Flocsym;
                symbol_add(sp);

                elinnum = el_var(sp);
            }

            elem *efilename = toEfilename(this);

            elem *e = el_var(rtlsym[rt]);
            e = el_bin(OPcall, TYvoid, e, el_param(elinnum, efilename));

            block *b = block_calloc();
            b->BC = bc;
            b->Belem = e;
            ma->Sfunc->Fstartline.Sfilename = arg;
            ma->Sfunc->Fstartblock = b;
            ma->Sclass = iscomdat ? SCcomdat : SCglobal;
            ma->Sfl = 0;
            ma->Sflags |= rtlsym[rt]->Sflags & SFLexit;
            writefunc(ma);
        }
    }
}
Esempio n. 5
0
static void genhelpers(Module *m)
{
    // If module assert
    for (int i = 0; i < 3; i++)
    {
        Symbol *ma;
        unsigned rt;
        unsigned bc;
        switch (i)
        {
            case 0:     ma = toModuleArray(m);    rt = RTLSYM_DARRAY;     bc = BCexit; break;
            case 1:     ma = toModuleAssert(m);   rt = RTLSYM_DASSERT;    bc = BCexit; break;
            case 2:     ma = toModuleUnittest(m); rt = RTLSYM_DUNITTEST;  bc = BCret;  break;
            default:    assert(0);
        }

        if (!ma)
            continue;


        localgot = NULL;

        // Call dassert(filename, line)
        // Get sole parameter, linnum
        Symbol *sp = symbol_calloc("linnum");
        sp->Stype = type_fake(TYint);
        sp->Stype->Tcount++;
        sp->Sclass = (config.exe == EX_WIN64) ? SCshadowreg : SCfastpar;

        FuncParamRegs fpr(TYjfunc);
        fpr.alloc(sp->Stype, sp->Stype->Tty, &sp->Spreg, &sp->Spreg2);

        sp->Sflags &= ~SFLspill;
        sp->Sfl = (sp->Sclass == SCshadowreg) ? FLpara : FLfast;
        cstate.CSpsymtab = &ma->Sfunc->Flocsym;
        symbol_add(sp);

        elem *elinnum = el_var(sp);


        elem *efilename = toEfilename(m);
        if (config.exe == EX_WIN64)
            efilename = addressElem(efilename, Type::tstring, true);

        elem *e = el_var(getRtlsym(rt));
        e = el_bin(OPcall, TYvoid, e, el_param(elinnum, efilename));

        block *b = block_calloc();
        b->BC = bc;
        b->Belem = e;
        ma->Sfunc->Fstartline.Sfilename = m->arg;
        ma->Sfunc->Fstartblock = b;
        ma->Sclass = SCglobal;
        ma->Sfl = 0;
        ma->Sflags |= getRtlsym(rt)->Sflags & SFLexit;
        writefunc(ma);
    }
}
Esempio n. 6
0
type *TypeAArray::toCtype()
{   type *t;

    if (ctype)
        return ctype;

    if (0 && global.params.symdebug)
    {
        /* An associative array is represented by:
         *      struct AArray { size_t length; void* ptr; }
         */

        static Symbol *s;

        if (!s)
        {
            s = symbol_calloc("_AArray");
            s->Sclass = SCstruct;
            s->Sstruct = struct_calloc();
            s->Sstruct->Sflags |= 0;
            s->Sstruct->Salignsize = alignsize();
            s->Sstruct->Sstructalign = global.structalign;
            s->Sstruct->Sstructsize = size(0);
            slist_add(s);

            Symbol *s1 = symbol_name("length", SCmember, Type::tsize_t->toCtype());
            list_append(&s->Sstruct->Sfldlst, s1);

            Symbol *s2 = symbol_name("data", SCmember, Type::tvoidptr->toCtype());
            s2->Smemoff = Type::tsize_t->size();
            list_append(&s->Sstruct->Sfldlst, s2);
        }

        t = type_alloc(TYstruct);
        t->Ttag = (Classsym *)s;                // structure tag name
        t->Tcount++;
        s->Stype = t;
    }
    else
    {
        if (global.params.symdebug == 1)
        {
            /* Generate D symbolic debug info, rather than C
             *   Tnext: element type
             *   Tkey: key type
             */
            t = type_allocn(TYaarray, next->toCtype());
            t->Tkey = index->toCtype();
            t->Tkey->Tcount++;
        }
        else
            t = type_fake(TYaarray);
    }
    t->Tcount++;
    ctype = t;
    return t;
}
Esempio n. 7
0
File: rtlsym.c Progetto: 9rnsr/dmd
static Symbol *symbolz(const char *name, type *t, int fl, SYMFLGS flags, regm_t regsaved)
{
    Symbol *s = symbol_calloc(name);
    s->Stype = t;
    s->Ssymnum = -1;
    s->Sclass = SCextern;
    s->Sfl = fl;
    s->Sregsaved = regsaved;
    s->Sflags = flags;
    return s;
}
Esempio n. 8
0
type *TypeDelegate::toCtype()
{   type *t;

    if (ctype)
        return ctype;

    if (0 && global.params.symdebug)
    {
        /* A delegate consists of:
         *    _Delegate { void* frameptr; Function *funcptr; }
         */

        static Symbol *s;

        if (!s)
        {
            s = symbol_calloc("_Delegate");
            s->Sclass = SCstruct;
            s->Sstruct = struct_calloc();
            s->Sstruct->Sflags |= 0;
            s->Sstruct->Salignsize = alignsize();
            s->Sstruct->Sstructalign = global.structalign;
            s->Sstruct->Sstructsize = size(0);
            slist_add(s);

            Symbol *s1 = symbol_name("frameptr", SCmember, Type::tvoidptr->toCtype());
            list_append(&s->Sstruct->Sfldlst, s1);

            Symbol *s2 = symbol_name("funcptr", SCmember, Type::tvoidptr->toCtype());
            s2->Smemoff = Type::tvoidptr->size();
            list_append(&s->Sstruct->Sfldlst, s2);
        }

        t = type_alloc(TYstruct);
        t->Ttag = (Classsym *)s;                // structure tag name
        t->Tcount++;
        s->Stype = t;
    }
    else
    {
        if (global.params.symdebug == 1)
        {
            // Generate D symbolic debug info, rather than C
            t = type_allocn(TYdelegate, next->toCtype());
        }
        else
            t = type_fake(TYdelegate);
    }

    t->Tcount++;
    ctype = t;
    return t;
}
Esempio n. 9
0
type *TypeDArray::toCtype()
{   type *t;

    if (ctype)
        return ctype;

    if (0 && global.params.symdebug)
    {
        /* Create a C type out of:
         *      struct _Array_T { size_t length; T* data; }
         */
        Symbol *s;
        char *id;

        assert(next->deco);
        id = (char *) alloca(7 + strlen(next->deco) + 1);
        sprintf(id, "_Array_%s", next->deco);
        s = symbol_calloc(id);
        s->Sclass = SCstruct;
        s->Sstruct = struct_calloc();
        s->Sstruct->Sflags |= 0;
        s->Sstruct->Salignsize = alignsize();
        s->Sstruct->Sstructalign = global.structalign;
        s->Sstruct->Sstructsize = size(0);
        slist_add(s);

        Symbol *s1 = symbol_name("length", SCmember, Type::tsize_t->toCtype());
        list_append(&s->Sstruct->Sfldlst, s1);

        Symbol *s2 = symbol_name("data", SCmember, next->pointerTo()->toCtype());
        s2->Smemoff = Type::tsize_t->size();
        list_append(&s->Sstruct->Sfldlst, s2);

        t = type_alloc(TYstruct);
        t->Ttag = (Classsym *)s;                // structure tag name
        t->Tcount++;
        s->Stype = t;
    }
    else
    {
        if (global.params.symdebug == 1)
        {
            // Generate D symbolic debug info, rather than C
            t = type_allocn(TYdarray, next->toCtype());
        }
        else
            t = type_fake(TYdarray);
    }
    t->Tcount++;
    ctype = t;
    return t;
}
Esempio n. 10
0
/*************************************
 * Create a reference to another dt.
 */
void DtBuilder::dtoff(dt_t *dt, unsigned offset)
{
    type *t = type_alloc(TYint);
    t->Tcount++;
    Symbol *s = symbol_calloc("internal");
    s->Sclass = SCstatic;
    s->Sfl = FLextern;
    s->Sflags |= SFLnodebug;
    s->Stype = t;
    s->Sdt = dt;
    outdata(s);

    xoff(s, offset);
}
Esempio n. 11
0
/***************************************
 * Create an enum type.
 * Input:
 *      name    name of enum
 *      tbase   "base" type of enum
 * Returns:
 *      Tcount already incremented
 */
type *type_enum(const char *name, type *tbase)
{
    Symbol *s = symbol_calloc(name);
    s->Sclass = SCenum;
    s->Senum = (enum_t *) MEM_PH_CALLOC(sizeof(enum_t));
    s->Senum->SEflags |= SENforward;        // forward reference

    type *t = type_allocn(TYenum, tbase);
    t->Ttag = (Classsym *)s;            // enum tag name
    t->Tcount++;
    s->Stype = t;
    t->Tcount++;
    return t;
}
Esempio n. 12
0
Symbol *static_sym()
{
    Symbol *s;
    type *t;

    t = type_alloc(TYint);
    t->Tcount++;
    s = symbol_calloc("internal");
    s->Sclass = SCstatic;
    s->Sfl = FLextern;
    s->Sflags |= SFLnodebug;
    s->Stype = t;
    slist_add(s);
    return s;
}
Esempio n. 13
0
type *TypeClass::toCtype()
{   type *t;
    Symbol *s;

    //printf("TypeClass::toCtype() %s\n", toChars());
    if (ctype)
        return ctype;

    /* Need this symbol to do C++ name mangling
     */
    const char *name = sym->isCPPinterface() ? sym->ident->toChars()
                                             : sym->toPrettyChars();
    s = symbol_calloc(name);
    s->Sclass = SCstruct;
    s->Sstruct = struct_calloc();
    s->Sstruct->Sflags |= STRclass;
    s->Sstruct->Salignsize = sym->alignsize;
    s->Sstruct->Sstructalign = sym->structalign;
    s->Sstruct->Sstructsize = sym->structsize;

    t = type_alloc(TYstruct);
    t->Ttag = (Classsym *)s;            // structure tag name
    t->Tcount++;
    s->Stype = t;
    slist_add(s);

    t = type_allocn(TYnptr, t);

    t->Tcount++;
    ctype = t;

    /* Add in fields of the class
     * (after setting ctype to avoid infinite recursion)
     */
    if (global.params.symdebug)
        for (int i = 0; i < sym->fields.dim; i++)
        {   VarDeclaration *v = sym->fields.tdata()[i];

            Symbol *s2 = symbol_name(v->ident->toChars(), SCmember, v->type->toCtype());
            s2->Smemoff = v->offset;
            list_append(&s->Sstruct->Sfldlst, s2);
        }

    return t;
}
Esempio n. 14
0
Symbol *static_sym()
{
    Symbol *s;
    type *t;

    t = type_alloc(TYint);
    t->Tcount++;
    s = symbol_calloc("internal");
    s->Sclass = SCstatic;
    s->Sfl = FLextern;
    s->Sflags |= SFLnodebug;
    s->Stype = t;
#if ELFOBJ // Burton
    s->Sseg = DATA;
#endif /* ELFOBJ */
    slist_add(s);
    return s;
}
Esempio n. 15
0
Symbol* StructLiteralExp::toSymbol()
{
    if (sym) return sym;
    TYPE *t = type_alloc(TYint);
    t->Tcount++;
    Symbol *s = symbol_calloc("internal");
    s->Sclass = SCstatic;
    s->Sfl = FLextern;
    s->Sflags |= SFLnodebug;
    s->Stype = t;
    sym = s;
    dt_t *d = NULL;
    toDt(&d);
    s->Sdt = d;
    slist_add(s);
    outdata(s);
    return sym;
}
Esempio n. 16
0
Symbol* ClassReferenceExp::toSymbol()
{
    if (value->sym) return value->sym;
    TYPE *t = type_alloc(TYint);
    t->Tcount++;
    Symbol *s = symbol_calloc("internal");
    s->Sclass = SCstatic;
    s->Sfl = FLextern;
    s->Sflags |= SFLnodebug;
    s->Stype = t;
    value->sym = s;
    dt_t *d = NULL;
    toInstanceDt(&d);
    s->Sdt = d;
    slist_add(s);
    outdata(s);
    return value->sym;
}
Esempio n. 17
0
Symbol *aaGetSymbol(TypeAArray *taa, const char *func, int flags)
{
#ifdef DEBUG
        assert((flags & ~1) == 0);
#endif

        // Dumb linear symbol table - should use associative array!
        static Symbols *sarray = NULL;

        //printf("aaGetSymbol(func = '%s', flags = %d, key = %p)\n", func, flags, key);
        char *id = (char *)alloca(3 + strlen(func) + 1);
        sprintf(id, "_aa%s", func);
        if (!sarray)
            sarray = Symbols_create();

        // See if symbol is already in sarray
        for (size_t i = 0; i < sarray->dim; i++)
        {
            Symbol *s = (*sarray)[i];
            if (strcmp(id, s->Sident) == 0)
            {
#ifdef DEBUG
                assert(s);
#endif
                return s;                       // use existing Symbol
            }
        }

        // Create new Symbol

        Symbol *s = symbol_calloc(id);
        slist_add(s);
        s->Sclass = SCextern;
        s->Ssymnum = -1;
        symbol_func(s);

        type *t = type_function(TYnfunc, NULL, 0, false, Type_toCtype(taa->next));
        t->Tmangle = mTYman_c;
        s->Stype = t;

        sarray->push(s);                        // remember it
        return s;
}
Esempio n. 18
0
symbol *param_search(const char *name, param_t **pp)
{   symbol *s = NULL;
    param_t *p;

    p = (*pp)->search((char *)name);
    if (p)
    {
        s = p->Psym;
        if (!s)
        {
            s = symbol_calloc(p->Pident);
            s->Sclass = SCparameter;
            s->Stype = p->Ptype;
            s->Stype->Tcount++;
            p->Psym = s;
        }
    }
    return s;
}
Esempio n. 19
0
Classsym *fake_classsym(char *name)
{   TYPE *t;
    Classsym *scc;

    scc = (Classsym *)symbol_calloc("ClassInfo");
    scc->Sclass = SCstruct;
    scc->Sstruct = struct_calloc();
    scc->Sstruct->Sstructalign = 8;
    //scc->Sstruct->ptrtype = TYnptr;
    scc->Sstruct->Sflags = STRglobal;

    t = type_alloc(TYstruct);
    t->Tflags |= TFsizeunknown | TFforward;
    t->Ttag = scc;		// structure tag name
    assert(t->Tmangle == 0);
    t->Tmangle = mTYman_c;
    t->Tcount++;
    scc->Stype = t;
    slist_add(scc);
    return scc;
}
Esempio n. 20
0
Symbol *AggregateDeclaration::toInitializer()
{
    char *id;
    char *n;
    Symbol *s;
    Classsym *stag;

    if (!sinit)
    {
	n = mangle();
	stag = fake_classsym(n);

	id = (char *) alloca(6 + strlen(n) + 1);
	sprintf(id,"_init_%s",n);
	s = symbol_calloc(id);
	s->Stype = stag->Stype;
	s->Sclass = SCextern;
	s->Sfl = FLextern;
	s->Sflags |= SFLnodebug;
	slist_add(s);
	sinit = s;
    }
    return sinit;
}
Esempio n. 21
0
Symbol *FuncDeclaration::toThunkSymbol(int offset)
{
    Symbol *sthunk;

    toSymbol();

#if 0
    char *id;
    char *n;
    type *t;

    n = sym->Sident;
    id = (char *) alloca(8 + 5 + strlen(n) + 1);
    sprintf(id,"_thunk%d__%s", offset, n);
    s = symbol_calloc(id);
    slist_add(s);
    s->Stype = csym->Stype;
    s->Stype->Tcount++;
#endif
    sthunk = symbol_generate(SCstatic, csym->Stype);
    sthunk->Sflags |= SFLimplem;
    cod3_thunk(sthunk, csym, 0, TYnptr, -offset, -1, 0);
    return sthunk;
}
Esempio n. 22
0
        void visit(FuncDeclaration *fd)
        {
            if (!fd->csym)
            {
                const char *id = mangleExact(fd);

                //printf("FuncDeclaration::toSymbol(%s %s)\n", fd->kind(), fd->toChars());
                //printf("\tid = '%s'\n", id);
                //printf("\ttype = %s\n", fd->type->toChars());
                Symbol *s = symbol_calloc(id);
                slist_add(s);

                s->prettyIdent = fd->toPrettyChars();
                s->Sclass = SCglobal;
                symbol_func(s);
                func_t *f = s->Sfunc;
                if (fd->isVirtual() && fd->vtblIndex != -1)
                    f->Fflags |= Fvirtual;
                else if (fd->isMember2() && fd->isStatic())
                    f->Fflags |= Fstatic;
                f->Fstartline.Slinnum = fd->loc.linnum;
                f->Fstartline.Scharnum = fd->loc.charnum;
                f->Fstartline.Sfilename = (char *)fd->loc.filename;
                if (fd->endloc.linnum)
                {
                    f->Fendline.Slinnum = fd->endloc.linnum;
                    f->Fendline.Scharnum = fd->endloc.charnum;
                    f->Fendline.Sfilename = (char *)fd->endloc.filename;
                }
                else
                {
                    f->Fendline.Slinnum = fd->loc.linnum;
                    f->Fendline.Scharnum = fd->loc.charnum;
                    f->Fendline.Sfilename = (char *)fd->loc.filename;
                }
                TYPE *t = Type_toCtype(fd->type);

                mangle_t msave = t->Tmangle;
                if (fd->isMain())
                {
                    t->Tty = TYnfunc;
                    t->Tmangle = mTYman_c;
                }
                else
                {
                    switch (fd->linkage)
                    {
                    case LINKwindows:
                        t->Tmangle = mTYman_std;
                        break;

                    case LINKpascal:
                        t->Tty = TYnpfunc;
                        t->Tmangle = mTYman_pas;
                        break;

                    case LINKc:
                        t->Tmangle = mTYman_c;
                        break;

                    case LINKd:
                        t->Tmangle = mTYman_d;
                        break;
                    case LINKcpp:
                        s->Sflags |= SFLpublic;
                        if (fd->isThis() && !global.params.is64bit && global.params.isWindows)
                        {
                            if (((TypeFunction *)fd->type)->varargs == 1)
                            {
                                t->Tty = TYnfunc;
                            }
                            else
                            {
                                t->Tty = TYmfunc;
                            }
                        }
                        t->Tmangle = mTYman_d;
                        break;
                    default:
                        printf("linkage = %d\n", fd->linkage);
                        assert(0);
                    }
                }

                if (msave)
                    assert(msave == t->Tmangle);
                //printf("Tty = %x, mangle = x%x\n", t->Tty, t->Tmangle);
                t->Tcount++;
                s->Stype = t;
                //s->Sfielddef = this;

                fd->csym = s;
            }
            result = fd->csym;
        }
Esempio n. 23
0
File: glue.c Progetto: alexrp/dmd
void Module::genobjfile(int multiobj)
{
    //EEcontext *ee = env->getEEcontext();

    //printf("Module::genobjfile(multiobj = %d) %s\n", multiobj, toChars());

    lastmname = srcfile->toChars();

    objmod->initfile(lastmname, NULL, toPrettyChars());

    eictor = NULL;
    ictorlocalgot = NULL;
    sctors.setDim(0);
    ectorgates.setDim(0);
    sdtors.setDim(0);
    ssharedctors.setDim(0);
    esharedctorgates.setDim(0);
    sshareddtors.setDim(0);
    stests.setDim(0);
    dtorcount = 0;
    shareddtorcount = 0;

    if (doppelganger)
    {
        /* Generate a reference to the moduleinfo, so the module constructors
         * and destructors get linked in.
         */
        Module *m = aimports[0];
        assert(m);
        if (m->sictor || m->sctor || m->sdtor || m->ssharedctor || m->sshareddtor)
        {
            Symbol *s = m->toSymbol();
            //objextern(s);
            //if (!s->Sxtrnnum) objextdef(s->Sident);
            if (!s->Sxtrnnum)
            {
                //printf("%s\n", s->Sident);
#if 0 /* This should work, but causes optlink to fail in common/newlib.asm */
                objextdef(s->Sident);
#else
                Symbol *sref = symbol_generate(SCstatic, type_fake(TYnptr));
                sref->Sfl = FLdata;
                dtxoff(&sref->Sdt, s, 0, TYnptr);
                outdata(sref);
#endif
            }
        }
    }

    if (global.params.cov)
    {
        /* Create coverage identifier:
         *  private uint[numlines] __coverage;
         */
        cov = symbol_calloc("__coverage");
        cov->Stype = type_fake(TYint);
        cov->Stype->Tmangle = mTYman_c;
        cov->Stype->Tcount++;
        cov->Sclass = SCstatic;
        cov->Sfl = FLdata;
        dtnzeros(&cov->Sdt, 4 * numlines);
        outdata(cov);
        slist_add(cov);

        covb = (unsigned *)calloc((numlines + 32) / 32, sizeof(*covb));
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *member = (*members)[i];
        //printf("toObjFile %s %s\n", member->kind(), member->toChars());
        member->toObjFile(multiobj);
    }

    if (global.params.cov)
    {
        /* Generate
         *      bit[numlines] __bcoverage;
         */
        Symbol *bcov = symbol_calloc("__bcoverage");
        bcov->Stype = type_fake(TYuint);
        bcov->Stype->Tcount++;
        bcov->Sclass = SCstatic;
        bcov->Sfl = FLdata;
        dtnbytes(&bcov->Sdt, (numlines + 32) / 32 * sizeof(*covb), (char *)covb);
        outdata(bcov);

        free(covb);
        covb = NULL;

        /* Generate:
         *  _d_cover_register(uint[] __coverage, BitArray __bcoverage, string filename);
         * and prepend it to the static constructor.
         */

        /* t will be the type of the functions generated:
         *      extern (C) void func();
         */
        type *t = type_function(TYnfunc, NULL, 0, false, tsvoid);
        t->Tmangle = mTYman_c;

        sictor = toSymbolX("__modictor", SCglobal, t, "FZv");
        cstate.CSpsymtab = &sictor->Sfunc->Flocsym;
        localgot = ictorlocalgot;

        elem *ecov  = el_pair(TYdarray, el_long(TYsize_t, numlines), el_ptr(cov));
        elem *ebcov = el_pair(TYdarray, el_long(TYsize_t, numlines), el_ptr(bcov));

        if (config.exe == EX_WIN64)
        {
            ecov  = addressElem(ecov,  Type::tvoid->arrayOf(), false);
            ebcov = addressElem(ebcov, Type::tvoid->arrayOf(), false);
        }

        elem *e = el_params(
                      el_long(TYuchar, global.params.covPercent),
                      ecov,
                      ebcov,
                      toEfilename(),
                      NULL);
        e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_DCOVER2]), e);
        eictor = el_combine(e, eictor);
        ictorlocalgot = localgot;
    }

    // If coverage / static constructor / destructor / unittest calls
    if (eictor || sctors.dim || ectorgates.dim || sdtors.dim ||
        ssharedctors.dim || esharedctorgates.dim || sshareddtors.dim || stests.dim)
    {
        if (eictor)
        {
            localgot = ictorlocalgot;

            block *b = block_calloc();
            b->BC = BCret;
            b->Belem = eictor;
            sictor->Sfunc->Fstartline.Sfilename = arg;
            sictor->Sfunc->Fstartblock = b;
            writefunc(sictor);
        }

        sctor = callFuncsAndGates(this, &sctors, &ectorgates, "__modctor");
        sdtor = callFuncsAndGates(this, &sdtors, NULL, "__moddtor");

#if DMDV2
        ssharedctor = callFuncsAndGates(this, &ssharedctors, (StaticDtorDeclarations *)&esharedctorgates, "__modsharedctor");
        sshareddtor = callFuncsAndGates(this, &sshareddtors, NULL, "__modshareddtor");
#endif
        stest = callFuncsAndGates(this, &stests, NULL, "__modtest");

        if (doppelganger)
            genmoduleinfo();
    }

    if (doppelganger)
    {
        objmod->termfile();
        return;
    }

    if (global.params.multiobj)
    {   /* This is necessary because the main .obj for this module is written
         * first, but determining whether marray or massert or munittest are needed is done
         * possibly later in the doppelganger modules.
         * Another way to fix it is do the main one last.
         */
        toModuleAssert();
        toModuleUnittest();
        toModuleArray();
    }

    /* Always generate module info, because of templates and -cov.
     * But module info needs the runtime library, so disable it for betterC.
     */
    if (!global.params.betterC /*|| needModuleInfo()*/)
        genmoduleinfo();

    // If module assert
    for (int i = 0; i < 3; i++)
    {
        Symbol *ma;
        unsigned rt;
        unsigned bc;
        switch (i)
        {
            case 0:     ma = marray;    rt = RTLSYM_DARRAY;     bc = BCexit; break;
            case 1:     ma = massert;   rt = RTLSYM_DASSERTM;   bc = BCexit; break;
            case 2:     ma = munittest; rt = RTLSYM_DUNITTESTM; bc = BCret;  break;
            default:    assert(0);
        }

        if (ma)
        {
            elem *elinnum;

            localgot = NULL;

            // Call dassert(filename, line)
            // Get sole parameter, linnum
            {
                Symbol *sp = symbol_calloc("linnum");
                sp->Stype = type_fake(TYint);
                sp->Stype->Tcount++;
                sp->Sclass = (config.exe == EX_WIN64) ? SCshadowreg : SCfastpar;

                FuncParamRegs fpr(TYjfunc);
                fpr.alloc(sp->Stype, sp->Stype->Tty, &sp->Spreg, &sp->Spreg2);

                sp->Sflags &= ~SFLspill;
                sp->Sfl = (sp->Sclass == SCshadowreg) ? FLpara : FLfast;
                cstate.CSpsymtab = &ma->Sfunc->Flocsym;
                symbol_add(sp);

                elinnum = el_var(sp);
            }

            elem *efilename = el_ptr(toSymbol());

            elem *e = el_var(rtlsym[rt]);
            e = el_bin(OPcall, TYvoid, e, el_param(elinnum, efilename));

            block *b = block_calloc();
            b->BC = bc;
            b->Belem = e;
            ma->Sfunc->Fstartline.Sfilename = arg;
            ma->Sfunc->Fstartblock = b;
            ma->Sclass = SCglobal;
            ma->Sfl = 0;
            ma->Sflags |= rtlsym[rt]->Sflags & SFLexit;
            writefunc(ma);
        }
    }

    objmod->termfile();
}
Esempio n. 24
0
File: glue.c Progetto: iteratif/dmd
void Module::genobjfile(int multiobj)
{
    //EEcontext *ee = env->getEEcontext();

    //printf("Module::genobjfile(multiobj = %d) %s\n", multiobj, toChars());

    lastmname = srcfile->toChars();

    obj_initfile(lastmname, NULL, toPrettyChars());

    eictor = NULL;
    ictorlocalgot = NULL;
    sctors.setDim(0);
    ectorgates.setDim(0);
    sdtors.setDim(0);
    ssharedctors.setDim(0);
    esharedctorgates.setDim(0);
    sshareddtors.setDim(0);
    stests.setDim(0);
    dtorcount = 0;
    shareddtorcount = 0;

    if (doppelganger)
    {
        /* Generate a reference to the moduleinfo, so the module constructors
         * and destructors get linked in.
         */
        Module *m = aimports[0];
        assert(m);
        if (m->sictor || m->sctor || m->sdtor || m->ssharedctor || m->sshareddtor)
        {
            Symbol *s = m->toSymbol();
            //objextern(s);
            //if (!s->Sxtrnnum) objextdef(s->Sident);
            if (!s->Sxtrnnum)
            {
                //printf("%s\n", s->Sident);
#if 0 /* This should work, but causes optlink to fail in common/newlib.asm */
                objextdef(s->Sident);
#else
#if ELFOBJ || MACHOBJ
                int nbytes = reftoident(DATA, Offset(DATA), s, 0, I64 ? (CFoff | CFoffset64) : CFoff);
#else
                int nbytes = reftoident(DATA, Doffset, s, 0, CFoff);
                Doffset += nbytes;
#endif
#endif
            }
        }
    }

    if (global.params.cov)
    {
        /* Create coverage identifier:
         *  private uint[numlines] __coverage;
         */
        cov = symbol_calloc("__coverage");
        cov->Stype = type_fake(TYint);
        cov->Stype->Tmangle = mTYman_c;
        cov->Stype->Tcount++;
        cov->Sclass = SCstatic;
        cov->Sfl = FLdata;
#if ELFOBJ || MACHOBJ
        cov->Sseg = UDATA;
#endif
        dtnzeros(&cov->Sdt, 4 * numlines);
        outdata(cov);
        slist_add(cov);

        covb = (unsigned *)calloc((numlines + 32) / 32, sizeof(*covb));
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *member = (*members)[i];
        member->toObjFile(multiobj);
    }

    if (global.params.cov)
    {
        /* Generate
         *      bit[numlines] __bcoverage;
         */
        Symbol *bcov = symbol_calloc("__bcoverage");
        bcov->Stype = type_fake(TYuint);
        bcov->Stype->Tcount++;
        bcov->Sclass = SCstatic;
        bcov->Sfl = FLdata;
#if ELFOBJ || MACHOBJ
        bcov->Sseg = DATA;
#endif
        dtnbytes(&bcov->Sdt, (numlines + 32) / 32 * sizeof(*covb), (char *)covb);
        outdata(bcov);

        free(covb);
        covb = NULL;

        /* Generate:
         *  _d_cover_register(uint[] __coverage, BitArray __bcoverage, string filename);
         * and prepend it to the static constructor.
         */

        /* t will be the type of the functions generated:
         *      extern (C) void func();
         */
        type *t = type_alloc(TYnfunc);
        t->Tflags |= TFprototype | TFfixed;
        t->Tmangle = mTYman_c;
        t->Tnext = tsvoid;
        tsvoid->Tcount++;

        sictor = toSymbolX("__modictor", SCglobal, t, "FZv");
        cstate.CSpsymtab = &sictor->Sfunc->Flocsym;
        localgot = ictorlocalgot;
        elem *e;

        e = el_params(el_pair(TYdarray, el_long(TYsize_t, numlines), el_ptr(cov)),
                      el_pair(TYdarray, el_long(TYsize_t, numlines), el_ptr(bcov)),
                      toEfilename(),
                      NULL);
        e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_DCOVER]), e);
        eictor = el_combine(e, eictor);
        ictorlocalgot = localgot;
    }

    // If coverage / static constructor / destructor / unittest calls
    if (eictor || sctors.dim || ectorgates.dim || sdtors.dim ||
        ssharedctors.dim || esharedctorgates.dim || sshareddtors.dim || stests.dim)
    {
        if (eictor)
        {
            localgot = ictorlocalgot;

            block *b = block_calloc();
            b->BC = BCret;
            b->Belem = eictor;
            sictor->Sfunc->Fstartline.Sfilename = arg;
            sictor->Sfunc->Fstartblock = b;
            writefunc(sictor);
        }

        sctor = callFuncsAndGates(this, &sctors, &ectorgates, "__modctor");
        sdtor = callFuncsAndGates(this, &sdtors, NULL, "__moddtor");

#if DMDV2
        ssharedctor = callFuncsAndGates(this, &ssharedctors, (StaticDtorDeclarations *)&esharedctorgates, "__modsharedctor");
        sshareddtor = callFuncsAndGates(this, &sshareddtors, NULL, "__modshareddtor");
#endif
        stest = callFuncsAndGates(this, &stests, NULL, "__modtest");

        if (doppelganger)
            genmoduleinfo();
    }

    if (doppelganger)
    {
        obj_termfile();
        return;
    }

    if (global.params.multiobj)
    {   /* This is necessary because the main .obj for this module is written
         * first, but determining whether marray or massert or munittest are needed is done
         * possibly later in the doppelganger modules.
         * Another way to fix it is do the main one last.
         */
        toModuleAssert();
        toModuleUnittest();
        toModuleArray();
    }

#if 1
    // Always generate module info, because of templates and -cov
    if (1 || needModuleInfo())
        genmoduleinfo();
#endif

    // If module assert
    for (int i = 0; i < 3; i++)
    {
        Symbol *ma;
        unsigned rt;
        unsigned bc;
        switch (i)
        {
            case 0:     ma = marray;    rt = RTLSYM_DARRAY;     bc = BCexit; break;
            case 1:     ma = massert;   rt = RTLSYM_DASSERTM;   bc = BCexit; break;
            case 2:     ma = munittest; rt = RTLSYM_DUNITTESTM; bc = BCret;  break;
            default:    assert(0);
        }

        if (ma)
        {
            elem *elinnum;

            localgot = NULL;

            // Call dassert(filename, line)
            // Get sole parameter, linnum
            {
                Symbol *sp = symbol_calloc("linnum");
                sp->Stype = type_fake(TYint);
                sp->Stype->Tcount++;
                sp->Sclass = SCfastpar;
                size_t num;
                sp->Spreg = getintegerparamsreglist(TYjfunc, &num)[0];
                sp->Sflags &= ~SFLspill;
                sp->Sfl = FLpara;       // FLauto?
                cstate.CSpsymtab = &ma->Sfunc->Flocsym;
                symbol_add(sp);

                elinnum = el_var(sp);
            }

            elem *efilename = el_ptr(toSymbol());

            elem *e = el_var(rtlsym[rt]);
            e = el_bin(OPcall, TYvoid, e, el_param(elinnum, efilename));

            block *b = block_calloc();
            b->BC = bc;
            b->Belem = e;
            ma->Sfunc->Fstartline.Sfilename = arg;
            ma->Sfunc->Fstartblock = b;
            ma->Sclass = SCglobal;
            ma->Sfl = 0;
            ma->Sflags |= rtlsym[rt]->Sflags & SFLexit;
            writefunc(ma);
        }
    }

    obj_termfile();
}
Esempio n. 25
0
Symbol *FuncDeclaration::toSymbol()
{
    if (!csym)
    {	Symbol *s;
	TYPE *t;
	const char *id;

#if 0
	id = ident->toChars();
#else
	id = mangle();
#endif
	//printf("FuncDeclaration::toSymbol(%s)\n", toChars());
	//printf("\tid = '%s'\n", id);
	//printf("\ttype = %s\n", type->toChars());
	s = symbol_calloc(id);
	slist_add(s);

	{   func_t *f;

	    s->Sclass = SCglobal;
	    symbol_func(s);
	    f = s->Sfunc;
	    f->Fstartline.Slinnum = loc.linnum;
	    if (endloc.linnum)
		f->Fendline.Slinnum = endloc.linnum;
	    else
		f->Fendline.Slinnum = loc.linnum;
	    t = type->toCtype();
	}

	mangle_t msave = t->Tmangle;
	if (isMain())
	{
	    t->Tty = TYnfunc;
	    t->Tmangle = mTYman_c;
	}
	else
	{
	    switch (linkage)
	    {
		case LINKwindows:
		    t->Tmangle = mTYman_std;
		    break;

		case LINKpascal:
		    t->Tty = TYnpfunc;
		    t->Tmangle = mTYman_pas;
		    break;

		case LINKc:
		    t->Tmangle = mTYman_c;
		    break;

		case LINKd:
		    t->Tmangle = mTYman_d;
		    break;

		case LINKcpp:
		    t->Tmangle = mTYman_cpp;
		    break;

		default:
		    printf("linkage = %d\n", linkage);
		    assert(0);
	    }
	}
	if (msave)
	    assert(msave == t->Tmangle);
	//printf("Tty = %d, mangle = x%x\n", t->Tty, t->Tmangle);
	t->Tcount++;
	s->Stype = t;
        //s->Sfielddef = this;

	csym = s;
    }
    return csym;
}
Esempio n. 26
0
Symbol *VarDeclaration::toSymbol()
{
    //printf("VarDeclaration::toSymbol(%s)\n", toChars());
    //if (needThis()) *(char*)0=0;
    assert(!needThis());
    if (!csym)
    {	Symbol *s;
	TYPE *t;
	const char *id;
	mangle_t m = 0;

	if (isDataseg())
	    id = mangle();
	else
	    id = ident->toChars();
	s = symbol_calloc(id);

	if (storage_class & STCout)
	    t = type_fake(TYnptr);
	else if (isParameter())
	    t = type->toCParamtype();
	else
	    t = type->toCtype();
	t->Tcount++;

	if (isDataseg())
	{
	    s->Sclass = SCextern;
	    s->Sfl = FLextern;
	    slist_add(s);
	}
	else
	{
	    s->Sclass = SCauto;
	    s->Sfl = FLauto;

	    if (nestedref)
	    {
		/* Symbol is accessed by a nested function. Make sure
		 * it is not put in a register, and that the optimizer
		 * assumes it is modified across function calls and pointer
		 * dereferences.
		 */
		//printf("\tnested ref, not register\n");
		type_setcv(&t, t->Tty | mTYvolatile);
	    }
	}
	if (storage_class & STCconst)
	{
	    // Insert const modifiers
	    tym_t tym = 0;

	    if (storage_class & STCconst)
		tym |= mTYconst;
	    type_setcv(&t, tym);
	}
	switch (linkage)
	{
	    case LINKwindows:
		m = mTYman_std;
		break;

	    case LINKpascal:
		m = mTYman_pas;
		break;

	    case LINKc:
		m = mTYman_c;
		break;

	    case LINKd:
		m = mTYman_d;
		break;

	    case LINKcpp:
		m = mTYman_cpp;
		break;

	    default:
		printf("linkage = %d\n", linkage);
		assert(0);
	}
	type_setmangle(&t, m);
	s->Stype = t;

	csym = s;
    }
    return csym;
}
Esempio n. 27
0
Symbol *VarDeclaration::toSymbol()
{
    //printf("VarDeclaration::toSymbol(%s)\n", toChars());
    //if (needThis()) *(char*)0=0;
    assert(!needThis());
    if (!csym)
    {
        TYPE *t;
        const char *id;

        if (isDataseg())
            id = mangle();
        else
            id = ident->toChars();
        Symbol *s = symbol_calloc(id);
        s->Salignment = alignment;

        if (storage_class & (STCout | STCref))
        {
            // should be TYref, but problems in back end
            t = type_pointer(type->toCtype());
        }
        else if (storage_class & STClazy)
        {
            if (config.exe == EX_WIN64 && isParameter())
                t = type_fake(TYnptr);
            else
                t = type_fake(TYdelegate);          // Tdelegate as C type
            t->Tcount++;
        }
        else if (isParameter())
        {
            if (config.exe == EX_WIN64 && type->size(Loc()) > REGSIZE)
            {
                // should be TYref, but problems in back end
                t = type_pointer(type->toCtype());
            }
            else
            {
                t = type->toCParamtype();
                t->Tcount++;
            }
        }
        else
        {
            t = type->toCtype();
            t->Tcount++;
        }

        if (isDataseg())
        {
            if (isThreadlocal())
            {   /* Thread local storage
                 */
                TYPE *ts = t;
                ts->Tcount++;   // make sure a different t is allocated
                type_setty(&t, t->Tty | mTYthread);
                ts->Tcount--;

                if (global.params.vtls)
                {
                    char *p = loc.toChars();
                    fprintf(stderr, "%s: %s is thread local\n", p ? p : "", toChars());
                    if (p)
                        mem.free(p);
                }
            }
            s->Sclass = SCextern;
            s->Sfl = FLextern;
            slist_add(s);
            /* if it's global or static, then it needs to have a qualified but unmangled name.
             * This gives some explanation of the separation in treating name mangling.
             * It applies to PDB format, but should apply to CV as PDB derives from CV.
             *    http://msdn.microsoft.com/en-us/library/ff553493(VS.85).aspx
             */
            s->prettyIdent = toPrettyChars();
        }
        else
        {
            s->Sclass = SCauto;
            s->Sfl = FLauto;

            if (nestedrefs.dim)
            {
                /* Symbol is accessed by a nested function. Make sure
                 * it is not put in a register, and that the optimizer
                 * assumes it is modified across function calls and pointer
                 * dereferences.
                 */
                //printf("\tnested ref, not register\n");
                type_setcv(&t, t->Tty | mTYvolatile);
            }
        }

        if (ident == Id::va_argsave)
            /* __va_argsave is set outside of the realm of the optimizer,
             * so we tell the optimizer to leave it alone
             */
            type_setcv(&t, t->Tty | mTYvolatile);

        mangle_t m = 0;
        switch (linkage)
        {
            case LINKwindows:
                m = mTYman_std;
                break;

            case LINKpascal:
                m = mTYman_pas;
                break;

            case LINKc:
                m = mTYman_c;
                break;

            case LINKd:
                m = mTYman_d;
                break;

            case LINKcpp:
            {
                m = mTYman_cpp;

                s->Sflags = SFLpublic;
                Dsymbol *parent = toParent();
                ClassDeclaration *cd = parent->isClassDeclaration();
                if (cd)
                {
                    ::type *tc = cd->type->toCtype();
                    s->Sscope = tc->Tnext->Ttag;
                }
                StructDeclaration *sd = parent->isStructDeclaration();
                if (sd)
                {
                    ::type *ts = sd->type->toCtype();
                    s->Sscope = ts->Ttag;
                }
                break;
            }
            default:
                printf("linkage = %d\n", linkage);
                assert(0);
        }
        type_setmangle(&t, m);
        s->Stype = t;

        csym = s;
    }
    return csym;
}
Esempio n. 28
0
File: glue.c Progetto: Geod24/dnet
void Module::genobjfile(int multiobj)
{
    //EEcontext *ee = env->getEEcontext();

    //printf("Module::genobjfile(multiobj = %d) %s\n", multiobj, toChars());

    lastmname = srcfile->toChars();

    obj_initfile(lastmname, NULL, toPrettyChars());

    eictor = NULL;
    ictorlocalgot = NULL;
    ector = NULL;
    ectorgates.setDim(0);
    edtor = NULL;
    etest = NULL;
    dtorcount = 0;

    if (doppelganger)
    {
	/* Generate a reference to the moduleinfo, so the module constructors
	 * and destructors get linked in.
	 */
	Module *m = (Module *)aimports.data[0];
	assert(m);
	if (m->sictor || m->sctor || m->sdtor)
	{
	    Symbol *s = m->toSymbol();
	    //objextern(s);
	    //if (!s->Sxtrnnum) objextdef(s->Sident);
	    if (!s->Sxtrnnum)
	    {
		//printf("%s\n", s->Sident);
#if 0 /* This should work, but causes optlink to fail in common/newlib.asm */
		objextdef(s->Sident);
#else
#if ELFOBJ || MACHOBJ
		int nbytes = reftoident(DATA, Offset(DATA), s, 0, CFoff);
		Offset(DATA) += nbytes;
#else
		int nbytes = reftoident(DATA, Doffset, s, 0, CFoff);
		Doffset += nbytes;
#endif
#endif
	    }
	}
    }

    if (global.params.cov)
    {
	/* Create coverage identifier:
	 *  private uint[numlines] __coverage;
	 */
	cov = symbol_calloc("__coverage");
	cov->Stype = type_fake(TYint);
	cov->Stype->Tmangle = mTYman_c;
	cov->Stype->Tcount++;
	cov->Sclass = SCstatic;
	cov->Sfl = FLdata;
#if ELFOBJ || MACHOBJ
	cov->Sseg = UDATA;
#endif
	dtnzeros(&cov->Sdt, 4 * numlines);
	outdata(cov);
	slist_add(cov);

	covb = (unsigned *)calloc((numlines + 32) / 32, sizeof(*covb));
    }

    for (int i = 0; i < members->dim; i++)
    {
	Dsymbol *member = (Dsymbol *)members->data[i];
	member->toObjFile(multiobj);
    }

    if (global.params.cov)
    {
	/* Generate
	 *	bit[numlines] __bcoverage;
	 */
	Symbol *bcov = symbol_calloc("__bcoverage");
	bcov->Stype = type_fake(TYuint);
	bcov->Stype->Tcount++;
	bcov->Sclass = SCstatic;
	bcov->Sfl = FLdata;
#if ELFOBJ || MACHOBJ
	bcov->Sseg = DATA;
#endif
	dtnbytes(&bcov->Sdt, (numlines + 32) / 32 * sizeof(*covb), (char *)covb);
	outdata(bcov);

	free(covb);
	covb = NULL;

	/* Generate:
	 *  _d_cover_register(uint[] __coverage, BitArray __bcoverage, string filename);
	 * and prepend it to the static constructor.
	 */

	/* t will be the type of the functions generated:
	 *	extern (C) void func();
	 */
	type *t = type_alloc(TYnfunc);
	t->Tflags |= TFprototype | TFfixed;
	t->Tmangle = mTYman_c;
	t->Tnext = tsvoid;
	tsvoid->Tcount++;

	sictor = toSymbolX("__modictor", SCglobal, t, "FZv");
	cstate.CSpsymtab = &sictor->Sfunc->Flocsym;
	localgot = ictorlocalgot;
	elem *e;

	e = el_params(el_ptr(cov), el_long(TYuint, numlines),
		      el_ptr(bcov), el_long(TYuint, numlines),
		      toEfilename(),
		      NULL);
	e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_DCOVER]), e);
	eictor = el_combine(e, eictor);
	ictorlocalgot = localgot;
    }

    // If coverage / static constructor / destructor / unittest calls
    if (eictor || ector || ectorgates.dim || edtor || etest)
    {
	/* t will be the type of the functions generated:
	 *	extern (C) void func();
	 */
	type *t = type_alloc(TYnfunc);
	t->Tflags |= TFprototype | TFfixed;
	t->Tmangle = mTYman_c;
	t->Tnext = tsvoid;
	tsvoid->Tcount++;

	static char moddeco[] = "FZv";

	if (eictor)
	{
	    localgot = ictorlocalgot;

	    block *b = block_calloc();
	    b->BC = BCret;
	    b->Belem = eictor;
	    sictor->Sfunc->Fstartblock = b;
	    writefunc(sictor);
	}

	if (ector || ectorgates.dim)
	{
	    localgot = NULL;
	    sctor = toSymbolX("__modctor", SCglobal, t, moddeco);
	    cstate.CSpsymtab = &sctor->Sfunc->Flocsym;

	    for (int i = 0; i < ectorgates.dim; i++)
	    {	StaticDtorDeclaration *f = (StaticDtorDeclaration *)ectorgates.data[i];

		Symbol *s = f->vgate->toSymbol();
		elem *e = el_var(s);
		e = el_bin(OPaddass, TYint, e, el_long(TYint, 1));
		ector = el_combine(ector, e);
	    }

	    block *b = block_calloc();
	    b->BC = BCret;
	    b->Belem = ector;
	    sctor->Sfunc->Fstartblock = b;
	    writefunc(sctor);
#if STATICCTOR
	    obj_staticctor(sctor, dtorcount, 1);
#endif
	}

	if (edtor)
	{
	    localgot = NULL;
	    sdtor = toSymbolX("__moddtor", SCglobal, t, moddeco);

	    block *b = block_calloc();
	    b->BC = BCret;
	    b->Belem = edtor;
	    sdtor->Sfunc->Fstartblock = b;
	    writefunc(sdtor);
	}

	if (etest)
	{
	    localgot = NULL;
	    stest = toSymbolX("__modtest", SCglobal, t, moddeco);

	    block *b = block_calloc();
	    b->BC = BCret;
	    b->Belem = etest;
	    stest->Sfunc->Fstartblock = b;
	    writefunc(stest);
	}

	if (doppelganger)
	    genmoduleinfo();
    }

    if (doppelganger)
    {
	obj_termfile();
	return;
    }

    if (global.params.multiobj)
    {	/* This is necessary because the main .obj for this module is written
	 * first, but determining whether marray or massert are needed is done
	 * possibly later in the doppelganger modules.
	 * Another way to fix it is do the main one last.
	 */
	toModuleAssert();
	toModuleArray();
    }

    // If module assert
    for (int i = 0; i < 2; i++)
    {
	Symbol *ma = i ? marray : massert;

	if (ma)
	{
	    elem *elinnum;
	    elem *efilename;

	    localgot = NULL;

	    // Call dassert(filename, line)
	    // Get sole parameter, linnum
	    {
		Symbol *sp;

		sp = symbol_calloc("linnum");
		sp->Stype = type_fake(TYint);
		sp->Stype->Tcount++;
		sp->Sclass = SCfastpar;
		sp->Spreg = AX;
		sp->Sflags &= ~SFLspill;
		sp->Sfl = FLpara;	// FLauto?
		cstate.CSpsymtab = &ma->Sfunc->Flocsym;
		symbol_add(sp);

		elinnum = el_var(sp);
	    }

	    efilename = toEmodulename();

	    elem *e = el_var(rtlsym[i ? RTLSYM_DARRAY : RTLSYM_DASSERT]);
	    e = el_bin(OPcall, TYvoid, e, el_param(elinnum, efilename));

	    block *b = block_calloc();
	    b->BC = BCret;
	    b->Belem = e;
	    ma->Sfunc->Fstartblock = b;
	    ma->Sclass = SCglobal;
	    ma->Sfl = 0;
	    writefunc(ma);
	}
    }

#if 1
    // Always generate module info, because of templates and -cov
    if (1 || needModuleInfo())
	genmoduleinfo();
#endif
    
    obj_termfile();
}
Esempio n. 29
0
void genObjFile(Module *m, bool multiobj)
{
    //EEcontext *ee = env->getEEcontext();

    //printf("Module::genobjfile(multiobj = %d) %s\n", multiobj, m->toChars());

    if (m->ident == Id::entrypoint)
    {
        bool v = global.params.verbose;
        global.params.verbose = false;

        for (size_t i = 0; i < m->members->dim; i++)
        {
            Dsymbol *member = (*m->members)[i];
            //printf("toObjFile %s %s\n", member->kind(), member->toChars());
            toObjFile(member, global.params.multiobj);
        }

        global.params.verbose = v;
        return;
    }

    lastmname = m->srcfile->toChars();

    objmod->initfile(lastmname, NULL, m->toPrettyChars());

    eictor = NULL;
    ictorlocalgot = NULL;
    sctors.setDim(0);
    ectorgates.setDim(0);
    sdtors.setDim(0);
    ssharedctors.setDim(0);
    esharedctorgates.setDim(0);
    sshareddtors.setDim(0);
    stests.setDim(0);

    if (m->doppelganger)
    {
        /* Generate a reference to the moduleinfo, so the module constructors
         * and destructors get linked in.
         */
        Module *mod = m->aimports[0];
        assert(mod);
        if (mod->sictor || mod->sctor || mod->sdtor || mod->ssharedctor || mod->sshareddtor)
        {
            Symbol *s = toSymbol(mod);
            //objextern(s);
            //if (!s->Sxtrnnum) objextdef(s->Sident);
            if (!s->Sxtrnnum)
            {
                //printf("%s\n", s->Sident);
#if 0 /* This should work, but causes optlink to fail in common/newlib.asm */
                objextdef(s->Sident);
#else
                Symbol *sref = symbol_generate(SCstatic, type_fake(TYnptr));
                sref->Sfl = FLdata;
                dtxoff(&sref->Sdt, s, 0, TYnptr);
                outdata(sref);
#endif
            }
        }
    }

    if (global.params.cov)
    {
        /* Create coverage identifier:
         *  private uint[numlines] __coverage;
         */
        m->cov = symbol_calloc("__coverage");
        m->cov->Stype = type_fake(TYint);
        m->cov->Stype->Tmangle = mTYman_c;
        m->cov->Stype->Tcount++;
        m->cov->Sclass = SCstatic;
        m->cov->Sfl = FLdata;
        dtnzeros(&m->cov->Sdt, 4 * m->numlines);
        outdata(m->cov);
        slist_add(m->cov);

        m->covb = (unsigned *)calloc((m->numlines + 32) / 32, sizeof(*m->covb));
    }

    for (size_t i = 0; i < m->members->dim; i++)
    {
        Dsymbol *member = (*m->members)[i];
        //printf("toObjFile %s %s\n", member->kind(), member->toChars());
        toObjFile(member, multiobj);
    }

    if (global.params.cov)
    {
        /* Generate
         *      bit[numlines] __bcoverage;
         */
        Symbol *bcov = symbol_calloc("__bcoverage");
        bcov->Stype = type_fake(TYuint);
        bcov->Stype->Tcount++;
        bcov->Sclass = SCstatic;
        bcov->Sfl = FLdata;
        dtnbytes(&bcov->Sdt, (m->numlines + 32) / 32 * sizeof(*m->covb), (char *)m->covb);
        outdata(bcov);

        free(m->covb);
        m->covb = NULL;

        /* Generate:
         *  _d_cover_register(uint[] __coverage, BitArray __bcoverage, string filename);
         * and prepend it to the static constructor.
         */

        /* t will be the type of the functions generated:
         *      extern (C) void func();
         */
        type *t = type_function(TYnfunc, NULL, 0, false, tsvoid);
        t->Tmangle = mTYman_c;

        m->sictor = toSymbolX(m, "__modictor", SCglobal, t, "FZv");
        cstate.CSpsymtab = &m->sictor->Sfunc->Flocsym;
        localgot = ictorlocalgot;

        elem *ecov  = el_pair(TYdarray, el_long(TYsize_t, m->numlines), el_ptr(m->cov));
        elem *ebcov = el_pair(TYdarray, el_long(TYsize_t, m->numlines), el_ptr(bcov));

        if (config.exe == EX_WIN64)
        {
            ecov  = addressElem(ecov,  Type::tvoid->arrayOf(), false);
            ebcov = addressElem(ebcov, Type::tvoid->arrayOf(), false);
        }

        elem *efilename = toEfilename(m);
        if (config.exe == EX_WIN64)
            efilename = addressElem(efilename, Type::tstring, true);

        elem *e = el_params(
                      el_long(TYuchar, global.params.covPercent),
                      ecov,
                      ebcov,
                      efilename,
                      NULL);
        e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_DCOVER2]), e);
        eictor = el_combine(e, eictor);
        ictorlocalgot = localgot;
    }

    // If coverage / static constructor / destructor / unittest calls
    if (eictor || sctors.dim || ectorgates.dim || sdtors.dim ||
        ssharedctors.dim || esharedctorgates.dim || sshareddtors.dim || stests.dim)
    {
        if (eictor)
        {
            localgot = ictorlocalgot;

            block *b = block_calloc();
            b->BC = BCret;
            b->Belem = eictor;
            m->sictor->Sfunc->Fstartline.Sfilename = m->arg;
            m->sictor->Sfunc->Fstartblock = b;
            writefunc(m->sictor);
        }

        m->sctor = callFuncsAndGates(m, &sctors, &ectorgates, "__modctor");
        m->sdtor = callFuncsAndGates(m, &sdtors, NULL, "__moddtor");

        m->ssharedctor = callFuncsAndGates(m, &ssharedctors, (StaticDtorDeclarations *)&esharedctorgates, "__modsharedctor");
        m->sshareddtor = callFuncsAndGates(m, &sshareddtors, NULL, "__modshareddtor");
        m->stest = callFuncsAndGates(m, &stests, NULL, "__modtest");

        if (m->doppelganger)
            genModuleInfo(m);
    }

    if (m->doppelganger)
    {
        objmod->termfile();
        return;
    }

    if (global.params.multiobj)
    {
        /* This is necessary because the main .obj for this module is written
         * first, but determining whether marray or massert or munittest are needed is done
         * possibly later in the doppelganger modules.
         * Another way to fix it is do the main one last.
         */
        toModuleAssert(m);
        toModuleUnittest(m);
        toModuleArray(m);
    }

    /* Always generate module info, because of templates and -cov.
     * But module info needs the runtime library, so disable it for betterC.
     */
    if (!global.params.betterC /*|| needModuleInfo()*/)
        genModuleInfo(m);

    genhelpers(m, false);

    objmod->termfile();
}
Esempio n. 30
0
Symbol *FuncDeclaration::toSymbol()
{
    if (!csym)
    {   Symbol *s;
        TYPE *t;
        const char *id;

#if 0
        id = ident->toChars();
#else
        id = mangle();
#endif
        //printf("FuncDeclaration::toSymbol(%s %s)\n", kind(), toChars());
        //printf("\tid = '%s'\n", id);
        //printf("\ttype = %s\n", type->toChars());
        s = symbol_calloc(id);
        slist_add(s);

        {
            s->prettyIdent = toPrettyChars();
            s->Sclass = SCglobal;
            symbol_func(s);
            func_t *f = s->Sfunc;
            if (isVirtual() && vtblIndex != -1)
                f->Fflags |= Fvirtual;
            else if (isMember2() && isStatic())
                f->Fflags |= Fstatic;
            f->Fstartline.Slinnum = loc.linnum;
            f->Fstartline.Sfilename = (char *)loc.filename;
            if (endloc.linnum)
            {   f->Fendline.Slinnum = endloc.linnum;
                f->Fendline.Sfilename = (char *)endloc.filename;
            }
            else
            {   f->Fendline.Slinnum = loc.linnum;
                f->Fendline.Sfilename = (char *)loc.filename;
            }
            t = type->toCtype();
        }

        mangle_t msave = t->Tmangle;
        if (isMain())
        {
            t->Tty = TYnfunc;
            t->Tmangle = mTYman_c;
        }
        else
        {
            switch (linkage)
            {
                case LINKwindows:
                    t->Tmangle = mTYman_std;
                    break;

                case LINKpascal:
                    t->Tty = TYnpfunc;
                    t->Tmangle = mTYman_pas;
                    break;

                case LINKc:
                    t->Tmangle = mTYman_c;
                    break;

                case LINKd:
                    t->Tmangle = mTYman_d;
                    break;

                case LINKcpp:
                {   t->Tmangle = mTYman_cpp;
                    if (isThis() && !global.params.is64bit && global.params.isWindows)
                        t->Tty = TYmfunc;
                    s->Sflags |= SFLpublic;
                    Dsymbol *parent = toParent();
                    ClassDeclaration *cd = parent->isClassDeclaration();
                    if (cd)
                    {
                        ::type *tc = cd->type->toCtype();
                        s->Sscope = tc->Tnext->Ttag;
                    }
                    StructDeclaration *sd = parent->isStructDeclaration();
                    if (sd)
                    {
                        ::type *ts = sd->type->toCtype();
                        s->Sscope = ts->Ttag;
                    }
                    break;
                }
                default:
                    printf("linkage = %d\n", linkage);
                    assert(0);
            }
        }
        if (msave)
            assert(msave == t->Tmangle);
        //printf("Tty = %x, mangle = x%x\n", t->Tty, t->Tmangle);
        t->Tcount++;
        s->Stype = t;
        //s->Sfielddef = this;

        csym = s;
    }
    return csym;
}