Esempio n. 1
0
void inferApplyArgTypesZ(TemplateDeclaration *tstart, Parameters *arguments)
{
    for (TemplateDeclaration *td = tstart; td; td = td->overnext)
    {
        if (!td->scope)
        {
            error("forward reference to template %s", td->toChars());
            return;
        }
        if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration())
        {
            error("is not a function template");
            return;
        }
        if (!td->parameters || td->parameters->dim != 1)
            continue;
        TemplateParameter *tp = td->parameters->tdata()[0];
        TemplateAliasParameter *tap = tp->isTemplateAliasParameter();
        if (!tap || !tap->specType || tap->specType->ty != Tfunction)
            continue;
        TypeFunction *tf = (TypeFunction *)tap->specType;
        if (inferApplyArgTypesY(tf, arguments) == 0)    // found it
            return;
    }
}
Esempio n. 2
0
File: opover.c Progetto: alexrp/dmd
static Dsymbol *inferApplyArgTypesX(Expression *ethis, FuncDeclaration *fstart, Parameters *arguments)
{
    struct Param3
    {
        Parameters *arguments;
        int mod;
        MATCH match;
        FuncDeclaration *fd_best;
        FuncDeclaration *fd_ambig;

        static int fp(void *param, FuncDeclaration *f)
        {
            Param3 *p = (Param3 *)param;
            TypeFunction *tf = (TypeFunction *)f->type;
            MATCH m = MATCHexact;

            if (f->isThis())
            {   if (!MODimplicitConv(p->mod, tf->mod))
                    m = MATCHnomatch;
                else if (p->mod != tf->mod)
                    m = MATCHconst;
            }
            if (!inferApplyArgTypesY(tf, p->arguments, 1))
                m = MATCHnomatch;

            if (m > p->match)
            {   p->fd_best = f;
                p->fd_ambig = NULL;
                p->match = m;
            }
            else if (m == p->match)
                p->fd_ambig = f;
            return 0;
        }
    };

    Param3 p;
    p.arguments = arguments;
    p.mod = ethis->type->mod;
    p.match = MATCHnomatch;
    p.fd_best = NULL;
    p.fd_ambig = NULL;
    overloadApply(fstart, &Param3::fp, &p);
    if (p.fd_best)
    {
        inferApplyArgTypesY((TypeFunction *)p.fd_best->type, arguments);
        if (p.fd_ambig)
        {   ::error(ethis->loc, "%s.%s matches more than one declaration:\n\t%s(%d):%s\nand:\n\t%s(%d):%s",
                    ethis->toChars(), fstart->ident->toChars(),
                    p.fd_best ->loc.filename, p.fd_best ->loc.linnum, p.fd_best ->type->toChars(),
                    p.fd_ambig->loc.filename, p.fd_ambig->loc.linnum, p.fd_ambig->type->toChars());
            p.fd_best = NULL;
        }
    }
    return p.fd_best;
}
Esempio n. 3
0
int fp3(void *param, FuncDeclaration *f)
{
    Parameters *arguments = (Parameters *)param;
    TypeFunction *tf = (TypeFunction *)f->type;
    if (inferApplyArgTypesY(tf, arguments) == 1)
        return 0;
    if (arguments->dim == 0)
        return 1;
    return 0;
}
Esempio n. 4
0
File: opover.c Progetto: alexrp/dmd
        static int fp(void *param, FuncDeclaration *f)
        {
            Param3 *p = (Param3 *)param;
            TypeFunction *tf = (TypeFunction *)f->type;
            MATCH m = MATCHexact;

            if (f->isThis())
            {   if (!MODimplicitConv(p->mod, tf->mod))
                    m = MATCHnomatch;
                else if (p->mod != tf->mod)
                    m = MATCHconst;
            }
            if (!inferApplyArgTypesY(tf, p->arguments, 1))
                m = MATCHnomatch;

            if (m > p->match)
            {   p->fd_best = f;
                p->fd_ambig = NULL;
                p->match = m;
            }
            else if (m == p->match)
                p->fd_ambig = f;
            return 0;
        }
Esempio n. 5
0
void inferApplyArgTypes(enum TOK op, Parameters *arguments, Expression *aggr, Module* from)
{
    if (!arguments || !arguments->dim)
        return;

    /* Return if no arguments need types.
     */
    for (size_t u = 0; 1; u++)
    {   if (u == arguments->dim)
            return;
        Parameter *arg = arguments->tdata()[u];
        if (!arg->type)
            break;
    }

    Dsymbol *s;
    AggregateDeclaration *ad;

    Parameter *arg = arguments->tdata()[0];
    Type *taggr = aggr->type;
    if (!taggr)
        return;
    Type *tab = taggr->toBasetype();
    switch (tab->ty)
    {
        case Tarray:
        case Tsarray:
        case Ttuple:
            if (arguments->dim == 2)
            {
                if (!arg->type)
                    arg->type = Type::tsize_t;  // key type
                arg = arguments->tdata()[1];
            }
            if (!arg->type && tab->ty != Ttuple)
                arg->type = tab->nextOf();      // value type
            break;

        case Taarray:
        {   TypeAArray *taa = (TypeAArray *)tab;

            if (arguments->dim == 2)
            {
                if (!arg->type)
                    arg->type = taa->index;     // key type
                arg = arguments->tdata()[1];
            }
            if (!arg->type)
                arg->type = taa->next;          // value type
            break;
        }

        case Tclass:
            ad = ((TypeClass *)tab)->sym;
            goto Laggr;

        case Tstruct:
            ad = ((TypeStruct *)tab)->sym;
            goto Laggr;

        Laggr:
            s = search_function(ad,
                        (op == TOKforeach_reverse) ? Id::applyReverse
                                                   : Id::apply);
            if (s)
                goto Lapply;                    // prefer opApply

            if (arguments->dim == 1)
            {
                if (!arg->type)
                {
                    /* Look for a head() or rear() overload
                     */
                    Identifier *id = (op == TOKforeach) ? Id::Fhead : Id::Ftoe;
                    Dsymbol *s = search_function(ad, id);
                    FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL;
                    if (!fd)
                    {   if (s && s->isTemplateDeclaration())
                            break;
                        goto Lapply;
                    }
                    arg->type = fd->type->nextOf();
                }
                break;
            }

        Lapply:
        {   /* Look for an
             *  int opApply(int delegate(ref Type [, ...]) dg);
             * overload
             */
            if (s)
            {
                FuncDeclaration *fd = s->isFuncDeclaration();
                if (fd)
		{   inferApplyArgTypesX(from, fd, arguments);
                    break;
                }
#if 0
                TemplateDeclaration *td = s->isTemplateDeclaration();
                if (td)
                {   inferApplyArgTypesZ(td, arguments);
                    break;
                }
#endif
            }
            break;
        }

        case Tdelegate:
        {
            if (0 && aggr->op == TOKdelegate)
            {   DelegateExp *de = (DelegateExp *)aggr;

                FuncDeclaration *fd = de->func->isFuncDeclaration();
                if (fd)
		    inferApplyArgTypesX(from, fd, arguments);
            }
            else
            {
                inferApplyArgTypesY((TypeFunction *)tab->nextOf(), arguments);
            }
            break;
        }

        default:
            break;              // ignore error, caught later
    }
}
Esempio n. 6
0
File: opover.c Progetto: alexrp/dmd
int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
{
    if (!arguments || !arguments->dim)
        return 0;

    if (sapply)     // prefer opApply
    {
        for (size_t u = 0; u < arguments->dim; u++)
        {   Parameter *arg = (*arguments)[u];
            if (arg->type)
            {
                arg->type = arg->type->semantic(loc, sc);
                arg->type = arg->type->addStorageClass(arg->storageClass);
            }
        }

        Expression *ethis;
        Type *tab = aggr->type->toBasetype();
        if (tab->ty == Tclass || tab->ty == Tstruct)
            ethis = aggr;
        else
        {   assert(tab->ty == Tdelegate && aggr->op == TOKdelegate);
            ethis = ((DelegateExp *)aggr)->e1;
        }

        /* Look for like an
         *  int opApply(int delegate(ref Type [, ...]) dg);
         * overload
         */
        FuncDeclaration *fd = sapply->isFuncDeclaration();
        if (fd)
        {   sapply = inferApplyArgTypesX(ethis, fd, arguments);
        }
#if 0
        TemplateDeclaration *td = sapply->isTemplateDeclaration();
        if (td)
        {   inferApplyArgTypesZ(td, arguments);
        }
#endif
        return sapply ? 1 : 0;
    }

    /* Return if no arguments need types.
     */
    for (size_t u = 0; u < arguments->dim; u++)
    {   Parameter *arg = (*arguments)[u];
        if (!arg->type)
            break;
    }

    AggregateDeclaration *ad;

    Parameter *arg = (*arguments)[0];
    Type *taggr = aggr->type;
    assert(taggr);
    Type *tab = taggr->toBasetype();
    switch (tab->ty)
    {
        case Tarray:
        case Tsarray:
        case Ttuple:
            if (arguments->dim == 2)
            {
                if (!arg->type)
                {
                    arg->type = Type::tsize_t;  // key type
                    arg->type = arg->type->addStorageClass(arg->storageClass);
                }
                arg = (*arguments)[1];
            }
            if (!arg->type && tab->ty != Ttuple)
            {
                arg->type = tab->nextOf();      // value type
                arg->type = arg->type->addStorageClass(arg->storageClass);
            }
            break;

        case Taarray:
        {   TypeAArray *taa = (TypeAArray *)tab;

            if (arguments->dim == 2)
            {
                if (!arg->type)
                {
                    arg->type = taa->index;     // key type
                    arg->type = arg->type->addStorageClass(arg->storageClass);
                }
                arg = (*arguments)[1];
            }
            if (!arg->type)
            {
                arg->type = taa->next;          // value type
                arg->type = arg->type->addStorageClass(arg->storageClass);
            }
            break;
        }

        case Tclass:
            ad = ((TypeClass *)tab)->sym;
            goto Laggr;

        case Tstruct:
            ad = ((TypeStruct *)tab)->sym;
            goto Laggr;

        Laggr:
            if (arguments->dim == 1)
            {
                if (!arg->type)
                {
                    /* Look for a front() or back() overload
                     */
                    Identifier *id = (op == TOKforeach) ? Id::Ffront : Id::Fback;
                    Dsymbol *s = ad->search(Loc(), id, 0);
                    FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL;
                    if (fd)
                    {
                        // Resolve inout qualifier of front type
                        arg->type = fd->type->nextOf();
                        if (arg->type)
                        {
                            arg->type = arg->type->substWildTo(tab->mod);
                            arg->type = arg->type->addStorageClass(arg->storageClass);
                        }
                    }
                    else if (s && s->isTemplateDeclaration())
                        ;
                    else if (s && s->isDeclaration())
                        arg->type = ((Declaration *)s)->type;
                    else
                        break;
                }
                break;
            }
            break;

        case Tdelegate:
        {
            if (!inferApplyArgTypesY((TypeFunction *)tab->nextOf(), arguments))
                return 0;
            break;
        }

        default:
            break;              // ignore error, caught later
    }
    return 1;
}