Example #1
0
File: clone.c Project: Zshazz/dmd
FuncDeclaration *hasIdentityOpAssign(AggregateDeclaration *ad, Scope *sc)
{
    Dsymbol *assign = search_function(ad, Id::assign);
    if (assign)
    {
        /* check identity opAssign exists
         */
        Expression *er = new NullExp(ad->loc, ad->type);    // dummy rvalue
        Expression *el = new IdentifierExp(ad->loc, Id::p); // dummy lvalue
        el->type = ad->type;
        Expressions *a = new Expressions();
        a->setDim(1);
        FuncDeclaration *f = NULL;

        unsigned errors = global.startGagging();    // Do not report errors, even if the
        unsigned oldspec = global.speculativeGag;   // template opAssign fbody makes it.
        global.speculativeGag = global.gag;
        sc = sc->push();
        sc->speculative = true;

        for (size_t i = 0; i < 2; i++)
        {
            (*a)[0] = (i == 0 ? er : el);
            f = resolveFuncCall(ad->loc, sc, assign, NULL, ad->type, a, 1);
            if (f)
                break;
        }

        sc = sc->pop();
        global.speculativeGag = oldspec;
        global.endGagging(errors);

        if (f)
        {
            if (f->errors)
                return NULL;
            int varargs;
            Parameters *fparams = f->getParameters(&varargs);
            if (fparams->dim >= 1)
            {
                Parameter *arg0 = Parameter::getNth(fparams, 0);
                if (arg0->type->toDsymbol(NULL) != ad)
                    f = NULL;
            }
        }
        // BUGS: This detection mechanism cannot find some opAssign-s like follows:
        // struct S { void opAssign(ref immutable S) const; }
        return f;
    }
    return NULL;
}
Example #2
0
File: clone.c Project: Ingrater/dmd
FuncDeclaration *AggregateDeclaration::hasIdentityOpAssign(Scope *sc, Dsymbol *assign)
{
    if (assign)
    {
        /* check identity opAssign exists
         */
        Expression *er = new NullExp(loc, type);        // dummy rvalue
        Expression *el = new IdentifierExp(loc, Id::p); // dummy lvalue
        el->type = type;
        Expressions ar;  ar.push(er);
        Expressions al;  al.push(el);
        FuncDeclaration *f = NULL;

        unsigned errors = global.startGagging();    // Do not report errors, even if the
        unsigned oldspec = global.speculativeGag;   // template opAssign fbody makes it.
        global.speculativeGag = global.gag;
        sc = sc->push();
        sc->speculative = true;

                 f = resolveFuncCall(loc, sc, assign, NULL, er, &ar, 1);
        if (!f)  f = resolveFuncCall(loc, sc, assign, NULL, er, &al, 1);

        sc = sc->pop();
        global.speculativeGag = oldspec;
        global.endGagging(errors);

        if (f)
        {
            int varargs;
            Parameters *fparams = f->getParameters(&varargs);
            if (fparams->dim >= 1)
            {
                Parameter *arg0 = Parameter::getNth(fparams, 0);
                if (arg0->type->toDsymbol(NULL) != this)
                    f = NULL;
            }
        }
        // BUGS: This detection mechanism cannot find some opAssign-s like follows:
        // struct S { void opAssign(ref immutable S) const; }
        return f;
    }
    return NULL;
}