Exemplo n.º 1
0
Arquivo: init.c Projeto: llucenic/GDC
Type *ExpInitializer::inferType(Scope *sc)
{
    //printf("ExpInitializer::inferType() %s\n", toChars());
    exp = exp->semantic(sc);
    exp = resolveProperties(sc, exp);
    if (exp->op == TOKimport)
    {   ScopeExp *se = (ScopeExp *)exp;
        TemplateInstance *ti = se->sds->isTemplateInstance();
        if (ti && ti->semanticRun == PASSsemantic && !ti->aliasdecl)
            se->error("cannot infer type from %s %s, possible circular dependency", se->sds->kind(), se->toChars());
        else
            se->error("cannot infer type from %s %s", se->sds->kind(), se->toChars());
        return Type::terror;
    }

    // Give error for overloaded function addresses
    if (exp->op == TOKsymoff)
    {   SymOffExp *se = (SymOffExp *)exp;
        if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique())
        {
            exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
            return Type::terror;
        }
    }

    // Give error for overloaded function addresses
    if (exp->op == TOKdelegate)
    {   DelegateExp *se = (DelegateExp *)exp;
        if (se->hasOverloads &&
            se->func->isFuncDeclaration() &&
            !se->func->isFuncDeclaration()->isUnique())
        {
            exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
            return Type::terror;
        }
    }

    Type *t = exp->type;
    if (!t)
        t = Initializer::inferType(sc);
    return t;
}
Exemplo n.º 2
0
Initializer *ExpInitializer::inferType(Scope *sc, Type *tx)
{
    //printf("ExpInitializer::inferType() %s\n", toChars());
    exp = ::inferType(exp, tx);
    exp = exp->semantic(sc);
    exp = resolveProperties(sc, exp);

    if (tx)
    {
        Type *tb = tx->toBasetype();
        Type *ti = exp->type->toBasetype();

        // Look for implicit constructor call
        if (tb->ty == Tstruct &&
            !(ti->ty == Tstruct && tb->toDsymbol(sc) == ti->toDsymbol(sc)) &&
            !exp->implicitConvTo(tx))
        {
            StructDeclaration *sd = ((TypeStruct *)tb)->sym;
            if (sd->ctor)
            {
                // Rewrite as S().ctor(exp)
                Expression *e;
                e = new StructLiteralExp(loc, sd, NULL);
                e = new DotIdExp(loc, e, Id::ctor);
                e = new CallExp(loc, e, exp);
                e = e->semantic(sc);
                exp = e->optimize(WANTvalue);
            }
        }
    }

    if (exp->op == TOKimport)
    {
        ScopeExp *se = (ScopeExp *)exp;
        TemplateInstance *ti = se->sds->isTemplateInstance();
        if (ti && ti->semanticRun == PASSsemantic && !ti->aliasdecl)
            se->error("cannot infer type from %s %s, possible circular dependency", se->sds->kind(), se->toChars());
        else
            se->error("cannot infer type from %s %s", se->sds->kind(), se->toChars());
        return new ErrorInitializer();
    }

    // Give error for overloaded function addresses
    if (exp->op == TOKsymoff)
    {
        SymOffExp *se = (SymOffExp *)exp;
        if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique())
        {
            exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
            return new ErrorInitializer();
        }
    }
    if (exp->op == TOKdelegate)
    {
        DelegateExp *se = (DelegateExp *)exp;
        if (se->hasOverloads &&
            se->func->isFuncDeclaration() &&
            !se->func->isFuncDeclaration()->isUnique())
        {
            exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
            return new ErrorInitializer();
        }
    }
    if (exp->op == TOKaddress)
    {
        AddrExp *ae = (AddrExp *)exp;
        if (ae->e1->op == TOKoverloadset)
        {
            exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
            return new ErrorInitializer();
        }
    }

    if (exp->op == TOKerror)
        return new ErrorInitializer();
    if (!exp->type)
        return new ErrorInitializer();
    return this;
}