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

Changeset 638

Show
Ignore:
Timestamp:
08/28/10 05:49:32 (14 years ago)
Author:
walter
Message:

partial apply of bugzilla 2511 - Covariant return type doesn't work with circular import

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/aggregate.h

    r618 r638  
    220220    ClassInfoDeclaration *vclassinfo;   // the ClassInfo object for this ClassDeclaration 
    221221    int com;                            // !=0 if this is a COM class (meaning 
    222222                                        // it derives from IUnknown) 
    223223    int isauto;                         // !=0 if this is an auto class 
    224224    int isabstract;                     // !=0 if abstract class 
    225225#if DMDV1 
    226226    int isnested;                       // !=0 if is nested 
    227227    VarDeclaration *vthis;              // 'this' parameter if this class is nested 
    228228#endif 
    229229    int inuse;                          // to prevent recursive attempts 
    230230 
    231231    ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 
    232232    Dsymbol *syntaxCopy(Dsymbol *s); 
    233233    void semantic(Scope *sc); 
    234234    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    235235    int isBaseOf2(ClassDeclaration *cd); 
    236236 
    237237    #define OFFSET_RUNTIME 0x76543210 
    238238    virtual int isBaseOf(ClassDeclaration *cd, int *poffset); 
    239239 
     240    virtual int isBaseInfoComplete(); 
    240241    Dsymbol *search(Loc, Identifier *ident, int flags); 
    241242#if DMDV2 
    242243    int isFuncHidden(FuncDeclaration *fd); 
    243244#endif 
    244245    FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 
    245246    void interfaceSemantic(Scope *sc); 
    246247#if DMDV1 
    247248    int isNested(); 
    248249#endif 
    249250    int isCOMclass(); 
    250251    virtual int isCOMinterface(); 
    251252#if DMDV2 
    252253    virtual int isCPPinterface(); 
    253254#endif 
    254255    int isAbstract(); 
    255256    virtual int vtblOffset(); 
    256257    const char *kind(); 
    257258    char *mangle(); 
    258259    void toDocBuffer(OutBuffer *buf); 
    259260 
     
    269270    Symbol *toVtblSymbol(); 
    270271    void toDt(dt_t **pdt); 
    271272    void toDt2(dt_t **pdt, ClassDeclaration *cd); 
    272273 
    273274    Symbol *vtblsym; 
    274275 
    275276    ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } 
    276277}; 
    277278 
    278279struct InterfaceDeclaration : ClassDeclaration 
    279280{ 
    280281#if DMDV2 
    281282    int cpp;                            // !=0 if this is a C++ interface 
    282283#endif 
    283284    InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 
    284285    Dsymbol *syntaxCopy(Dsymbol *s); 
    285286    void semantic(Scope *sc); 
    286287    int isBaseOf(ClassDeclaration *cd, int *poffset); 
    287288    int isBaseOf(BaseClass *bc, int *poffset); 
    288289    const char *kind(); 
     290    int isBaseInfoComplete(); 
    289291    int vtblOffset(); 
    290292#if DMDV2 
    291293    int isCPPinterface(); 
    292294#endif 
    293295    virtual int isCOMinterface(); 
    294296 
    295297    void toObjFile(int multiobj);                       // compile to .obj file 
    296298    Symbol *toSymbol(); 
    297299 
    298300    InterfaceDeclaration *isInterfaceDeclaration() { return this; } 
    299301}; 
    300302 
    301303#endif /* DMD_AGGREGATE_H */ 
  • branches/dmd-1.x/src/class.c

    r520 r638  
    802802    //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); 
    803803    if (poffset) 
    804804        *poffset = 0; 
    805805    while (cd) 
    806806    { 
    807807        if (this == cd->baseClass) 
    808808            return 1; 
    809809 
    810810        /* cd->baseClass might not be set if cd is forward referenced. 
    811811         */ 
    812812        if (!cd->baseClass && cd->baseclasses->dim && !cd->isInterfaceDeclaration()) 
    813813        { 
    814814            cd->error("base class is forward referenced by %s", toChars()); 
    815815        } 
    816816 
    817817        cd = cd->baseClass; 
    818818    } 
    819819    return 0; 
    820820} 
    821821 
     822/********************************************* 
     823 * Determine if 'this' has complete base class information. 
     824 * This is used to detect forward references in covariant overloads. 
     825 */ 
     826 
     827int ClassDeclaration::isBaseInfoComplete() 
     828{ 
     829    if (!baseClass) 
     830        return 0; 
     831    for (int i = 0; i < baseclasses->dim; i++) 
     832    {   BaseClass *b = (BaseClass *)baseclasses->data[i]; 
     833        if (!b->base || !b->base->isBaseInfoComplete()) 
     834            return 0; 
     835    } 
     836    return 1; 
     837} 
     838 
    822839Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) 
    823840{ 
    824841    Dsymbol *s; 
    825842    //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 
    826843 
    827844    if (scope) 
    828845    {   Scope *sc = scope; 
    829846        sc->mustsemantic++; 
    830847        semantic(sc); 
    831848        sc->mustsemantic--; 
    832849    } 
    833850 
    834851    if (!members || !symtab || scope) 
    835852    { 
    836853        error("is forward referenced when looking for '%s'", ident->toChars()); 
    837854        //*(char*)0=0; 
    838855        return NULL; 
    839856    } 
    840857 
    841858    s = ScopeDsymbol::search(loc, ident, flags); 
     
    12931310        if (this == b->base) 
    12941311        { 
    12951312            if (poffset) 
    12961313            {   *poffset = b->offset; 
    12971314                if (j && bc->base->isInterfaceDeclaration()) 
    12981315                    *poffset = OFFSET_RUNTIME; 
    12991316            } 
    13001317            return 1; 
    13011318        } 
    13021319        if (isBaseOf(b, poffset)) 
    13031320        {   if (j && poffset && bc->base->isInterfaceDeclaration()) 
    13041321                *poffset = OFFSET_RUNTIME; 
    13051322            return 1; 
    13061323        } 
    13071324    } 
    13081325    if (poffset) 
    13091326        *poffset = 0; 
    13101327    return 0; 
    13111328} 
    13121329 
     1330/********************************************* 
     1331 * Determine if 'this' has clomplete base class information. 
     1332 * This is used to detect forward references in covariant overloads. 
     1333 */ 
     1334 
     1335int InterfaceDeclaration::isBaseInfoComplete() 
     1336{ 
     1337    assert(!baseClass); 
     1338    for (int i = 0; i < baseclasses->dim; i++) 
     1339    {   BaseClass *b = (BaseClass *)baseclasses->data[i]; 
     1340        if (!b->base || !b->base->isBaseInfoComplete ()) 
     1341            return 0; 
     1342    } 
     1343    return 1; 
     1344} 
     1345 
    13131346/**************************************** 
    13141347 * Determine if slot 0 of the vtbl[] is reserved for something else. 
    13151348 * For class objects, yes, this is where the ClassInfo ptr goes. 
    13161349 * For COM interfaces, no. 
    13171350 * For non-COM interfaces, yes, this is where the Interface ptr goes. 
    13181351 */ 
    13191352 
    13201353int InterfaceDeclaration::vtblOffset() 
    13211354{ 
    13221355    if (isCOMinterface()) 
    13231356        return 0; 
    13241357    return 1; 
    13251358} 
    13261359 
    13271360int InterfaceDeclaration::isCOMinterface() 
    13281361{ 
    13291362    return com; 
    13301363} 
    13311364 
    13321365#if DMDV2 
  • trunk/src/aggregate.h

    r618 r638  
    223223    TypeInfoClassDeclaration *vclassinfo;       // the ClassInfo object for this ClassDeclaration 
    224224    int com;                            // !=0 if this is a COM class (meaning 
    225225                                        // it derives from IUnknown) 
    226226    int isauto;                         // !=0 if this is an auto class 
    227227    int isabstract;                     // !=0 if abstract class 
    228228#if DMDV1 
    229229    int isnested;                       // !=0 if is nested 
    230230    VarDeclaration *vthis;              // 'this' parameter if this class is nested 
    231231#endif 
    232232    int inuse;                          // to prevent recursive attempts 
    233233 
    234234    ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 
    235235    Dsymbol *syntaxCopy(Dsymbol *s); 
    236236    void semantic(Scope *sc); 
    237237    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    238238    int isBaseOf2(ClassDeclaration *cd); 
    239239 
    240240    #define OFFSET_RUNTIME 0x76543210 
    241241    virtual int isBaseOf(ClassDeclaration *cd, int *poffset); 
    242242 
     243    virtual int isBaseInfoComplete(); 
    243244    Dsymbol *search(Loc, Identifier *ident, int flags); 
    244245#if DMDV2 
    245246    int isFuncHidden(FuncDeclaration *fd); 
    246247#endif 
    247248    FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 
    248249    void interfaceSemantic(Scope *sc); 
    249250#if DMDV1 
    250251    int isNested(); 
    251252#endif 
    252253    int isCOMclass(); 
    253254    virtual int isCOMinterface(); 
    254255#if DMDV2 
    255256    virtual int isCPPinterface(); 
    256257#endif 
    257258    int isAbstract(); 
    258259    virtual int vtblOffset(); 
    259260    const char *kind(); 
    260261    char *mangle(); 
    261262    void toDocBuffer(OutBuffer *buf); 
    262263 
     
    272273    Symbol *toVtblSymbol(); 
    273274    void toDt(dt_t **pdt); 
    274275    void toDt2(dt_t **pdt, ClassDeclaration *cd); 
    275276 
    276277    Symbol *vtblsym; 
    277278 
    278279    ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } 
    279280}; 
    280281 
    281282struct InterfaceDeclaration : ClassDeclaration 
    282283{ 
    283284#if DMDV2 
    284285    int cpp;                            // !=0 if this is a C++ interface 
    285286#endif 
    286287    InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 
    287288    Dsymbol *syntaxCopy(Dsymbol *s); 
    288289    void semantic(Scope *sc); 
    289290    int isBaseOf(ClassDeclaration *cd, int *poffset); 
    290291    int isBaseOf(BaseClass *bc, int *poffset); 
    291292    const char *kind(); 
     293    int isBaseInfoComplete(); 
    292294    int vtblOffset(); 
    293295#if DMDV2 
    294296    int isCPPinterface(); 
    295297#endif 
    296298    virtual int isCOMinterface(); 
    297299 
    298300    void toObjFile(int multiobj);                       // compile to .obj file 
    299301    Symbol *toSymbol(); 
    300302 
    301303    InterfaceDeclaration *isInterfaceDeclaration() { return this; } 
    302304}; 
    303305 
    304306#endif /* DMD_AGGREGATE_H */ 
  • trunk/src/class.c

    r520 r638  
    819819    //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); 
    820820    if (poffset) 
    821821        *poffset = 0; 
    822822    while (cd) 
    823823    { 
    824824        if (this == cd->baseClass) 
    825825            return 1; 
    826826 
    827827        /* cd->baseClass might not be set if cd is forward referenced. 
    828828         */ 
    829829        if (!cd->baseClass && cd->baseclasses->dim && !cd->isInterfaceDeclaration()) 
    830830        { 
    831831            cd->error("base class is forward referenced by %s", toChars()); 
    832832        } 
    833833 
    834834        cd = cd->baseClass; 
    835835    } 
    836836    return 0; 
    837837} 
    838838 
     839/********************************************* 
     840 * Determine if 'this' has complete base class information. 
     841 * This is used to detect forward references in covariant overloads. 
     842 */ 
     843 
     844int ClassDeclaration::isBaseInfoComplete() 
     845{ 
     846    if (!baseClass) 
     847        return 0; 
     848    for (int i = 0; i < baseclasses->dim; i++) 
     849    {   BaseClass *b = (BaseClass *)baseclasses->data[i]; 
     850        if (!b->base || !b->base->isBaseInfoComplete()) 
     851            return 0; 
     852    } 
     853    return 1; 
     854} 
     855 
    839856Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) 
    840857{ 
    841858    Dsymbol *s; 
    842859    //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 
    843860 
    844861    if (scope) 
    845862    {   Scope *sc = scope; 
    846863        sc->mustsemantic++; 
    847864        semantic(sc); 
    848865        sc->mustsemantic--; 
    849866    } 
    850867 
    851868    if (!members || !symtab || scope) 
    852869    { 
    853870        error("is forward referenced when looking for '%s'", ident->toChars()); 
    854871        //*(char*)0=0; 
    855872        return NULL; 
    856873    } 
    857874 
    858875    s = ScopeDsymbol::search(loc, ident, flags); 
     
    13381355        if (this == b->base) 
    13391356        { 
    13401357            if (poffset) 
    13411358            {   *poffset = b->offset; 
    13421359                if (j && bc->base->isInterfaceDeclaration()) 
    13431360                    *poffset = OFFSET_RUNTIME; 
    13441361            } 
    13451362            return 1; 
    13461363        } 
    13471364        if (isBaseOf(b, poffset)) 
    13481365        {   if (j && poffset && bc->base->isInterfaceDeclaration()) 
    13491366                *poffset = OFFSET_RUNTIME; 
    13501367            return 1; 
    13511368        } 
    13521369    } 
    13531370    if (poffset) 
    13541371        *poffset = 0; 
    13551372    return 0; 
    13561373} 
    13571374 
     1375/********************************************* 
     1376 * Determine if 'this' has clomplete base class information. 
     1377 * This is used to detect forward references in covariant overloads. 
     1378 */ 
     1379 
     1380int InterfaceDeclaration::isBaseInfoComplete() 
     1381{ 
     1382    assert(!baseClass); 
     1383    for (int i = 0; i < baseclasses->dim; i++) 
     1384    {   BaseClass *b = (BaseClass *)baseclasses->data[i]; 
     1385        if (!b->base || !b->base->isBaseInfoComplete ()) 
     1386            return 0; 
     1387    } 
     1388    return 1; 
     1389} 
     1390 
    13581391/**************************************** 
    13591392 * Determine if slot 0 of the vtbl[] is reserved for something else. 
    13601393 * For class objects, yes, this is where the ClassInfo ptr goes. 
    13611394 * For COM interfaces, no. 
    13621395 * For non-COM interfaces, yes, this is where the Interface ptr goes. 
    13631396 */ 
    13641397 
    13651398int InterfaceDeclaration::vtblOffset() 
    13661399{ 
    13671400    if (isCOMinterface() || isCPPinterface()) 
    13681401        return 0; 
    13691402    return 1; 
    13701403} 
    13711404 
    13721405int InterfaceDeclaration::isCOMinterface() 
    13731406{ 
    13741407    return com; 
    13751408} 
    13761409 
    13771410#if DMDV2 
  • trunk/src/mtype.c

    r619 r638  
    45234523    Type *t1n = t1->next; 
    45244524    Type *t2n = t2->next; 
    45254525 
    45264526    if (!t1n || !t2n)           // happens with return type inference 
    45274527        goto Lnotcovariant; 
    45284528 
    45294529    if (t1n->equals(t2n)) 
    45304530        goto Lcovariant; 
    45314531    if (t1n->ty == Tclass && t2n->ty == Tclass) 
    45324532    { 
    45334533        /* If same class type, but t2n is const, then it's 
    45344534         * covariant. Do this test first because it can work on 
    45354535         * forward references. 
    45364536         */ 
    45374537        if (((TypeClass *)t1n)->sym == ((TypeClass *)t2n)->sym && 
    45384538            MODimplicitConv(t1n->mod, t2n->mod)) 
    45394539            goto Lcovariant; 
    45404540 
    45414541        // If t1n is forward referenced: 
    45424542        ClassDeclaration *cd = ((TypeClass *)t1n)->sym; 
     4543#if 1 
    45434544        if (!cd->baseClass && cd->baseclasses->dim && !cd->isInterfaceDeclaration()) 
    4544         { 
    4545             return 3; 
     4545#else 
     4546        if (!cd->isBaseInfoComplete()) 
     4547#endif 
     4548        { 
     4549            return 3;   // forward references 
    45464550        } 
    45474551    } 
    45484552    if (t1n->implicitConvTo(t2n)) 
    45494553        goto Lcovariant; 
    45504554  } 
    45514555    goto Lnotcovariant; 
    45524556 
    45534557Lcovariant: 
    45544558    /* Can convert mutable to const 
    45554559     */ 
    45564560    if (!MODimplicitConv(t2->mod, t1->mod)) 
    45574561        goto Lnotcovariant; 
    45584562#if 0 
    45594563    if (t1->mod != t2->mod) 
    45604564    { 
    45614565        if (!(t1->mod & MODconst) && (t2->mod & MODconst)) 
    45624566            goto Lnotcovariant; 
    45634567        if (!(t1->mod & MODshared) && (t2->mod & MODshared)) 
    45644568            goto Lnotcovariant; 
    45654569    }