Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 616

Show
Ignore:
Timestamp:
08/12/10 06:10:46 (14 years ago)
Author:
walter
Message:

bugzilla 3294 forward reference to inferred return type of function call

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/expression.c

    r615 r616  
    476476        e = new CommaExp(loc, ae, new VarExp(loc, tmp)); 
    477477        e = e->semantic(sc); 
    478478    } 
    479479    return e; 
    480480} 
    481481#endif 
    482482 
    483483/**************************************** 
    484484 * Now that we know the exact type of the function we're calling, 
    485485 * the arguments[] need to be adjusted: 
    486486 *      1. implicitly convert argument to the corresponding parameter type 
    487487 *      2. add default arguments for any missing arguments 
    488488 *      3. do default promotions on arguments corresponding to ... 
    489489 *      4. add hidden _arguments[] argument 
    490490 *      5. call copy constructor for struct value arguments 
    491491 * Returns: 
    492492 *      return type from function 
    493493 */ 
    494494 
    495495Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, 
    496         Expressions *arguments
     496        Expressions *arguments, FuncDeclaration *fd
    497497{ 
    498498    //printf("functionParameters()\n"); 
    499499    assert(arguments); 
    500500    size_t nargs = arguments ? arguments->dim : 0; 
    501501    size_t nparams = Parameter::dim(tf->parameters); 
    502502 
    503503    if (nargs > nparams && tf->varargs == 0) 
    504504        error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars()); 
    505505 
    506506    unsigned n = (nargs > nparams) ? nargs : nparams;   // n = max(nargs, nparams) 
    507507 
    508508    unsigned wildmatch = 0; 
    509509    int done = 0; 
    510510    for (size_t i = 0; i < n; i++) 
    511511    { 
    512512        Expression *arg; 
    513513 
    514514        if (i < nargs) 
    515515            arg = (Expression *)arguments->data[i]; 
    516516        else 
     
    762762                    !se->var->isFuncDeclaration()->isUnique()) 
    763763                    arg->error("function %s is overloaded", arg->toChars()); 
    764764            } 
    765765            arg->rvalue(); 
    766766        } 
    767767        arg = arg->optimize(WANTvalue); 
    768768    L3: 
    769769        arguments->data[i] = (void *) arg; 
    770770        if (done) 
    771771            break; 
    772772    } 
    773773 
    774774    // If D linkage and variadic, add _arguments[] as first argument 
    775775    if (tf->linkage == LINKd && tf->varargs == 1) 
    776776    { 
    777777        assert(arguments->dim >= nparams); 
    778778        Expression *e = createTypeInfoArray(sc, (Expression **)&arguments->data[nparams], 
    779779                arguments->dim - nparams); 
    780780        arguments->insert(0, e); 
    781781    } 
     782 
     783    // If inferring return type, and semantic3() needs to be run if not already run 
     784    if (!tf->next && fd->inferRetType) 
     785        fd->semantic3(fd->scope); 
     786 
    782787    Type *tret = tf->next; 
    783788    if (wildmatch) 
    784789    {   /* Adjust function return type based on wildmatch 
    785790         */ 
    786791        //printf("wildmatch = x%x\n", wildmatch); 
    787792        assert(tret->isWild()); 
    788793        if (wildmatch & MODconst || wildmatch & (wildmatch - 1)) 
    789794            tret = tret->constOf(); 
    790795        else if (wildmatch & MODimmutable) 
    791796            tret = tret->invariantOf(); 
    792797        else 
    793798        {   assert(wildmatch & MODmutable); 
    794799            tret = tret->mutableOf(); 
    795800        } 
    796801    } 
    797802    return tret; 
    798803} 
    799804 
    800805/************************************************** 
    801806 * Write expression out to buf, but wrap it 
     
    38193824        else if (thisexp) 
    38203825        {   error("e.new is only for allocating nested classes"); 
    38213826            goto Lerr; 
    38223827        } 
    38233828 
    38243829        FuncDeclaration *f = NULL; 
    38253830        if (cd->ctor) 
    38263831            f = resolveFuncCall(sc, loc, cd->ctor, NULL, NULL, arguments, 0); 
    38273832        if (f) 
    38283833        { 
    38293834            checkDeprecated(sc, f); 
    38303835            member = f->isCtorDeclaration(); 
    38313836            assert(member); 
    38323837 
    38333838            cd->accessCheck(loc, sc, member); 
    38343839 
    38353840            tf = (TypeFunction *)f->type; 
    38363841 
    38373842            if (!arguments) 
    38383843                arguments = new Expressions(); 
    3839             functionParameters(loc, sc, tf, arguments); 
     3844            functionParameters(loc, sc, tf, arguments, f); 
    38403845 
    38413846            type = type->addMod(tf->nextOf()->mod); 
    38423847        } 
    38433848        else 
    38443849        { 
    38453850            if (arguments && arguments->dim) 
    38463851            {   error("no constructor for %s", cd->toChars()); 
    38473852                goto Lerr; 
    38483853            } 
    38493854        } 
    38503855 
    38513856        if (cd->aggNew) 
    38523857        { 
    38533858            // Prepend the size argument to newargs[] 
    38543859            Expression *e = new IntegerExp(loc, cd->size(loc), Type::tsize_t); 
    38553860            if (!newargs) 
    38563861                newargs = new Expressions(); 
    38573862            newargs->shift(e); 
    38583863 
    38593864            f = cd->aggNew->overloadResolve(loc, NULL, newargs); 
    38603865            allocator = f->isNewDeclaration(); 
    38613866            assert(allocator); 
    38623867 
    38633868            tf = (TypeFunction *)f->type; 
    3864             functionParameters(loc, sc, tf, newargs); 
     3869            functionParameters(loc, sc, tf, newargs, f); 
    38653870        } 
    38663871        else 
    38673872        { 
    38683873            if (newargs && newargs->dim) 
    38693874            {   error("no allocator for %s", cd->toChars()); 
    38703875                goto Lerr; 
    38713876            } 
    38723877        } 
    38733878    } 
    38743879    else if (tb->ty == Tstruct) 
    38753880    { 
    38763881        TypeStruct *ts = (TypeStruct *)tb; 
    38773882        StructDeclaration *sd = ts->sym; 
    38783883        TypeFunction *tf; 
    38793884 
    38803885        FuncDeclaration *f = NULL; 
    38813886        if (sd->ctor) 
    38823887            f = resolveFuncCall(sc, loc, sd->ctor, NULL, NULL, arguments, 0); 
    38833888        if (f) 
    38843889        { 
    38853890            checkDeprecated(sc, f); 
    38863891            member = f->isCtorDeclaration(); 
    38873892            assert(member); 
    38883893 
    38893894            sd->accessCheck(loc, sc, member); 
    38903895 
    38913896            tf = (TypeFunction *)f->type; 
    38923897            type = tf->next; 
    38933898 
    38943899            if (!arguments) 
    38953900                arguments = new Expressions(); 
    3896             functionParameters(loc, sc, tf, arguments); 
     3901            functionParameters(loc, sc, tf, arguments, f); 
    38973902        } 
    38983903        else 
    38993904        { 
    39003905            if (arguments && arguments->dim) 
    39013906            {   error("no constructor for %s", sd->toChars()); 
    39023907                goto Lerr; 
    39033908            } 
    39043909        } 
    39053910 
    39063911 
    39073912        if (sd->aggNew) 
    39083913        { 
    39093914            // Prepend the uint size argument to newargs[] 
    39103915            Expression *e = new IntegerExp(loc, sd->size(loc), Type::tuns32); 
    39113916            if (!newargs) 
    39123917                newargs = new Expressions(); 
    39133918            newargs->shift(e); 
    39143919 
    39153920            f = sd->aggNew->overloadResolve(loc, NULL, newargs); 
    39163921            allocator = f->isNewDeclaration(); 
    39173922            assert(allocator); 
    39183923 
    39193924            tf = (TypeFunction *)f->type; 
    3920             functionParameters(loc, sc, tf, newargs); 
     3925            functionParameters(loc, sc, tf, newargs, f); 
    39213926#if 0 
    39223927            e = new VarExp(loc, f); 
    39233928            e = new CallExp(loc, e, newargs); 
    39243929            e = e->semantic(sc); 
    39253930            e->type = type->pointerTo(); 
    39263931            return e; 
    39273932#endif 
    39283933        } 
    39293934        else 
    39303935        { 
    39313936            if (newargs && newargs->dim) 
    39323937            {   error("no allocator for %s", sd->toChars()); 
    39333938                goto Lerr; 
    39343939            } 
    39353940        } 
    39363941 
    39373942        type = type->pointerTo(); 
    39383943    } 
    39393944    else if (tb->ty == Tarray && (arguments && arguments->dim)) 
    39403945    { 
     
    71317136 
    71327137            e1 = new DotVarExp(loc, new ThisExp(loc), f); 
    71337138            goto Lagain; 
    71347139        } 
    71357140 
    71367141        accessCheck(loc, sc, NULL, f); 
    71377142 
    71387143        ve->var = f; 
    71397144//      ve->hasOverloads = 0; 
    71407145        ve->type = f->type; 
    71417146        t1 = f->type; 
    71427147    } 
    71437148    assert(t1->ty == Tfunction); 
    71447149    tf = (TypeFunction *)(t1); 
    71457150 
    71467151Lcheckargs: 
    71477152    assert(tf->ty == Tfunction); 
    71487153 
    71497154    if (!arguments) 
    71507155        arguments = new Expressions(); 
    7151     type = functionParameters(loc, sc, tf, arguments); 
    7152  
    7153     if (!type && f && f->scope) 
    7154     {   f->semantic3(f->scope); 
    7155         type = f->type->nextOf(); 
    7156     } 
     7156    type = functionParameters(loc, sc, tf, arguments, f); 
    71577157 
    71587158    if (!type) 
    71597159    { 
    71607160        error("forward reference to inferred return type of function call %s", toChars()); 
    71617161        return new ErrorExp(); 
    71627162    } 
    71637163 
    71647164    if (f && f->tintro) 
    71657165    { 
    71667166        Type *t = type; 
    71677167        int offset = 0; 
    71687168        TypeFunction *tf = (TypeFunction *)f->tintro; 
    71697169 
    71707170        if (tf->next->isBaseOf(t, &offset) && offset) 
    71717171        { 
    71727172            type = tf->next; 
    71737173            return castTo(sc, t); 
    71747174        } 
    71757175    } 
    71767176 
  • trunk/src/mars.c

    r584 r616  
    7474#else 
    7575#error "fix this" 
    7676#endif 
    7777 
    7878#if TARGET_WINDOS 
    7979    dll_ext  = "dll"; 
    8080#elif TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS 
    8181    dll_ext  = "so"; 
    8282#elif TARGET_OSX 
    8383    dll_ext = "dylib"; 
    8484#else 
    8585#error "fix this" 
    8686#endif 
    8787 
    8888    copyright = "Copyright (c) 1999-2010 by Digital Mars"; 
    8989    written = "written by Walter Bright" 
    9090#if TARGET_NET 
    9191    "\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates."; 
    9292#endif 
    9393    ; 
    94     version = "v2.048"; 
     94    version = "v2.049"; 
    9595    global.structalign = 8; 
    9696 
    9797    memset(&params, 0, sizeof(Param)); 
    9898} 
    9999 
    100100char *Loc::toChars() 
    101101{ 
    102102    OutBuffer buf; 
    103103    char *p; 
    104104 
    105105    if (filename) 
    106106    { 
    107107        buf.printf("%s", filename); 
    108108    } 
    109109 
    110110    if (linnum) 
    111111        buf.printf("(%d)", linnum); 
    112112    buf.writeByte(0); 
    113113    return (char *)buf.extractData(); 
    114114}