Ejemplo n.º 1
0
Archivo: import.c Proyecto: jsmdnq/dmd
int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
    int result = 0;

    if (names.dim == 0)
        return Dsymbol::addMember(sc, sd, memnum);

    if (aliasId)
        result = Dsymbol::addMember(sc, sd, memnum);

    /* Instead of adding the import to sd's symbol table,
     * add each of the alias=name pairs
     */
    for (size_t i = 0; i < names.dim; i++)
    {
        Identifier *name = names[i];
        Identifier *alias = aliases[i];

        if (!alias)
            alias = name;

        TypeIdentifier *tname = new TypeIdentifier(loc, name);
        AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname);
        result |= ad->addMember(sc, sd, memnum);

        aliasdecls.push(ad);
    }

    return result;
}
Ejemplo n.º 2
0
int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
    int result = 0;

    if (names.dim == 0)
	return Dsymbol::addMember(sc, sd, memnum);

    if (aliasId)
	result = Dsymbol::addMember(sc, sd, memnum);

    for (size_t i = 0; i < names.dim; i++)
    {
	Identifier *name = (Identifier *)names.data[i];
	Identifier *alias = (Identifier *)aliases.data[i];

	if (!alias)
	    alias = name;

#if 1
	TypeIdentifier *tname = new TypeIdentifier(loc, name);
#else
	TypeIdentifier *tname = new TypeIdentifier(loc, NULL);
	if (packages)
	{
	    for (size_t j = 0; j < packages->dim; j++)
	    {   Identifier *pid = (Identifier *)packages->data[j];

		if (!tname->ident)
		    tname->ident = pid;
		else
		    tname->addIdent(pid);
	    }
	}
	if (!tname->ident)
	    tname->ident = id;
	else
	    tname->addIdent(id);
	tname->addIdent(name);
#endif
	AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname);
	result |= ad->addMember(sc, sd, memnum);

	aliasdecls.push(ad);
    }

    return result;
}
Ejemplo n.º 3
0
Archivo: clone.c Proyecto: nrTQgc/ldc
/*****************************************
 * Create inclusive destructor for struct/class by aggregating
 * all the destructors in dtors[] with the destructors for
 * all the members.
 * Note the close similarity with StructDeclaration::buildPostBlit(),
 * and the ordering changes (runs backward instead of forwards).
 */
FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc)
{
    //printf("AggregateDeclaration::buildDtor() %s\n", ad->toChars());
    StorageClass stc = STCsafe | STCnothrow | STCpure | STCnogc;
    Loc declLoc = ad->dtors.dim ? ad->dtors[0]->loc : ad->loc;
    Loc loc = Loc();    // internal code should have no loc to prevent coverage

    Expression *e = NULL;
    for (size_t i = 0; i < ad->fields.dim; i++)
    {
        VarDeclaration *v = ad->fields[i];
        if (v->storage_class & STCref)
            continue;
        Type *tv = v->type->baseElemOf();
        if (tv->ty != Tstruct || !v->type->size())
            continue;
        StructDeclaration *sdv = ((TypeStruct *)tv)->sym;
        if (!sdv->dtor)
            continue;
        sdv->dtor->functionSemantic();

        stc = mergeFuncAttrs(stc, sdv->dtor);
        if (stc & STCdisable)
        {
            e = NULL;
            break;
        }

        Expression *ex = new ThisExp(loc);
        ex = new DotVarExp(loc, ex, v, 0);
        if (v->type->toBasetype()->ty == Tstruct)
        {
            // this.v.__xdtor()

            // This is a hack so we can call destructors on const/immutable objects.
            ex = new AddrExp(loc, ex);
            ex = new CastExp(loc, ex, v->type->mutableOf()->pointerTo());
            ex = new PtrExp(loc, ex);
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            ex = new DotVarExp(loc, ex, sdv->dtor, 0);
            ex = new CallExp(loc, ex);
        }
        else
        {
            // _ArrayDtor((cast(S*)this.v.ptr)[0 .. n])

            // This is a hack so we can call destructors on const/immutable objects.
            ex = new DotIdExp(loc, ex, Id::ptr);
            ex = new CastExp(loc, ex, sdv->type->pointerTo());
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            uinteger_t n = v->type->size() / sdv->type->size();
            ex = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type::tsize_t),
                                       new IntegerExp(loc, n, Type::tsize_t));
            // Prevent redundant bounds check
            ((SliceExp *)ex)->upperIsInBounds = true;
            ((SliceExp *)ex)->lowerIsLessThanUpper = true;

            ex = new CallExp(loc, new IdentifierExp(loc, Id::_ArrayDtor), ex);
        }
        e = Expression::combine(ex, e); // combine in reverse order
    }

    /* Build our own "destructor" which executes e
     */
    if (e || (stc & STCdisable))
    {
        //printf("Building __fieldDtor()\n");
        DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Id::__fieldDtor);
        dd->storage_class |= STCinference;
        dd->fbody = new ExpStatement(loc, e);
        ad->dtors.shift(dd);
        ad->members->push(dd);
        dd->semantic(sc);
    }

    FuncDeclaration *xdtor = NULL;
    switch (ad->dtors.dim)
    {
        case 0:
            break;

        case 1:
            xdtor = ad->dtors[0];
            break;

        default:
            e = NULL;
            stc = STCsafe | STCnothrow | STCpure | STCnogc;
            for (size_t i = 0; i < ad->dtors.dim; i++)
            {
                FuncDeclaration *fd = ad->dtors[i];
                stc = mergeFuncAttrs(stc, fd);
                if (stc & STCdisable)
                {
                    e = NULL;
                    break;
                }
                Expression *ex = new ThisExp(loc);
                ex = new DotVarExp(loc, ex, fd, 0);
                ex = new CallExp(loc, ex);
                e = Expression::combine(ex, e);
            }
            DtorDeclaration *dd = new DtorDeclaration(declLoc, Loc(), stc, Id::__aggrDtor);
            dd->storage_class |= STCinference;
            dd->fbody = new ExpStatement(loc, e);
            ad->members->push(dd);
            dd->semantic(sc);
            xdtor = dd;
            break;
    }
    // Add an __xdtor alias to make the inclusive dtor accessible
    if (xdtor)
    {
        AliasDeclaration *alias = new AliasDeclaration(Loc(), Id::__xdtor, xdtor);
        alias->semantic(sc);
        ad->members->push(alias);
        alias->addMember(sc, ad); // add to symbol table
    }
    return xdtor;
}
Ejemplo n.º 4
0
Archivo: clone.c Proyecto: nrTQgc/ldc
/*****************************************
 * Create inclusive postblit for struct by aggregating
 * all the postblits in postblits[] with the postblits for
 * all the members.
 * Note the close similarity with AggregateDeclaration::buildDtor(),
 * and the ordering changes (runs forward instead of backwards).
 */
FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
{
    //printf("StructDeclaration::buildPostBlit() %s\n", sd->toChars());
    StorageClass stc = STCsafe | STCnothrow | STCpure | STCnogc;
    Loc declLoc = sd->postblits.dim ? sd->postblits[0]->loc : sd->loc;
    Loc loc = Loc();    // internal code should have no loc to prevent coverage

    for (size_t i = 0; i < sd->postblits.dim; i++)
    {
        stc |= sd->postblits[i]->storage_class & STCdisable;
    }

    Statements *a = NULL;
    for (size_t i = 0; i < sd->fields.dim && !(stc & STCdisable); i++)
    {
        VarDeclaration *v = sd->fields[i];
        if (v->storage_class & STCref)
            continue;
        Type *tv = v->type->baseElemOf();
        if (tv->ty != Tstruct || !v->type->size())
            continue;
        StructDeclaration *sdv = ((TypeStruct *)tv)->sym;
        if (!sdv->postblit)
            continue;
        sdv->postblit->functionSemantic();

        stc = mergeFuncAttrs(stc, sdv->postblit);
        stc = mergeFuncAttrs(stc, sdv->dtor);
        if (stc & STCdisable)
        {
            a = NULL;
            break;
        }
        if (!a)
            a = new Statements();

        Expression *ex = new ThisExp(loc);
        ex = new DotVarExp(loc, ex, v, 0);
        if (v->type->toBasetype()->ty == Tstruct)
        {
            // this.v.__xpostblit()

            // This is a hack so we can call postblits on const/immutable objects.
            ex = new AddrExp(loc, ex);
            ex = new CastExp(loc, ex, v->type->mutableOf()->pointerTo());
            ex = new PtrExp(loc, ex);
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            ex = new DotVarExp(loc, ex, sdv->postblit, 0);
            ex = new CallExp(loc, ex);
        }
        else
        {
            // _ArrayPostblit((cast(S*)this.v.ptr)[0 .. n])

            // This is a hack so we can call postblits on const/immutable objects.
            ex = new DotIdExp(loc, ex, Id::ptr);
            ex = new CastExp(loc, ex, sdv->type->pointerTo());
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            uinteger_t n = v->type->size() / sdv->type->size();
            ex = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type::tsize_t),
                                       new IntegerExp(loc, n, Type::tsize_t));
            // Prevent redundant bounds check
            ((SliceExp *)ex)->upperIsInBounds = true;
            ((SliceExp *)ex)->lowerIsLessThanUpper = true;

            ex = new CallExp(loc, new IdentifierExp(loc, Id::_ArrayPostblit), ex);
        }
        a->push(new ExpStatement(loc, ex)); // combine in forward order

        /* Bugzilla 10972: When the following field postblit calls fail,
         * this field should be destructed for Exception Safety.
         */
        if (!sdv->dtor)
            continue;
        sdv->dtor->functionSemantic();

        ex = new ThisExp(loc);
        ex = new DotVarExp(loc, ex, v, 0);
        if (v->type->toBasetype()->ty == Tstruct)
        {
            // this.v.__xdtor()

            // This is a hack so we can call destructors on const/immutable objects.
            ex = new AddrExp(loc, ex);
            ex = new CastExp(loc, ex, v->type->mutableOf()->pointerTo());
            ex = new PtrExp(loc, ex);
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            ex = new DotVarExp(loc, ex, sdv->dtor, 0);
            ex = new CallExp(loc, ex);
        }
        else
        {
            // _ArrayDtor((cast(S*)this.v.ptr)[0 .. n])

            // This is a hack so we can call destructors on const/immutable objects.
            ex = new DotIdExp(loc, ex, Id::ptr);
            ex = new CastExp(loc, ex, sdv->type->pointerTo());
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;

            uinteger_t n = v->type->size() / sdv->type->size();
            ex = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type::tsize_t),
                                       new IntegerExp(loc, n, Type::tsize_t));
            // Prevent redundant bounds check
            ((SliceExp *)ex)->upperIsInBounds = true;
            ((SliceExp *)ex)->lowerIsLessThanUpper = true;

            ex = new CallExp(loc, new IdentifierExp(loc, Id::_ArrayDtor), ex);
        }
        a->push(new OnScopeStatement(loc, TOKon_scope_failure, new ExpStatement(loc, ex)));
    }

    /* Build our own "postblit" which executes a
     */
    if (a || (stc & STCdisable))
    {
        //printf("Building __fieldPostBlit()\n");
        PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Id::__fieldPostblit);
        dd->storage_class |= STCinference;
        dd->fbody = a ? new CompoundStatement(loc, a) : NULL;
        sd->postblits.shift(dd);
        sd->members->push(dd);
        dd->semantic(sc);
    }

    FuncDeclaration *xpostblit = NULL;
    switch (sd->postblits.dim)
    {
        case 0:
            break;

        case 1:
            xpostblit = sd->postblits[0];
            break;

        default:
            Expression *e = NULL;
            stc = STCsafe | STCnothrow | STCpure | STCnogc;
            for (size_t i = 0; i < sd->postblits.dim; i++)
            {
                FuncDeclaration *fd = sd->postblits[i];
                stc = mergeFuncAttrs(stc, fd);
                if (stc & STCdisable)
                {
                    e = NULL;
                    break;
                }
                Expression *ex = new ThisExp(loc);
                ex = new DotVarExp(loc, ex, fd, 0);
                ex = new CallExp(loc, ex);
                e = Expression::combine(e, ex);
            }
            PostBlitDeclaration *dd = new PostBlitDeclaration(declLoc, Loc(), stc, Id::__aggrPostblit);
            dd->storage_class |= STCinference;
            dd->fbody = new ExpStatement(loc, e);
            sd->members->push(dd);
            dd->semantic(sc);
            xpostblit = dd;
            break;
    }
    // Add an __xpostblit alias to make the inclusive postblit accessible
    if (xpostblit)
    {
        AliasDeclaration *alias = new AliasDeclaration(Loc(), Id::__xpostblit, xpostblit);
        alias->semantic(sc);
        sd->members->push(alias);
        alias->addMember(sc, sd); // add to symbol table
    }
    return xpostblit;
}