Esempio n. 1
0
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
    if (global.params.is64bit)
        verifyStructSize(Type::typeinfostruct, 17 * Target::ptrsize);
    else
        verifyStructSize(Type::typeinfostruct, 15 * Target::ptrsize);

    dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0); // vtbl for TypeInfo_Struct
    dtsize_t(pdt, 0);                        // monitor

    assert(tinfo->ty == Tstruct);

    TypeStruct *tc = (TypeStruct *)tinfo;
    StructDeclaration *sd = tc->sym;

    if (!sd->members)
        return;

    /* Put out:
     *  char[] name;
     *  void[] init;
     *  hash_t function(in void*) xtoHash;
     *  bool function(in void*, in void*) xopEquals;
     *  int function(in void*, in void*) xopCmp;
     *  string function(const(void)*) xtoString;
     *  StructFlags m_flags;
     *  //xgetMembers;
     *  xdtor;
     *  xpostblit;
     *  uint m_align;
     *  version (X86_64)
     *      TypeInfo m_arg1;
     *      TypeInfo m_arg2;
     *  xgetRTInfo
     */

    const char *name = sd->toPrettyChars();
    size_t namelen = strlen(name);
    dtsize_t(pdt, namelen);
    dtabytes(pdt, 0, namelen + 1, name);

    // void[] init;
    dtsize_t(pdt, sd->structsize);       // init.length
    if (sd->zeroInit)
        dtsize_t(pdt, 0);                // NULL for 0 initialization
    else
        dtxoff(pdt, sd->toInitializer(), 0);    // init.ptr

    if (FuncDeclaration *fd = search_toHash(sd))
    {
        dtxoff(pdt, fd->toSymbol(), 0);
        TypeFunction *tf = (TypeFunction *)fd->type;
        assert(tf->ty == Tfunction);
        /* I'm a little unsure this is the right way to do it. Perhaps a better
         * way would to automatically add these attributes to any struct member
         * function with the name "toHash".
         * So I'm leaving this here as an experiment for the moment.
         */
        if (!tf->isnothrow || tf->trust == TRUSTsystem /*|| tf->purity == PUREimpure*/)
            warning(fd->loc, "toHash() must be declared as extern (D) size_t toHash() const nothrow @safe, not %s", tf->toChars());
    }
    else
        dtsize_t(pdt, 0);

    if (sd->xeq)
        dtxoff(pdt, sd->xeq->toSymbol(), 0);
    else
        dtsize_t(pdt, 0);

    if (sd->xcmp)
        dtxoff(pdt, sd->xcmp->toSymbol(), 0);
    else
        dtsize_t(pdt, 0);

    if (FuncDeclaration *fd = search_toString(sd))
    {
        dtxoff(pdt, fd->toSymbol(), 0);
    }
    else
        dtsize_t(pdt, 0);

    // StructFlags m_flags;
    StructFlags::Type m_flags = 0;
    if (tc->hasPointers()) m_flags |= StructFlags::hasPointers;
    dtsize_t(pdt, m_flags);

#if DMDV2
#if 0
    // xgetMembers
    FuncDeclaration *sgetmembers = sd->findGetMembers();
    if (sgetmembers)
        dtxoff(pdt, sgetmembers->toSymbol(), 0);
    else
        dtsize_t(pdt, 0);                        // xgetMembers
#endif

    // xdtor
    FuncDeclaration *sdtor = sd->dtor;
    if (sdtor)
        dtxoff(pdt, sdtor->toSymbol(), 0);
    else
        dtsize_t(pdt, 0);                        // xdtor

    // xpostblit
    FuncDeclaration *spostblit = sd->postblit;
    if (spostblit && !(spostblit->storage_class & STCdisable))
        dtxoff(pdt, spostblit->toSymbol(), 0);
    else
        dtsize_t(pdt, 0);                        // xpostblit
#endif

    // uint m_align;
    dtsize_t(pdt, tc->alignsize());

    if (global.params.is64bit)
    {
        Type *t = sd->arg1type;
        for (int i = 0; i < 2; i++)
        {
            // m_argi
            if (t)
            {
                t->getTypeInfo(NULL);
                dtxoff(pdt, t->vtinfo->toSymbol(), 0);
            }
            else
                dtsize_t(pdt, 0);

            t = sd->arg2type;
        }
    }

    // xgetRTInfo
    if (sd->getRTInfo)
        sd->getRTInfo->toDt(pdt);
    else if (m_flags & StructFlags::hasPointers)
        dtsize_t(pdt, 1);
    else
        dtsize_t(pdt, 0);
}
Esempio n. 2
0
Expression *Type::getTypeInfo(Scope *sc)
{
    //printf("Type::getTypeInfo() %p, %s\n", this, toChars());
    if (!Type::dtypeinfo)
    {
        error(Loc(), "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch");
        fatal();
    }

    Type *t = merge2(); // do this since not all Type's are merge'd
    if (!t->vtinfo)
    {
#if DMDV2
        if (t->isShared())      // does both 'shared' and 'shared const'
            t->vtinfo = new TypeInfoSharedDeclaration(t);
        else if (t->isConst())
            t->vtinfo = new TypeInfoConstDeclaration(t);
        else if (t->isImmutable())
            t->vtinfo = new TypeInfoInvariantDeclaration(t);
        else if (t->isWild())
            t->vtinfo = new TypeInfoWildDeclaration(t);
        else
#endif
            t->vtinfo = t->getTypeInfoDeclaration();
        assert(t->vtinfo);
        vtinfo = t->vtinfo;

        /* If this has a custom implementation in std/typeinfo, then
         * do not generate a COMDAT for it.
         */
        if (!t->builtinTypeInfo())
        {
            // Generate COMDAT
            if (sc)                     // if in semantic() pass
            {
                // Find module that will go all the way to an object file
                Module *m = sc->module->importedFrom;
                m->members->push(t->vtinfo);

                if (ty == Tstruct)
                {
                    Dsymbol *s;
                    StructDeclaration *sd = ((TypeStruct *)this)->sym;
                    if ((sd->xeq  && sd->xeq  != sd->xerreq  ||
                         sd->xcmp && sd->xcmp != sd->xerrcmp ||
                         search_toHash(sd) ||
                         search_toString(sd)
                        ) && inNonRoot(sd))
                    {
                        //printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), inNonRoot(sd));
                        Module::addDeferredSemantic3(sd);
                    }
                }
            }
            else                        // if in obj generation pass
            {
                t->vtinfo->toObjFile(global.params.multiobj);
            }
        }
    }
    if (!vtinfo)
        vtinfo = t->vtinfo;     // Types aren't merged, but we can share the vtinfo's
    Expression *e = new VarExp(Loc(), t->vtinfo);
    e = e->addressOf(sc);
    e->type = t->vtinfo->type;          // do this so we don't get redundant dereference
    return e;
}
Esempio n. 3
0
void AggregateDeclaration::semantic3(Scope *sc)
{
    //printf("AggregateDeclaration::semantic3(%s)\n", toChars());
    if (members)
    {
        StructDeclaration *sd = isStructDeclaration();
        if (!sc)    // from runDeferredSemantic3 for TypeInfo generation
            goto Lxop;

        sc = sc->push(this);
        sc->parent = this;
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            s->semantic3(sc);
        }
        sc = sc->pop();

        if (!getRTInfo && Type::rtinfo &&
            (!isDeprecated() || global.params.useDeprecated) && // don't do it for unused deprecated types
            (type && type->ty != Terror)) // or error types
        {
            // Evaluate: RTinfo!type
            Objects *tiargs = new Objects();
            tiargs->push(type);
            TemplateInstance *ti = new TemplateInstance(loc, Type::rtinfo, tiargs);
            ti->semantic(sc);
            ti->semantic2(sc);
            ti->semantic3(sc);
            Dsymbol *s = ti->toAlias();
            Expression *e = new DsymbolExp(Loc(), s, 0);

            Scope *sc2 = ti->tempdecl->scope->startCTFE();
            sc2->instantiatingModule = sc->instantiatingModule ? sc->instantiatingModule : sc->module;
            e = e->semantic(sc2);
            sc2->endCTFE();

            e = e->ctfeInterpret();
            getRTInfo = e;
        }

        if (sd)
        {
        Lxop:
            if (sd->xeq &&
                sd->xeq->scope &&
                sd->xeq->semanticRun < PASSsemantic3done)
            {
                unsigned errors = global.startGagging();
                sd->xeq->semantic3(sd->xeq->scope);
                if (global.endGagging(errors))
                    sd->xeq = sd->xerreq;
            }

            if (sd->xcmp &&
                sd->xcmp->scope &&
                sd->xcmp->semanticRun < PASSsemantic3done)
            {
                unsigned errors = global.startGagging();
                sd->xcmp->semantic3(sd->xcmp->scope);
                if (global.endGagging(errors))
                    sd->xcmp = sd->xerrcmp;
            }

            FuncDeclaration *ftostr = search_toString(sd);
            if (ftostr &&
                ftostr->scope &&
                ftostr->semanticRun < PASSsemantic3done)
            {
                ftostr->semantic3(ftostr->scope);
            }

            FuncDeclaration *ftohash = search_toHash(sd);
            if (ftohash &&
                ftohash->scope &&
                ftohash->semanticRun < PASSsemantic3done)
            {
                ftohash->semantic3(ftohash->scope);
            }
        }
    }
}
Esempio n. 4
0
File: typinf.c Progetto: rainers/dmd
TypeInfoDeclaration *Type::buildTypeInfo(Scope *sc, bool checkNeedSemantic)
{
    if (vtinfo)
        return vtinfo;
    if (sc && checkNeedSemantic && !typeInfoNeedsSemantic())
        return 0;

    //printf("Type::getTypeInfo() %p, %s\n", this, toChars());
    if (!Type::dtypeinfo)
    {
        error(Loc(), "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch");
        fatal();
    }

    Type *t = merge2(); // do this since not all Type's are merge'd
    if (!t->vtinfo)
    {
        if (t->isShared())      // does both 'shared' and 'shared const'
            t->vtinfo = new TypeInfoSharedDeclaration(t);
        else if (t->isConst())
            t->vtinfo = new TypeInfoConstDeclaration(t);
        else if (t->isImmutable())
            t->vtinfo = new TypeInfoInvariantDeclaration(t);
        else if (t->isWild())
            t->vtinfo = new TypeInfoWildDeclaration(t);
        else
            t->vtinfo = t->getTypeInfoDeclaration();
        assert(t->vtinfo);
        vtinfo = t->vtinfo;

        /* If this has a custom implementation in std/typeinfo, then
         * do not generate a COMDAT for it.
         */
        if (t->ty == Terror)
            vtinfo->errors = 1;
        else if (!t->builtinTypeInfo())
        {
            // Generate COMDAT
            if (sc)                     // if in semantic() pass
            {
                // Find module that will go all the way to an object file
                Module *m = sc->module->importedFrom;
                m->members->push(t->vtinfo);
                if(m->semanticRun >= 3)
                {
                    Module::addDeferredSemantic3(t->vtinfo);
                    t->vtinfo->deferredScope = sc;
                    sc->setNoFree();
                }
                if (ty == Tstruct)
                {
                    Dsymbol *s;
                    StructDeclaration *sd = ((TypeStruct *)this)->sym;
                    if (sd->members &&
                        (sd->xeq  && sd->xeq  != sd->xerreq  ||
                         sd->xcmp && sd->xcmp != sd->xerrcmp ||
                         search_toHash(sd) ||
                         search_toString(sd)
                        ) && inNonRoot(sd))
                    {
                        //printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), inNonRoot(sd));
                        Module::addDeferredSemantic3(sd);
                    }
                }
            }
            else                        // if in obj generation pass
            {
                // it is always a problem if this is called from the backend without
                //  being added to the AST for semantic analysis (no RTInfo generated)
                // to ease transition, modifier types are just put out as they just forward
                //  to the actual TypeInfo
                if (t->typeInfoNeedsSemantic())
                    error(Loc(), "ICE: unexpected type info request for %s", t->toChars());
                t->vtinfo->toObjFile(global.params.multiobj);
            }
        }
    }
    if (!vtinfo)
        vtinfo = t->vtinfo;     // Types aren't merged, but we can share the vtinfo's
    return vtinfo;
}
Esempio n. 5
0
File: struct.c Progetto: rainers/dmd
void AggregateDeclaration::semantic3(Scope *sc)
{
    //printf("AggregateDeclaration::semantic3(%s)\n", toChars());
    if (members)
    {
        StructDeclaration *sd = isStructDeclaration();
        if (!sc)    // from runDeferredSemantic3 for TypeInfo generation
            goto Lxop;

        sc = sc->push(this);
        sc->parent = this;
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            s->semantic3(sc);
        }
        sc = sc->pop();

        type->buildTypeInfo(sc, false); // implicitely calls generateTypeInfoData
        if (type->vtinfo && type->builtinTypeInfo())
            type->vtinfo->semantic3(sc);

        if (sd)
        {
        Lxop:
            if (sd->xeq &&
                sd->xeq->scope &&
                sd->xeq->semanticRun < PASSsemantic3done)
            {
                unsigned errors = global.startGagging();
                sd->xeq->semantic3(sd->xeq->scope);
                if (global.endGagging(errors))
                    sd->xeq = sd->xerreq;
            }

            if (sd->xcmp &&
                sd->xcmp->scope &&
                sd->xcmp->semanticRun < PASSsemantic3done)
            {
                unsigned errors = global.startGagging();
                sd->xcmp->semantic3(sd->xcmp->scope);
                if (global.endGagging(errors))
                    sd->xcmp = sd->xerrcmp;
            }

            FuncDeclaration *ftostr = search_toString(sd);
            if (ftostr &&
                ftostr->scope &&
                ftostr->semanticRun < PASSsemantic3done)
            {
                ftostr->semantic3(ftostr->scope);
            }

            FuncDeclaration *ftohash = search_toHash(sd);
            if (ftohash &&
                ftohash->scope &&
                ftohash->semanticRun < PASSsemantic3done)
            {
                ftohash->semantic3(ftohash->scope);
            }
        }
    }
}