Changeset 638
- Timestamp:
- 08/28/10 05:49:32 (14 years ago)
- Files:
-
- branches/dmd-1.x/src/aggregate.h (modified) (2 diffs)
- branches/dmd-1.x/src/class.c (modified) (2 diffs)
- trunk/src/aggregate.h (modified) (2 diffs)
- trunk/src/class.c (modified) (2 diffs)
- trunk/src/mtype.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/aggregate.h
r618 r638 220 220 ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration 221 221 int com; // !=0 if this is a COM class (meaning 222 222 // it derives from IUnknown) 223 223 int isauto; // !=0 if this is an auto class 224 224 int isabstract; // !=0 if abstract class 225 225 #if DMDV1 226 226 int isnested; // !=0 if is nested 227 227 VarDeclaration *vthis; // 'this' parameter if this class is nested 228 228 #endif 229 229 int inuse; // to prevent recursive attempts 230 230 231 231 ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 232 232 Dsymbol *syntaxCopy(Dsymbol *s); 233 233 void semantic(Scope *sc); 234 234 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 235 235 int isBaseOf2(ClassDeclaration *cd); 236 236 237 237 #define OFFSET_RUNTIME 0x76543210 238 238 virtual int isBaseOf(ClassDeclaration *cd, int *poffset); 239 239 240 virtual int isBaseInfoComplete(); 240 241 Dsymbol *search(Loc, Identifier *ident, int flags); 241 242 #if DMDV2 242 243 int isFuncHidden(FuncDeclaration *fd); 243 244 #endif 244 245 FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 245 246 void interfaceSemantic(Scope *sc); 246 247 #if DMDV1 247 248 int isNested(); 248 249 #endif 249 250 int isCOMclass(); 250 251 virtual int isCOMinterface(); 251 252 #if DMDV2 252 253 virtual int isCPPinterface(); 253 254 #endif 254 255 int isAbstract(); 255 256 virtual int vtblOffset(); 256 257 const char *kind(); 257 258 char *mangle(); 258 259 void toDocBuffer(OutBuffer *buf); 259 260 … … 269 270 Symbol *toVtblSymbol(); 270 271 void toDt(dt_t **pdt); 271 272 void toDt2(dt_t **pdt, ClassDeclaration *cd); 272 273 273 274 Symbol *vtblsym; 274 275 275 276 ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } 276 277 }; 277 278 278 279 struct InterfaceDeclaration : ClassDeclaration 279 280 { 280 281 #if DMDV2 281 282 int cpp; // !=0 if this is a C++ interface 282 283 #endif 283 284 InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 284 285 Dsymbol *syntaxCopy(Dsymbol *s); 285 286 void semantic(Scope *sc); 286 287 int isBaseOf(ClassDeclaration *cd, int *poffset); 287 288 int isBaseOf(BaseClass *bc, int *poffset); 288 289 const char *kind(); 290 int isBaseInfoComplete(); 289 291 int vtblOffset(); 290 292 #if DMDV2 291 293 int isCPPinterface(); 292 294 #endif 293 295 virtual int isCOMinterface(); 294 296 295 297 void toObjFile(int multiobj); // compile to .obj file 296 298 Symbol *toSymbol(); 297 299 298 300 InterfaceDeclaration *isInterfaceDeclaration() { return this; } 299 301 }; 300 302 301 303 #endif /* DMD_AGGREGATE_H */ branches/dmd-1.x/src/class.c
r520 r638 802 802 //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); 803 803 if (poffset) 804 804 *poffset = 0; 805 805 while (cd) 806 806 { 807 807 if (this == cd->baseClass) 808 808 return 1; 809 809 810 810 /* cd->baseClass might not be set if cd is forward referenced. 811 811 */ 812 812 if (!cd->baseClass && cd->baseclasses->dim && !cd->isInterfaceDeclaration()) 813 813 { 814 814 cd->error("base class is forward referenced by %s", toChars()); 815 815 } 816 816 817 817 cd = cd->baseClass; 818 818 } 819 819 return 0; 820 820 } 821 821 822 /********************************************* 823 * Determine if 'this' has complete base class information. 824 * This is used to detect forward references in covariant overloads. 825 */ 826 827 int 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 822 839 Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) 823 840 { 824 841 Dsymbol *s; 825 842 //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 826 843 827 844 if (scope) 828 845 { Scope *sc = scope; 829 846 sc->mustsemantic++; 830 847 semantic(sc); 831 848 sc->mustsemantic--; 832 849 } 833 850 834 851 if (!members || !symtab || scope) 835 852 { 836 853 error("is forward referenced when looking for '%s'", ident->toChars()); 837 854 //*(char*)0=0; 838 855 return NULL; 839 856 } 840 857 841 858 s = ScopeDsymbol::search(loc, ident, flags); … … 1293 1310 if (this == b->base) 1294 1311 { 1295 1312 if (poffset) 1296 1313 { *poffset = b->offset; 1297 1314 if (j && bc->base->isInterfaceDeclaration()) 1298 1315 *poffset = OFFSET_RUNTIME; 1299 1316 } 1300 1317 return 1; 1301 1318 } 1302 1319 if (isBaseOf(b, poffset)) 1303 1320 { if (j && poffset && bc->base->isInterfaceDeclaration()) 1304 1321 *poffset = OFFSET_RUNTIME; 1305 1322 return 1; 1306 1323 } 1307 1324 } 1308 1325 if (poffset) 1309 1326 *poffset = 0; 1310 1327 return 0; 1311 1328 } 1312 1329 1330 /********************************************* 1331 * Determine if 'this' has clomplete base class information. 1332 * This is used to detect forward references in covariant overloads. 1333 */ 1334 1335 int 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 1313 1346 /**************************************** 1314 1347 * Determine if slot 0 of the vtbl[] is reserved for something else. 1315 1348 * For class objects, yes, this is where the ClassInfo ptr goes. 1316 1349 * For COM interfaces, no. 1317 1350 * For non-COM interfaces, yes, this is where the Interface ptr goes. 1318 1351 */ 1319 1352 1320 1353 int InterfaceDeclaration::vtblOffset() 1321 1354 { 1322 1355 if (isCOMinterface()) 1323 1356 return 0; 1324 1357 return 1; 1325 1358 } 1326 1359 1327 1360 int InterfaceDeclaration::isCOMinterface() 1328 1361 { 1329 1362 return com; 1330 1363 } 1331 1364 1332 1365 #if DMDV2 trunk/src/aggregate.h
r618 r638 223 223 TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration 224 224 int com; // !=0 if this is a COM class (meaning 225 225 // it derives from IUnknown) 226 226 int isauto; // !=0 if this is an auto class 227 227 int isabstract; // !=0 if abstract class 228 228 #if DMDV1 229 229 int isnested; // !=0 if is nested 230 230 VarDeclaration *vthis; // 'this' parameter if this class is nested 231 231 #endif 232 232 int inuse; // to prevent recursive attempts 233 233 234 234 ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 235 235 Dsymbol *syntaxCopy(Dsymbol *s); 236 236 void semantic(Scope *sc); 237 237 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 238 238 int isBaseOf2(ClassDeclaration *cd); 239 239 240 240 #define OFFSET_RUNTIME 0x76543210 241 241 virtual int isBaseOf(ClassDeclaration *cd, int *poffset); 242 242 243 virtual int isBaseInfoComplete(); 243 244 Dsymbol *search(Loc, Identifier *ident, int flags); 244 245 #if DMDV2 245 246 int isFuncHidden(FuncDeclaration *fd); 246 247 #endif 247 248 FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 248 249 void interfaceSemantic(Scope *sc); 249 250 #if DMDV1 250 251 int isNested(); 251 252 #endif 252 253 int isCOMclass(); 253 254 virtual int isCOMinterface(); 254 255 #if DMDV2 255 256 virtual int isCPPinterface(); 256 257 #endif 257 258 int isAbstract(); 258 259 virtual int vtblOffset(); 259 260 const char *kind(); 260 261 char *mangle(); 261 262 void toDocBuffer(OutBuffer *buf); 262 263 … … 272 273 Symbol *toVtblSymbol(); 273 274 void toDt(dt_t **pdt); 274 275 void toDt2(dt_t **pdt, ClassDeclaration *cd); 275 276 276 277 Symbol *vtblsym; 277 278 278 279 ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } 279 280 }; 280 281 281 282 struct InterfaceDeclaration : ClassDeclaration 282 283 { 283 284 #if DMDV2 284 285 int cpp; // !=0 if this is a C++ interface 285 286 #endif 286 287 InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 287 288 Dsymbol *syntaxCopy(Dsymbol *s); 288 289 void semantic(Scope *sc); 289 290 int isBaseOf(ClassDeclaration *cd, int *poffset); 290 291 int isBaseOf(BaseClass *bc, int *poffset); 291 292 const char *kind(); 293 int isBaseInfoComplete(); 292 294 int vtblOffset(); 293 295 #if DMDV2 294 296 int isCPPinterface(); 295 297 #endif 296 298 virtual int isCOMinterface(); 297 299 298 300 void toObjFile(int multiobj); // compile to .obj file 299 301 Symbol *toSymbol(); 300 302 301 303 InterfaceDeclaration *isInterfaceDeclaration() { return this; } 302 304 }; 303 305 304 306 #endif /* DMD_AGGREGATE_H */ trunk/src/class.c
r520 r638 819 819 //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); 820 820 if (poffset) 821 821 *poffset = 0; 822 822 while (cd) 823 823 { 824 824 if (this == cd->baseClass) 825 825 return 1; 826 826 827 827 /* cd->baseClass might not be set if cd is forward referenced. 828 828 */ 829 829 if (!cd->baseClass && cd->baseclasses->dim && !cd->isInterfaceDeclaration()) 830 830 { 831 831 cd->error("base class is forward referenced by %s", toChars()); 832 832 } 833 833 834 834 cd = cd->baseClass; 835 835 } 836 836 return 0; 837 837 } 838 838 839 /********************************************* 840 * Determine if 'this' has complete base class information. 841 * This is used to detect forward references in covariant overloads. 842 */ 843 844 int 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 839 856 Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) 840 857 { 841 858 Dsymbol *s; 842 859 //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 843 860 844 861 if (scope) 845 862 { Scope *sc = scope; 846 863 sc->mustsemantic++; 847 864 semantic(sc); 848 865 sc->mustsemantic--; 849 866 } 850 867 851 868 if (!members || !symtab || scope) 852 869 { 853 870 error("is forward referenced when looking for '%s'", ident->toChars()); 854 871 //*(char*)0=0; 855 872 return NULL; 856 873 } 857 874 858 875 s = ScopeDsymbol::search(loc, ident, flags); … … 1338 1355 if (this == b->base) 1339 1356 { 1340 1357 if (poffset) 1341 1358 { *poffset = b->offset; 1342 1359 if (j && bc->base->isInterfaceDeclaration()) 1343 1360 *poffset = OFFSET_RUNTIME; 1344 1361 } 1345 1362 return 1; 1346 1363 } 1347 1364 if (isBaseOf(b, poffset)) 1348 1365 { if (j && poffset && bc->base->isInterfaceDeclaration()) 1349 1366 *poffset = OFFSET_RUNTIME; 1350 1367 return 1; 1351 1368 } 1352 1369 } 1353 1370 if (poffset) 1354 1371 *poffset = 0; 1355 1372 return 0; 1356 1373 } 1357 1374 1375 /********************************************* 1376 * Determine if 'this' has clomplete base class information. 1377 * This is used to detect forward references in covariant overloads. 1378 */ 1379 1380 int 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 1358 1391 /**************************************** 1359 1392 * Determine if slot 0 of the vtbl[] is reserved for something else. 1360 1393 * For class objects, yes, this is where the ClassInfo ptr goes. 1361 1394 * For COM interfaces, no. 1362 1395 * For non-COM interfaces, yes, this is where the Interface ptr goes. 1363 1396 */ 1364 1397 1365 1398 int InterfaceDeclaration::vtblOffset() 1366 1399 { 1367 1400 if (isCOMinterface() || isCPPinterface()) 1368 1401 return 0; 1369 1402 return 1; 1370 1403 } 1371 1404 1372 1405 int InterfaceDeclaration::isCOMinterface() 1373 1406 { 1374 1407 return com; 1375 1408 } 1376 1409 1377 1410 #if DMDV2 trunk/src/mtype.c
r619 r638 4523 4523 Type *t1n = t1->next; 4524 4524 Type *t2n = t2->next; 4525 4525 4526 4526 if (!t1n || !t2n) // happens with return type inference 4527 4527 goto Lnotcovariant; 4528 4528 4529 4529 if (t1n->equals(t2n)) 4530 4530 goto Lcovariant; 4531 4531 if (t1n->ty == Tclass && t2n->ty == Tclass) 4532 4532 { 4533 4533 /* If same class type, but t2n is const, then it's 4534 4534 * covariant. Do this test first because it can work on 4535 4535 * forward references. 4536 4536 */ 4537 4537 if (((TypeClass *)t1n)->sym == ((TypeClass *)t2n)->sym && 4538 4538 MODimplicitConv(t1n->mod, t2n->mod)) 4539 4539 goto Lcovariant; 4540 4540 4541 4541 // If t1n is forward referenced: 4542 4542 ClassDeclaration *cd = ((TypeClass *)t1n)->sym; 4543 #if 1 4543 4544 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 4546 4550 } 4547 4551 } 4548 4552 if (t1n->implicitConvTo(t2n)) 4549 4553 goto Lcovariant; 4550 4554 } 4551 4555 goto Lnotcovariant; 4552 4556 4553 4557 Lcovariant: 4554 4558 /* Can convert mutable to const 4555 4559 */ 4556 4560 if (!MODimplicitConv(t2->mod, t1->mod)) 4557 4561 goto Lnotcovariant; 4558 4562 #if 0 4559 4563 if (t1->mod != t2->mod) 4560 4564 { 4561 4565 if (!(t1->mod & MODconst) && (t2->mod & MODconst)) 4562 4566 goto Lnotcovariant; 4563 4567 if (!(t1->mod & MODshared) && (t2->mod & MODshared)) 4564 4568 goto Lnotcovariant; 4565 4569 }
