示例#1
0
文件: opover.c 项目: odis-project/ldc
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
    }
}
示例#2
0
文件: opover.c 项目: 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;
}