Changeset 1587:def7a1d494fd
- Timestamp:
- 11/06/09 17:58:01 (2 years ago)
- Files:
-
- dmd/aggregate.h (modified) (3 diffs)
- dmd/arrayop.c (modified) (7 diffs)
- dmd/attrib.c (modified) (17 diffs)
- dmd/attrib.h (modified) (11 diffs)
- dmd/cast.c (modified) (6 diffs)
- dmd/class.c (modified) (16 diffs)
- dmd/constfold.c (modified) (5 diffs)
- dmd/declaration.c (modified) (28 diffs)
- dmd/declaration.h (modified) (27 diffs)
- dmd/doc.c (modified) (21 diffs)
- dmd/dsymbol.c (modified) (25 diffs)
- dmd/dsymbol.h (modified) (16 diffs)
- dmd/enum.h (modified) (4 diffs)
- dmd/expression.c (modified) (72 diffs)
- dmd/expression.h (modified) (9 diffs)
- dmd/func.c (modified) (46 diffs)
- dmd/idgen.c (modified) (2 diffs)
- dmd/import.c (modified) (9 diffs)
- dmd/import.h (modified) (1 diff)
- dmd/init.c (modified) (5 diffs)
- dmd/inline.c (modified) (6 diffs)
- dmd/interpret.c (modified) (47 diffs)
- dmd/lexer.c (modified) (2 diffs)
- dmd/lexer.h (modified) (2 diffs)
- dmd/mangle.c (modified) (1 diff)
- dmd/mars.c (modified) (7 diffs)
- dmd/mars.h (modified) (8 diffs)
- dmd/module.c (modified) (15 diffs)
- dmd/module.h (modified) (6 diffs)
- dmd/mtype.c (modified) (22 diffs)
- dmd/mtype.h (modified) (1 diff)
- dmd/opover.c (modified) (17 diffs)
- dmd/optimize.c (modified) (2 diffs)
- dmd/parse.c (modified) (3 diffs)
- dmd/root/async.c (modified) (2 diffs)
- dmd/root/man.c (modified) (1 diff)
- dmd/root/root.c (modified) (1 diff)
- dmd/scope.c (modified) (3 diffs)
- dmd/scope.h (modified) (1 diff)
- dmd/statement.c (modified) (63 diffs)
- dmd/statement.h (modified) (11 diffs)
- dmd/struct.c (modified) (3 diffs)
- dmd/template.c (modified) (36 diffs)
- dmd/template.h (modified) (4 diffs)
- gen/classes.cpp (modified) (1 diff)
- gen/main.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
dmd/aggregate.h
r1530 r1587 63 63 // 2: cannot determine size; fwd referenced 64 64 int isdeprecated; // !=0 if deprecated 65 Scope *scope; // !=NULL means context to use66 65 67 66 // Special member functions … … 69 68 NewDeclaration *aggNew; // allocator 70 69 DeleteDeclaration *aggDelete; // deallocator 70 71 #if DMDV2 72 //CtorDeclaration *ctor; 73 Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration 74 CtorDeclaration *defaultCtor; // default constructor 75 Dsymbol *aliasthis; // forward unresolved lookups to aliasthis 76 #endif 71 77 72 78 FuncDeclarations dtors; // Array of destructors … … 89 95 90 96 void emitComment(Scope *sc); 97 void toJsonBuffer(OutBuffer *buf); 91 98 void toDocBuffer(OutBuffer *buf); 92 99 dmd/arrayop.c
r1408 r1587 1 1 2 // Copyright (c) 1999-200 8by Digital Mars2 // Copyright (c) 1999-2009 by Digital Mars 3 3 // All Rights Reserved 4 4 // written by Walter Bright … … 32 32 Expression *BinExp::arrayOp(Scope *sc) 33 33 { 34 //printf("BinExp::arrayOp() %s\n", toChars()); 35 36 if (type->toBasetype()->nextOf()->toBasetype()->ty == Tvoid) 37 { 38 error("Cannot perform array operations on void[] arrays"); 39 return new ErrorExp(); 40 } 41 34 42 Expressions *arguments = new Expressions(); 35 43 … … 289 297 sc->linkage = LINKd; 290 298 fd->semantic(sc); 299 fd->semantic2(sc); 300 fd->semantic3(sc); 291 301 sc->pop(); 292 302 // } … … 319 329 } 320 330 331 void CastExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 332 { 333 Type *tb = type->toBasetype(); 334 if (tb->ty == Tarray || tb->ty == Tsarray) 335 { 336 e1->buildArrayIdent(buf, arguments); 337 } 338 else 339 Expression::buildArrayIdent(buf, arguments); 340 } 341 321 342 void SliceExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 322 343 { … … 403 424 } 404 425 426 Expression *CastExp::buildArrayLoop(Arguments *fparams) 427 { 428 Type *tb = type->toBasetype(); 429 if (tb->ty == Tarray || tb->ty == Tsarray) 430 { 431 return e1->buildArrayLoop(fparams); 432 } 433 else 434 return Expression::buildArrayLoop(fparams); 435 } 436 405 437 Expression *SliceExp::buildArrayLoop(Arguments *fparams) 406 438 { … … 421 453 */ 422 454 Expression *ex2 = e2->buildArrayLoop(fparams); 455 #if DMDV2 456 /* Need the cast because: 457 * b = c + p[i]; 458 * where b is a byte fails because (c + p[i]) is an int 459 * which cannot be implicitly cast to byte. 460 */ 461 ex2 = new CastExp(0, ex2, e1->type->nextOf()); 462 #endif 423 463 Expression *ex1 = e1->buildArrayLoop(fparams); 424 464 Argument *param = (Argument *)fparams->data[0]; … … 489 529 490 530 531 /*********************************************** 532 * Test if operand is a valid array op operand. 533 */ 534 535 int Expression::isArrayOperand() 536 { 537 //printf("Expression::isArrayOperand() %s\n", toChars()); 538 if (op == TOKslice) 539 return 1; 540 if (type->toBasetype()->ty == Tarray) 541 { 542 switch (op) 543 { 544 case TOKadd: 545 case TOKmin: 546 case TOKmul: 547 case TOKdiv: 548 case TOKmod: 549 case TOKxor: 550 case TOKand: 551 case TOKor: 552 case TOKneg: 553 case TOKtilde: 554 return 1; 555 556 default: 557 break; 558 } 559 } 560 return 0; 561 } dmd/attrib.c
r1392 r1587 27 27 #include "parse.h" 28 28 #include "template.h" 29 #if TARGET_NET 30 #include "frontend.net/pragma.h" 31 #endif 29 32 30 33 #if IN_LLVM … … 73 76 } 74 77 return m; 78 } 79 80 void AttribDeclaration::setScopeNewSc(Scope *sc, 81 unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, 82 unsigned structalign) 83 { 84 if (decl) 85 { 86 Scope *newsc = sc; 87 if (stc != sc->stc || 88 linkage != sc->linkage || 89 protection != sc->protection || 90 explicitProtection != sc->explicitProtection || 91 structalign != sc->structalign) 92 { 93 // create new one for changes 94 newsc = new Scope(*sc); 95 newsc->flags &= ~SCOPEfree; 96 newsc->stc = stc; 97 newsc->linkage = linkage; 98 newsc->protection = protection; 99 newsc->explicitProtection = explicitProtection; 100 newsc->structalign = structalign; 101 } 102 for (unsigned i = 0; i < decl->dim; i++) 103 { Dsymbol *s = (Dsymbol *)decl->data[i]; 104 105 s->setScope(newsc); // yes, the only difference from semanticNewSc() 106 } 107 if (newsc != sc) 108 { 109 sc->offset = newsc->offset; 110 newsc->pop(); 111 } 112 } 113 } 114 115 void AttribDeclaration::semanticNewSc(Scope *sc, 116 unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, 117 unsigned structalign) 118 { 119 if (decl) 120 { 121 Scope *newsc = sc; 122 if (stc != sc->stc || 123 linkage != sc->linkage || 124 protection != sc->protection || 125 explicitProtection != sc->explicitProtection || 126 structalign != sc->structalign) 127 { 128 // create new one for changes 129 newsc = new Scope(*sc); 130 newsc->flags &= ~SCOPEfree; 131 newsc->stc = stc; 132 newsc->linkage = linkage; 133 newsc->protection = protection; 134 newsc->explicitProtection = explicitProtection; 135 newsc->structalign = structalign; 136 } 137 for (unsigned i = 0; i < decl->dim; i++) 138 { Dsymbol *s = (Dsymbol *)decl->data[i]; 139 140 s->semantic(newsc); 141 } 142 if (newsc != sc) 143 { 144 sc->offset = newsc->offset; 145 newsc->pop(); 146 } 147 } 75 148 } 76 149 … … 303 376 } 304 377 378 void StorageClassDeclaration::setScope(Scope *sc) 379 { 380 if (decl) 381 { 382 unsigned scstc = sc->stc; 383 384 /* These sets of storage classes are mutually exclusive, 385 * so choose the innermost or most recent one. 386 */ 387 if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 388 scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 389 if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared)) 390 scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared); 391 if (stc & (STCconst | STCimmutable | STCmanifest)) 392 scstc &= ~(STCconst | STCimmutable | STCmanifest); 393 if (stc & (STCgshared | STCshared | STCtls)) 394 scstc &= ~(STCgshared | STCshared | STCtls); 395 scstc |= stc; 396 397 setScopeNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); 398 } 399 } 400 305 401 void StorageClassDeclaration::semantic(Scope *sc) 306 402 { 307 403 if (decl) 308 { unsigned stc_save = sc->stc; 309 310 if (stc & (STCauto | STCscope | STCstatic | STCextern)) 311 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 312 sc->stc |= stc; 313 for (unsigned i = 0; i < decl->dim; i++) 314 { 315 Dsymbol *s = (Dsymbol *)decl->data[i]; 316 317 s->semantic(sc); 318 } 319 sc->stc = stc_save; 320 } 321 else 322 sc->stc = stc; 404 { 405 unsigned scstc = sc->stc; 406 407 /* These sets of storage classes are mutually exclusive, 408 * so choose the innermost or most recent one. 409 */ 410 if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 411 scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 412 if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared)) 413 scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared); 414 if (stc & (STCconst | STCimmutable | STCmanifest)) 415 scstc &= ~(STCconst | STCimmutable | STCmanifest); 416 if (stc & (STCgshared | STCshared | STCtls)) 417 scstc &= ~(STCgshared | STCshared | STCtls); 418 scstc |= stc; 419 420 semanticNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); 421 } 323 422 } 324 423 … … 338 437 { STCextern, TOKextern }, 339 438 { STCconst, TOKconst }, 340 // { STCinvariant, TOKimmutable },341 // { STCshared, TOKshared },342 439 { STCfinal, TOKfinal }, 343 440 { STCabstract, TOKabstract }, … … 345 442 { STCdeprecated, TOKdeprecated }, 346 443 { STCoverride, TOKoverride }, 347 // { STCnothrow, TOKnothrow },348 // { STCpure, TOKpure },349 // { STCref, TOKref },350 // { STCtls, TOKtls },351 444 }; 352 445 … … 385 478 } 386 479 480 void LinkDeclaration::setScope(Scope *sc) 481 { 482 //printf("LinkDeclaration::setScope(linkage = %d, decl = %p)\n", linkage, decl); 483 if (decl) 484 { 485 setScopeNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); 486 } 487 } 488 387 489 void LinkDeclaration::semantic(Scope *sc) 388 490 { 389 491 //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl); 390 492 if (decl) 391 { enum LINK linkage_save = sc->linkage; 392 393 sc->linkage = linkage; 394 for (unsigned i = 0; i < decl->dim; i++) 395 { 396 Dsymbol *s = (Dsymbol *)decl->data[i]; 397 398 s->semantic(sc); 399 } 400 sc->linkage = linkage_save; 401 } 402 else 403 { 404 sc->linkage = linkage; 493 { 494 semanticNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); 405 495 } 406 496 } … … 474 564 } 475 565 566 void ProtDeclaration::setScope(Scope *sc) 567 { 568 if (decl) 569 { 570 setScopeNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); 571 } 572 } 573 574 void ProtDeclaration::importAll(Scope *sc) 575 { 576 Scope *newsc = sc; 577 if (sc->protection != protection || 578 sc->explicitProtection != 1) 579 { 580 // create new one for changes 581 newsc = new Scope(*sc); 582 newsc->flags &= ~SCOPEfree; 583 newsc->protection = protection; 584 newsc->explicitProtection = 1; 585 } 586 587 for (int i = 0; i < decl->dim; i++) 588 { 589 Dsymbol *s = (Dsymbol *)decl->data[i]; 590 s->importAll(newsc); 591 } 592 593 if (newsc != sc) 594 newsc->pop(); 595 } 596 476 597 void ProtDeclaration::semantic(Scope *sc) 477 598 { 478 599 if (decl) 479 { enum PROT protection_save = sc->protection; 480 int explicitProtection_save = sc->explicitProtection; 481 482 sc->protection = protection; 483 sc->explicitProtection = 1; 484 for (unsigned i = 0; i < decl->dim; i++) 485 { 486 Dsymbol *s = (Dsymbol *)decl->data[i]; 487 488 s->semantic(sc); 489 } 490 sc->protection = protection_save; 491 sc->explicitProtection = explicitProtection_save; 492 } 493 else 494 { sc->protection = protection; 495 sc->explicitProtection = 1; 496 } 497 } 498 499 void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 500 { const char *p; 600 { 601 semanticNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); 602 } 603 } 604 605 void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, enum PROT protection) 606 { 607 const char *p; 501 608 502 609 switch (protection) … … 512 619 } 513 620 buf->writestring(p); 621 buf->writeByte(' '); 622 } 623 624 void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 625 { 626 protectionToCBuffer(buf, protection); 514 627 AttribDeclaration::toCBuffer(buf, hgs); 515 628 } … … 533 646 } 534 647 648 void AlignDeclaration::setScope(Scope *sc) 649 { 650 //printf("\tAlignDeclaration::setScope '%s'\n",toChars()); 651 if (decl) 652 { 653 setScopeNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); 654 } 655 } 656 535 657 void AlignDeclaration::semantic(Scope *sc) 536 658 { … … 538 660 // we only support packed structs, as from the spec: align(1) struct Packed { ... } 539 661 // other alignments are simply ignored. my tests show this is what llvm-gcc does too ... 540 541 //printf("\tAlignDeclaration::semantic '%s'\n",toChars()); 542 if (decl) 543 { unsigned salign_save = sc->structalign; 544 545 for (unsigned i = 0; i < decl->dim; i++) 546 { 547 Dsymbol *s = (Dsymbol *)decl->data[i]; 548 549 if (s->isStructDeclaration() && salign == 1) 550 { 551 sc->structalign = salign; 552 s->semantic(sc); 553 sc->structalign = salign_save; 554 } 555 else 556 { 557 s->semantic(sc); 558 } 559 } 560 sc->structalign = salign_save; 561 } 562 else 563 assert(0 && "what kind of align use triggers this?"); 662 { 663 semanticNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); 664 } 564 665 } 565 666 … … 578 679 this->loc = loc; 579 680 this->isunion = isunion; 580 this->scope = NULL;581 681 this->sem = 0; 582 682 } … … 781 881 } 782 882 883 void PragmaDeclaration::setScope(Scope *sc) 884 { 885 #if TARGET_NET 886 if (ident == Lexer::idPool("assembly")) 887 { 888 if (!args || args->dim != 1) 889 { 890 error("pragma has invalid number of arguments"); 891 } 892 else 893 { 894 Expression *e = (Expression *)args->data[0]; 895 e = e->semantic(sc); 896 e = e->optimize(WANTvalue | WANTinterpret); 897 args->data[0] = (void *)e; 898 if (e->op != TOKstring) 899 { 900 error("string expected, not '%s'", e->toChars()); 901 } 902 PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e)); 903 904 assert(sc); 905 pragma->setScope(sc); 906 907 //add to module members 908 assert(sc->module); 909 assert(sc->module->members); 910 sc->module->members->push(pragma); 911 } 912 } 913 #endif // TARGET_NET 914 } 915 783 916 void PragmaDeclaration::semantic(Scope *sc) 784 917 { // Should be merged with PragmaStatement … … 804 937 { 805 938 StringExp *se = (StringExp *)e; 806 fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);939 fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); 807 940 } 808 941 else 809 error("string expected for message, not '%s'", e->toChars());942 fprintf(stdmsg, e->toChars()); 810 943 } 811 944 fprintf(stdmsg, "\n"); … … 874 1007 } 875 1008 #endif 1009 #if TARGET_NET 1010 else if (ident == Lexer::idPool("assembly")) 1011 { 1012 if (!args || args->dim != 1) 1013 error("pragma has invalid number of arguments"); 1014 else 1015 { 1016 Expression *e = (Expression *)args->data[0]; 1017 e = e->semantic(sc); 1018 e = e->optimize(WANTvalue | WANTinterpret); 1019 args->data[0] = (void *)e; 1020 if (e->op != TOKstring) 1021 { 1022 error("string expected, not '%s'", e->toChars()); 1023 } 1024 PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e)); 1025 decl = new Array; 1026 decl->push(pragma); 1027 } 1028 } 1029 #endif // TARGET_NET 876 1030 877 1031 // LDC … … 1001 1155 1002 1156 #endif // LDC 1157 1003 1158 1004 1159 else if (ignoreUnsupportedPragmas) … … 1299 1454 } 1300 1455 1456 void ConditionalDeclaration::setScope(Scope *sc) 1457 { 1458 Array *d = include(sc, NULL); 1459 1460 //printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d); 1461 if (d) 1462 { 1463 for (unsigned i = 0; i < d->dim; i++) 1464 { 1465 Dsymbol *s = (Dsymbol *)d->data[i]; 1466 1467 s->setScope(sc); 1468 } 1469 } 1470 } 1471 1472 void ConditionalDeclaration::importAll(Scope *sc) 1473 { 1474 Array *d = include(sc, NULL); 1475 1476 //printf("\tConditionalDeclaration::importAll '%s', d = %p\n",toChars(), d); 1477 if (d) 1478 { 1479 for (unsigned i = 0; i < d->dim; i++) 1480 { 1481 Dsymbol *s = (Dsymbol *)d->data[i]; 1482 1483 s->importAll(sc); 1484 } 1485 } 1486 } 1301 1487 1302 1488 void ConditionalDeclaration::addComment(unsigned char *comment) … … 1419 1605 1420 1606 1607 void StaticIfDeclaration::importAll(Scope *sc) 1608 { 1609 // do not evaluate condition before semantic pass 1610 } 1611 1612 void StaticIfDeclaration::setScope(Scope *sc) 1613 { 1614 // do not evaluate condition before semantic pass 1615 } 1616 1421 1617 void StaticIfDeclaration::semantic(Scope *sc) 1422 1618 { dmd/attrib.h
r1228 r1587 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 37 37 virtual Array *include(Scope *sc, ScopeDsymbol *s); 38 38 int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 39 void setScopeNewSc(Scope *sc, 40 unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection, 41 unsigned structalign); 42 void semanticNewSc(Scope *sc, 43 unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection, 44 unsigned structalign); 39 45 void semantic(Scope *sc); 40 46 void semantic2(Scope *sc); … … 49 55 void addLocalClass(ClassDeclarations *); 50 56 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 57 void toJsonBuffer(OutBuffer *buf); 51 58 AttribDeclaration *isAttribDeclaration() { return this; } 52 59 … … 67 74 StorageClassDeclaration(unsigned stc, Array *decl); 68 75 Dsymbol *syntaxCopy(Dsymbol *s); 76 void setScope(Scope *sc); 69 77 void semantic(Scope *sc); 70 78 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 79 87 LinkDeclaration(enum LINK p, Array *decl); 80 88 Dsymbol *syntaxCopy(Dsymbol *s); 89 void setScope(Scope *sc); 81 90 void semantic(Scope *sc); 82 91 void semantic3(Scope *sc); … … 91 100 ProtDeclaration(enum PROT p, Array *decl); 92 101 Dsymbol *syntaxCopy(Dsymbol *s); 93 void semantic(Scope *sc); 94 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 102 void importAll(Scope *sc); 103 void setScope(Scope *sc); 104 void semantic(Scope *sc); 105 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 106 107 static void protectionToCBuffer(OutBuffer *buf, enum PROT protection); 95 108 }; 96 109 … … 101 114 AlignDeclaration(Loc loc, unsigned sa, Array *decl); 102 115 Dsymbol *syntaxCopy(Dsymbol *s); 116 void setScope(Scope *sc); 103 117 void semantic(Scope *sc); 104 118 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 108 122 { 109 123 int isunion; 110 Scope *scope; // !=NULL means context to use111 124 int sem; // 1 if successful semantic() 112 125 … … 125 138 Dsymbol *syntaxCopy(Dsymbol *s); 126 139 void semantic(Scope *sc); 140 void setScope(Scope *sc); 127 141 int oneMember(Dsymbol **ps); 128 142 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 150 164 void addComment(unsigned char *comment); 151 165 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 166 void toJsonBuffer(OutBuffer *buf); 167 void importAll(Scope *sc); 168 void setScope(Scope *sc); 152 169 }; 153 170 … … 161 178 int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 162 179 void semantic(Scope *sc); 180 void importAll(Scope *sc); 181 void setScope(Scope *sc); 163 182 const char *kind(); 164 183 }; dmd/cast.c
r1367 r1587 1079 1079 Expression *SymOffExp::castTo(Scope *sc, Type *t) 1080 1080 { 1081 Type *tb;1082 1083 1081 #if 0 1084 1082 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", … … 1087 1085 Expression *e = this; 1088 1086 1089 tb = t->toBasetype();1090 type= type->toBasetype();1091 if (tb != type )1087 Type *tb = t->toBasetype(); 1088 Type *typeb = type->toBasetype(); 1089 if (tb != typeb) 1092 1090 { 1093 1091 // Look for pointers to functions where the functions are overloaded. 1094 1092 FuncDeclaration *f; 1095 1093 1096 if (type ->ty == Tpointer && type->next->ty == Tfunction &&1094 if (typeb->ty == Tpointer && typeb->next->ty == Tfunction && 1097 1095 tb->ty == Tpointer && tb->next->ty == Tfunction) 1098 1096 { … … 1103 1101 if (f) 1104 1102 { 1105 e = new SymOffExp(loc, f, 0); 1106 e->type = t; 1103 #if DMDV2 1104 if (tb->ty == Tdelegate) 1105 { 1106 if (f->needThis() && hasThis(sc)) 1107 { 1108 e = new DelegateExp(loc, new ThisExp(loc), f); 1109 e = e->semantic(sc); 1110 } 1111 else if (f->isNested()) 1112 { 1113 e = new DelegateExp(loc, new IntegerExp(0), f); 1114 e = e->semantic(sc); 1115 } 1116 else if (f->needThis()) 1117 { error("no 'this' to create delegate for %s", f->toChars()); 1118 e = new ErrorExp(); 1119 } 1120 else 1121 { error("cannot cast from function pointer to delegate"); 1122 e = new ErrorExp(); 1123 } 1124 } 1125 else 1126 #endif 1127 { 1128 e = new SymOffExp(loc, f, 0); 1129 e->type = t; 1130 } 1131 #if DMDV2 1132 f->tookAddressOf++; 1133 #endif 1107 1134 return e; 1108 1135 } … … 1111 1138 e = Expression::castTo(sc, t); 1112 1139 } 1113 e->type = t; 1140 else 1141 { 1142 e->type = t; 1143 } 1114 1144 return e; 1115 1145 } … … 1485 1515 assert(0); 1486 1516 } 1487 else if (e1-> op == TOKslice&& t1->ty == Tarray &&1517 else if (e1->isArrayOperand() && t1->ty == Tarray && 1488 1518 e2->implicitConvTo(t1->nextOf())) 1489 1519 { // T[] op T … … 1491 1521 t = t1->nextOf()->arrayOf(); 1492 1522 } 1493 else if (e2-> op == TOKslice&& t2->ty == Tarray &&1523 else if (e2->isArrayOperand() && t2->ty == Tarray && 1494 1524 e1->implicitConvTo(t2->nextOf())) 1495 1525 { // T op T[] dmd/class.c
r1530 r1587 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 8by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 162 162 Type::typeinfoinvariant = this; 163 163 } 164 165 if (id == Id::TypeInfo_Shared) 166 { if (Type::typeinfoshared) 167 Type::typeinfoshared->error("%s", msg); 168 Type::typeinfoshared = this; 169 } 164 170 #endif 165 171 } … … 227 233 228 234 if (!ident) // if anonymous class 229 { c har *id = "__anonclass";235 { const char *id = "__anonclass"; 230 236 231 237 ident = Identifier::generateId(id); 232 238 } 233 239 234 if (!sc ope)235 { 236 if (!parent && sc->parent && !sc->parent->isModule())237 parent = sc->parent;238 239 type = type->semantic(loc, sc);240 handle = handle->semantic(loc, sc);241 } 240 if (!sc) 241 sc = scope; 242 if (!parent && sc->parent && !sc->parent->isModule()) 243 parent = sc->parent; 244 245 type = type->semantic(loc, sc); 246 handle = type; 247 242 248 if (!members) // if forward reference 243 249 { //printf("\tclass '%s' is forward referenced\n", toChars()); … … 330 336 } 331 337 } 338 if (!tc->sym->symtab || tc->sym->sizeok == 0) 339 { // Try to resolve forward reference 340 if (sc->mustsemantic && tc->sym->scope) 341 tc->sym->semantic(NULL); 342 } 332 343 if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0) 333 344 { 345 //printf("%s: forward reference of base class %s\n", toChars(), tc->sym->toChars()); 334 346 //error("forward reference of base class %s", baseClass->toChars()); 335 347 // Forward reference of base class, try again later … … 337 349 scope = scx ? scx : new Scope(*sc); 338 350 scope->setNoFree(); 351 if (tc->sym->scope) 352 tc->sym->scope->module->addDeferredSemantic(tc->sym); 339 353 scope->module->addDeferredSemantic(this); 340 354 return; … … 390 404 } 391 405 406 if (!tc->sym->symtab) 407 { // Try to resolve forward reference 408 if (sc->mustsemantic && tc->sym->scope) 409 tc->sym->semantic(NULL); 410 } 411 392 412 b->base = tc->sym; 393 413 if (!b->base->symtab || b->base->scope) … … 398 418 scope = scx ? scx : new Scope(*sc); 399 419 scope->setNoFree(); 420 if (tc->sym->scope) 421 tc->sym->scope->module->addDeferredSemantic(tc->sym); 400 422 scope->module->addDeferredSemantic(this); 401 423 return; … … 501 523 if (s) 502 524 { 503 ClassDeclaration *cd = s->isClassDeclaration();525 AggregateDeclaration *ad = s->isClassDeclaration(); 504 526 FuncDeclaration *fd = s->isFuncDeclaration(); 505 527 506 528 507 if ( cd || fd)529 if (ad || fd) 508 530 { isnested = 1; 509 531 Type *t; 510 if ( cd)511 t = cd->type;532 if (ad) 533 t = ad->handle; 512 534 else if (fd) 513 535 { AggregateDeclaration *ad = fd->isMember2(); … … 565 587 } 566 588 else 567 { sc->offset = PTRSIZE * 2; // allow room for vptr[] andmonitor589 { sc->offset = PTRSIZE * 2; // allow room for __vptr and __monitor 568 590 alignsize = PTRSIZE; 569 591 } … … 704 726 b->type->toCBuffer(buf, NULL, hgs); 705 727 } 706 buf->writenl(); 707 buf->writeByte('{'); 708 buf->writenl(); 709 for (int i = 0; i < members->dim; i++) 710 { 711 Dsymbol *s = (Dsymbol *)members->data[i]; 712 713 buf->writestring(" "); 714 s->toCBuffer(buf, hgs); 715 } 716 buf->writestring("}"); 728 if (members) 729 { 730 buf->writenl(); 731 buf->writeByte('{'); 732 buf->writenl(); 733 for (int i = 0; i < members->dim; i++) 734 { 735 Dsymbol *s = (Dsymbol *)members->data[i]; 736 737 buf->writestring(" "); 738 s->toCBuffer(buf, hgs); 739 } 740 buf->writestring("}"); 741 } 742 else 743 buf->writeByte(';'); 717 744 buf->writenl(); 718 745 } … … 778 805 { 779 806 Dsymbol *s; 780 781 807 //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 808 782 809 if (scope) 783 semantic(scope); 810 { Scope *sc = scope; 811 sc->mustsemantic++; 812 semantic(sc); 813 sc->mustsemantic--; 814 } 784 815 785 816 if (!members || !symtab || scope) 786 { error("is forward referenced when looking for '%s'", ident->toChars()); 817 { 818 error("is forward referenced when looking for '%s'", ident->toChars()); 787 819 //*(char*)0=0; 788 820 return NULL; … … 832 864 int ClassDeclaration::isFuncHidden(FuncDeclaration *fd) 833 865 { 834 //printf("ClassDeclaration::isFuncHidden( %s)\n", fd->toChars());866 //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars()); 835 867 Dsymbol *s = search(0, fd->ident, 4|2); 836 868 if (!s) … … 917 949 } 918 950 951 #if DMDV2 952 int ClassDeclaration::isCPPinterface() 953 { 954 return 0; 955 } 956 #endif 957 919 958 920 959 /**************************************** … … 1007 1046 if (inuse) 1008 1047 return; 1009 if (!scope) 1010 { type = type->semantic(loc, sc); 1011 handle = handle->semantic(loc, sc); 1012 } 1048 1049 if (!sc) 1050 sc = scope; 1051 if (!parent && sc->parent && !sc->parent->isModule()) 1052 parent = sc->parent; 1053 1054 type = type->semantic(loc, sc); 1055 handle = type; 1056 1013 1057 if (!members) // if forward reference 1014 1058 { //printf("\tinterface '%s' is forward referenced\n", toChars()); … … 1090 1134 baseclasses.remove(i); 1091 1135 continue; 1136 } 1137 if (!b->base->symtab) 1138 { // Try to resolve forward reference 1139 if (sc->mustsemantic && b->base->scope) 1140 b->base->semantic(NULL); 1092 1141 } 1093 1142 if (!b->base->symtab || b->base->scope || b->base->inuse) … … 1263 1312 } 1264 1313 1314 #if DMDV2 1315 int InterfaceDeclaration::isCPPinterface() 1316 { 1317 return cpp; 1318 } 1319 #endif 1320 1265 1321 /******************************************* 1266 1322 */ dmd/constfold.c
r1367 r1587 71 71 72 72 int ComplexExp::isConst() 73 { 74 return 1; 75 } 76 77 int NullExp::isConst() 73 78 { 74 79 return 1; … … 846 851 cmp = e1->toComplex() == e2->toComplex(); 847 852 } 848 else if (e1->type->isintegral() )853 else if (e1->type->isintegral() || e1->type->toBasetype()->ty == Tpointer) 849 854 { 850 855 cmp = (e1->toInteger() == e2->toInteger()); … … 863 868 int cmp; 864 869 865 if (e1->op == TOKnull && e2->op == TOKnull) 866 { 867 cmp = 1; 870 if (e1->op == TOKnull) 871 { 872 cmp = (e2->op == TOKnull); 873 } 874 else if (e2->op == TOKnull) 875 { 876 cmp = 0; 868 877 } 869 878 else if (e1->op == TOKsymoff && e2->op == TOKsymoff) … … 1047 1056 1048 1057 Type *tb = to->toBasetype(); 1049 Type *typeb = type->toBasetype(); 1050 1051 // LDC: ported from D2 to allow char[] ~ char[n] arguments in CTFE1058 1059 /* Allow casting from one string type to another 1060 */ 1052 1061 if (e1->op == TOKstring) 1053 1062 { 1063 Type *typeb = type->toBasetype(); 1054 1064 if (tb->ty == Tarray && typeb->ty == Tarray && 1055 1065 tb->nextOf()->size() == typeb->nextOf()->size()) … … 1070 1080 real_t r = e1->toReal(); 1071 1081 1072 switch (type b->ty)1082 switch (type->toBasetype()->ty) 1073 1083 { 1074 1084 case Tint8: result = (d_int8)r; break; dmd/declaration.c
r1538 r1587 68 68 69 69 int Declaration::isDataseg() 70 { 71 return FALSE; 72 } 73 74 int Declaration::isThreadlocal() 70 75 { 71 76 return FALSE; … … 133 138 if (v && v->canassign == 0) 134 139 { 135 c har *p = NULL;140 const char *p = NULL; 136 141 if (isConst()) 137 142 p = "const"; 138 143 else if (isInvariant()) 139 p = "i nvariant";144 p = "immutable"; 140 145 else if (storage_class & STCmanifest) 141 p = " manifest constant";146 p = "enum"; 142 147 else if (!t->isAssignable()) 143 148 p = "struct with immutable members"; 144 149 if (p) 145 150 { error(loc, "cannot modify %s", p); 146 halt();147 151 } 148 152 } … … 201 205 args->setDim(objects->dim); 202 206 OutBuffer buf; 207 int hasdeco = 1; 203 208 for (size_t i = 0; i < objects->dim; i++) 204 209 { Type *t = (Type *)objects->data[i]; … … 214 219 #endif 215 220 args->data[i] = (void *)arg; 221 if (!t->deco) 222 hasdeco = 0; 216 223 } 217 224 218 225 tupletype = new TypeTuple(args); 226 if (hasdeco) 227 return tupletype->semantic(0, NULL); 219 228 } 220 229 … … 457 466 */ 458 467 s = type->toDsymbol(sc); 459 if (s) 468 if (s 469 #if DMDV2 470 ` && ((s->getType() && type->equals(s->getType())) || s->isEnumMember()) 471 #endif 472 ) 460 473 goto L2; // it's a symbolic alias 461 474 462 //printf("alias type is %s\n", type->toChars()); 463 type->resolve(loc, sc, &e, &t, &s); 475 #if DMDV2 476 if (storage_class & (STCref | STCnothrow | STCpure)) 477 { // For 'ref' to be attached to function types, and picked 478 // up by Type::resolve(), it has to go into sc. 479 sc = sc->push(); 480 sc->stc |= storage_class & (STCref | STCnothrow | STCpure); 481 type->resolve(loc, sc, &e, &t, &s); 482 sc = sc->pop(); 483 } 484 else 485 #endif 486 type->resolve(loc, sc, &e, &t, &s); 464 487 if (s) 465 488 { … … 524 547 } 525 548 } 526 aliassym = s; 549 if (!aliassym) 550 aliassym = s; 527 551 this->inSemantic = 0; 528 552 } … … 536 560 //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars()); 537 561 if (overnext == NULL) 538 { overnext = s; 562 { 563 if (s == this) 564 { 565 return TRUE; 566 } 567 overnext = s; 539 568 return TRUE; 540 569 } … … 552 581 Type *AliasDeclaration::getType() 553 582 { 583 //printf("AliasDeclaration::getType() %s\n", type->toChars()); 584 #if 0 585 if (!type->deco && scope) 586 semantic(scope); 587 if (type && !type->deco) 588 error("forward reference to alias %s\n", toChars()); 589 #endif 554 590 return type; 555 591 } … … 559 595 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); 560 596 assert(this != aliassym); 561 //static int count; if (++count == 10)*(char*)0=0;597 //static int count; if (++count == 75) exit(0); //*(char*)0=0; 562 598 if (inSemantic) 563 599 { error("recursive alias declaration"); … … 621 657 offset = 0; 622 658 noscope = 0; 659 #if DMDV1 623 660 nestedref = 0; 661 #endif 624 662 ctorinit = 0; 625 663 aliassym = NULL; … … 685 723 void VarDeclaration::semantic(Scope *sc) 686 724 { 687 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 688 //printf(" type = %s\n", type ? type->toChars() : "null"); 689 //printf(" stc = x%x\n", sc->stc); 690 //printf(" storage_class = x%x\n", storage_class); 691 //printf("linkage = %d\n", sc->linkage); 725 #if 0 726 printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 727 printf(" type = %s\n", type ? type->toChars() : "null"); 728 printf(" stc = x%x\n", sc->stc); 729 printf(" storage_class = x%x\n", storage_class); 730 printf("linkage = %d\n", sc->linkage); 692 731 //if (strcmp(toChars(), "mul") == 0) halt(); 732 #endif 693 733 694 734 storage_class |= sc->stc; … … 725 765 //printf("sc->stc = %x\n", sc->stc); 726 766 //printf("storage_class = x%x\n", storage_class); 767 768 #if DMDV2 769 if (storage_class & STCgshared && global.params.safe && !sc->module->safe) 770 { 771 error("__gshared not allowed in safe mode; use shared"); 772 } 773 #endif 727 774 728 775 Dsymbol *parent = toParent(); … … 833 880 if (aad) 834 881 { 835 aad->addField(sc, this); 882 #if DMDV2 883 assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared))); 884 885 if (storage_class & (STCconst | STCimmutable) && init) 886 { 887 if (!type->toBasetype()->isTypeBasic()) 888 storage_class |= STCstatic; 889 } 890 else 891 #endif 892 aad->addField(sc, this); 836 893 } 837 894 … … 865 922 } 866 923 924 #if DMDV2 925 if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 926 ident != Id::This) 927 { 928 error("only parameters or foreach declarations can be ref"); 929 } 930 #endif 931 867 932 if (type->isscope() && !noscope) 868 933 { … … 879 944 } 880 945 946 enum TOK op = TOKconstruct; 881 947 if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 882 948 !(storage_class & (STCfield | STCin | STCforeach)) && … … 897 963 e1 = new VarExp(loc, this); 898 964 e = new AssignExp(loc, e1, e); 899 e->type = e1->type; 900 init = new ExpInitializer(loc, e/*->type->defaultInit()*/); 965 e->op = TOKconstruct; 966 e->type = e1->type; // don't type check this, it would fail 967 init = new ExpInitializer(loc, e); 901 968 return; 902 969 } … … 917 984 init = getExpInitializer(); 918 985 } 986 // Default initializer is always a blit 987 op = TOKblit; 919 988 } 920 989 … … 922 991 { 923 992 sc = sc->push(); 924 sc->stc &= ~(STC const | STCinvariant | STCpure);993 sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCref); 925 994 926 995 ArrayInitializer *ai = init->isArrayInitializer(); … … 933 1002 ExpInitializer *ei = init->isExpInitializer(); 934 1003 935 // See if we can allocateon the stack1004 // See if initializer is a NewExp that can be allocated on the stack 936 1005 if (ei && isScope() && ei->exp->op == TOKnew) 937 1006 { NewExp *ne = (NewExp *)ei->exp; … … 971 1040 972 1041 Type *t = type->toBasetype(); 973 if (t->ty == Tsarray )1042 if (t->ty == Tsarray && !(storage_class & (STCref | STCout))) 974 1043 { 975 1044 ei->exp = ei->exp->semantic(sc); … … 992 1061 { 993 1062 ei->exp = ei->exp->semantic(sc); 1063 ei->exp = resolveProperties(sc, ei->exp); 1064 StructDeclaration *sd = ((TypeStruct *)t)->sym; 1065 #if DMDV2 1066 /* Look to see if initializer is a call to the constructor 1067 */ 1068 if (sd->ctor && // there are constructors 1069 ei->exp->type->ty == Tstruct && // rvalue is the same struct 1070 ((TypeStruct *)ei->exp->type)->sym == sd && 1071 ei->exp->op == TOKstar) 1072 { 1073 /* Look for form of constructor call which is: 1074 * *__ctmp.ctor(arguments...) 1075 */ 1076 PtrExp *pe = (PtrExp *)ei->exp; 1077 if (pe->e1->op == TOKcall) 1078 { CallExp *ce = (CallExp *)pe->e1; 1079 if (ce->e1->op == TOKdotvar) 1080 { DotVarExp *dve = (DotVarExp *)ce->e1; 1081 if (dve->var->isCtorDeclaration()) 1082 { /* It's a constructor call, currently constructing 1083 * a temporary __ctmp. 1084 */ 1085 /* Before calling the constructor, initialize 1086 * variable with a bit copy of the default 1087 * initializer 1088 */ 1089 Expression *e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc)); 1090 e->op = TOKblit; 1091 e->type = t; 1092 ei->exp = new CommaExp(loc, e, ei->exp); 1093 1094 /* Replace __ctmp being constructed with e1 1095 */ 1096 dve->e1 = e1; 1097 return; 1098 } 1099 } 1100 } 1101 } 1102 #endif 994 1103 if (!ei->exp->implicitConvTo(type)) 995 ei->exp = new CastExp(loc, ei->exp, type); 1104 { 1105 /* Look for opCall 1106 * See bugzilla 2702 for more discussion 1107 */ 1108 Type *ti = ei->exp->type->toBasetype(); 1109 // Don't cast away invariant or mutability in initializer 1110 if (search_function(sd, Id::call) && 1111 /* Initializing with the same type is done differently 1112 */ 1113 !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc))) 1114 { // Rewrite as e1.call(arguments) 1115 Expression * eCall = new DotIdExp(loc, e1, Id::call); 1116 ei->exp = new CallExp(loc, eCall, ei->exp); 1117 } 1118 } 996 1119 } 997 1120 ei->exp = new AssignExp(loc, e1, ei->exp); … … 1011 1134 } 1012 1135 } 1013 else if (isConst() || isFinal()) 1136 else if (isConst() || isFinal() || 1137 parent->isAggregateDeclaration()) 1014 1138 { 1015 1139 /* Because we may need the results of a const declaration in a … … 1044 1168 if (global.gag == 0) 1045 1169 global.errors = errors; // act as if nothing happened 1170 #if DMDV2 1171 /* Save scope for later use, to try again 1172 */ 1173 scope = new Scope(*sc); 1174 scope->setNoFree(); 1175 #endif 1046 1176 } 1047 1177 else if (ei) 1048 1178 { 1049 1179 e = e->optimize(WANTvalue | WANTinterpret); 1050 if (e->op == TOKint64 || e->op == TOKstring )1180 if (e->op == TOKint64 || e->op == TOKstring || e->op == TOKfloat64) 1051 1181 { 1052 1182 ei->exp = e; // no errors, keep result 1053 1183 } 1184 #if DMDV2 1185 else 1186 { 1187 /* Save scope for later use, to try again 1188 */ 1189 scope = new Scope(*sc); 1190 scope->setNoFree(); 1191 } 1192 #endif 1054 1193 } 1055 1194 else … … 1132 1271 if (init) 1133 1272 { buf->writestring(" = "); 1134 init->toCBuffer(buf, hgs); 1273 #if DMDV2 1274 ExpInitializer *ie = init->isExpInitializer(); 1275 if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit)) 1276 ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs); 1277 else 1278 #endif 1279 init->toCBuffer(buf, hgs); 1135 1280 } 1136 1281 buf->writeByte(';'); … … 1211 1356 } 1212 1357 1358 /************************************ 1359 * Does symbol go into thread local storage? 1360 */ 1361 1362 int VarDeclaration::isThreadlocal() 1363 { 1364 return 0; 1365 } 1366 1213 1367 int VarDeclaration::hasPointers() 1214 1368 { 1369 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); 1215 1370 return (!isDataseg() && type->hasPointers()); 1216 1371 } … … 1229 1384 */ 1230 1385 1231 Expression *VarDeclaration::callScopeDtor( )1386 Expression *VarDeclaration::callScopeDtor(Scope *sc) 1232 1387 { Expression *e = NULL; 1233 1388 … … 1342 1497 #endif 1343 1498 1499 /***************************** TypeInfoSharedDeclaration **********************/ 1500 1501 #if DMDV2 1502 TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo) 1503 : TypeInfoDeclaration(tinfo, 0) 1504 { 1505 } 1506 #endif 1507 1344 1508 /***************************** TypeInfoStructDeclaration **********************/ 1345 1509 … … 1451 1615 storage_class |= STCconst; 1452 1616 } 1453 dmd/declaration.h
r1530 r1587 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 8by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 93 93 }; 94 94 95 void overloadResolveX(Match *m, FuncDeclaration *f, Expressions *arguments, Module* from); 95 void overloadResolveX(Match *m, FuncDeclaration *f, 96 Expression *ethis, Expressions *arguments, Module *from); 96 97 int overloadApply(Module* from, FuncDeclaration *fstart, 97 98 int (*fp)(void *, FuncDeclaration *), … … 116 117 117 118 void emitComment(Scope *sc); 119 void toJsonBuffer(OutBuffer *buf); 118 120 void toDocBuffer(OutBuffer *buf); 119 121 … … 124 126 virtual int isDelete(); 125 127 virtual int isDataseg(); 128 virtual int isThreadlocal(); 126 129 virtual int isCodeseg(); 127 130 int isCtorinit() { return storage_class & STCctorinit; } … … 129 132 int isAbstract() { return storage_class & STCabstract; } 130 133 int isConst() { return storage_class & STCconst; } 131 int isInvariant() { return 0; }134 int isInvariant() { return storage_class & STCinvariant; } 132 135 int isAuto() { return storage_class & STCauto; } 133 136 int isScope() { return storage_class & STCscope; } … … 256 259 unsigned offset; 257 260 int noscope; // no scope semantics 261 #if DMDV2 262 FuncDeclarations nestedrefs; // referenced by these lexically nested functions 263 #else 258 264 int nestedref; // referenced by a lexically nested function 265 #endif 259 266 int ctorinit; // it has been initialized in a ctor 260 267 int onstack; // 1: it has been allocated on the stack … … 264 271 Expression *value; // when interpreting, this is the value 265 272 // (NULL if value not determinable) 266 Scope *scope; // !=NULL means context to use 273 #if DMDV2 274 VarDeclaration *rundtor; // if !NULL, rundtor is tested at runtime to see 275 // if the destructor should be run. Used to prevent 276 // dtor calls on postblitted vars 277 #endif 267 278 268 279 VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init); … … 279 290 int isImportedSymbol(); 280 291 int isDataseg(); 292 int isThreadlocal(); 281 293 int hasPointers(); 282 Expression *callScopeDtor(); 294 #if DMDV2 295 int canTakeAddressOf(); 296 int needsAutoDtor(); 297 #endif 298 Expression *callScopeDtor(Scope *sc); 283 299 ExpInitializer *getExpInitializer(); 300 Expression *getConstInitializer(); 284 301 void checkCtorConstInit(); 285 302 void checkNestedReference(Scope *sc, Loc loc); … … 346 363 347 364 void emitComment(Scope *sc); 365 void toJsonBuffer(OutBuffer *buf); 348 366 349 367 #if IN_DMD … … 363 381 364 382 void emitComment(Scope *sc); 383 void toJsonBuffer(OutBuffer *buf); 365 384 366 385 #if IN_DMD … … 378 397 379 398 void emitComment(Scope *sc); 399 void toJsonBuffer(OutBuffer *buf); 380 400 381 401 #if IN_DMD … … 617 637 Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments); 618 638 639 #else 640 enum BUILTIN { }; 619 641 #endif 620 642 … … 625 647 Statement *fensure; 626 648 Statement *fbody; 649 650 FuncDeclarations foverrides; // functions this function overrides 651 FuncDeclaration *fdrequire; // function that does the in contract 652 FuncDeclaration *fdensure; // function that does the out contract 627 653 628 654 Identifier *outId; // identifier for out statement … … 659 685 // this one is overriding 660 686 int inferRetType; // !=0 if return type is to be inferred 661 Scope *scope; // !=NULL means context to use662 687 663 688 // Things that should really go into Scope … … 693 718 void semantic2(Scope *sc); 694 719 void semantic3(Scope *sc); 720 // called from semantic3 721 void varArgs(Scope *sc, TypeFunction*, VarDeclaration *&, VarDeclaration *&); 722 695 723 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 696 724 void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 699 727 int overloadInsert(Dsymbol *s); 700 728 FuncDeclaration *overloadExactMatch(Type *t, Module* from); 701 FuncDeclaration *overloadResolve(Loc loc, Expressions *arguments, Module* from); 729 FuncDeclaration *overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, Module *from, int flags = 0); 730 MATCH leastAsSpecialized(FuncDeclaration *g); 702 731 LabelDsymbol *searchLabel(Identifier *ident); 703 732 AggregateDeclaration *isThis(); … … 707 736 void appendState(Statement *s); 708 737 char *mangle(); 738 const char *toPrettyChars(); 709 739 int isMain(); 710 740 int isWinMain(); 711 741 int isDllMain(); 742 enum BUILTIN isBuiltin(); 712 743 int isExport(); 713 744 int isImportedSymbol(); 714 745 int isAbstract(); 715 746 int isCodeseg(); 747 int isOverloadable(); 748 int isPure(); 716 749 virtual int isNested(); 717 750 int needThis(); … … 720 753 virtual int addPreInvariant(); 721 754 virtual int addPostInvariant(); 722 Expression *interpret(InterState *istate, Expressions *arguments );755 Expression *interpret(InterState *istate, Expressions *arguments, Expression *thisexp = NULL); 723 756 void inlineScan(); 724 757 int canInline(int hasthis, int hdrscan = 0); … … 726 759 const char *kind(); 727 760 void toDocBuffer(OutBuffer *buf); 761 FuncDeclaration *isUnique(); 762 int needsClosure(); 763 Statement *mergeFrequire(Statement *); 764 Statement *mergeFensure(Statement *); 728 765 729 766 // LDC: give argument types to runtime functions … … 736 773 void toObjFile(int multiobj); // compile to .obj file 737 774 int cvMember(unsigned char *p); 775 void buildClosure(IRState *irs); 738 776 #endif 739 777 … … 771 809 #endif 772 810 }; 811 812 #if DMDV2 813 FuncDeclaration *resolveFuncCall(Scope *sc, Loc loc, Dsymbol *s, 814 Objects *tiargs, 815 Expression *ethis, 816 Expressions *arguments, 817 int flags); 818 #endif 773 819 774 820 struct FuncAliasDeclaration : FuncDeclaration … … 832 878 int overloadInsert(Dsymbol *s); 833 879 void emitComment(Scope *sc); 880 void toJsonBuffer(OutBuffer *buf); 834 881 835 882 PostBlitDeclaration *isPostBlitDeclaration() { return this; } … … 844 891 void semantic(Scope *sc); 845 892 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 893 const char *kind(); 894 char *toChars(); 846 895 int isVirtual(); 847 896 int addPreInvariant(); … … 849 898 int overloadInsert(Dsymbol *s); 850 899 void emitComment(Scope *sc); 900 void toJsonBuffer(OutBuffer *buf); 851 901 852 902 DtorDeclaration *isDtorDeclaration() { return this; } … … 864 914 int addPostInvariant(); 865 915 void emitComment(Scope *sc); 916 void toJsonBuffer(OutBuffer *buf); 866 917 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 867 918 … … 881 932 int addPostInvariant(); 882 933 void emitComment(Scope *sc); 934 void toJsonBuffer(OutBuffer *buf); 883 935 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 884 936 … … 895 947 int addPostInvariant(); 896 948 void emitComment(Scope *sc); 949 void toJsonBuffer(OutBuffer *buf); 897 950 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 898 951 dmd/doc.c
r1133 r1587 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 8by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 34 34 #include "doc.h" 35 35 #include "mtype.h" 36 #include "utf.h" 36 37 37 38 struct Escape … … 90 91 int isDitto(unsigned char *comment); 91 92 unsigned char *skipwhitespace(unsigned char *p); 92 unsigned skiptoident(OutBuffer *buf, unsignedi);93 unsigned skippastident(OutBuffer *buf, unsignedi);94 unsigned skippastURL(OutBuffer *buf, unsignedi);93 unsigned skiptoident(OutBuffer *buf, size_t i); 94 unsigned skippastident(OutBuffer *buf, size_t i); 95 unsigned skippastURL(OutBuffer *buf, size_t i); 95 96 void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 96 97 void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 97 98 void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 98 99 Argument *isFunctionParameter(Dsymbol *s, unsigned char *p, unsigned len); 100 101 int isIdStart(unsigned char *p); 102 int isIdTail(unsigned char *p); 103 int utfStride(unsigned char *p); 99 104 100 105 static unsigned char ddoc_default[] = "\ … … 239 244 240 245 // Set the title to be the name of the module 241 { c har *p = toPrettyChars();246 { const char *p = toPrettyChars(); 242 247 Macro::define(¯otable, (unsigned char *)"TITLE", 5, (unsigned char *)p, strlen(p)); 243 248 } … … 675 680 #if DMDV2 676 681 if (d->isInvariant()) 677 buf->writestring("i nvariant");682 buf->writestring("immutable "); 678 683 #endif 679 684 if (d->isFinal()) … … 949 954 unsigned char *pstart; 950 955 unsigned char *pend; 951 unsigned char *q;952 956 unsigned char *idstart; 953 957 unsigned idlen; … … 964 968 965 969 /* Find end of section, which is ended by one of: 966 * 'identifier:' 970 * 'identifier:' (but not inside a code section) 967 971 * '\0' 968 972 */ 969 973 idlen = 0; 974 int inCode = 0; 970 975 while (1) 971 976 { 972 if (isalpha(*p) || *p == '_') 977 // Check for start/end of a code section 978 if (*p == '-') 973 979 { 974 q = p + 1; 975 while (isalnum(*q) || *q == '_') 976 q++; 980 int numdash = 0; 981 while (*p == '-') 982 { 983 ++numdash; 984 p++; 985 } 986 // BUG: handle UTF PS and LS too 987 if (!*p || *p == '\r' || *p == '\n' && numdash >= 3) 988 inCode ^= 1; 989 } 990 991 if (!inCode && isIdStart(p)) 992 { 993 unsigned char *q = p + utfStride(p); 994 while (isIdTail(q)) 995 q += utfStride(q); 977 996 if (*q == ':') // identifier: ends it 978 997 { idlen = q - p; … … 1142 1161 { 1143 1162 // Skip to start of macro 1144 for (; 1; p++)1163 while (1) 1145 1164 { 1146 1165 switch (*p) … … 1148 1167 case ' ': 1149 1168 case '\t': 1169 p++; 1150 1170 continue; 1151 1171 … … 1155 1175 1156 1176 default: 1157 if (!(isalpha(*p) || *p == '_')) 1158 { 1159 if (namelen) 1160 goto Ltext; // continuation of prev macro 1161 goto Lskipline; 1162 } 1163 break; 1177 if (isIdStart(p)) 1178 break; 1179 if (namelen) 1180 goto Ltext; // continuation of prev macro 1181 goto Lskipline; 1164 1182 } 1165 1183 break; … … 1167 1185 tempstart = p; 1168 1186 1169 while (is alnum(*p) || *p == '_')1170 p ++;1187 while (isIdTail(p)) 1188 p += utfStride(p); 1171 1189 templen = p - tempstart; 1172 1190 … … 1270 1288 { 1271 1289 // Skip to start of macro 1272 for (; 1; p++)1290 while (1) 1273 1291 { 1274 1292 if (p >= pend) … … 1278 1296 case ' ': 1279 1297 case '\t': 1298 p++; 1280 1299 continue; 1281 1300 … … 1285 1304 1286 1305 default: 1287 if (!(isalpha(*p) || *p == '_')) 1288 { 1289 if (namelen) 1290 goto Ltext; // continuation of prev macro 1291 goto Lskipline; 1292 } 1293 break; 1306 if (isIdStart(p)) 1307 break; 1308 if (namelen) 1309 goto Ltext; // continuation of prev macro 1310 goto Lskipline; 1294 1311 } 1295 1312 break; … … 1301 1318 if (p >= pend) 1302 1319 goto Ldone; 1303 if (! (isalnum(*p) || *p == '_'))1320 if (!isIdTail(p)) 1304 1321 break; 1305 p ++;1322 p += utfStride(p); 1306 1323 } 1307 1324 templen = p - tempstart; … … 1487 1504 */ 1488 1505 1489 unsigned skiptoident(OutBuffer *buf, unsigned i) 1490 { 1491 for (; i < buf->offset; i++) 1492 { 1493 // BUG: handle unicode alpha's 1494 unsigned char c = buf->data[i]; 1495 if (isalpha(c) || c == '_') 1506 unsigned skiptoident(OutBuffer *buf, size_t i) 1507 { 1508 while (i < buf->offset) 1509 { dchar_t c; 1510 1511 size_t oi = i; 1512 if (utf_decodeChar((unsigned char *)buf->data, buf->offset, &i, &c)) 1513 /* Ignore UTF errors, but still consume input 1514 */ 1496 1515 break; 1497 if (c == '\n') 1498 break; 1516 if (c >= 0x80) 1517 { 1518 if (!isUniAlpha(c)) 1519 continue; 1520 } 1521 else if (!(isalpha(c) || c == '_' || c == '\n')) 1522 continue; 1523 i = oi; 1524 break; 1499 1525 } 1500 1526 return i; … … 1505 1531 */ 1506 1532 1507 unsigned skippastident(OutBuffer *buf, unsigned i) 1508 { 1509 for (; i < buf->offset; i++) 1510 { 1511 // BUG: handle unicode alpha's 1512 unsigned char c = buf->data[i]; 1513 if (!(isalnum(c) || c == '_')) 1533 unsigned skippastident(OutBuffer *buf, size_t i) 1534 { 1535 while (i < buf->offset) 1536 { dchar_t c; 1537 1538 size_t oi = i; 1539 if (utf_decodeChar((unsigned char *)buf->data, buf->offset, &i, &c)) 1540 /* Ignore UTF errors, but still consume input 1541 */ 1514 1542 break; 1543 if (c >= 0x80) 1544 { 1545 if (isUniAlpha(c)) 1546 continue; 1547 } 1548 else if (isalnum(c) || c == '_') 1549 continue; 1550 i = oi; 1551 break; 1515 1552 } 1516 1553 return i; … … 1526 1563 */ 1527 1564 1528 unsigned skippastURL(OutBuffer *buf, unsignedi)1565 unsigned skippastURL(OutBuffer *buf, size_t i) 1529 1566 { unsigned length = buf->offset - i; 1530 1567 unsigned char *p = &buf->data[i]; … … 1811 1848 default: 1812 1849 leadingBlank = 0; 1813 if (sc && !inCode && (isalpha(c) || c == '_'))1850 if (sc && !inCode && isIdStart(&buf->data[i])) 1814 1851 { unsigned j; 1815 1852 … … 1882 1919 i--; // point to ';' 1883 1920 } 1884 else if (is alpha(c) || c == '_')1921 else if (isIdStart(&buf->data[i])) 1885 1922 { unsigned j; 1886 1923 … … 2018 2055 } 2019 2056 2057 /**************************************** 2058 * Determine if p points to the start of an identifier. 2059 */ 2060 2061 int isIdStart(unsigned char *p) 2062 { 2063 unsigned c = *p; 2064 if (isalpha(c) || c == '_') 2065 return 1; 2066 if (c >= 0x80) 2067 { size_t i = 0; 2068 if (utf_decodeChar(p, 4, &i, &c)) 2069 return 0; // ignore errors 2070 if (isUniAlpha(c)) 2071 return 1; 2072 } 2073 return 0; 2074 } 2075 2076 /**************************************** 2077 * Determine if p points to the rest of an identifier. 2078 */ 2079 2080 int isIdTail(unsigned char *p) 2081 { 2082 unsigned c = *p; 2083 if (isalnum(c) || c == '_') 2084 return 1; 2085 if (c >= 0x80) 2086 { size_t i = 0; 2087 if (utf_decodeChar(p, 4, &i, &c)) 2088 return 0; // ignore errors 2089 if (isUniAlpha(c)) 2090 return 1; 2091 } 2092 return 0; 2093 } 2094 2095 /***************************************** 2096 * Return number of bytes in UTF character. 2097 */ 2098 2099 int utfStride(unsigned char *p) 2100 { 2101 unsigned c = *p; 2102 if (c < 0x80) 2103 return 1; 2104 size_t i = 0; 2105 utf_decodeChar(p, 4, &i, &c); // ignore errors, but still consume input 2106 return i; 2107 } dmd/dsymbol.c
r1358 r1587 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 8by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 29 29 #include "import.h" 30 30 #include "template.h" 31 31 #include "attrib.h" 32 32 #include "../gen/enums.h" 33 33 … … 46 46 this->loc = 0; 47 47 this->comment = NULL; 48 48 this->scope = NULL; 49 49 #if IN_LLVM 50 50 this->llvmInternal = LLVMnone; … … 65 65 this->loc = 0; 66 66 this->comment = NULL; 67 67 this->scope = NULL; 68 68 #if IN_LLVM 69 69 this->llvmInternal = LLVMnone; … … 165 165 } 166 166 167 c har *Dsymbol::toPrettyChars()167 const char *Dsymbol::toPrettyChars() 168 168 { Dsymbol *p; 169 169 char *s; … … 191 191 break; 192 192 q--; 193 #if TARGET_NET 194 if (AggregateDeclaration* ad = p->isAggregateDeclaration()) 195 { 196 if (ad->isNested() && p->parent && p->parent->isAggregateDeclaration()) 197 { 198 *q = '/'; 199 continue; 200 } 201 } 202 #endif 193 203 *q = '.'; 194 204 } … … 267 277 } 268 278 279 /************************************* 280 * Set scope for future semantic analysis so we can 281 * deal better with forward references. 282 */ 283 284 void Dsymbol::setScope(Scope *sc) 285 { 286 //printf("Dsymbol::setScope() %p %s\n", this, toChars()); 287 if (!sc->nofree) 288 sc->setNoFree(); // may need it even after semantic() finishes 289 scope = sc; 290 } 291 292 void Dsymbol::importAll(Scope *sc) 293 { 294 } 295 296 /************************************* 297 * Does semantic analysis on the public face of declarations. 298 */ 299 269 300 void Dsymbol::semantic(Scope *sc) 270 301 { … … 272 303 } 273 304 305 /************************************* 306 * Does semantic analysis on initializers and members of aggregates. 307 */ 308 274 309 void Dsymbol::semantic2(Scope *sc) 275 310 { … … 277 312 } 278 313 314 /************************************* 315 * Does semantic analysis on function bodies. 316 */ 317 279 318 void Dsymbol::semantic3(Scope *sc) 280 319 { … … 282 321 } 283 322 323 /************************************* 324 * Look for function inlining possibilities. 325 */ 326 284 327 void Dsymbol::inlineScan() 285 328 { 286 // Most Dsymbols have no further semantic analysis needed329 // Most Dsymbols aren't functions 287 330 } 288 331 … … 342 385 } 343 386 ti->tempdecl = td; 344 if (!ti->semantic done)387 if (!ti->semanticRun) 345 388 ti->semantic(sc); 346 389 sm = ti->toAlias(); … … 408 451 return FALSE; 409 452 } 453 454 #if DMDV2 455 int Dsymbol::isOverloadable() 456 { 457 return 0; 458 } 459 #endif 410 460 411 461 LabelDsymbol *Dsymbol::isLabel() // is this a LabelDsymbol()? … … 440 490 if (!isAnonymous()) // no name, so can't add it to symbol table 441 491 { 442 if (!sd->symtab ->insert(this)) // if name is already defined492 if (!sd->symtabInsert(this)) // if name is already defined 443 493 { 444 494 Dsymbol *s2; … … 632 682 void Dsymbol::addComment(unsigned char *comment) 633 683 { 634 //if (comment)635 //printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars());684 //if (comment) 685 //printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); 636 686 637 687 if (!this->comment) … … 644 694 #endif 645 695 } 696 697 /********************************* OverloadSet ****************************/ 698 699 #if DMDV2 700 OverloadSet::OverloadSet() 701 : Dsymbol() 702 { 703 } 704 705 void OverloadSet::push(Dsymbol *s) 706 { 707 a.push(s); 708 } 709 710 const char *OverloadSet::kind() 711 { 712 return "overloadset"; 713 } 714 #endif 646 715 647 716 … … 682 751 { 683 752 //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags); 753 //if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0; 684 754 685 755 // Look in symbols declared in this module … … 772 842 773 843 ss = (ScopeDsymbol *) imports->data[i]; 774 if (ss == s) 844 if (ss == s) // if already imported 775 845 { 776 846 if (protection > prots[i]) … … 850 920 } 851 921 922 Dsymbol *ScopeDsymbol::symtabInsert(Dsymbol *s) 923 { 924 return symtab->insert(s); 925 } 926 927 /*************************************** 928 * Determine number of Dsymbols, folding in AttribDeclaration members. 929 */ 930 931 #if DMDV2 932 size_t ScopeDsymbol::dim(Array *members) 933 { 934 size_t n = 0; 935 if (members) 936 { 937 for (size_t i = 0; i < members->dim; i++) 938 { Dsymbol *s = (Dsymbol *)members->data[i]; 939 AttribDeclaration *a = s->isAttribDeclaration(); 940 941 if (a) 942 { 943 n += dim(a->decl); 944 } 945 else 946 n++; 947 } 948 } 949 return n; 950 } 951 #endif 952 953 /*************************************** 954 * Get nth Dsymbol, folding in AttribDeclaration members. 955 * Returns: 956 * Dsymbol* nth Dsymbol 957 * NULL not found, *pn gets incremented by the number 958 * of Dsymbols 959 */ 960 961 #if DMDV2 962 Dsymbol *ScopeDsymbol::getNth(Array *members, size_t nth, size_t *pn) 963 { 964 if (!members) 965 return NULL; 966 967 size_t n = 0; 968 for (size_t i = 0; i < members->dim; i++) 969 { Dsymbol *s = (Dsymbol *)members->data[i]; 970 AttribDeclaration *a = s->isAttribDeclaration(); 971 972 if (a) 973 { 974 s = getNth(a->decl, nth - n, &n); 975 if (s) 976 return s; 977 } 978 else if (n == nth) 979 return s; 980 else 981 n++; 982 } 983 984 if (pn) 985 *pn += n; 986 return NULL; 987 } 988 #endif 852 989 853 990 /******************************************* … … 939 1076 940 1077 if (td) 941 { 1078 { /* $ gives the number of elements in the tuple 1079 */ 942 1080 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 943 1081 Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); … … 948 1086 949 1087 if (type) 950 { 1088 { /* $ gives the number of type entries in the type tuple 1089 */ 951 1090 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 952 1091 Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); … … 957 1096 958 1097 if (exp->op == TOKindex) 959 { 1098 { /* array[index] where index is some function of $ 1099 */ 960 1100 IndexExp *ie = (IndexExp *)exp; 961 1101 … … 964 1104 } 965 1105 else if (exp->op == TOKslice) 966 { 1106 { /* array[lwr .. upr] where lwr or upr is some function of $ 1107 */ 967 1108 SliceExp *se = (SliceExp *)exp; 968 1109 … … 971 1112 } 972 1113 else 1114 /* Didn't find $, look in enclosing scope(s). 1115 */ 973 1116 return NULL; 974 1117 1118 /* If we are indexing into an array that is really a type 1119 * tuple, rewrite this as an index into a type tuple and 1120 * try again. 1121 */ 975 1122 if (ce->op == TOKtype) 976 1123 { … … 982 1129 } 983 1130 984 if (!*pvar) 985 { 1131 /* *pvar is lazily initialized, so if we refer to $ 1132 * multiple times, it gets set only once. 1133 */ 1134 if (!*pvar) // if not already initialized 1135 { /* Create variable v and set it to the value of $, 1136 * which will be a constant. 1137 */ 986 1138 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 987 1139 … … 1031 1183 1032 1184 Dsymbol *DsymbolTable::lookup(Identifier *ident) 1033 { StringValue *sv; 1034 1185 { 1035 1186 #ifdef DEBUG 1036 1187 assert(ident); 1037 1188 assert(tab); 1038 1189 #endif 1039 sv = tab->lookup((char*)ident->string, ident->len);1190 StringValue *sv = tab->lookup((char*)ident->string, ident->len); 1040 1191 return (Dsymbol *)(sv ? sv->ptrvalue : NULL); 1041 1192 } dmd/dsymbol.h
r1372 r1587 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 8by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 29 29 struct DsymbolTable; 30 30 struct Declaration; 31 struct ThisDeclaration; 31 32 struct TupleDeclaration; 32 33 struct TypedefDeclaration; … … 42 43 struct FuncLiteralDeclaration; 43 44 struct CtorDeclaration; 45 struct PostBlitDeclaration; 44 46 struct DtorDeclaration; 45 47 struct StaticCtorDeclaration; … … 71 73 struct TypeInfoDeclaration; 72 74 struct ClassInfoDeclaration; 73 75 struct OverloadSet; 76 #if TARGET_NET 77 struct PragmaScope; 78 #endif 74 79 #if IN_DMD 75 80 struct Symbol; 76 81 #endif 77 78 82 #if IN_GCC 79 83 union tree_node; … … 82 86 struct TYPE; 83 87 #endif 88 89 // Back end 90 struct Classsym; 84 91 85 92 #if IN_LLVM … … 115 122 unsigned char *comment; // documentation comment for this Dsymbol 116 123 Loc loc; // where defined 124 Scope *scope; // !=NULL means context to use for semantic() 117 125 118 126 Dsymbol(); 119 127 Dsymbol(Identifier *); 120 128 char *toChars(); 121 char *toPrettyChars();122 129 char *locToChars(); 123 130 int equals(Object *o); … … 137 144 static Array *arraySyntaxCopy(Array *a); 138 145 146 virtual const char *toPrettyChars(); 139 147 virtual const char *kind(); 140 148 virtual Dsymbol *toAlias(); // resolve real symbol 141 149 virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 150 virtual void setScope(Scope *sc); 151 virtual void importAll(Scope *sc); 142 152 virtual void semantic(Scope *sc); 143 153 virtual void semantic2(Scope *sc); … … 153 163 virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 154 164 virtual void toDocBuffer(OutBuffer *buf); 165 virtual void toJsonBuffer(OutBuffer *buf); 155 166 virtual unsigned size(Loc loc); 156 167 virtual int isforwardRef(); … … 161 172 virtual int isImportedSymbol(); // is Dsymbol imported? 162 173 virtual int isDeprecated(); // is Dsymbol deprecated? 174 #if DMDV2 175 virtual int isOverloadable(); 176 #endif 163 177 virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol? 164 178 virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration? … … 199 213 virtual TemplateMixin *isTemplateMixin() { return NULL; } 200 214 virtual Declaration *isDeclaration() { return NULL; } 215 virtual ThisDeclaration *isThisDeclaration() { return NULL; } 201 216 virtual TupleDeclaration *isTupleDeclaration() { return NULL; } 202 217 virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; } … … 207 222 virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; } 208 223 virtual CtorDeclaration *isCtorDeclaration() { return NULL; } 224 virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; } 209 225 virtual DtorDeclaration *isDtorDeclaration() { return NULL; } 210 226 virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; } … … 231 247 virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; } 232 248 249 virtual OverloadSet *isOverloadSet() { return NULL; } 250 #if TARGET_NET 251 virtual PragmaScope* isPragmaScope() { return NULL; } 252 #endif 253 233 254 #if IN_LLVM 234 255 /// Codegen traversal … … 251 272 252 273 Array *imports; // imported ScopeDsymbol's 253 unsigned char *prots; // PROTfor each import274 unsigned char *prots; // array of PROT, one for each import 254 275 255 276 ScopeDsymbol(); … … 263 284 Dsymbol *nameCollision(Dsymbol *s); 264 285 const char *kind(); 286 FuncDeclaration *findGetMembers(); 287 virtual Dsymbol *symtabInsert(Dsymbol *s); 265 288 266 289 void emitMemberComments(Scope *sc); 290 291 static size_t dim(Array *members); 292 static Dsymbol *getNth(Array *members, size_t nth, size_t *pn = NULL); 267 293 268 294 ScopeDsymbol *isScopeDsymbol() { return this; } … … 288 314 TypeTuple *type; // for tuple[length] 289 315 TupleDeclaration *td; // for tuples of objects 316 Scope *sc; 290 317 291 318 ArrayScopeSymbol(Expression *e); … … 297 324 }; 298 325 326 // Overload Sets 327 328 #if DMDV2 329 struct OverloadSet : Dsymbol 330 { 331 Dsymbols a; // array of Dsymbols 332 333 OverloadSet(); 334 void push(Dsymbol *s); 335 OverloadSet *isOverloadSet() { return this; } 336 const char *kind(); 337 }; 338 #endif 339 299 340 // Table of Dsymbol's 300 341 dmd/enum.h
r1195 r1587 28 28 29 29 struct EnumDeclaration : ScopeDsymbol 30 { 30 { /* enum ident : memtype { ... } 31 */ 31 32 Type *type; // the TypeEnum 32 33 Type *memtype; // type of the members … … 40 41 Expression *minval; 41 42 Expression *defaultval; // default initializer 42 43 Scope *scope; // !=NULL means context to use44 43 #endif 45 44 int isdeprecated; … … 58 57 59 58 void emitComment(Scope *sc); 59 void toJsonBuffer(OutBuffer *buf); 60 60 void toDocBuffer(OutBuffer *buf); 61 61 … … 87 87 88 88 void emitComment(Scope *sc); 89 void toJsonBuffer(OutBuffer *buf); 89 90 void toDocBuffer(OutBuffer *buf); 90 91 dmd/expression.c
r1530 r1587 36 36 37 37 #include "rmem.h" 38 39 //#include "port.h" 38 #include "port.h" 39 40 40 #include "mtype.h" 41 41 #include "init.h" … … 374 374 375 375 } 376 else if (e->op == TOKdottd) 377 { 378 e = new CallExp(e->loc, e); 379 e = e->semantic(sc); 380 } 376 381 return e; 377 382 } … … 544 549 545 550 if (nargs > nparams && tf->varargs == 0) 546 error(loc, "expected %zu arguments, not %zu ", nparams, nargs);551 error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars()); 547 552 548 553 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) … … 569 574 if (tf->varargs == 2 && i + 1 == nparams) 570 575 goto L2; 571 error(loc, "expected %zu arguments, not %zu", nparams, nargs);576 error(loc, "expected %zu function arguments, not %zu", nparams, nargs); 572 577 break; 573 578 } … … 591 596 { 592 597 if (nargs != nparams) 593 error(loc, "expected %zu arguments, not %zu", nparams, nargs);598 error(loc, "expected %zu function arguments, not %zu", nparams, nargs); 594 599 goto L1; 595 600 } … … 670 675 L1: 671 676 if (!(p->storageClass & STClazy && p->type->ty == Tvoid)) 672 arg = arg->implicitCastTo(sc, p->type); 677 { 678 if (p->type != arg->type) 679 { 680 //printf("arg->type = %s, p->type = %s\n", arg->type->toChars(), p->type->toChars()); 681 if (arg->op == TOKtype) 682 arg->error("cannot pass type %s as function argument", arg->toChars()); 683 arg = arg->implicitCastTo(sc, p->type); 684 arg = arg->optimize(WANTvalue); 685 } 686 } 673 687 if (p->storageClass & (STCout | STCref)) 674 688 { … … 774 788 arg = callCpCtor(loc, sc, arg); 775 789 } 790 #endif 776 791 777 792 // Give error for overloaded function addresses 793 #if DMDV2 778 794 if (arg->op == TOKsymoff) 779 795 { SymOffExp *se = (SymOffExp *)arg; 780 if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique()) 796 if ( 797 se->hasOverloads && 798 !se->var->isFuncDeclaration()->isUnique()) 781 799 arg->error("function %s is overloaded", arg->toChars()); 782 800 } … … 1215 1233 { 1216 1234 //printf("Expression::deref()\n"); 1217 if (type->ty == Treference)1218 { Expression *e;1219 1220 e = new PtrExp(loc, this);1235 // type could be null if forward referencing an 'auto' variable 1236 if (type && type->ty == Treference) 1237 { 1238 Expression *e = new PtrExp(loc, this); 1221 1239 e->type = ((TypeReference *)type)->next; 1222 1240 return e; … … 2156 2174 if (f) 2157 2175 { //printf("'%s' is a function\n", f->toChars()); 2176 if (!f->type->deco) 2177 { 2178 error("forward reference to %s", toChars()); 2179 } 2158 2180 return new VarExp(loc, f); 2159 2181 } … … 2210 2232 TemplateInstance *ti = s->isTemplateInstance(); 2211 2233 if (ti && !global.errors) 2212 { if (!ti->semantic done)2234 { if (!ti->semanticRun) 2213 2235 ti->semantic(sc); 2214 2236 s = ti->inst->toAlias(); … … 3167 3189 { e = v->init->toExpression(); 3168 3190 if (!e) 3169 error("cannot make expression out of initializer for %s", v->toChars()); 3191 { error("cannot make expression out of initializer for %s", v->toChars()); 3192 e = new ErrorExp(); 3193 } 3194 else if (v->scope) 3195 { // Do deferred semantic anaylsis 3196 Initializer *i2 = v->init->syntaxCopy(); 3197 i2 = i2->semantic(v->scope, v->type); 3198 e = i2->toExpression(); 3199 v->scope = NULL; 3200 } 3170 3201 } 3171 3202 else … … 3201 3232 if (e) 3202 3233 { 3203 e = e->copy(); 3204 e->type = type; 3234 //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars()); 3235 3236 /* If type is a static array, and e is an initializer for that array, 3237 * then the field initializer should be an array literal of e. 3238 */ 3239 if (e->type != type && type->ty == Tsarray) 3240 { TypeSArray *tsa = (TypeSArray *)type; 3241 uinteger_t length = tsa->dim->toInteger(); 3242 Expressions *z = new Expressions; 3243 z->setDim(length); 3244 for (int q = 0; q < length; ++q) 3245 z->data[q] = e->copy(); 3246 e = new ArrayLiteralExp(loc, z); 3247 e->type = type; 3248 } 3249 else 3250 { 3251 e = e->copy(); 3252 e->type = type; 3253 } 3205 3254 } 3206 3255 } … … 3217 3266 /* Find which field offset is by looking at the field offsets 3218 3267 */ 3219 for (size_t i = 0; i < sd->fields.dim; i++) 3220 { 3221 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 3222 VarDeclaration *v = s->isVarDeclaration(); 3223 assert(v); 3224 3225 if (offset == v->offset && 3226 type->size() == v->type->size()) 3227 { Expression *e = (Expression *)elements->data[i]; 3228 if (e) 3229 { 3230 return i; 3231 } 3232 break; 3268 if (elements->dim) 3269 { 3270 for (size_t i = 0; i < sd->fields.dim; i++) 3271 { 3272 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 3273 VarDeclaration *v = s->isVarDeclaration(); 3274 assert(v); 3275 3276 if (offset == v->offset && 3277 type->size() == v->type->size()) 3278 { Expression *e = (Expression *)elements->data[i]; 3279 if (e) 3280 { 3281 return i; 3282 } 3283 break; 3284 } 3233 3285 } 3234 3286 } … … 3366 3418 if (ti && !global.errors) 3367 3419 { Dsymbol *s; 3368 if (!ti->semantic done)3420 if (!ti->semanticRun) 3369 3421 ti->semantic(sc); 3370 3422 s = ti->inst->toAlias(); … … 3584 3636 error("e.new is only for allocating nested classes"); 3585 3637 else if (fdn) 3586 {3638 { 3587 3639 // make sure the parent context fdn of cd is reachable from sc 3588 3640 for (Dsymbol *sp = sc->parent; 1; sp = sp->parent) … … 3607 3659 { 3608 3660 assert(f); 3609 f = f->overloadResolve(loc, arguments, sc->module);3661 f = f->overloadResolve(loc, NULL, arguments, sc->module); 3610 3662 checkDeprecated(sc, f); 3611 3663 member = f->isCtorDeclaration(); … … 3635 3687 newargs->shift(e); 3636 3688 3637 f = cd->aggNew->overloadResolve(loc, newargs, sc->module);3689 f = cd->aggNew->overloadResolve(loc, NULL, newargs, sc->module); 3638 3690 allocator = f->isNewDeclaration(); 3639 3691 assert(allocator); … … 3668 3720 newargs->shift(e); 3669 3721 3670 f = f->overloadResolve(loc, newargs, sc->module);3722 f = f->overloadResolve(loc, NULL, newargs, sc->module); 3671 3723 allocator = f->isNewDeclaration(); 3672 3724 assert(allocator); … … 4201 4253 } 4202 4254 type = new TypeTuple(exps); 4255 type = type->semantic(loc, sc); 4203 4256 //printf("-TupleExp::semantic(%s)\n", toChars()); 4204 4257 return this; … … 4264 4317 if (global.errors) 4265 4318 { 4266 if (!fd->type->next)4267 fd->type->next = Type::terror;4268 4319 } 4269 4320 else 4270 4321 { 4271 4322 fd->semantic2(sc); 4272 if (!global.errors) 4323 if (!global.errors || 4324 // need to infer return type 4325 (fd->type && fd->type->ty == Tfunction && !fd->type->nextOf())) 4273 4326 { 4274 4327 fd->semantic3(sc); … … 4278 4331 } 4279 4332 } 4333 4334 // need to infer return type 4335 if (global.errors && fd->type && fd->type->ty == Tfunction && !fd->type->nextOf()) 4336 ((TypeFunction *)fd->type)->next = Type::terror; 4280 4337 4281 4338 // Type is a "delegate to" or "pointer to" the function literal … … 4378 4435 if (!s->isVarDeclaration()) 4379 4436 { 4380 declaration->semantic(sc); 4437 Scope *sc2 = sc; 4438 if (sc2->stc & (STCpure | STCnothrow)) 4439 sc2 = sc->push(); 4440 sc2->stc &= ~(STCpure | STCnothrow); 4441 declaration->semantic(sc2); 4442 if (sc2 != sc) 4443 sc2->pop(); 4381 4444 s->parent = sc->parent; 4382 4445 } … … 4921 4984 if (op == TOKmodass && e2->type->iscomplex()) 4922 4985 { error("cannot perform modulo complex arithmetic"); 4923 return new IntegerExp(0);4986 return new ErrorExp(); 4924 4987 } 4925 4988 } … … 4986 5049 } 4987 5050 5051 // generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary 5052 void BinExp::checkComplexMulAssign() 5053 { 5054 // Any multiplication by an imaginary or complex number yields a complex result. 5055 // r *= c, i*=c, r*=i, i*=i are all forbidden operations. 5056 const char *opstr = Token::toChars(op); 5057 if ( e1->type->isreal() && e2->type->iscomplex()) 5058 { 5059 error("%s %s %s is undefined. Did you mean %s %s %s.re ?", 5060 e1->type->toChars(), opstr, e2->type->toChars(), 5061 e1->type->toChars(), opstr, e2->type->toChars()); 5062 } 5063 else if (e1->type->isimaginary() && e2->type->iscomplex()) 5064 { 5065 error("%s %s %s is undefined. Did you mean %s %s %s.im ?", 5066 e1->type->toChars(), opstr, e2->type->toChars(), 5067 e1->type->toChars(), opstr, e2->type->toChars()); 5068 } 5069 else if ((e1->type->isreal() || e1->type->isimaginary()) && 5070 e2->type->isimaginary()) 5071 { 5072 error("%s %s %s is an undefined operation", e1->type->toChars(), 5073 opstr, e2->type->toChars()); 5074 } 5075 } 5076 5077 // generate an error if this is a nonsensical += or -=, eg real += imaginary 5078 void BinExp::checkComplexAddAssign() 5079 { 5080 // Addition or subtraction of a real and an imaginary is a complex result. 5081 // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations. 5082 if ( (e1->type->isreal() && (e2->type->isimaginary() || e2->type->iscomplex())) || 5083 (e1->type->isimaginary() && (e2->type->isreal() || e2->type->iscomplex())) 5084 ) 5085 { 5086 error("%s %s %s is undefined (result is complex)", 5087 e1->type->toChars(), Token::toChars(op), e2->type->toChars()); 5088 } 5089 } 5090 4988 5091 void BinExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4989 5092 { … … 5095 5198 5096 5199 if (global.params.verbose) 5097 printf("file %s\t(%s)\n", (char *)se->string, name);5200 printf("file %s\t(%s)\n", (char *)se->string, name); 5098 5201 5099 5202 { File f(name); … … 5178 5281 int AssertExp::canThrow() 5179 5282 { 5180 return (global.params.useAssert != 0); 5283 /* assert()s are non-recoverable errors, so functions that 5284 * use them can be considered "nothrow" 5285 */ 5286 return 0; //(global.params.useAssert != 0); 5181 5287 } 5182 5288 #endif … … 5480 5586 ident != Id::alignof && ident != Id::offsetof && 5481 5587 ident != Id::mangleof && ident != Id::stringof) 5482 { 5588 { /* Rewrite: 5589 * p.ident 5590 * as: 5591 * (*p).ident 5592 */ 5483 5593 e = new PtrExp(loc, e1); 5484 5594 e->type = ((TypePointer *)e1->type)->next; … … 5599 5709 if (!type && global.errors) 5600 5710 { // var is goofed up, just return 0 5601 return new IntegerExp(0);5711 return new ErrorExp(); 5602 5712 } 5603 5713 assert(type); … … 5936 6046 { 5937 6047 Expressions *arguments = new Expressions(); 5938 arguments->setDim(1); 5939 arguments->data[0] = (void *)earg1; 5940 6048 if (earg1) 6049 { arguments->setDim(1); 6050 arguments->data[0] = (void *)earg1; 6051 } 5941 6052 this->arguments = arguments; 5942 6053 } … … 6041 6152 { ScopeExp *se = (ScopeExp *)e1; 6042 6153 TemplateInstance *ti = se->sds->isTemplateInstance(); 6043 if (ti && !ti->semantic done)6154 if (ti && !ti->semanticRun) 6044 6155 { 6045 6156 /* Attempt to instantiate ti. If that works, go with it. … … 6068 6179 { DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1; 6069 6180 TemplateInstance *ti = se->ti; 6070 if (!ti->semantic done)6181 if (!ti->semanticRun) 6071 6182 { 6072 6183 /* Attempt to instantiate ti. If that works, go with it. … … 6164 6275 { 6165 6276 ad = ((TypeStruct *)t1)->sym; 6277 #if DMDV2 6278 // First look for constructor 6279 if (ad->ctor && arguments && arguments->dim) 6280 { 6281 // Create variable that will get constructed 6282 Identifier *idtmp = Lexer::uniqueId("__ctmp"); 6283 VarDeclaration *tmp = new VarDeclaration(loc, t1, idtmp, NULL); 6284 Expression *av = new DeclarationExp(loc, tmp); 6285 av = new CommaExp(loc, av, new VarExp(loc, tmp)); 6286 6287 Expression *e; 6288 CtorDeclaration *cf = ad->ctor->isCtorDeclaration(); 6289 if (cf) 6290 e = new DotVarExp(loc, av, cf, 1); 6291 else 6292 { TemplateDeclaration *td = ad->ctor->isTemplateDeclaration(); 6293 assert(td); 6294 e = new DotTemplateExp(loc, av, td); 6295 } 6296 e = new CallExp(loc, e, arguments); 6297 #if !STRUCTTHISREF 6298 /* Constructors return a pointer to the instance 6299 */ 6300 e = new PtrExp(loc, e); 6301 #endif 6302 e = e->semantic(sc); 6303 return e; 6304 } 6305 #endif 6306 // No constructor, look for overload of opCall 6166 6307 if (search_function(ad, Id::call)) 6167 6308 goto L1; // overload of opCall, therefore it's a call … … 6206 6347 f = dve->var->isFuncDeclaration(); 6207 6348 assert(f); 6208 f = f->overloadResolve(loc, arguments, sc->module);6349 f = f->overloadResolve(loc, NULL, arguments, sc->module); 6209 6350 6210 6351 ad = f->toParent()->isAggregateDeclaration(); … … 6307 6448 } 6308 6449 6309 f = f->overloadResolve(loc, arguments, sc->module);6450 f = f->overloadResolve(loc, NULL, arguments, sc->module); 6310 6451 checkDeprecated(sc, f); 6311 6452 #if DMDV2 … … 6347 6488 6348 6489 f = cd->ctor; 6349 f = f->overloadResolve(loc, arguments, sc->module);6490 f = f->overloadResolve(loc, NULL, arguments, sc->module); 6350 6491 checkDeprecated(sc, f); 6351 6492 #if DMDV2 … … 6441 6582 } 6442 6583 6443 f = f->overloadResolve(loc, arguments, sc->module);6584 f = f->overloadResolve(loc, NULL, arguments, sc->module); 6444 6585 checkDeprecated(sc, f); 6445 6586 #if DMDV2 … … 6524 6665 int CallExp::canThrow() 6525 6666 { 6667 //printf("CallExp::canThrow() %s\n", toChars()); 6526 6668 if (e1->canThrow()) 6527 6669 return 1; … … 6532 6674 { Expression *e = (Expression *)arguments->data[i]; 6533 6675 6534 if (e ->canThrow())6676 if (e && e->canThrow()) 6535 6677 return 1; 6536 6678 } 6679 6680 if (global.errors && !e1->type) 6681 return 0; // error recovery 6537 6682 6538 6683 /* If calling a function or delegate that is typed as nothrow, … … 6553 6698 int CallExp::isLvalue() 6554 6699 { 6555 if (type->toBasetype()->ty == Tstruct)6556 return 1;6700 // if (type->toBasetype()->ty == Tstruct) 6701 // return 1; 6557 6702 Type *tb = e1->type->toBasetype(); 6558 6703 if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref) … … 6564 6709 Expression *CallExp::toLvalue(Scope *sc, Expression *e) 6565 6710 { 6711 #if 1 6566 6712 if (type->toBasetype()->ty == Tstruct) 6567 6713 return this; 6568 6714 else 6715 #endif 6569 6716 return Expression::toLvalue(sc, e); 6717 } 6718 6719 Expression *CallExp::modifiableLvalue(Scope *sc, Expression *e) 6720 { 6721 #if 1 6722 return Expression::modifiableLvalue(sc, e); 6723 #else 6724 /* Although function return values being usable as "ref" parameters is 6725 * unsound, disabling it breaks existing code. 6726 * Bugzilla 3167 6727 */ 6728 error("cannot assign to function call"); 6729 return toLvalue(sc, e); 6730 #endif 6570 6731 } 6571 6732 … … 6601 6762 { 6602 6763 error("cannot take address of %s", e1->toChars()); 6603 type = Type::tint32; 6604 return this; 6764 return new ErrorExp(); 6765 } 6766 if (!e1->type->deco) 6767 { 6768 /* No deco means semantic() was not run on the type. 6769 * We have to run semantic() on the symbol to get the right type: 6770 * auto x = &bar; 6771 * pure: int bar() { return 1;} 6772 * otherwise the 'pure' is missing from the type assigned to x. 6773 */ 6774 6775 error("forward reference to %s", e1->toChars()); 6776 return new ErrorExp(); 6605 6777 } 6606 6778 type = e1->type->pointerTo(); … … 6654 6826 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) 6655 6827 { 6656 if (e->type)6657 type = ((TypePointer *)e->type)->next;6828 // if (e->type) 6829 // type = ((TypePointer *)e->type)->next; 6658 6830 } 6659 6831 … … 6665 6837 6666 6838 Expression *PtrExp::semantic(Scope *sc) 6667 { Type *tb; 6668 6839 { 6669 6840 #if LOGSEMANTIC 6670 6841 printf("PtrExp::semantic('%s')\n", toChars()); 6671 6842 #endif 6672 UnaExp::semantic(sc); 6673 e1 = resolveProperties(sc, e1); 6674 if (type) 6675 return this; 6676 if (!e1->type) 6677 printf("PtrExp::semantic('%s')\n", toChars()); 6678 tb = e1->type->toBasetype(); 6679 switch (tb->ty) 6680 { 6681 case Tpointer: 6682 type = tb->next; 6683 if (type->isbit()) 6684 { Expression *e; 6685 6686 // Rewrite *p as p[0] 6687 e = new IndexExp(loc, e1, new IntegerExp(0)); 6688 return e->semantic(sc); 6689 } 6690 break; 6691 6692 case Tsarray: 6693 case Tarray: 6694 type = tb->next; 6695 e1 = e1->castTo(sc, type->pointerTo()); 6696 break; 6697 6698 default: 6699 error("can only * a pointer, not a '%s'", e1->type->toChars()); 6700 type = Type::tint32; 6701 break; 6702 } 6703 rvalue(); 6843 if (!type) 6844 { 6845 UnaExp::semantic(sc); 6846 e1 = resolveProperties(sc, e1); 6847 if (!e1->type) 6848 printf("PtrExp::semantic('%s')\n", toChars()); 6849 Type *tb = e1->type->toBasetype(); 6850 switch (tb->ty) 6851 { 6852 case Tpointer: 6853 type = tb->next; 6854 break; 6855 6856 case Tsarray: 6857 case Tarray: 6858 type = tb->next; 6859 e1 = e1->castTo(sc, type->pointerTo()); 6860 break; 6861 6862 default: 6863 error("can only * a pointer, not a '%s'", e1->type->toChars()); 6864 return new ErrorExp(); 6865 } 6866 rvalue(); 6867 } 6704 6868 return this; 6705 6869 } … … 6767 6931 6768 6932 e1->checkNoBool(); 6769 if ( e1->op != TOKslice)6933 if (!e1->isArrayOperand()) 6770 6934 e1->checkArithmetic(); 6771 6935 type = e1->type; … … 6817 6981 6818 6982 e1->checkNoBool(); 6819 if ( e1->op != TOKslice)6983 if (!e1->isArrayOperand()) 6820 6984 e1 = e1->checkIntegral(); 6821 6985 type = e1->type; … … 7013 7177 } 7014 7178 7179 if (e1->op == TOKtemplate) 7180 { 7181 error("cannot cast template %s to type %s", e1->toChars(), to->toChars()); 7182 return new ErrorExp(); 7183 } 7184 7185 Type *t1b = e1->type->toBasetype(); 7015 7186 Type *tob = to->toBasetype(); 7016 7187 if (tob->ty == Tstruct && 7017 !tob->equals( e1->type->toBasetype()) &&7188 !tob->equals(t1b) && 7018 7189 ((TypeStruct *)to)->sym->search(0, Id::call, 0) 7019 7190 ) … … 7031 7202 e = e->semantic(sc); 7032 7203 return e; 7204 } 7205 7206 // Struct casts are possible only when the sizes match 7207 if (tob->ty == Tstruct || t1b->ty == Tstruct) 7208 { 7209 size_t fromsize = t1b->size(loc); 7210 size_t tosize = tob->size(loc); 7211 if (fromsize != tosize) 7212 { 7213 error("cannot cast from %s to %s", e1->type->toChars(), to->toChars()); 7214 return new ErrorExp(); 7215 } 7033 7216 } 7034 7217 } … … 7738 7921 /************************************************************/ 7739 7922 7740 /* Can be TOKconstruct too*/7923 /* op can be TOKassign, TOKconstruct, or TOKblit */ 7741 7924 7742 7925 AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2) … … 7747 7930 7748 7931 Expression *AssignExp::semantic(Scope *sc) 7749 { Type *t1;7932 { 7750 7933 Expression *e1old = e1; 7751 7934 … … 7754 7937 #endif 7755 7938 //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op)); 7939 //printf("e2->op = %d, '%s'\n", e2->op, Token::toChars(e2->op)); 7940 7941 if (type) 7942 return this; 7943 7944 if (e2->op == TOKcomma) 7945 { /* Rewrite to get rid of the comma from rvalue 7946 */ 7947 AssignExp *ea = new AssignExp(loc, e1, ((CommaExp *)e2)->e2); 7948 ea->op = op; 7949 Expression *e = new CommaExp(loc, ((CommaExp *)e2)->e1, ea); 7950 return e->semantic(sc); 7951 } 7756 7952 7757 7953 /* Look for operator overloading of a[i]=value. … … 7760 7956 */ 7761 7957 if (e1->op == TOKarray) 7762 { Type *t1;7958 { 7763 7959 ArrayExp *ae = (ArrayExp *)e1; 7764 7960 AggregateDeclaration *ad; … … 7766 7962 7767 7963 ae->e1 = ae->e1->semantic(sc); 7768 t1 = ae->e1->type->toBasetype();7964 Type *t1 = ae->e1->type->toBasetype(); 7769 7965 if (t1->ty == Tstruct) 7770 7966 { … … 7881 8077 } 7882 8078 7883 t1 = e1->type->toBasetype(); 8079 // Determine if this is an initialization of a reference 8080 int refinit = 0; 8081 if (op == TOKconstruct && e1->op == TOKvar) 8082 { VarExp *ve = (VarExp *)e1; 8083 VarDeclaration *v = ve->var->isVarDeclaration(); 8084 if (v->storage_class & (STCout | STCref)) 8085 refinit = 1; 8086 } 8087 8088 Type *t1 = e1->type->toBasetype(); 7884 8089 7885 8090 if (t1->ty == Tfunction) 7886 8091 { // Rewrite f=value to f(value) 7887 Expression *e; 7888 7889 e = new CallExp(loc, e1, e2); 8092 Expression *e = new CallExp(loc, e1, e2); 7890 8093 e = e->semantic(sc); 7891 8094 return e; … … 7919 8122 { // Try to do a decent error message with the expression 7920 8123 // before it got constant folded 7921 e1 = e1->modifiableLvalue(sc, e1old); 8124 if (op != TOKconstruct) 8125 e1 = e1->modifiableLvalue(sc, e1old); 7922 8126 } 7923 8127 … … 7931 8135 e2 = e2->implicitCastTo(sc, t1->next); 7932 8136 } 7933 else if (t1->ty == Tsarray )8137 else if (t1->ty == Tsarray && !refinit) 7934 8138 { 7935 8139 error("cannot assign to static array %s", e1->toChars()); … … 8062 8266 e1->checkArithmetic(); 8063 8267 e2->checkArithmetic(); 8268 checkComplexAddAssign(); 8064 8269 if (type->isreal() || type->isimaginary()) 8065 8270 { … … 8112 8317 e1 = e1->checkArithmetic(); 8113 8318 e2 = e2->checkArithmetic(); 8319 checkComplexAddAssign(); 8114 8320 type = e1->type; 8115 8321 typeCombine(sc); … … 8216 8422 e1->checkArithmetic(); 8217 8423 e2->checkArithmetic(); 8424 checkComplexMulAssign(); 8218 8425 if (e2->type->isfloating()) 8219 8426 { Type *t1; … … 8282 8489 e1->checkArithmetic(); 8283 8490 e2->checkArithmetic(); 8491 checkComplexMulAssign(); 8284 8492 if (e2->type->isimaginary()) 8285 8493 { Type *t1; … … 8329 8537 Expression *ModAssignExp::semantic(Scope *sc) 8330 8538 { 8539 BinExp::semantic(sc); 8540 checkComplexMulAssign(); 8331 8541 return commonSemanticAssign(sc); 8332 8542 } … … 8737 8947 8738 8948 typeCombine(sc); 8739 if (e1->op != TOKslice && e2->op != TOKslice) 8740 { e1->checkArithmetic(); 8949 if (!e1->isArrayOperand()) 8950 e1->checkArithmetic(); 8951 if (!e2->isArrayOperand()) 8741 8952 e2->checkArithmetic(); 8742 }8743 8953 if (type->isfloating()) 8744 8954 { Type *t1 = e1->type; … … 8803 9013 8804 9014 typeCombine(sc); 8805 if (e1->op != TOKslice && e2->op != TOKslice) 8806 { e1->checkArithmetic(); 9015 if (!e1->isArrayOperand()) 9016 e1->checkArithmetic(); 9017 if (!e2->isArrayOperand()) 8807 9018 e2->checkArithmetic(); 8808 }8809 9019 if (type->isfloating()) 8810 9020 { Type *t1 = e1->type; … … 8870 9080 8871 9081 typeCombine(sc); 8872 if (e1->op != TOKslice && e2->op != TOKslice) 8873 { e1->checkArithmetic(); 9082 if (!e1->isArrayOperand()) 9083 e1->checkArithmetic(); 9084 if (!e2->isArrayOperand()) 8874 9085 e2->checkArithmetic(); 8875 }8876 9086 if (type->isfloating()) 8877 9087 { type = e1->type; … … 8984 9194 { 8985 9195 typeCombine(sc); 8986 if (e1->op != TOKslice && e2->op != TOKslice) 8987 { e1->checkIntegral(); 9196 if (!e1->isArrayOperand()) 9197 e1->checkIntegral(); 9198 if (!e2->isArrayOperand()) 8988 9199 e2->checkIntegral(); 8989 }8990 9200 } 8991 9201 } … … 9017 9227 { 9018 9228 typeCombine(sc); 9019 if (e1->op != TOKslice && e2->op != TOKslice) 9020 { e1->checkIntegral(); 9229 if (!e1->isArrayOperand()) 9230 e1->checkIntegral(); 9231 if (!e2->isArrayOperand()) 9021 9232 e2->checkIntegral(); 9022 }9023 9233 } 9024 9234 } … … 9050 9260 { 9051 9261 typeCombine(sc); 9052 if (e1->op != TOKslice && e2->op != TOKslice) 9053 { e1->checkIntegral(); 9262 if (!e1->isArrayOperand()) 9263 e1->checkIntegral(); 9264 if (!e2->isArrayOperand()) 9054 9265 e2->checkIntegral(); 9055 }9056 9266 } 9057 9267 } … … 9255 9465 Expression *CmpExp::semantic(Scope *sc) 9256 9466 { Expression *e; 9257 Type *t1;9258 Type *t2;9259 9467 9260 9468 #if LOGSEMANTIC … … 9266 9474 BinExp::semanticp(sc); 9267 9475 9268 if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull || 9269 e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull) 9476 Type *t1 = e1->type->toBasetype(); 9477 Type *t2 = e2->type->toBasetype(); 9478 if (t1->ty == Tclass && e2->op == TOKnull || 9479 t2->ty == Tclass && e1->op == TOKnull) 9270 9480 { 9271 9481 error("do not use null when comparing class types"); … … 9285 9495 } 9286 9496 return e; 9497 } 9498 9499 /* Disallow comparing T[]==T and T==T[] 9500 */ 9501 if (e1->op == TOKslice && t1->ty == Tarray && e2->implicitConvTo(t1->nextOf()) || 9502 e2->op == TOKslice && t2->ty == Tarray && e1->implicitConvTo(t2->nextOf())) 9503 { 9504 incompatibleTypes(); 9505 return new ErrorExp(); 9287 9506 } 9288 9507 … … 9338 9557 Expression *EqualExp::semantic(Scope *sc) 9339 9558 { Expression *e; 9340 Type *t1;9341 Type *t2;9342 9559 9343 9560 //printf("EqualExp::semantic('%s')\n", toChars()); … … 9368 9585 } 9369 9586 9370 if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull || 9371 e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull) 9587 Type *t1 = e1->type->toBasetype(); 9588 Type *t2 = e2->type->toBasetype(); 9589 if (t1->ty == Tclass && e2->op == TOKnull || 9590 t2->ty == Tclass && e1->op == TOKnull) 9372 9591 { 9373 9592 error("use '%s' instead of '%s' when comparing with null", … … 9388 9607 return e; 9389 9608 } 9609 } 9610 9611 /* Disallow comparing T[]==T and T==T[] 9612 */ 9613 if (e1->op == TOKslice && t1->ty == Tarray && e2->implicitConvTo(t1->nextOf()) || 9614 e2->op == TOKslice && t2->ty == Tarray && e1->implicitConvTo(t2->nextOf())) 9615 { 9616 incompatibleTypes(); 9617 return new ErrorExp(); 9390 9618 } 9391 9619 dmd/expression.h
r1499 r1587 82 82 int arrayExpressionCanThrow(Expressions *exps); 83 83 84 struct IntRange 85 { uinteger_t imin; 86 uinteger_t imax; 87 }; 88 84 89 struct Expression : Object 85 90 { … … 158 163 virtual void buildArrayIdent(OutBuffer *buf, Expressions *arguments); 159 164 virtual Expression *buildArrayLoop(Arguments *fparams); 165 int isArrayOperand(); 160 166 161 167 #if IN_DMD … … 292 298 { 293 299 Dsymbol *s; 300 int hasOverloads; 294 301 295 302 DsymbolExp(Loc loc, Dsymbol *s); … … 307 314 ThisExp(Loc loc); 308 315 Expression *semantic(Scope *sc); 316 Expression *interpret(InterState *istate); 309 317 int isBool(int result); 310 318 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 344 352 Expression *semantic(Scope *sc); 345 353 int isBool(int result); 354 int isConst(); 346 355 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 347 356 void toMangleBuffer(OutBuffer *buf); … … 592 601 Expression *syntaxCopy(); 593 602 Expression *semantic(Scope *sc); 603 Expression *optimize(int result); 594 604 #if IN_DMD 595 605 elem *toElem(IRState *irs); … … 843 853 Expression *commonSemanticAssignIntegral(Scope *sc); 844 854 int checkSideEffect(int flag); 855 void checkComplexMulAssign(); 856 void checkComplexAddAssign(); 845 857 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 846 858 Expression *scaleFactor(Scope *sc); … … 1023 1035 void scanForNestedRef(Scope *sc); 1024 1036 Expression *toLvalue(Scope *sc, Expression *e); 1037 Expression *modifiableLvalue(Scope *sc, Expression *e); 1025 1038 1026 1039 int inlineCost(InlineCostState *ics); … … 1183 1196 void checkEscape(); 1184 1197 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 1198 void buildArrayIdent(OutBuffer *buf, Expressions *arguments); 1199 Expression *buildArrayLoop(Arguments *fparams); 1185 1200 #if IN_DMD 1186 1201 elem *toElem(IRState *irs); dmd/func.c
r1530 r1587 1 1 // Compiler implementation of the D programming language 2 // Copyright (c) 1999-200 8by Digital Mars2 // Copyright (c) 1999-2009 by Digital Mars 3 3 // All Rights Reserved 4 4 // written by Walter Bright … … 36 36 { 37 37 //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type); 38 //printf("storage_class = x%x\n", storage_class); 38 39 this->storage_class = storage_class; 39 40 this->type = type; … … 42 43 fthrows = NULL; 43 44 frequire = NULL; 45 fdrequire = NULL; 46 fdensure = NULL; 44 47 outId = NULL; 45 48 vresult = NULL; … … 64 67 cantInterpret = 0; 65 68 semanticRun = 0; 69 #if DMDV1 66 70 nestedFrameRef = 0; 71 #endif 67 72 fes = NULL; 68 73 introducing = 0; … … 72 77 */ 73 78 inferRetType = (type && type->nextOf() == NULL); 74 scope = NULL;75 79 hasReturnExp = 0; 76 80 nrvo_can = 1; … … 78 82 #if IN_DMD 79 83 shidden = NULL; 84 #endif 85 86 #if DMDV2 87 builtin = BUILTINunknown; 88 tookAddressOf = 0; 80 89 #endif 81 90 … … 143 152 if (isFuncLiteralDeclaration()) 144 153 printf("\tFuncLiteralDeclaration()\n"); 145 printf("sc->parent = %s \n", sc->parent->toChars());154 printf("sc->parent = %s, parent = %s\n", sc->parent->toChars(), parent ? parent->toChars() : ""); 146 155 printf("type: %p, %s\n", type, type->toChars()); 147 156 #endif … … 159 168 semanticRun = 1; 160 169 161 if (type->nextOf()) 170 if (!type->deco) 171 { 162 172 type = type->semantic(loc, sc); 173 } 163 174 //type->print(); 164 175 if (type->ty != Tfunction) … … 250 261 251 262 if (isCtorDeclaration() || 263 #if DMDV2 264 isPostBlitDeclaration() || 265 #endif 252 266 isDtorDeclaration() || 253 267 isInvariantDeclaration() || … … 398 412 vtblIndex = vi; 399 413 414 /* Remember which functions this overrides 415 */ 416 foverrides.push(fdv); 417 400 418 /* This works by whenever this function is called, 401 419 * it actually returns tintro, which gets dynamically … … 444 462 { FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi]; 445 463 Type *ti = NULL; 464 465 /* Remember which functions this overrides 466 */ 467 foverrides.push(fdv); 446 468 447 469 if (fdv->tintro) … … 601 623 } 602 624 603 if (f->nextOf()->ty != Tint32 && f->nextOf()->ty != Tvoid) 625 if (!f->nextOf()) 626 error("must return int or void"); 627 else if (f->nextOf()->ty != Tint32 && f->nextOf()->ty != Tvoid) 604 628 error("must return int or void, not %s", f->nextOf()->toChars()); 605 629 if (f->varargs) … … 636 660 } 637 661 662 if (isVirtual()) 663 { 664 /* Rewrite contracts as nested functions, then call them. 665 * Doing it as nested functions means that overriding functions 666 * can call them. 667 */ 668 if (frequire) 669 { /* in { ... } 670 * becomes: 671 * void __require() { ... } 672 * __require(); 673 */ 674 Loc loc = frequire->loc; 675 TypeFunction *tf = new TypeFunction(NULL, Type::tvoid, 0, LINKd); 676 FuncDeclaration *fd = new FuncDeclaration(loc, loc, 677 Id::require, STCundefined, tf); 678 fd->fbody = frequire; 679 Statement *s1 = new DeclarationStatement(loc, fd); 680 Expression *e = new CallExp(loc, new VarExp(loc, fd), (Expressions *)NULL); 681 Statement *s2 = new ExpStatement(loc, e); 682 frequire = new CompoundStatement(loc, s1, s2); 683 fdrequire = fd; 684 } 685 686 if (fensure) 687 { /* out (result) { ... } 688 * becomes: 689 * tret __ensure(ref tret result) { ... } 690 * __ensure(result); 691 */ 692 if (!outId && f->nextOf()->toBasetype()->ty != Tvoid) 693 outId = Id::result; // provide a default 694 695 Loc loc = fensure->loc; 696 Arguments *arguments = new Arguments(); 697 Argument *a = NULL; 698 if (outId) 699 { a = new Argument(STCref, f->nextOf(), outId, NULL); 700 arguments->push(a); 701 } 702 TypeFunction *tf = new TypeFunction(arguments, Type::tvoid, 0, LINKd); 703 FuncDeclaration *fd = new FuncDeclaration(loc, loc, 704 Id::ensure, STCundefined, tf); 705 fd->fbody = fensure; 706 Statement *s1 = new DeclarationStatement(loc, fd); 707 Expression *eresult = NULL; 708 if (outId) 709 eresult = new IdentifierExp(loc, outId); 710 Expression *e = new CallExp(loc, new VarExp(loc, fd), eresult); 711 Statement *s2 = new ExpStatement(loc, e); 712 fensure = new CompoundStatement(loc, s1, s2); 713 fdensure = fd; 714 } 715 } 716 638 717 Ldone: 639 718 /* Save scope for possible later use (if we need the … … 656 735 void FuncDeclaration::semantic3(Scope *sc) 657 736 { TypeFunction *f; 658 AggregateDeclaration *ad;659 737 VarDeclaration *argptr = NULL; 660 738 VarDeclaration *_arguments = NULL; … … 669 747 //printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars()); 670 748 //fflush(stdout); 749 //printf("storage class = x%x %x\n", sc->stc, storage_class); 671 750 //{ static int x; if (++x == 2) *(char*)0=0; } 672 751 //printf("\tlinkage = %d\n", sc->linkage); … … 684 763 return; 685 764 f = (TypeFunction *)(type); 686 size_t nparams = Argument::dim(f->parameters);687 765 688 766 // Check the 'throws' clause … … 698 776 } 699 777 } 778 779 frequire = mergeFrequire(frequire); 780 fensure = mergeFensure(fensure); 700 781 701 782 if (fbody || frequire) … … 728 809 729 810 // Declare 'this' 730 ad = isThis();811 AggregateDeclaration *ad = isThis(); 731 812 if (ad) 732 813 { VarDeclaration *v; … … 767 848 // Declare hidden variable _arguments[] and _argptr 768 849 if (f->varargs == 1) 769 { Type *t; 850 { 851 #if TARGET_NET 852 varArgs(sc2, f, argptr, _arguments); 853 #else 854 Type *t; 770 855 771 856 if (f->linkage == LINKd) … … 804 889 argptr->parent = this; 805 890 } 891 #endif 806 892 } 807 893 … … 825 911 } 826 912 } 827 // update nparams to include expanded tuples828 nparams = Argument::dim(f->parameters);829 913 } 830 914 #endif … … 836 920 { Argument *arg = (Argument *)f->parameters->data[i]; 837 921 922 //printf("[%d] arg->type->ty = %d %s\n", i, arg->type->ty, arg->type->toChars()); 838 923 if (arg->type->ty == Ttuple) 839 924 { TypeTuple *t = (TypeTuple *)arg->type; … … 847 932 } 848 933 849 // Declare all the function parameters as variables 934 /* Declare all the function parameters as variables 935 * and install them in parameters[] 936 */ 937 size_t nparams = Argument::dim(f->parameters); 850 938 if (nparams) 851 939 { /* parameters[] has all the tuples removed, as the back end … … 865 953 arg->ident = id = Identifier::generateId("_param_", i); 866 954 } 867 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL); 955 Type *vtype = arg->type; 956 VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL); 868 957 //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars()); 869 958 v->storage_class |= STCparameter; … … 936 1025 { /* fensure is composed of the [out] contracts 937 1026 */ 1027 if (!type->nextOf()) 1028 { // Have to do semantic() on fbody first 1029 error("post conditions are not supported if the return type is inferred"); 1030 return; 1031 } 1032 938 1033 ScopeDsymbol *sym = new ScopeDsymbol(); 939 1034 sym->parent = sc2->scopesym; … … 962 1057 v = new VarDeclaration(loc, type->nextOf(), outId, NULL); 963 1058 v->noscope = 1; 1059 #if DMDV2 1060 if (f->isref) 1061 { 1062 v->storage_class |= STCref | STCforeach; 1063 } 1064 #endif 964 1065 sc2->incontract--; 965 1066 v->semantic(sc2); … … 1012 1113 else 1013 1114 { // Call invariant virtually 1014 ThisExp*v = new ThisExp(0);1115 Expression *v = new ThisExp(0); 1015 1116 v->type = vthis->type; 1117 #if STRUCTTHISREF 1118 if (ad->isStructDeclaration()) 1119 v = v->addressOf(sc); 1120 #endif 1016 1121 e = new AssertExp(0, v); 1017 1122 } … … 1135 1240 else if (!inlineAsm) 1136 1241 { 1242 #if DMDV2 1243 int blockexit = fbody ? fbody->blockExit() : BEfallthru; 1244 if (f->isnothrow && blockexit & BEthrow) 1245 error("'%s' is nothrow yet may throw", toChars()); 1246 1247 int offend = blockexit & BEfallthru; 1248 #endif 1137 1249 if (type->nextOf()->ty == Tvoid) 1138 1250 { … … 1147 1259 if (offend) 1148 1260 { Expression *e; 1149 1150 warning(loc, "no return at end of function"); 1151 1261 #if DMDV1 1262 warning(loc, "no return exp; or assert(0); at end of function"); 1263 #else 1264 error("no return exp; or assert(0); at end of function"); 1265 #endif 1152 1266 if (global.params.useAssert && 1153 1267 !global.params.useInline) … … 1210 1324 else 1211 1325 p = v_arguments; // last parameter is _arguments[] 1212 offset = p->type->size(); 1326 if (p->storage_class & STClazy) 1327 // If the last parameter is lazy, it's the size of a delegate 1328 offset = PTRSIZE * 2; 1329 else 1330 offset = p->type->size(); 1213 1331 offset = (offset + 3) & ~3; // assume stack aligns on 4 1214 1332 e = new SymOffExp(0, p, offset); … … 1228 1346 Expression *e1 = new VarExp(0, _arguments); 1229 1347 e = new AssignExp(0, e1, e); 1230 e = e->semantic(sc); 1348 e->op = TOKconstruct; 1349 e = e->semantic(sc2); 1231 1350 a->push(new ExpStatement(0, e)); 1232 1351 } … … 1285 1404 ThisExp* v = new ThisExp(0); 1286 1405 v->type = vthis->type; 1406 #if STRUCTTHISREF 1407 if (ad->isStructDeclaration()) 1408 v = v->addressOf(sc); 1409 #endif 1287 1410 v->var = vthis; 1288 1411 … … 1333 1456 1334 1457 fbody = new CompoundStatement(0, a); 1458 #if DMDV2 1459 /* Append destructor calls for parameters as finally blocks. 1460 */ 1461 if (parameters) 1462 { for (size_t i = 0; i < parameters->dim; i++) 1463 { 1464 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 1465 1466 if (v->storage_class & (STCref | STCout)) 1467 continue; 1468 1469 /* Don't do this for static arrays, since static 1470 * arrays are called by reference. Remove this 1471 * when we change them to call by value. 1472 */ 1473 if (v->type->toBasetype()->ty == Tsarray) 1474 continue; 1475 1476 Expression *e = v->callAutoDtor(sc); 1477 if (e) 1478 { Statement *s = new ExpStatement(0, e); 1479 s = s->semantic(sc); 1480 if (fbody->blockExit() == BEfallthru) 1481 fbody = new CompoundStatement(0, fbody, s); 1482 else 1483 fbody = new TryFinallyStatement(0, fbody, s); 1484 } 1485 } 1486 } 1487 #endif 1335 1488 1336 1489 // wrap body of synchronized functions in a synchronized statement … … 1431 1584 1432 1585 /**************************************************** 1586 * Merge into this function the 'in' contracts of all it overrides. 1587 * 'in's are OR'd together, i.e. only one of them needs to pass. 1588 */ 1589 1590 Statement *FuncDeclaration::mergeFrequire(Statement *sf) 1591 { 1592 /* Implementing this is done by having the overriding function call 1593 * nested functions (the fdrequire functions) nested inside the overridden 1594 * function. This requires that the stack layout of the calling function's 1595 * parameters and 'this' pointer be in the same place (as the nested 1596 * function refers to them). 1597 * This is easy for the parameters, as they are all on the stack in the same 1598 * place by definition, since it's an overriding function. The problem is 1599 * getting the 'this' pointer in the same place, since it is a local variable. 1600 * We did some hacks in the code generator to make this happen: 1601 * 1. always generate exception handler frame, or at least leave space for it 1602 * in the frame (Windows 32 SEH only) 1603 * 2. always generate an EBP style frame 1604 * 3. since 'this' is passed in a register that is subsequently copied into 1605 * a stack local, allocate that local immediately following the exception 1606 * handler block, so it is always at the same offset from EBP. 1607 */ 1608 for (int i = 0; i < foverrides.dim; i++) 1609 { 1610 FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; 1611 sf = fdv->mergeFrequire(sf); 1612 if (fdv->fdrequire) 1613 { 1614 //printf("fdv->frequire: %s\n", fdv->frequire->toChars()); 1615 /* Make the call: 1616 * try { __require(); } 1617 * catch { frequire; } 1618 */ 1619 Expression *eresult = NULL; 1620 Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdrequire), eresult); 1621 Statement *s2 = new ExpStatement(loc, e); 1622 1623 if (sf) 1624 { Catch *c = new Catch(loc, NULL, NULL, sf); 1625 Array *catches = new Array(); 1626 catches->push(c); 1627 sf = new TryCatchStatement(loc, s2, catches); 1628 } 1629 else 1630 sf = s2; 1631 } 1632 } 1633 return sf; 1634 } 1635 1636 /**************************************************** 1637 * Merge into this function the 'out' contracts of all it overrides. 1638 * 'out's are AND'd together, i.e. all of them need to pass. 1639 */ 1640 1641 Statement *FuncDeclaration::mergeFensure(Statement *sf) 1642 { 1643 /* Same comments as for mergeFrequire(), except that we take care 1644 * of generating a consistent reference to the 'result' local by 1645 * explicitly passing 'result' to the nested function as a reference 1646 * argument. 1647 * This won't work for the 'this' parameter as it would require changing 1648 * the semantic code for the nested function so that it looks on the parameter 1649 * list for the 'this' pointer, something that would need an unknown amount 1650 * of tweaking of various parts of the compiler that I'd rather leave alone. 1651 */ 1652 for (int i = 0; i < foverrides.dim; i++) 1653 { 1654 FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; 1655 sf = fdv->mergeFensure(sf); 1656 if (fdv->fdensure) 1657 { 1658 //printf("fdv->fensure: %s\n", fdv->fensure->toChars()); 1659 // Make the call: __ensure(result) 1660 Expression *eresult = NULL; 1661 if (outId) 1662 eresult = new IdentifierExp(loc, outId); 1663 Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdensure), eresult); 1664 Statement *s2 = new ExpStatement(loc, e); 1665 1666 if (sf) 1667 { 1668 sf = new CompoundStatement(fensure->loc, s2, sf); 1669 } 1670 else 1671 sf = s2; 1672 } 1673 } 1674 return sf; 1675 } 1676 1677 /**************************************************** 1433 1678 * Determine if 'this' overrides fd. 1434 1679 * Return !=0 if it does. … … 1605 1850 1606 1851 /******************************************** 1852 * If there are no overloads of function f, return that function, 1853 * otherwise return NULL. 1854 */ 1855 1856 static int fpunique(void *param, FuncDeclaration *f) 1857 { FuncDeclaration **pf = (FuncDeclaration **)param; 1858 1859 if (*pf) 1860 { *pf = NULL; 1861 return 1; // ambiguous, done 1862 } 1863 else 1864 { *pf = f; 1865 return 0; 1866 } 1867 } 1868 1869 FuncDeclaration *FuncDeclaration::isUnique() 1870 { FuncDeclaration *result = NULL; 1871 1872 overloadApply(getModule(), this, &fpunique, &result); 1873 return result; 1874 } 1875 1876 /******************************************** 1607 1877 * Find function in overload list that exactly matches t. 1608 1878 */ … … 1748 2018 1749 2019 1750 void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments, Module* from) 2020 void overloadResolveX(Match *m, FuncDeclaration *fstart, 2021 Expression *ethis, Expressions *arguments, Module *from) 1751 2022 { 1752 2023 Param2 p; … … 1774 2045 if (fa) 1775 2046 { 1776 overloadResolveX(m, fa->funcalias, arguments);2047 overloadResolveX(m, fa->funcalias, NULL, arguments); 1777 2048 next = fa->overnext; 1778 2049 } … … 1838 2109 #endif 1839 2110 1840 FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression s *arguments, Module* from)2111 FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, Module *from, int flags) 1841 2112 { 1842 2113 TypeFunction *tf; … … 1861 2132 memset(&m, 0, sizeof(m)); 1862 2133 m.last = MATCHnomatch; 1863 overloadResolveX(&m, this, arguments, from);2134 overloadResolveX(&m, this, NULL, arguments, from); 1864 2135 1865 2136 if (m.count == 1) // exactly one match … … 2040 2311 } 2041 2312 2313 const char *FuncDeclaration::toPrettyChars() 2314 { 2315 if (isMain()) 2316 return "D main"; 2317 else 2318 return Dsymbol::toPrettyChars(); 2319 } 2042 2320 2043 2321 int FuncDeclaration::isMain() … … 2405 2683 tret = cd->type; //->referenceTo(); 2406 2684 type = new TypeFunction(arguments, tret, varargs, LINKd); 2685 #if STRUCTTHISREF 2686 if (ad && ad->isStructDeclaration()) 2687 ((TypeFunction *)type)->isref = 1; 2688 #endif 2407 2689 if (!originalType) 2408 2690 originalType = type; … … 2416 2698 // to the function body 2417 2699 if (fbody) 2418 { Expression *e; 2419 Statement *s; 2420 2421 e = new ThisExp(0); 2422 s = new ReturnStatement(0, e); 2423 fbody = new CompoundStatement(0, fbody, s); 2700 { 2701 Expression *e = new ThisExp(loc); 2702 Statement *s = new ReturnStatement(loc, e); 2703 fbody = new CompoundStatement(loc, fbody, s); 2424 2704 } 2425 2705 … … 2466 2746 } 2467 2747 2748 /********************************* PostBlitDeclaration ****************************/ 2749 2750 #if DMDV2 2751 PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc) 2752 : FuncDeclaration(loc, endloc, Id::_postblit, STCundefined, NULL) 2753 { 2754 } 2755 2756 PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc, Identifier *id) 2757 : FuncDeclaration(loc, endloc, id, STCundefined, NULL) 2758 { 2759 } 2760 2761 Dsymbol *PostBlitDeclaration::syntaxCopy(Dsymbol *s) 2762 { 2763 assert(!s); 2764 PostBlitDeclaration *dd = new PostBlitDeclaration(loc, endloc, ident); 2765 return FuncDeclaration::syntaxCopy(dd); 2766 } 2767 2768 2769 void PostBlitDeclaration::semantic(Scope *sc) 2770 { 2771 //printf("PostBlitDeclaration::semantic() %s\n", toChars()); 2772 //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor); 2773 parent = sc->parent; 2774 Dsymbol *parent = toParent(); 2775 StructDeclaration *ad = parent->isStructDeclaration(); 2776 if (!ad) 2777 { 2778 error("post blits are only for struct/union definitions, not %s %s", parent->kind(), parent->toChars()); 2779 } 2780 else if (ident == Id::_postblit) 2781 ad->postblits.push(this); 2782 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2783 2784 sc = sc->push(); 2785 sc->stc &= ~STCstatic; // not static 2786 sc->linkage = LINKd; 2787 2788 FuncDeclaration::semantic(sc); 2789 2790 sc->pop(); 2791 } 2792 2793 int PostBlitDeclaration::overloadInsert(Dsymbol *s) 2794 { 2795 return FALSE; // cannot overload postblits 2796 } 2797 2798 int PostBlitDeclaration::addPreInvariant() 2799 { 2800 return FALSE; 2801 } 2802 2803 int PostBlitDeclaration::addPostInvariant() 2804 { 2805 return (isThis() && vthis && global.params.useInvariants); 2806 } 2807 2808 int PostBlitDeclaration::isVirtual() 2809 { 2810 return FALSE; 2811 } 2812 2813 void PostBlitDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2814 { 2815 if (hgs->hdrgen) 2816 return; 2817 buf->writestring("=this()"); 2818 bodyToCBuffer(buf, hgs); 2819 } 2820 #endif 2821 2468 2822 /********************************* DtorDeclaration ****************************/ 2469 2823 … … 2488 2842 void DtorDeclaration::semantic(Scope *sc) 2489 2843 { 2490 ClassDeclaration *cd;2491 2844 //printf("DtorDeclaration::semantic() %s\n", toChars()); 2845 //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor); 2492 2846 parent = sc->parent; 2493 2847 Dsymbol *parent = toParent(); 2494 cd = parent->isClassDeclaration();2848 ClassDeclaration *cd = parent->isClassDeclaration(); 2495 2849 if (!cd) 2496 2850 { 2497 error("destructors only are for class definitions");2851 error("destructors are only for class/struct/union definitions, not %s %s", parent->kind(), parent->toChars()); 2498 2852 fatal(); 2499 2853 } … … 2524 2878 { 2525 2879 return FALSE; 2880 } 2881 2882 const char *DtorDeclaration::kind() 2883 { 2884 return "destructor"; 2885 } 2886 2887 char *DtorDeclaration::toChars() 2888 { 2889 return (char *)"~this"; 2526 2890 } 2527 2891 … … 2864 3228 } 2865 3229 3230 #if 0 2866 3231 // We're going to need ModuleInfo even if the unit tests are not 2867 3232 // compiled in, because other modules may import this module and refer 2868 3233 // to this ModuleInfo. 3234 // (This doesn't make sense to me?) 2869 3235 Module *m = getModule(); 2870 3236 if (!m) 2871 3237 m = sc->module; 2872 3238 if (m) 3239 { 3240 //printf("module3 %s needs moduleinfo\n", m->toChars()); 2873 3241 m->needmoduleinfo = 1; 3242 } 3243 #endif 2874 3244 } 2875 3245 dmd/idgen.c
r1152 r1587 39 39 { "classInvariant", "__invariant" }, 40 40 { "unitTest", "_unitTest" }, 41 { "require", "__require" }, 42 { "ensure", "__ensure" }, 41 43 { "init" }, 42 44 { "size" }, … … 208 210 { "aaValues", "_aaValues" }, 209 211 { "aaRehash", "_aaRehash" }, 212 { "monitorenter", "_d_monitorenter" }, 213 { "monitorexit", "_d_monitorexit" }, 214 { "criticalenter", "_d_criticalenter" }, 215 { "criticalexit", "_d_criticalexit" }, 210 216 211 217 // For pragma's dmd/import.c
r1402 r1587 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 6by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 22 22 #include "declaration.h" 23 23 #include "id.h" 24 #include "attrib.h" 24 25 25 26 /********************************* Import ****************************/ … … 29 30 : Dsymbol(id) 30 31 { 32 assert(id); 31 33 this->loc = loc; 32 34 this->packages = packages; … … 85 87 void Import::load(Scope *sc) 86 88 { 87 DsymbolTable *dst;88 Dsymbol *s;89 90 89 //printf("Import::load('%s')\n", toChars()); 91 90 92 91 // See if existing module 93 dst = Package::resolve(packages, NULL, &pkg);94 95 s = dst->lookup(id);92 DsymbolTable *dst = Package::resolve(packages, NULL, &pkg); 93 94 Dsymbol *s = dst->lookup(id); 96 95 if (s) 97 96 { 97 #if TARGET_NET 98 mod = (Module *)s; 99 #else 98 100 if (s->isModule()) 99 101 mod = (Module *)s; 100 102 else 101 103 error("package and module have the same name"); 104 #endif 102 105 } 103 106 … … 117 120 } 118 121 119 char* escapePath(char* fname, char* buffer, int bufLen) { 120 char* res = buffer; 121 bufLen -= 2; // for \0 and an occasional escape char 122 int dst = 0; 123 for (; dst < bufLen && *fname; ++dst, ++fname) { 124 switch (*fname) { 122 void escapePath(OutBuffer *buf, const char *fname) 123 { 124 while (1) 125 { 126 switch (*fname) 127 { 128 case 0: 129 return; 125 130 case '(': 126 131 case ')': 127 132 case '\\': 128 buffer[dst++] = '\\'; 129 // fall through 130 133 buf->writebyte('\\'); 131 134 default: 132 buffer[dst] = *fname; 133 } 134 } 135 buffer[dst] = '\0'; 136 return buffer; 135 buf->writebyte(*fname); 136 break; 137 } 138 fname++; 139 } 140 } 141 142 void Import::importAll(Scope *sc) 143 { 144 if (!mod) 145 { 146 load(sc); 147 mod->importAll(0); 148 149 if (!isstatic && !aliasId && !names.dim) 150 { 151 /* Default to private importing 152 */ 153 enum PROT prot = sc->protection; 154 if (!sc->explicitProtection) 155 prot = PROTprivate; 156 sc->scopesym->importScope(mod, prot); 157 } 158 } 137 159 } 138 160 … … 141 163 //printf("Import::semantic('%s')\n", toChars()); 142 164 143 load(sc); 165 // Load if not already done so 166 if (!mod) 167 { load(sc); 168 mod->importAll(0); 169 } 144 170 145 171 if (mod) … … 159 185 sc->module->aimports.push(mod); 160 186 161 mod->semantic();162 163 187 /* Default to private importing 164 188 */ … … 172 196 } 173 197 198 mod->semantic(); 199 174 200 if (mod->needmoduleinfo) 175 201 sc->module->needmoduleinfo = 1; … … 190 216 //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg); 191 217 192 193 if (global.params.moduleDeps != NULL) { 194 char fnameBuf[262]; // MAX_PATH+2 195 196 OutBuffer *const ob = global.params.moduleDeps; 197 ob->printf("%s (%s) : ", 198 sc->module->toPrettyChars(), 199 escapePath(sc->module->srcfile->toChars(), fnameBuf, sizeof(fnameBuf) / sizeof(*fnameBuf)) 200 ); 201 202 char* protStr = ""; 203 switch (sc->protection) { 204 case PROTpublic: protStr = "public"; break; 205 case PROTprivate: protStr = "private"; break; 206 case PROTpackage: protStr = "package"; break; 207 default: break; 208 } 209 ob->writestring(protStr); 210 if (isstatic) { 211 ob->writestring(" static"); 212 } 213 ob->writestring(" : "); 214 215 if (this->packages) { 216 for (size_t i = 0; i < this->packages->dim; i++) { 217 Identifier *pid = (Identifier *)this->packages->data[i]; 218 if (global.params.moduleDeps != NULL) 219 { 220 /* The grammar of the file is: 221 * ImportDeclaration 222 * ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> " 223 * ModuleAliasIdentifier ] "\n" 224 * 225 * BasicImportDeclaration 226 * ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection 227 * " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")" 228 * 229
