Changeset 223
- Timestamp:
- 10/29/09 04:58:14 (15 years ago)
- Files:
-
- trunk/src/expression.c (modified) (3 diffs)
- trunk/src/mtype.c (modified) (1 diff)
- trunk/src/mtype.h (modified) (2 diffs)
- trunk/src/template.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/expression.c
r222 r223 1392 1392 case Tenum: 1393 1393 { 1394 1394 TypeEnum *te = (TypeEnum *)t; 1395 1395 t = te->sym->memtype; 1396 1396 continue; 1397 1397 } 1398 1398 1399 1399 case Ttypedef: 1400 1400 { 1401 1401 TypeTypedef *tt = (TypeTypedef *)t; 1402 1402 t = tt->sym->basetype; 1403 1403 continue; 1404 1404 } 1405 1405 1406 1406 default: 1407 1407 /* This can happen if errors, such as 1408 1408 * the type is painted on like in fromConstInitializer(). 1409 1409 */ 1410 1410 if (!global.errors) 1411 1411 { 1412 printf("ty = %d, %d\n", type->ty, t->ty);1413 if (type->ty == Tenum) printf("test1\n");1414 1412 type->print(); 1415 1413 assert(0); 1416 1414 } 1417 1415 break; 1418 1416 } 1419 1417 break; 1420 1418 } 1421 1419 return value; 1422 1420 } 1423 1421 1424 1422 real_t IntegerExp::toReal() 1425 1423 { 1426 1424 Type *t; 1427 1425 1428 1426 toInteger(); 1429 1427 t = type->toBasetype(); 1430 1428 if (t->ty == Tuns64) 1431 1429 return (real_t)(d_uns64)value; 1432 1430 else 1433 1431 return (real_t)(d_int64)value; … … 4734 4732 p->setDim(parameters->dim); 4735 4733 for (int i = 0; i < p->dim; i++) 4736 4734 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 4737 4735 p->data[i] = (void *)tp->syntaxCopy(); 4738 4736 } 4739 4737 } 4740 4738 4741 4739 return new IsExp(loc, 4742 4740 targ->syntaxCopy(), 4743 4741 id, 4744 4742 tok, 4745 4743 tspec ? tspec->syntaxCopy() : NULL, 4746 4744 tok2, 4747 4745 p); 4748 4746 } 4749 4747 4750 4748 Expression *IsExp::semantic(Scope *sc) 4751 4749 { Type *tded; 4752 4750 4753 4751 /* is(targ id tok tspec) 4752 * is(targ id : tok2) 4754 4753 * is(targ id == tok2) 4755 4754 */ 4756 4755 4757 4756 //printf("IsExp::semantic(%s)\n", toChars()); 4758 4757 if (id && !(sc->flags & SCOPEstaticif)) 4759 4758 error("can only declare type aliases within static if conditionals"); 4760 4759 4761 4760 Type *t = targ->trySemantic(loc, sc); 4762 4761 if (!t) 4763 4762 goto Lno; // errors, so condition is false 4764 4763 targ = t; 4765 4764 if (tok2 != TOKreserved) 4766 4765 { 4767 4766 switch (tok2) 4768 4767 { 4769 4768 case TOKtypedef: 4770 4769 if (targ->ty != Ttypedef) 4771 4770 goto Lno; 4772 4771 tded = ((TypeTypedef *)targ)->sym->basetype; 4773 4772 break; … … 4886 4885 else if (targ->ty == Tpointer && 4887 4886 ((TypePointer *)targ)->next->ty == Tfunction) 4888 4887 { tded = ((TypePointer *)targ)->next; 4889 4888 tded = ((TypeFunction *)tded)->next; 4890 4889 } 4891 4890 else 4892 4891 goto Lno; 4893 4892 break; 4894 4893 4895 4894 default: 4896 4895 assert(0); 4897 4896 } 4898 4897 goto Lyes; 4899 4898 } 4900 4899 else if (id && tspec) 4901 4900 { 4902 4901 /* Evaluate to TRUE if targ matches tspec. 4903 4902 * If TRUE, declare id as an alias for the specialized type. 4904 4903 */ 4905 4904 4906 MATCH m;4907 4905 assert(parameters && parameters->dim); 4908 4906 4909 4907 Objects dedtypes; 4910 4908 dedtypes.setDim(parameters->dim); 4911 4909 dedtypes.zero(); 4912 4910 4913 m = targ->deduceType(NULL, tspec, parameters, &dedtypes); 4911 MATCH m = targ->deduceType(NULL, tspec, parameters, &dedtypes); 4912 //printf("targ: %s\n", targ->toChars()); 4913 //printf("tspec: %s\n", tspec->toChars()); 4914 //printf("test1 %d\n", m); 4914 4915 if (m == MATCHnomatch || 4915 4916 (m != MATCHexact && tok == TOKequal)) 4916 4917 { 4917 4918 goto Lno; 4918 4919 } 4919 4920 else 4920 4921 { 4921 4922 tded = (Type *)dedtypes.data[0]; 4922 4923 if (!tded) 4923 4924 tded = targ; 4924 4925 4925 4926 Objects tiargs; 4926 4927 tiargs.setDim(1); 4927 4928 tiargs.data[0] = (void *)targ; 4928 4929 4929 4930 /* Declare trailing parameters 4930 4931 */ 4931 4932 for (int i = 1; i < parameters->dim; i++) 4932 4933 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 4933 4934 Declaration *s = NULL; trunk/src/mtype.c
r222 r223 328 328 * MATCHequal 'this' == 'to' 329 329 * MATCHconst 'to' is const 330 330 * MATCHnomatch conversion to mutable or invariant 331 331 */ 332 332 333 333 MATCH Type::constConv(Type *to) 334 334 { 335 335 if (equals(to)) 336 336 return MATCHexact; 337 337 if (ty == to->ty && to->mod == MODconst) 338 338 return MATCHconst; 339 339 return MATCHnomatch; 340 340 } 341 341 342 342 /******************************** 343 343 * Convert to 'const'. 344 344 */ 345 345 346 346 Type *Type::constOf() 347 347 { 348 #if 0349 //printf("Type::constOf() %p %s\n", this, toChars());350 if (isConst())351 return this;352 if (cto)353 return cto;354 Type *t = makeConst();355 t = t->merge();356 cto = t;357 if (ito)358 ito->cto = t;359 //if (t->nextOf()) assert(t->nextOf()->isConst());360 //printf("-Type::constOf() %p %s\n", t, toChars());361 return t;362 #else363 348 //printf("Type::constOf() %p %s\n", this, toChars()); 364 349 if (mod == MODconst) 365 350 return this; 366 351 if (cto) 367 352 { assert(cto->mod == MODconst); 368 353 return cto; 369 354 } 370 355 Type *t = makeConst(); 371 356 t = t->merge(); 372 357 t->fixTo(this); 373 358 //printf("-Type::constOf() %p %s\n", t, toChars()); 374 359 return t; 375 #endif376 360 } 377 361 378 362 /******************************** 379 363 * Convert to 'immutable'. 380 364 */ 381 365 382 366 Type *Type::invariantOf() 383 367 { 384 #if 0385 //printf("Type::invariantOf() %p %s\n", this, toChars());386 if (isInvariant())387 {388 return this;389 }390 if (ito)391 {392 //if (!ito->isInvariant()) printf("\tito is %p %s\n", ito, ito->toChars());393 assert(ito->isInvariant());394 return ito;395 }396 Type *t = makeInvariant();397 t = t->merge();398 ito = t;399 if (cto)400 cto->ito = t;401 #if 0 // fails for function types402 if (t->nextOf() && !t->nextOf()->isInvariant())403 {404 assert(0);405 }406 #endif407 //printf("\t%p\n", t);408 return t;409 #else410 368 //printf("Type::invariantOf() %p %s\n", this, toChars()); 411 369 if (isInvariant()) 412 370 { 413 371 return this; 414 372 } 415 373 if (ito) 416 374 { 417 375 assert(ito->isInvariant()); 418 376 return ito; 419 377 } 420 378 Type *t = makeInvariant(); 421 379 t = t->merge(); 422 380 t->fixTo(this); 423 381 //printf("\t%p\n", t); 424 382 return t; 425 #endif426 383 } 427 384 428 385 /******************************** 429 386 * Make type mutable. 430 387 */ 431 388 432 389 Type *Type::mutableOf() 433 390 { 434 #if 0435 //printf("Type::mutableOf() %p, %s\n", this, toChars());436 Type *t = this;437 if (isConst())438 { t = cto;439 assert(!t || t->isMutable());440 }441 else if (isInvariant())442 { t = ito;443 assert(!t || t->isMutable());444 }445 if (!t)446 {447 unsigned sz = sizeTy[ty];448 t = (Type *)mem.malloc(sz);449 memcpy(t, this, sz);450 t->mod = 0;451 t->deco = NULL;452 t->arrayof = NULL;453 t->pto = NULL;454 t->rto = NULL;455 t->cto = NULL;456 t->ito = NULL;457 t->sto = NULL;458 t->scto = NULL;459 t->vtinfo = NULL;460 if (ty == Tsarray)461 { TypeSArray *ta = (TypeSArray *)t;462 //ta->next = ta->next->mutableOf();463 }464 t = t->merge();465 if (isConst())466 { cto = t;467 t->cto = this;468 if (ito)469 ito->cto = this;470 }471 else if (isInvariant())472 { ito = t;473 t->ito = this;474 if (cto)475 cto->ito = this;476 }477 }478 return t;479 #else480 391 //printf("Type::mutableOf() %p, %s\n", this, toChars()); 481 392 Type *t = this; 482 393 if (isConst()) 483 394 { if (isShared()) 484 395 t = sto; // shared const => shared 485 396 else 486 397 t = cto; 487 398 assert(!t || t->isMutable()); 488 399 } 489 400 else if (isInvariant()) 490 401 { t = ito; 491 402 assert(!t || (t->isMutable() && !t->isShared())); 492 403 } 493 404 if (!t) 494 405 { 495 406 unsigned sz = sizeTy[ty]; 496 407 t = (Type *)mem.malloc(sz); 497 408 memcpy(t, this, sz); 498 t->mod = 0;409 t->mod = mod & MODshared; 499 410 t->deco = NULL; 500 411 t->arrayof = NULL; 501 412 t->pto = NULL; 502 413 t->rto = NULL; 503 414 t->cto = NULL; 504 415 t->ito = NULL; 505 416 t->sto = NULL; 506 417 t->scto = NULL; 507 418 t->vtinfo = NULL; 508 419 t = t->merge(); 509 420 510 421 t->fixTo(this); 511 422 512 423 switch (mod) 513 424 { 514 425 case MODconst: 515 426 t->cto = this; 516 427 break; 517 428 518 429 case MODinvariant: 519 430 t->ito = this; 520 431 break; 521 432 522 case MODshared:523 t->sto = this;524 break;525 526 433 case MODshared | MODconst: 527 434 t->scto = this; 528 435 break; 529 436 530 437 default: 531 438 assert(0); 532 439 } 533 440 } 534 441 return t; 535 #endif536 442 } 537 443 538 444 Type *Type::sharedOf() 539 445 { 540 446 //printf("Type::sharedOf() %p, %s\n", this, toChars()); 541 447 if (mod == MODshared) 542 448 { 543 449 return this; 544 450 } 545 451 if (sto) 546 452 { 547 453 assert(sto->isShared()); 548 454 return sto; 549 455 } 550 456 Type *t = makeShared(); 551 457 t = t->merge(); 552 458 t->fixTo(this); 553 459 //printf("\t%p\n", t); 554 460 return t; 555 461 } 556 462 557 463 Type *Type::sharedConstOf() 558 464 { 559 465 //printf("Type::sharedConstOf() %p, %s\n", this, toChars()); 560 466 if (mod == (MODshared | MODconst)) 561 467 { 562 468 return this; 563 469 } 564 470 if (scto) 565 471 { 566 472 assert(scto->mod == (MODshared | MODconst)); 567 473 return scto; 568 474 } 569 475 Type *t = makeSharedConst(); 570 476 t = t->merge(); 571 477 t->fixTo(this); 572 478 //printf("\t%p\n", t); 573 479 return t; 574 480 } 575 481 482 483 /******************************** 484 * Make type unshared. 485 */ 486 487 Type *Type::unSharedOf() 488 { 489 //printf("Type::unSharedOf() %p, %s\n", this, toChars()); 490 Type *t = this; 491 492 if (isShared()) 493 { 494 if (isConst()) 495 t = cto; // shared const => const 496 else 497 t = sto; 498 assert(!t || !t->isShared()); 499 } 500 501 if (!t) 502 { 503 unsigned sz = sizeTy[ty]; 504 t = (Type *)mem.malloc(sz); 505 memcpy(t, this, sz); 506 t->mod = mod & ~MODshared; 507 t->deco = NULL; 508 t->arrayof = NULL; 509 t->pto = NULL; 510 t->rto = NULL; 511 t->cto = NULL; 512 t->ito = NULL; 513 t->sto = NULL; 514 t->scto = NULL; 515 t->vtinfo = NULL; 516 t = t->merge(); 517 518 t->fixTo(this); 519 520 switch (mod) 521 { 522 case MODshared: 523 t->sto = this; 524 break; 525 526 case MODshared | MODconst: 527 t->scto = this; 528 break; 529 530 default: 531 assert(0); 532 } 533 } 534 assert(!t->isShared()); 535 return t; 536 } 576 537 577 538 /********************************** 578 539 * For our new type 'this', which is type-constructed from t, 579 540 * fill in the cto, ito, sto, scto shortcuts. 580 541 */ 581 542 582 543 void Type::fixTo(Type *t) 583 544 { 584 545 ito = t->ito; 585 546 #if 0 586 547 /* Cannot do these because these are not fully transitive: 587 548 * there can be a shared ptr to immutable, for example. 588 549 * Immutable subtypes are always immutable, though. 589 550 */ 590 551 cto = t->cto; 591 552 sto = t->sto; 592 553 scto = t->scto; 593 554 #endif 594 555 595 556 assert(mod != t->mod); trunk/src/mtype.h
r221 r223 98 98 Ttuple, 99 99 Tslice, 100 100 Treturn, 101 101 TMAX 102 102 }; 103 103 typedef unsigned char TY; // ENUMTY 104 104 105 105 #define Tascii Tchar 106 106 107 107 extern int Tsize_t; 108 108 extern int Tptrdiff_t; 109 109 110 110 111 111 struct Type : Object 112 112 { 113 113 TY ty; 114 114 unsigned char mod; // modifiers MODxxxx 115 115 /* pick this order of numbers so switch statements work better 116 116 */ 117 117 #define MODconst 1 // type is const 118 #define MODinvariant 4 // type is invariant 118 #define MODinvariant 4 // type is immutable 119 #define MODimmutable 4 // type is immutable 119 120 #define MODshared 2 // type is shared 120 121 char *deco; 121 122 122 123 /* These are cached values that are lazily evaluated by constOf(), invariantOf(), etc. 123 124 * They should not be referenced by anybody but mtype.c. 124 125 * They can be NULL if not lazily evaluated yet. 125 126 * Note that there is no "shared immutable", because that is just immutable 126 127 */ 127 128 128 129 Type *cto; // MODconst ? mutable version of this type : const version 129 130 Type *ito; // MODinvariant ? mutable version of this type : invariant version 130 131 Type *sto; // MODshared ? mutable version of this type : shared mutable version 131 132 Type *scto; // MODshared|MODconst ? mutable version of this type : shared const version 132 133 133 134 Type *pto; // merged pointer to this type 134 135 Type *rto; // reference to this type 135 136 Type *arrayof; // array of this type 136 137 TypeInfoDeclaration *vtinfo; // TypeInfo object for this Type 137 138 138 139 type *ctype; // for back end … … 236 237 virtual int isreal(); 237 238 virtual int isimaginary(); 238 239 virtual int iscomplex(); 239 240 virtual int isscalar(); 240 241 virtual int isunsigned(); 241 242 virtual int isauto(); 242 243 virtual int isString(); 243 244 virtual int isAssignable(); 244 245 virtual int checkBoolean(); // if can be converted to boolean value 245 246 virtual void checkDeprecated(Loc loc, Scope *sc); 246 247 int isConst() { return mod & MODconst; } 247 248 int isInvariant() { return mod & MODinvariant; } 248 249 int isMutable() { return !(mod & (MODconst | MODinvariant)); } 249 250 int isShared() { return mod & MODshared; } 250 251 int isSharedConst() { return mod == (MODshared | MODconst); } 251 252 Type *constOf(); 252 253 Type *invariantOf(); 253 254 Type *mutableOf(); 254 255 Type *sharedOf(); 255 256 Type *sharedConstOf(); 257 Type *unSharedOf(); 256 258 void fixTo(Type *t); 257 259 void check(); 258 260 Type *castMod(unsigned mod); 259 261 Type *addMod(unsigned mod); 260 262 Type *addStorageClass(unsigned stc); 261 263 Type *pointerTo(); 262 264 Type *referenceTo(); 263 265 Type *arrayOf(); 264 266 virtual Type *makeConst(); 265 267 virtual Type *makeInvariant(); 266 268 virtual Type *makeShared(); 267 269 virtual Type *makeSharedConst(); 268 270 virtual Dsymbol *toDsymbol(Scope *sc); 269 271 virtual Type *toBasetype(); 270 272 virtual Type *toHeadMutable(); 271 273 virtual int isBaseOf(Type *t, int *poffset); 272 274 virtual MATCH constConv(Type *to); 273 275 virtual MATCH implicitConvTo(Type *to); 274 276 virtual ClassDeclaration *isClassHandle(); 275 277 virtual Expression *getProperty(Loc loc, Identifier *ident); trunk/src/template.c
r202 r223 1574 1574 TemplateParameter *tp = (TemplateParameter *)parameters->data[0]; 1575 1575 loc = tp->loc; 1576 1576 } 1577 1577 1578 1578 /* BUG: what if tparam is a template instance, that 1579 1579 * has as an argument another Tident? 1580 1580 */ 1581 1581 tparam = tparam->semantic(loc, sc); 1582 1582 assert(tparam->ty != Tident); 1583 1583 return deduceType(sc, tparam, parameters, dedtypes); 1584 1584 } 1585 1585 1586 1586 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 1587 1587 1588 1588 // Found the corresponding parameter tp 1589 1589 if (!tp->isTemplateTypeParameter()) 1590 1590 goto Lnomatch; 1591 1591 Type *tt = this; 1592 1592 Type *at = (Type *)dedtypes->data[i]; 1593 1593 1594 // 3*3 == 9 cases 1595 if (tparam->isMutable()) 1596 { // foo(U:U) T => T 1597 // foo(U:U) const(T) => const(T) 1598 // foo(U:U) invariant(T) => invariant(T) 1599 if (!at) 1600 { dedtypes->data[i] = (void *)this; 1601 goto Lexact; 1602 } 1603 } 1604 else if (mod == tparam->mod) 1605 { // foo(U:const(U)) const(T) => T 1606 // foo(U:invariant(U)) invariant(T) => T 1607 tt = mutableOf(); 1608 if (!at) 1609 { dedtypes->data[i] = (void *)tt; 1610 goto Lexact; 1611 } 1612 } 1613 else if (tparam->isConst()) 1614 { // foo(U:const(U)) T => T 1615 // foo(U:const(U)) invariant(T) => T 1616 tt = mutableOf(); 1617 if (!at) 1618 { dedtypes->data[i] = (void *)tt; 1619 goto Lconst; 1620 } 1621 } 1622 else 1623 { // foo(U:invariant(U)) T => nomatch 1624 // foo(U:invariant(U)) const(T) => nomatch 1625 if (!at) 1626 goto Lnomatch; 1627 } 1594 // 5*5 == 25 cases 1595 1596 #define X(U,T) ((U) << 3) | (T) 1597 switch (X(tparam->mod, mod)) 1598 { 1599 case X(0, 0): 1600 case X(0, MODconst): 1601 case X(0, MODinvariant): 1602 case X(0, MODshared): 1603 case X(0, MODconst | MODshared): 1604 // foo(U:U) T => T 1605 // foo(U:U) const(T) => const(T) 1606 // foo(U:U) immutable(T) => immutable(T) 1607 // foo(U:U) shared(T) => shared(T) 1608 // foo(U:U) const(shared(T)) => const(shared(T)) 1609 if (!at) 1610 { dedtypes->data[i] = (void *)tt; 1611 goto Lexact; 1612 } 1613 break; 1614 1615 case X(MODconst, MODconst): 1616 case X(MODinvariant, MODinvariant): 1617 case X(MODshared, MODshared): 1618 case X(MODconst | MODshared, MODconst | MODshared): 1619 // foo(U:const(U)) const(T) => T 1620 // foo(U:immutable(U)) immutable(T) => T 1621 // foo(U:shared(U)) shared(T) => T 1622 // foo(U:const(shared(U)) const(shared(T)) => T 1623 tt = mutableOf()->unSharedOf(); 1624 if (!at) 1625 { dedtypes->data[i] = (void *)tt; 1626 goto Lexact; 1627 } 1628 break; 1629 1630 case X(MODconst, 0): 1631 case X(MODconst, MODimmutable): 1632 case X(MODconst, MODconst | MODshared): 1633 case X(MODconst | MODshared, MODimmutable): 1634 // foo(U:const(U)) T => T 1635 // foo(U:const(U)) immutable(T) => T 1636 // foo(U:const(U)) const(shared(T)) => shared(T) 1637 // foo(U:const(shared(U)) immutable(T) => T 1638 tt = mutableOf(); 1639 if (!at) 1640 { dedtypes->data[i] = (void *)tt; 1641 goto Lconst; 1642 } 1643 break; 1644 1645 case X(MODshared, MODconst | MODshared): 1646 case X(MODconst | MODshared, MODshared): 1647 // foo(U:shared(U)) const(shared(T)) => const(T) 1648 // foo(U:const(shared(U)) shared(T) => T 1649 tt = unSharedOf(); 1650 if (!at) 1651 { dedtypes->data[i] = (void *)tt; 1652 goto Lconst; 1653 } 1654 break; 1655 1656 case X(MODimmutable, 0): 1657 case X(MODimmutable, MODconst): 1658 case X(MODimmutable, MODshared): 1659 case X(MODimmutable, MODconst | MODshared): 1660 case X(MODconst, MODshared): 1661 case X(MODshared, 0): 1662 case X(MODshared, MODconst): 1663 case X(MODshared, MODimmutable): 1664 case X(MODconst | MODshared, 0): 1665 case X(MODconst | MODshared, MODconst): 1666 // foo(U:immutable(U)) T => nomatch 1667 // foo(U:immutable(U)) const(T) => nomatch 1668 // foo(U:immutable(U)) shared(T) => nomatch 1669 // foo(U:immutable(U)) const(shared(T)) => nomatch 1670 // foo(U:const(U)) shared(T) => nomatch 1671 // foo(U:shared(U)) T => nomatch 1672 // foo(U:shared(U)) const(T) => nomatch 1673 // foo(U:shared(U)) immutable(T) => nomatch 1674 // foo(U:const(shared(U)) T => nomatch 1675 // foo(U:const(shared(U)) const(T) => nomatch 1676 //if (!at) 1677 goto Lnomatch; 1678 break; 1679 1680 default: 1681 assert(0); 1682 } 1683 #undef X 1628 1684 1629 1685 if (tt->equals(at)) 1630 1686 goto Lexact; 1631 1687 else if (tt->ty == Tclass && at->ty == Tclass) 1632 1688 { 1633 1689 return tt->implicitConvTo(at); 1634 1690 } 1635 1691 else if (tt->ty == Tsarray && at->ty == Tarray && 1636 1692 tt->nextOf()->implicitConvTo(at->nextOf()) >= MATCHconst) 1637 1693 { 1638 1694 goto Lexact; 1639 1695 } 1640 1696 else 1641 1697 goto Lnomatch; 1642 1698 } 1643 1699 1644 1700 if (ty != tparam->ty) 1645 1701 return implicitConvTo(tparam); 1646 1702 // goto Lnomatch; 1647 1703
