Changeset 1630:44b145be2ef5
- Timestamp:
- 02/06/10 10:53:52 (2 years ago)
- Files:
-
- dmd/access.c (modified) (1 diff)
- dmd/aggregate.h (modified) (3 diffs)
- dmd/arrayop.c (modified) (1 diff)
- dmd/attrib.c (modified) (8 diffs)
- dmd/class.c (modified) (2 diffs)
- dmd/cond.c (modified) (1 diff)
- dmd/declaration.c (modified) (3 diffs)
- dmd/declaration.h (modified) (1 diff)
- dmd/dsymbol.c (modified) (1 diff)
- dmd/dsymbol.h (modified) (4 diffs)
- dmd/enum.c (modified) (4 diffs)
- dmd/expression.c (modified) (8 diffs)
- dmd/expression.h (modified) (4 diffs)
- dmd/func.c (modified) (41 diffs)
- dmd/identifier.h (modified) (1 diff)
- dmd/inline.c (modified) (1 diff)
- dmd/interpret.c (modified) (24 diffs)
- dmd/mangle.c (modified) (1 diff)
- dmd/mars.c (modified) (5 diffs)
- dmd/mars.h (modified) (5 diffs)
- dmd/module.c (modified) (5 diffs)
- dmd/module.h (modified) (1 diff)
- dmd/mtype.c (modified) (1 diff)
- dmd/optimize.c (modified) (5 diffs)
- dmd/statement.c (modified) (1 diff)
- dmd/statement.h (modified) (4 diffs)
- dmd/struct.c (modified) (3 diffs)
- dmd/template.c (modified) (2 diffs)
- tests/mini/bug372.d (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
dmd/access.c
r1406 r1630 393 393 if (!e) 394 394 { 395 if (d->getModule() != sc->module) 396 if (d->prot() == PROTprivate || 397 d->prot() == PROTpackage && !hasPackageAccess(sc, d)) 398 399 error(loc, "%s %s.%s is not accessible from %s", 400 d->kind(), d->getModule()->toChars(), d->toChars(), sc->module->toChars()); 395 if (d->prot() == PROTprivate && d->getModule() != sc->module || 396 d->prot() == PROTpackage && !hasPackageAccess(sc, d)) 397 398 error(loc, "%s %s.%s is not accessible from %s", 399 d->kind(), d->getModule()->toChars(), d->toChars(), sc->module->toChars()); 401 400 } 402 401 else if (e->type->ty == Tclass) dmd/aggregate.h
r1624 r1630 20 20 #include "dsymbol.h" 21 21 22 #if IN_LLVM 22 23 #include <vector> 23 24 #include <set> 24 25 #include <map> 26 #endif 25 27 26 28 struct Identifier; … … 39 41 struct dt_t; 40 42 43 #if IN_LLVM 41 44 namespace llvm 42 45 { … … 47 50 class GlobalVariable; 48 51 } 52 #endif 49 53 50 54 struct AggregateDeclaration : ScopeDsymbol dmd/arrayop.c
r1607 r1630 25 25 #include "init.h" 26 26 27 #if IN_DMD 28 extern int binary(const char *p , const char **tab, int high); 29 30 /************************************** 31 * Hash table of array op functions already generated or known about. 32 */ 33 34 StringTable arrayfuncs; 35 #endif 27 36 28 37 /*********************************** dmd/attrib.c
r1602 r1630 393 393 if (stc & (STCgshared | STCshared | STCtls)) 394 394 scstc &= ~(STCgshared | STCshared | STCtls); 395 if (stc & (STCsafe | STCtrusted | STCsystem)) 396 scstc &= ~(STCsafe | STCtrusted | STCsystem); 395 397 scstc |= stc; 396 398 … … 416 418 if (stc & (STCgshared | STCshared | STCtls)) 417 419 scstc &= ~(STCgshared | STCshared | STCtls); 420 if (stc & (STCsafe | STCtrusted | STCsystem)) 421 scstc &= ~(STCsafe | STCtrusted | STCsystem); 418 422 scstc |= stc; 419 423 … … 454 458 { STCtls, TOKtls }, 455 459 { STCgshared, TOKgshared }, 460 { STCproperty, TOKat }, 461 { STCsafe, TOKat }, 462 { STCtrusted, TOKat }, 463 { STCdisable, TOKat }, 456 464 #endif 457 465 }; … … 715 723 } 716 724 725 unsigned dprogress_save = Module::dprogress; 726 717 727 assert(sc->parent); 718 728 … … 744 754 sc = sc->push(); 745 755 sc->anonAgg = &aad; 746 sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls );756 sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCgshared); 747 757 sc->inunion = isunion; 748 758 sc->offset = 0; … … 776 786 scope->module->addDeferredSemantic(this); 777 787 } 788 Module::dprogress = dprogress_save; 778 789 //printf("\tforward reference %p\n", this); 779 790 return; … … 806 817 VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; 807 818 808 // LDC 819 #if IN_LLVM 809 820 v->offset2 = sc->offset; 810 821 #endif 811 822 v->offset += sc->offset; 812 823 813 // LDC 824 #if IN_LLVM 814 825 if (!v->anonDecl) 815 826 v->anonDecl = this; 816 827 #endif 817 828 ad->fields.push(v); 818 829 } … … 1370 1381 memcpy(name, se->string, se->len); 1371 1382 name[se->len] = 0; 1383 #if OMFOBJ 1384 /* The OMF format allows library names to be inserted 1385 * into the object file. The linker will then automatically 1386 * search that library, too. 1387 */ 1372 1388 obj_includelib(name); 1389 #elif ELFOBJ || MACHOBJ 1390 /* The format does not allow embedded library names, 1391 * so instead append the library name to the list to be passed 1392 * to the linker. 1393 */ 1394 global.params.libfiles->push((void *) name); 1395 #else 1396 error("pragma lib not supported"); 1397 #endif 1373 1398 } 1374 1399 #if DMDV2 dmd/class.c
r1628 r1630 265 265 scope = NULL; 266 266 } 267 unsigned dprogress_save = Module::dprogress; 267 268 #ifdef IN_GCC 268 269 methods.setDim(0); … … 629 630 scope->module->addDeferredSemantic(this); 630 631 632 Module::dprogress = dprogress_save; 633 631 634 //printf("\tsemantic('%s') failed due to forward references\n", toChars()); 632 635 return; dmd/cond.c
r1387 r1630 143 143 "none", 144 144 145 // LDC 145 #if IN_LLVM 146 146 "LLVM", "LDC", "LLVM64", 147 147 "PPC", "PPC64", 148 148 "darwin","solaris","freebsd" 149 #endif 149 150 }; 150 151 dmd/declaration.c
r1621 r1630 836 836 v->semantic(sc); 837 837 838 /* 838 #if !IN_LLVM 839 839 // removed for LDC since TupleDeclaration::toObj already creates the fields; 840 840 // adding them to the scope again leads to duplicates … … 844 844 sc->scopesym->members->push(v); 845 845 } 846 */ 846 #endif 847 847 848 Expression *e = new DsymbolExp(loc, v); 848 849 exps->data[i] = e; … … 1491 1492 { 1492 1493 assert(linkage == LINKc); 1493 // LDC 1494 #if IN_LLVM 1494 1495 if (!global.params.useAvailableExternally) 1495 1496 availableExternally = false; 1497 #endif 1496 1498 } 1497 1499 dmd/declaration.h
r1621 r1630 16 16 #endif /* __DMC__ */ 17 17 18 #if IN_LLVM 18 19 #include <set> 19 20 #include <map> 20 21 #include <string> 22 #endif 21 23 22 24 #include "dsymbol.h" dmd/dsymbol.c
r1607 r1630 30 30 #include "template.h" 31 31 #include "attrib.h" 32 #if IN_LLVM 32 33 #include "../gen/enums.h" 34 #endif 33 35 34 36 /****************************** Dsymbol ******************************/ dmd/dsymbol.h
r1587 r1630 22 22 #include "arraytypes.h" 23 23 24 // llvm 24 #if IN_LLVM 25 25 #include "../ir/irdsymbol.h" 26 #endif 26 27 27 28 struct Identifier; … … 52 53 struct VarDeclaration; 53 54 struct AttribDeclaration; 55 #if IN_DMD 56 struct Symbol; 57 #endif 54 58 struct Package; 55 59 struct Module; … … 77 81 struct PragmaScope; 78 82 #endif 79 #if IN_DMD80 struct Symbol;81 #endif82 83 #if IN_GCC 83 84 union tree_node; … … 110 111 }; 111 112 113 /* State of symbol in winding its way through the passes of the compiler 114 */ 115 enum PASS 116 { 117 PASSinit, // initial state 118 PASSsemantic, // semantic() started 119 PASSsemanticdone, // semantic() done 120 PASSsemantic2, // semantic2() run 121 PASSsemantic3, // semantic3() started 122 PASSsemantic3done, // semantic3() done 123 PASSobj, // toObjFile() run 124 }; 112 125 113 126 struct Dsymbol : Object dmd/enum.c
r1628 r1630 1 1 2 // Copyright (c) 1999-20 09by Digital Mars2 // Copyright (c) 1999-2010 by Digital Mars 3 3 // All Rights Reserved 4 4 // written by Walter Bright … … 15 15 #include "mtype.h" 16 16 #include "scope.h" 17 #include "module.h" 17 18 #include "declaration.h" 18 19 … … 75 76 } 76 77 78 unsigned dprogress_save = Module::dprogress; 79 77 80 if (sc->stc & STCdeprecated) 78 81 isdeprecated = 1; … … 98 101 99 102 isdone = 1; 103 Module::dprogress++; 100 104 101 105 t = isAnonymous() ? memtype : type; dmd/expression.c
r1629 r1630 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-20 09by Digital Mars3 // Copyright (c) 1999-2010 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 3711 3711 } 3712 3712 } 3713 3714 3713 } 3715 3714 } … … 8778 8777 e1->checkIntegral(); 8779 8778 e2 = e2->checkIntegral(); 8780 //e2 = e2->castTo(sc, Type::tshiftcnt); 8781 e2 = e2->castTo(sc, e1->type); // LDC 8779 #if !IN_LLVM 8780 e2 = e2->castTo(sc, Type::tshiftcnt); 8781 #else 8782 e2 = e2->castTo(sc, e1->type); 8783 #endif 8782 8784 return this; 8783 8785 } … … 8807 8809 e1->checkIntegral(); 8808 8810 e2 = e2->checkIntegral(); 8809 //e2 = e2->castTo(sc, Type::tshiftcnt); 8810 e2 = e2->castTo(sc, e1->type); // LDC 8811 #if !IN_LLVM 8812 e2 = e2->castTo(sc, Type::tshiftcnt); 8813 #else 8814 e2 = e2->castTo(sc, e1->type); 8815 #endif 8811 8816 return this; 8812 8817 } … … 8836 8841 e1->checkIntegral(); 8837 8842 e2 = e2->checkIntegral(); 8838 //e2 = e2->castTo(sc, Type::tshiftcnt); 8839 e2 = e2->castTo(sc, e1->type); // LDC 8843 #if !IN_LLVM 8844 e2 = e2->castTo(sc, Type::tshiftcnt); 8845 #else 8846 e2 = e2->castTo(sc, e1->type); 8847 #endif 8840 8848 return this; 8841 8849 } … … 9324 9332 e2 = e2->checkIntegral(); 9325 9333 e1 = e1->integralPromotions(sc); 9326 //e2 = e2->castTo(sc, Type::tshiftcnt); 9327 e2 = e2->castTo(sc, e1->type); // LDC 9334 #if !IN_LLVM 9335 e2 = e2->castTo(sc, Type::tshiftcnt); 9336 #else 9337 e2 = e2->castTo(sc, e1->type); 9338 #endif 9328 9339 type = e1->type; 9329 9340 } … … 9349 9360 e2 = e2->checkIntegral(); 9350 9361 e1 = e1->integralPromotions(sc); 9351 //e2 = e2->castTo(sc, Type::tshiftcnt); 9352 e2 = e2->castTo(sc, e1->type); // LDC 9362 #if !IN_LLVM 9363 e2 = e2->castTo(sc, Type::tshiftcnt); 9364 #else 9365 e2 = e2->castTo(sc, e1->type); 9366 #endif 9353 9367 type = e1->type; 9354 9368 } … … 9374 9388 e2 = e2->checkIntegral(); 9375 9389 e1 = e1->integralPromotions(sc); 9376 //e2 = e2->castTo(sc, Type::tshiftcnt); 9377 e2 = e2->castTo(sc, e1->type); // LDC 9390 #if !IN_LLVM 9391 e2 = e2->castTo(sc, Type::tshiftcnt); 9392 #else 9393 e2 = e2->castTo(sc, e1->type); 9394 #endif 9378 9395 type = e1->type; 9379 9396 } dmd/expression.h
r1626 r1630 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-20 09by Digital Mars3 // Copyright (c) 1999-2010 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 646 646 SymOffExp(Loc loc, Declaration *var, unsigned offset); 647 647 Expression *semantic(Scope *sc); 648 Expression *interpret(InterState *istate); 648 649 void checkEscape(); 649 650 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 723 724 Expression *syntaxCopy(); 724 725 Expression *semantic(Scope *sc); 726 Expression *interpret(InterState *istate); 725 727 void scanForNestedRef(Scope *sc); 726 728 char *toChars(); … … 986 988 DelegateExp(Loc loc, Expression *e, FuncDeclaration *func); 987 989 Expression *semantic(Scope *sc); 990 Expression *interpret(InterState *istate); 988 991 MATCH implicitConvTo(Type *t); 989 992 Expression *castTo(Scope *sc, Type *t); dmd/func.c
r1617 r1630 1 1 // Compiler implementation of the D programming language 2 // Copyright (c) 1999-20 09by Digital Mars2 // Copyright (c) 1999-2010 by Digital Mars 3 3 // All Rights Reserved 4 4 // written by Walter Bright … … 66 66 inlineAsm = 0; 67 67 cantInterpret = 0; 68 semanticRun = 0;68 semanticRun = PASSinit; 69 69 #if DMDV1 70 70 nestedFrameRef = 0; … … 132 132 assert(!fthrows); // deprecated 133 133 134 // LDC 134 #if IN_LLVM 135 135 f->intrinsicName = intrinsicName; 136 #endif 136 137 137 138 return f; … … 156 157 #endif 157 158 158 if (semanticRun && isFuncLiteralDeclaration())159 if (semanticRun != PASSinit && isFuncLiteralDeclaration()) 159 160 { 160 161 /* Member functions that have return types that are … … 165 166 return; 166 167 } 167 assert(semanticRun <= 1); 168 semanticRun = 1; 168 parent = sc->parent; 169 Dsymbol *parent = toParent(); 170 171 if (semanticRun == PASSsemanticdone) 172 { 173 if (!parent->isClassDeclaration()) 174 return; 175 // need to re-run semantic() in order to set the class's vtbl[] 176 } 177 else 178 { 179 assert(semanticRun <= PASSsemantic); 180 semanticRun = PASSsemantic; 181 } 182 183 unsigned dprogress_save = Module::dprogress; 184 185 foverrides.setDim(0); // reset in case semantic() is being retried for this function 169 186 170 187 if (!type->deco) … … 182 199 183 200 linkage = sc->linkage; 184 // if (!parent)185 {186 //parent = sc->scopesym;187 parent = sc->parent;188 }189 201 protection = sc->protection; 190 202 storage_class |= sc->stc; 191 203 //printf("function storage_class = x%x\n", storage_class); 192 Dsymbol *parent = toParent();193 204 194 205 if (ident == Id::ctor && !isCtorDeclaration()) … … 268 279 isUnitTestDeclaration() || isNewDeclaration() || isDelete()) 269 280 error("special function not allowed in interface %s", id->toChars()); 270 if (fbody )281 if (fbody && isVirtual()) 271 282 error("function body is not abstract in interface %s", id->toChars()); 272 283 } … … 338 349 } 339 350 340 // Find index of existing function in vtbl[] to override 341 vi = findVtblIndex(&cd->vtbl, cd->baseClass ? cd->baseClass->vtbl.dim : 0); 351 /* Find index of existing function in base class's vtbl[] to override 352 * (the index will be the same as in cd's current vtbl[]) 353 */ 354 vi = cd->baseClass ? findVtblIndex(&cd->baseClass->vtbl, cd->baseClass->vtbl.dim) 355 : -1; 356 342 357 switch (vi) 343 358 { … … 379 394 case -2: // can't determine because of fwd refs 380 395 cd->sizeok = 2; // can't finish due to forward reference 396 Module::dprogress = dprogress_save; 381 397 return; 382 398 383 399 default: 384 { FuncDeclaration *fdv = (FuncDeclaration *)cd-> vtbl.data[vi];400 { FuncDeclaration *fdv = (FuncDeclaration *)cd->baseClass->vtbl.data[vi]; 385 401 // This function is covariant with fdv 386 402 if (fdv->isFinal()) … … 456 472 case -2: 457 473 cd->sizeok = 2; // can't finish due to forward reference 474 Module::dprogress = dprogress_save; 458 475 return; 459 476 … … 473 490 * offsets differ 474 491 */ 492 unsigned errors = global.errors; 493 global.gag++; // suppress printing of error messages 475 494 int offset; 476 if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 495 int baseOf = fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset); 496 global.gag--; // suppress printing of error messages 497 if (errors != global.errors) 498 { 499 // any error in isBaseOf() is a forward reference error, so we bail out 500 global.errors = errors; 501 cd->sizeok = 2; // can't finish due to forward reference 502 Module::dprogress = dprogress_save; 503 return; 504 } 505 if (baseOf) 477 506 { 478 507 ti = fdv->type; 479 #if 0480 if (offset)481 ti = fdv->type;482 else if (type->nextOf()->ty == Tclass)483 { ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym;484 if (cdn && cdn->sizeok != 1)485 ti = fdv->type;486 }487 #endif488 508 } 489 509 } … … 597 617 } 598 618 599 if (isVirtual() )619 if (isVirtual() && semanticRun != PASSsemanticdone) 600 620 { 601 621 /* Rewrite contracts as nested functions, then call them. … … 653 673 654 674 Ldone: 675 Module::dprogress++; 676 semanticRun = PASSsemanticdone; 677 655 678 /* Save scope for possible later use (if we need the 656 679 * function internals) … … 689 712 690 713 //printf(" sc->incontract = %d\n", sc->incontract); 691 if (semanticRun >= 3)714 if (semanticRun >= PASSsemantic3) 692 715 return; 693 semanticRun = 3;694 695 // LDC 716 semanticRun = PASSsemantic3; 717 718 #if IN_LLVM 696 719 if (!global.params.useAvailableExternally) 697 720 availableExternally = false; 698 721 #endif 699 722 if (!type || type->ty != Tfunction) 700 723 return; … … 1467 1490 sc2->pop(); 1468 1491 } 1469 semanticRun = 4;1492 semanticRun = PASSsemantic3done; 1470 1493 } 1471 1494 … … 1639 1662 * Find index of function in vtbl[0..dim] that 1640 1663 * this function overrides. 1664 * Prefer an exact match to a covariant one. 1641 1665 * Returns: 1642 1666 * -1 didn't find one … … 1646 1670 int FuncDeclaration::findVtblIndex(Array *vtbl, int dim) 1647 1671 { 1672 FuncDeclaration *mismatch = NULL; 1673 int bestvi = -1; 1648 1674 for (int vi = 0; vi < dim; vi++) 1649 1675 { … … 1651 1677 if (fdv && fdv->ident == ident) 1652 1678 { 1679 if (type->equals(fdv->type)) // if exact match 1680 return vi; // no need to look further 1681 1653 1682 int cov = type->covariant(fdv->type); 1654 1683 //printf("\tbaseclass cov = %d\n", cov); … … 1659 1688 1660 1689 case 1: 1661 return vi; 1690 bestvi = vi; // covariant, but not identical 1691 break; // keep looking for an exact match 1662 1692 1663 1693 case 2: 1664 //type->print(); 1665 //fdv->type->print(); 1666 //printf("%s %s\n", type->deco, fdv->type->deco); 1667 error("of type %s overrides but is not covariant with %s of type %s", 1668 type->toChars(), fdv->toPrettyChars(), fdv->type->toChars()); 1669 break; 1694 mismatch = fdv; // overrides, but is not covariant 1695 break; // keep looking for an exact match 1670 1696 1671 1697 case 3: … … 1677 1703 } 1678 1704 } 1679 return -1; 1705 if (bestvi == -1 && mismatch) 1706 { 1707 //type->print(); 1708 //mismatch->type->print(); 1709 //printf("%s %s\n", type->deco, mismatch->type->deco); 1710 error("of type %s overrides but is not covariant with %s of type %s", 1711 type->toChars(), mismatch->toPrettyChars(), mismatch->type->toChars()); 1712 } 1713 return bestvi; 1680 1714 } 1681 1715 … … 2555 2589 else 2556 2590 id = "__funcliteral"; 2557 this->ident = Identifier::generateId(id);2591 this->ident = Lexer::uniqueId(id); 2558 2592 this->tok = tok; 2559 2593 this->fes = fes; … … 2569 2603 f = (FuncLiteralDeclaration *)s; 2570 2604 else 2571 f = new FuncLiteralDeclaration(loc, endloc, type->syntaxCopy(), tok, fes); 2605 { f = new FuncLiteralDeclaration(loc, endloc, type->syntaxCopy(), tok, fes); 2606 f->ident = ident; // keep old identifier 2607 } 2572 2608 FuncDeclaration::syntaxCopy(f); 2573 2609 return f; … … 2635 2671 void CtorDeclaration::semantic(Scope *sc) 2636 2672 { 2637 ClassDeclaration *cd; 2638 Type *tret; 2639 2640 //printf("CtorDeclaration::semantic()\n"); 2641 if (type) 2642 return; 2643 2673 //printf("CtorDeclaration::semantic() %s\n", toChars()); 2644 2674 sc = sc->push(); 2645 2675 sc->stc &= ~STCstatic; // not a static constructor … … 2647 2677 parent = sc->parent; 2648 2678 Dsymbol *parent = toParent(); 2649 cd = parent->isClassDeclaration(); 2679 Type *tret; 2680 ClassDeclaration *cd = parent->isClassDeclaration(); 2650 2681 if (!cd) 2651 2682 { … … 2656 2687 else 2657 2688 tret = cd->type; //->referenceTo(); 2658 type = new TypeFunction(arguments, tret, varargs, LINKd); 2689 if (!type) 2690 type = new TypeFunction(arguments, tret, varargs, LINKd); 2659 2691 #if STRUCTTHISREF 2660 2692 if (ad && ad->isStructDeclaration()) … … 2671 2703 // return this; 2672 2704 // to the function body 2673 if (fbody )2705 if (fbody && semanticRun < PASSsemantic) 2674 2706 { 2675 2707 Expression *e = new ThisExp(loc); … … 2745 2777 //printf("PostBlitDeclaration::semantic() %s\n", toChars()); 2746 2778 //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor); 2779 //printf("stc = x%llx\n", sc->stc); 2747 2780 parent = sc->parent; 2748 2781 Dsymbol *parent = toParent(); … … 2752 2785 error("post blits are only for struct/union definitions, not %s %s", parent->kind(), parent->toChars()); 2753 2786 } 2754 else if (ident == Id::_postblit )2787 else if (ident == Id::_postblit && semanticRun < PASSsemantic) 2755 2788 ad->postblits.push(this); 2756 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2789 2790 if (!type) 2791 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2757 2792 2758 2793 sc = sc->push(); … … 2787 2822 void PostBlitDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2788 2823 { 2789 if (hgs->hdrgen) 2790 return; 2791 buf->writestring("=this()"); 2824 buf->writestring("this(this)"); 2792 2825 bodyToCBuffer(buf, hgs); 2793 2826 } … … 2826 2859 fatal(); 2827 2860 } 2828 else 2861 else if (semanticRun < PASSsemantic) 2829 2862 cd->dtors.push(this); 2830 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2863 2864 if (!type) 2865 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2831 2866 2832 2867 sc = sc->push(); … … 2894 2929 Dsymbol *StaticCtorDeclaration::syntaxCopy(Dsymbol *s) 2895 2930 { 2896 StaticCtorDeclaration *scd;2897 2898 2931 assert(!s); 2899 scd = new StaticCtorDeclaration(loc, endloc);2932 StaticCtorDeclaration *scd = new StaticCtorDeclaration(loc, endloc); 2900 2933 return FuncDeclaration::syntaxCopy(scd); 2901 2934 } … … 2906 2939 //printf("StaticCtorDeclaration::semantic()\n"); 2907 2940 2908 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2941 if (!type) 2942 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2909 2943 2910 2944 /* If the static ctor appears within a template instantiation, … … 2912 2946 * for different modules. Thus, protect it with a gate. 2913 2947 */ 2914 if (inTemplateInstance() )2948 if (inTemplateInstance() && semanticRun < PASSsemantic) 2915 2949 { 2916 2950 /* Add this prefix to the function: … … 2944 2978 if (m) 2945 2979 { m->needmoduleinfo = 1; 2980 //printf("module1 %s needs moduleinfo\n", m->toChars()); 2946 2981 #ifdef IN_GCC 2947 2982 m->strictlyneedmoduleinfo = 1; … … 3006 3041 void StaticDtorDeclaration::semantic(Scope *sc) 3007 3042 { 3008 ClassDeclaration *cd; 3009 Type *tret; 3010 3011 cd = sc->scopesym->isClassDeclaration(); 3012 if (!cd) 3013 { 3014 } 3015 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 3043 ClassDeclaration *cd = sc->scopesym->isClassDeclaration(); 3044 3045 if (!type) 3046 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 3016 3047 3017 3048 /* If the static ctor appears within a template instantiation, … … 3019 3050 * for different modules. Thus, protect it with a gate. 3020 3051 */ 3021 if (inTemplateInstance() )3052 if (inTemplateInstance() && semanticRun < PASSsemantic) 3022 3053 { 3023 3054 /* Add this prefix to the function: … … 3113 3144 void InvariantDeclaration::semantic(Scope *sc) 3114 3145 { 3115 AggregateDeclaration *ad;3116 Type *tret;3117 3118 3146 parent = sc->parent; 3119 3147 Dsymbol *parent = toParent(); 3120 ad = parent->isAggregateDeclaration();3148 AggregateDeclaration *ad = parent->isAggregateDeclaration(); 3121 3149 if (!ad) 3122 3150 { … … 3124 3152 return; 3125 3153 } 3126 else if (ad->inv && ad->inv != this )3154 else if (ad->inv && ad->inv != this && semanticRun < PASSsemantic) 3127 3155 { 3128 3156 error("more than one invariant for %s", ad->toChars()); 3129 3157 } 3130 3158 ad->inv = this; 3131 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 3159 if (!type) 3160 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 3132 3161 3133 3162 sc = sc->push(); … … 3196 3225 if (global.params.useUnitTests) 3197 3226 { 3198 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 3227 if (!type) 3228 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 3199 3229 Scope *sc2 = sc->push(); 3200 3230 sc2->linkage = LINKd; … … 3272 3302 void NewDeclaration::semantic(Scope *sc) 3273 3303 { 3274 ClassDeclaration *cd;3275 Type *tret;3276 3277 3304 //printf("NewDeclaration::semantic()\n"); 3278 3305 3279 3306 parent = sc->parent; 3280 3307 Dsymbol *parent = toParent(); 3281 cd = parent->isClassDeclaration();3308 ClassDeclaration *cd = parent->isClassDeclaration(); 3282 3309 if (!cd && !parent->isStructDeclaration()) 3283 3310 { 3284 3311 error("new allocators only are for class or struct definitions"); 3285 3312 } 3286 tret = Type::tvoid->pointerTo(); 3287 type = new TypeFunction(arguments, tret, varargs, LINKd); 3313 Type *tret = Type::tvoid->pointerTo(); 3314 if (!type) 3315 type = new TypeFunction(arguments, tret, varargs, LINKd); 3288 3316 3289 3317 type = type->semantic(loc, sc); … … 3358 3386 void DeleteDeclaration::semantic(Scope *sc) 3359 3387 { 3360 ClassDeclaration *cd;3361 3362 3388 //printf("DeleteDeclaration::semantic()\n"); 3363 3389 3364 3390 parent = sc->parent; 3365 3391 Dsymbol *parent = toParent(); 3366 cd = parent->isClassDeclaration();3392 ClassDeclaration *cd = parent->isClassDeclaration(); 3367 3393 if (!cd && !parent->isStructDeclaration()) 3368 3394 { 3369 3395 error("new allocators only are for class or struct definitions"); 3370 3396 } 3371 type = new TypeFunction(arguments, Type::tvoid, 0, LINKd); 3397 if (!type) 3398 type = new TypeFunction(arguments, Type::tvoid, 0, LINKd); 3372 3399 3373 3400 type = type->semantic(loc, sc); dmd/identifier.h
r1195 r1630 17 17 18 18 #include "root.h" 19 19 #if IN_LLVM 20 20 namespace llvm 21 21 { 22 22 class Value; 23 23 } 24 #endif 24 25 25 26 struct Identifier : Object dmd/inline.c
r1587 r1630 1282 1282 return 0; 1283 1283 1284 if (inlineNest || (semanticRun < 3 && !hdrscan))1284 if (inlineNest || (semanticRun < PASSsemantic3 && !hdrscan)) 1285 1285 { 1286 1286 #if CANINLINE_LOG dmd/interpret.c
r1627 r1630 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-20 09by Digital Mars3 // Copyright (c) 1999-2010 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 53 53 Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclaration *fd); 54 54 55 ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Type *type, Expression *elem, size_t dim); 56 55 57 /************************************* 56 58 * Attempt to interpret a function given the arguments. … … 93 95 #endif 94 96 95 if (cantInterpret || semanticRun == 3)97 if (cantInterpret || semanticRun == PASSsemantic3) 96 98 return NULL; 97 99 … … 101 103 } 102 104 103 if (semanticRun < 3 && scope)105 if (semanticRun < PASSsemantic3 && scope) 104 106 { 105 107 semantic3(scope); … … 107 109 return NULL; 108 110 } 109 if (semanticRun < 4)111 if (semanticRun < PASSsemantic3done) 110 112 return NULL; 111 113 … … 161 163 Parameter *arg = Parameter::getNth(tf->parameters, i); 162 164 163 if (arg->storageClass & (STCout | STCref ))165 if (arg->storageClass & (STCout | STCref | STClazy)) 164 166 { 165 167 } … … 1006 1008 } 1007 1009 1010 Expression *FuncExp::interpret(InterState *istate) 1011 { 1012 #if LOG 1013 printf("FuncExp::interpret() %s\n", toChars()); 1014 #endif 1015 return this; 1016 } 1017 1018 Expression *SymOffExp::interpret(InterState *istate) 1019 { 1020 #if LOG 1021 printf("SymOffExp::interpret() %s\n", toChars()); 1022 #endif 1023 if (var->isFuncDeclaration() && offset == 0) 1024 { 1025 return this; 1026 } 1027 error("Cannot interpret %s at compile time", toChars()); 1028 return EXP_CANT_INTERPRET; 1029 } 1030 1031 Expression *DelegateExp::interpret(InterState *istate) 1032 { 1033 #if LOG 1034 printf("DelegateExp::interpret() %s\n", toChars()); 1035 #endif 1036 return this; 1037 } 1038 1008 1039 Expression *getVarExp(Loc loc, InterState *istate, Declaration *d) 1009 1040 { … … 1014 1045 { 1015 1046 #if DMDV2 1047 /* Magic variable __ctfe always returns true when interpreting 1048 */ 1049 if (v->ident == Id::ctfe) 1050 return new IntegerExp(loc, 1, Type::tbool); 1051 1016 1052 if ((v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) && v->init && !v->value) 1017 1053 #else … … 1021 1057 if (e && !e->type) 1022 1058 e->type = v->type; 1059 } 1060 else if (v->isCTFE() && !v->value) 1061 { 1062 if (v->init) 1063 { 1064 e = v->init->toExpression(); 1065 e = e->interpret(istate); 1066 } 1067 else // This should never happen 1068 e = v->type->defaultInitLiteral(); 1023 1069 } 1024 1070 else … … 1483 1529 1484 1530 /*************************************** 1485 * Returns oldelems[0..insertpoint] ~ newelems ~ oldelems[insertpoint ..$]1531 * Returns oldelems[0..insertpoint] ~ newelems ~ oldelems[insertpoint+newelems.length..$] 1486 1532 */ 1487 1533 Expressions *spliceElements(Expressions *oldelems, … … 1498 1544 } 1499 1545 return expsx; 1546 } 1547 1548 /*************************************** 1549 * Returns oldstr[0..insertpoint] ~ newstr ~ oldstr[insertpoint+newlen..$] 1550 */ 1551 StringExp *spliceStringExp(StringExp *oldstr, StringExp *newstr, size_t insertpoint) 1552 { 1553 assert(oldstr->sz==newstr->sz); 1554 unsigned char *s; 1555 size_t oldlen = oldstr->len; 1556 size_t newlen = newstr->len; 1557 size_t sz = oldstr->sz; 1558 s = (unsigned char *)mem.calloc(oldlen + 1, sz); 1559 memcpy(s, oldstr->string, oldlen * sz); 1560 memcpy(s + insertpoint * sz, newstr->string, newlen * sz); 1561 StringExp *se2 = new StringExp(oldstr->loc, s, oldlen); 1562 se2->committed = oldstr->committed; 1563 se2->postfix = oldstr->postfix; 1564 se2->type = oldstr->type; 1565 return se2; 1500 1566 } 1501 1567 … … 1515 1581 } 1516 1582 1583 /****************************** 1584 * Create a string literal consisting of 'value' duplicated 'dim' times. 1585 */ 1586 StringExp *createBlockDuplicatedStringLiteral(Type *type, 1587 unsigned value, size_t dim, int sz) 1588 { 1589 unsigned char *s; 1590 s = (unsigned char *)mem.calloc(dim + 1, sz); 1591 for (int elemi=0; elemi<dim; ++elemi) 1592 { 1593 switch (sz) 1594 { 1595 case 1: s[elemi] = value; break; 1596 case 2: ((unsigned short *)s)[elemi] = value; break; 1597 case 4: ((unsigned *)s)[elemi] = value; break; 1598 default: assert(0); 1599 } 1600 } 1601 StringExp *se = new StringExp(0, s, dim); 1602 se->type = type; 1603 return se; 1604 } 1517 1605 1518 1606 /******************************** … … 1583 1671 // extract the aggregate now. 1584 1672 Expression *aggregate; 1585 if (e1->op == TOKdotvar) { 1673 if (e1->op == TOKdotvar) 1674 { 1586 1675 aggregate = ((DotVarExp *)e1)->e1; 1587 1676 // Get rid of 'this'. 1588 1677 if (aggregate->op == TOKthis && istate->localThis) 1589 aggregate = istate->localThis; 1590 } 1591 1678 aggregate = istate->localThis; 1679 } 1680 if (e1->op == TOKthis && istate->localThis) 1681 e1 = istate->localThis; 1682 1592 1683 /* Assignment to variable of the form: 1593 1684 * v = e2 … … 1624 1715 return e2; 1625 1716 1626 addVarToInterstate(istate, v); 1717 if (istate) 1718 addVarToInterstate(istate, v); 1627 1719 v->value = e2; 1628 1720 e = Cast(type, type, post ? ev : e2); … … 1669 1761 * That's probably a good enhancement idea. 1670 1762 */ 1671 v->value = v->type->defaultInit ();1763 v->value = v->type->defaultInitLiteral(); 1672 1764 } 1673 1765 Expression *vie = v->value; 1766 assert(vie != EXP_CANT_INTERPRET); 1767 1674 1768 if (vie->op == TOKvar) 1675 1769 { … … 1678 1772 } 1679 1773 if (vie->op != TOKstructliteral) 1774 { 1775 error("Cannot assign %s=%s in CTFE", v->toChars(), vie->toChars()); 1680 1776 return EXP_CANT_INTERPRET; 1777 } 1681 1778 StructLiteralExp *se = (StructLiteralExp *)vie; 1682 1779 VarDeclaration *vf = ((DotVarExp *)e1)->var->isVarDeclaration(); … … 2016 2113 return EXP_CANT_INTERPRET; 2017 2114 } 2018 // Chase down rebinding of out and ref2019 if (v->value && v->value->op == TOKvar)2020 {2021 VarExp *ve2 = (VarExp *)v->value;2022 if (ve2->var->isStaticStructInitDeclaration())2023 { // This can happen if v is a struct initialized to2024 // 0 using an __initZ SymbolDeclaration from2025 // TypeStruct::defaultInit()2026 }2027 else2028 v = ve2->var->isVarDeclaration();2029 assert(v);2030 }2115 // Chase down rebinding of out and ref 2116 if (v->value && v->value->op == TOKvar) 2117 { 2118 VarExp *ve2 = (VarExp *)v->value; 2119 if (ve2->var->isStaticStructInitDeclaration()) 2120 { // This can happen if v is a struct initialized to 2121 // 0 using an __initZ SymbolDeclaration from 2122 // TypeStruct::defaultInit() 2123 } 2124 else 2125 v = ve2->var->isVarDeclaration(); 2126 assert(v); 2127 } 2031 2128 /* Set the $ variable 2032 2129 */ … … 2063 2160 dim = ((ArrayLiteralExp *)v->value)->elements->dim; 2064 2161 else if (v->value->op ==TOKstring) 2065 { 2066 error("String slice assignment is not yet supported in CTFE"); 2067 return EXP_CANT_INTERPRET; 2068 } 2162 dim = ((StringExp *)v->value)->len; 2069 2163 } 2070 2164 else … … 2076 2170 int lowerbound = lower ? lower->toInteger() : 0; 2077 2171 2078 ArrayLiteralExp *existing;2079 2172 if (((int)lowerbound < 0) || (upperbound > dim)) 2080 2173 { 2081 error("Array bounds [0..%d] exceeded in slice [%d..%d]", dim, lowerbound, upperbound); 2174 error("Array bounds [0..%d] exceeded in slice [%d..%d]", 2175 dim, lowerbound, upperbound); 2082 2176 return EXP_CANT_INTERPRET; 2083 2177 } 2084 if (upperbound-lowerbound != dim) 2085 { 2086 // Only modifying part of the array. Must create a new array literal. 2087 // If the existing array is uninitialized (this can only happen 2088 // with static arrays), create it. 2089 if (v->value && v->value->op == TOKarrayliteral) 2090 existing = (ArrayLiteralExp *)v->value; 2091 else 2092 { 2093 // this can only happen with static arrays 2094 existing = createBlockDuplicatedArrayLiteral(v->type, v->type->defaultInit(), dim); 2095 } 2096 } 2097 2178 // Could either be slice assignment (v[] = e[]), 2179 // or block assignment (v[] = val). 2180 // For the former, we check that the lengths match. 2181 bool isSliceAssignment = (e2->op == TOKarrayliteral) 2182 || (e2->op == TOKstring); 2183 size_t srclen = 0; 2184 if (e2->op == TOKarrayliteral) 2185 srclen = ((ArrayLiteralExp *)e2)->elements->dim; 2186 else if (e2->op == TOKstring) 2187 srclen = ((StringExp *)e2)->len; 2188 if (isSliceAssignment && srclen != (upperbound - lowerbound)) 2189 { 2190 error("Array length mismatch assigning [0..%d] to [%d..%d]", srclen, lowerbound, upperbound); 2191 return e; 2192 } 2098 2193 if (e2->op == TOKarrayliteral) 2099 2194 { 2100 2195 // Static array assignment from literal 2101 2196 ArrayLiteralExp *ae = (ArrayLiteralExp *)e2; 2102 if (ae->elements->dim != (upperbound - lowerbound))2103 {2104 error("Array length mismatch assigning [0..%d] to [%d..%d]", ae->elements->dim, lowerbound, upperbound);2105 return e;2106 }2107 2197 if (upperbound - lowerbound == dim) 2108 2198 v->value = ae; 2109 2199 else 2110 2200 { 2201 ArrayLiteralExp *existing; 2202 // Only modifying part of the array. Must create a new array literal. 2203 // If the existing array is uninitialized (this can only happen 2204 // with static arrays), create it. 2205 if (v->value && v->value->op == TOKarrayliteral) 2206 existing = (ArrayLiteralExp *)v->value; 2207 else // this can only happen with static arrays 2208 existing = createBlockDuplicatedArrayLiteral(v->type, v->type->defaultInit(), dim); 2111 2209 // value[] = value[0..lower] ~ ae ~ value[upper..$] 2112 2210 existing->elements = spliceElements(existing->elements, ae->elements, lowerbound); … … 2115 2213 return e2; 2116 2214 } 2215 else if (e2->op == TOKstring) 2216 { 2217 StringExp *se = (StringExp *)e2; 2218 if (upperbound-lowerbound == dim) 2219 v->value = e2; 2220 else 2221 { 2222 if (!v->value) 2223 v->value = createBlockDuplicatedStringLiteral(se->type, 2224 se->type->defaultInit()->toInteger(), dim, se->sz); 2225 if (v->value->op==TOKstring) 2226 v->value = spliceStringExp((StringExp *)v->value, se, lowerbound); 2227 else 2228 error("String slice assignment is not yet supported in CTFE"); 2229 } 2230 return e2; 2231 } 2117 2232 else if (t->nextOf()->ty == e2->type->ty) 2118 2233 { 2119 // Static array block assignment2120 if (upperbound -lowerbound ==dim)2234 // Static array block assignment 2235 if (upperbound - lowerbound == dim) 2121 2236 v->value = createBlockDuplicatedArrayLiteral(v->type, e2, dim); 2122 2237 else 2123 2238 { 2239 ArrayLiteralExp *existing; 2240 // Only modifying part of the array. Must create a new array literal. 2241 // If the existing array is uninitialized (this can only happen 2242 // with static arrays), create it. 2243 if (v->value && v->value->op == TOKarrayliteral) 2244 existing = (ArrayLiteralExp *)v->value; 2245 else // this can only happen with static arrays 2246 existing = createBlockDuplicatedArrayLiteral(v->type, v->type->defaultInit(), dim); 2124 2247 // value[] = value[0..lower] ~ ae ~ value[upper..$] 2125 existing->elements = spliceElements(existing->elements, createBlockDuplicatedArrayLiteral(v->type, e2, upperbound-lowerbound)->elements, lowerbound); 2248 existing->elements = spliceElements(existing->elements, 2249 createBlockDuplicatedArrayLiteral(v->type, e2, upperbound-lowerbound)->elements, 2250 lowerbound); 2126 2251 v->value = existing; 2127 2252 } 2128 return e2;2129 }2130 else if (e2->op == TOKstring)2131 {2132 StringExp *se = (StringExp *)e2;2133 // This is problematic. char[8] should be storing2134 // values as a string literal, not2135 // as an array literal. Then, for static arrays, we2136 // could do modifications2137 // in-place, with a dramatic memory and speed improvement.2138 error("String slice assignment is not yet supported in CTFE");2139 2253 return e2; 2140 2254 } … … 2261 2375 printf("CallExp::interpret() %s\n", toChars()); 2262 2376 #endif 2263 if (e1->op == TOKdotvar) 2264 { 2265 Expression * pthis = ((DotVarExp*)e1)->e1; 2266 FuncDeclaration *fd = ((DotVarExp*)e1)->var->isFuncDeclaration(); 2267 TypeFunction *tf = fd ? (TypeFunction *)(fd->type) : NULL; 2268 if (tf) 2269 { // Member function call 2270 if(pthis->op == TOKthis) 2271 pthis = istate->localThis; 2272 Expression *eresult = fd->interpret(istate, arguments, pthis); 2377 2378 Expression * pthis = NULL; 2379 FuncDeclaration *fd = NULL; 2380 Expression *ecall = e1; 2381 if (ecall->op == TOKindex) 2382 ecall = e1->interpret(istate); 2383 if (ecall->op == TOKdotvar && !((DotVarExp*)ecall)->var->isFuncDeclaration()) 2384 ecall = e1->interpret(istate); 2385 2386 if (ecall->op == TOKdotvar) 2387 { // Calling a member function 2388 pthis = ((DotVarExp*)e1)->e1; 2389 fd = ((DotVarExp*)e1)->var->isFuncDeclaration(); 2390 } 2391 else if (ecall->op == TOKvar) 2392 { 2393 VarDeclaration *vd = ((VarExp *)ecall)->var->isVarDeclaration(); 2394 if (vd && vd->value) 2395 ecall = vd->value; 2396 else // Calling a function 2397 fd = ((VarExp *)e1)->var->isFuncDeclaration(); 2398 } 2399 if (ecall->op == TOKdelegate) 2400 { // Calling a delegate 2401 fd = ((DelegateExp *)ecall)->func; 2402 pthis = ((DelegateExp *)ecall)->e1; 2403 } 2404 else if (ecall->op == TOKfunction) 2405 { // Calling a delegate literal 2406 fd = ((FuncExp*)ecall)->fd; 2407 } 2408 else if (ecall->op == TOKstar && ((PtrExp*)ecall)->e1->op==TOKfunction) 2409 { // Calling a function literal 2410 fd = ((FuncExp*)((PtrExp*)ecall)->e1)->fd; 2411 } 2412 else if (ecall->op == TOKstar && ((PtrExp*)ecall)->e1->op==TOKvar) 2413 { // Calling a function pointer 2414 VarDeclaration *vd = ((VarExp *)((PtrExp*)ecall)->e1)->var->isVarDeclaration(); 2415 if (vd && vd->value && vd->value->op==TOKsymoff) 2416 fd = ((SymOffExp *)vd->value)->var->isFuncDeclaration(); 2417 } 2418 2419 TypeFunction *tf = fd ? (TypeFunction *)(fd->type) : NULL; 2420 if (!tf) 2421 { // DAC: I'm not sure if this ever happens 2422 //printf("ecall=%s %d %d\n", ecall->toChars(), ecall->op, TOKcall); 2423 error("cannot evaluate %s at compile time", toChars()); 2424 return EXP_CANT_INTERPRET; 2425 } 2426 if (pthis && fd) 2427 { // Member function call 2428 if (pthis->op == TOKthis) 2429 pthis = istate->localThis; 2430 else if (pthis->op == TOKcomma) 2431 pthis = pthis->interpret(istate); 2432 Expression *eresult = fd->interpret(istate, arguments, pthis); 2433 if (eresult) 2434 e = eresult; 2435 else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors) 2436 e = EXP_VOID_INTERPRET; 2437 else 2438 error("cannot evaluate %s at compile time", toChars()); 2439 return e; 2440 } 2441 else if (fd) 2442 { // function call 2443 #if DMDV2 2444 enum BUILTIN b = fd->isBuiltin(); 2445 if (b) 2446 { Expressions args; 2447 args.setDim(arguments->dim); 2448 for (size_t i = 0; i < args.dim; i++) 2449 { 2450 Expression *earg = (Expression *)arguments->data[i]; 2451 earg = earg->interpret(istate); 2452 if (earg == EXP_CANT_INTERPRET) 2453 return earg; 2454 args.data[i] = (void *)earg; 2455 } 2456 e = eval_builtin(b, &args); 2457 if (!e) 2458 e = EXP_CANT_INTERPRET; 2459 } 2460 else 2461 #endif 2462 // Inline .dup 2463 if (fd->ident == Id::adDup && arguments && arguments->dim == 2) 2464 { 2465 e = (Expression *)arguments->data[1]; 2466 e = e->interpret(istate); 2467 if (e != EXP_CANT_INTERPRET) 2468 { 2469 e = expType(type, e); 2470 } 2471 } 2472 else 2473 { 2474 Expression *eresult = fd->interpret(istate, arguments); 2273 2475 if (eresult) 2274 2476 e = eresult; … … 2277 2479 else 2278 2480 error("cannot evaluate %s at compile time", toChars()); 2279 return e; 2280 } 2481 } 2482 } 2483 else 2484 { 2281 2485 error("cannot evaluate %s at compile time", toChars()); 2282 2486 return EXP_CANT_INTERPRET; 2283 2487 } 2284 if (e1->op == TOKvar) 2285 { 2286 FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration(); 2287 if (fd) 2288 { 2289 #if DMDV2 2290 enum BUILTIN b = fd->isBuiltin(); 2291 if (b) 2292 { Expressions args; 2293 args.setDim(arguments->dim); 2294 for (size_t i = 0; i < args.dim; i++) 2295 { 2296 Expression *earg = (Expression *)arguments->data[i]; 2297 earg = earg->interpret(istate); 2298 if (earg == EXP_CANT_INTERPRET) 2299 return earg; 2300 args.data[i] = (void *)earg; 2301 } 2302 e = eval_builtin(b, &args); 2303 if (!e) 2304 e = EXP_CANT_INTERPRET; 2305 } 2306 else 2307 #endif 2308 // Inline .dup 2309 if (fd->ident == Id::adDup && arguments && arguments->dim == 2) 2310 { 2311 e = (Expression *)arguments->data[1]; 2312 e = e->interpret(istate); 2313 if (e != EXP_CANT_INTERPRET) 2314 { 2315 e = expType(type, e); 2316 } 2317 } 2318 else 2319 { 2320 Expression *eresult = fd->interpret(istate, arguments); 2321 if (eresult) 2322 e = eresult; 2323 else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors) 2324 e = EXP_VOID_INTERPRET; 2325 else 2326 error("cannot evaluate %s at compile time", toChars()); 2327 } 2328 } 2329 } 2330 return e; 2488 return e; 2331 2489 } 2332 2490 … … 2336 2494 printf("CommaExp::interpret() %s\n", toChars()); 2337 2495 #endif 2496 // If the comma returns a temporary variable, it needs to be an lvalue 2497 // (this is particularly important for struct constructors) 2498 if (e1->op == TOKdeclaration && e2->op == TOKvar 2499 && ((DeclarationExp *)e1)->declaration == ((VarExp*)e2)->var) 2500 { 2501 VarExp* ve = (VarExp *)e2; 2502 VarDeclaration *v = ve->var->isVarDeclaration(); 2503 if (!v->init && !v->value) 2504 v->value = v->type->defaultInitLiteral(); 2505 if (!v->value) 2506 v->value = v->init->toExpression(); 2507 v->value = v->value->interpret(istate); 2508 return e2; 2509 } 2510 2338 2511 Expression *e = e1->interpret(istate); 2339 2512 if (e != EXP_CANT_INTERPRET) … … 2517 2690 { // Special case: deal with compiler-inserted assert(&this, "null this") 2518 2691 AddrExp *ade = (AddrExp *)this->e1; 2519 if(ade->e1->op == TOKthis && istate->localThis) 2520 return istate->localThis->interpret(istate); 2521 } 2522 if (this->e1->op == TOKthis) 2523 { 2524 if(istate->localThis) 2525 return istate->localThis->interpret(istate); 2526 } 2692 if (ade->e1->op == TOKthis && istate->localThis) 2693 if (ade->e1->op == TOKdotvar 2694 && ((DotVarExp *)(istate->localThis))->e1->op == TOKthis) 2695 return getVarExp(loc, istate, ((DotVarExp*)(istate->localThis))->var); 2696 else 2697 return istate->localThis->interpret(istate); 2698 } 2699 if (this->e1->op == TOKthis) 2700 { 2701 if (istate->localThis) 2702 return istate->localThis->interpret(istate); 2703 } 2527 2704 e1 = this->e1->interpret(istate); 2528 2705 if (e1 == EXP_CANT_INTERPRET) dmd/mangle.c
r1587 r1630 114 114 break; 115 115 116 // LDC 116 #if IN_LLVM 117 117 case LINKintrinsic: 118 118 #endif 119 119 case LINKc: 120 120 case LINKwindows: dmd/mars.c
r1628 r1630 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-20 09by Digital Mars3 // Copyright (c) 1999-2010 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 14 14 #include <assert.h> 15 15 #include <limits.h> 16 #if IN_LLVM 16 17 #include <string> 17 18 #include <cstdarg> 19 #endif 18 20 19 21 #if POSIX … … 35 37 #include "json.h" 36 38 39 #if IN_LLVM 37 40 #include "gen/revisions.h" 41 #endif 38 42 39 43 Global global; … … 47 51 ddoc_ext = "ddoc"; 48 52 json_ext = "json"; 53 map_ext = "map"; 49 54 50 55 // LDC … … 59 64 copyright = "Copyright (c) 1999-2009 by Digital Mars and Tomas Lindquist Olsen"; 60 65 written = "written by Walter Bright and Tomas Lindquist Olsen"; 61 version = "v1.05 5";66 version = "v1.056"; 62 67 ldc_version = LDC_REV; 63 68 llvm_version = LLVM_REV_STR; dmd/mars.h
r1621 r1630 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-20 09by Digital Mars3 // Copyright (c) 1999-2010 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 236 236 char *resfile; 237 237 char *exefile; 238 238 char *mapfile; 239 240 #if IN_LLVM 239 241 // LDC stuff 240 242 OUTPUTFLAG output_ll; … … 251 253 const char *targetTriple; 252 254 const char *dataLayout; 255 #endif 253 256 }; 254 257 … … 269 272 const char *hdr_ext; // for D 'header' import files 270 273 const char *json_ext; // for JSON files 274 const char *map_ext; // for .map files 271 275 const char *copyright; 272 276 const char *written; … … 394 398 LINKpascal, 395 399 396 // LDC 400 #if IN_LLVM 397 401 LINKintrinsic, 402 #endif 398 403 }; 399 404 dmd/module.c
r1587 r1630 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-20 09by Digital Mars3 // Copyright (c) 1999-2010 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 45 45 #endif 46 46 47 47 #if IN_LLVM 48 48 #include "llvm/Support/CommandLine.h" 49 49 #include <map> … … 56 56 llvm::cl::desc("Write object files with fully qualified names"), 57 57 llvm::cl::ZeroOrMore); 58 59 58 #endif 60 59 61 60 ClassDeclaration *Module::moduleinfo; … … 972 971 void Module::runDeferredSemantic() 973 972 { 974 size_t len; 973 if (dprogress == 0) 974 return; 975 975 976 976 static int nested; … … 980 980 nested++; 981 981 982 size_t len; 982 983 do 983 984 { dmd/module.h
r1587 r1630 154 154 void deleteObjFile(); 155 155 void addDeferredSemantic(Dsymbol *s); 156 void runDeferredSemantic();156 static void runDeferredSemantic(); 157 157 int imports(Module *m); 158 158 dmd/mtype.c
r1627 r1630 4062 4062 { 4063 4063 if (sym->scope) 4064 { 4065 sym->semantic(NULL); // attempt to resolve forward reference 4064 { // Enum is forward referenced. We don't need to resolve the whole thing, 4065 // just the base type 4066 if (sym->memtype) 4067 { sym->memtype = sym->memtype->semantic(sym->loc, sym->scope); 4068 } 4069 else 4070 { if (!sym->isAnonymous()) 4071 sym->memtype = Type::tint32; 4072 } 4066 4073 } 4067 4074 if (!sym->memtype) dmd/optimize.c
r1622 r1630 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-20 09by Digital Mars3 // Copyright (c) 1999-2010 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 345 345 346 346 Expression *CallExp::optimize(int result) 347 { Expression *e = this; 347 { 348 //printf("CallExp::optimize(result = %d) %s\n", result, toChars()); 349 Expression *e = this; 348 350 349 351 // Optimize parameters … … 359 361 360 362 e1 = e1->optimize(result); 361 if (e1->op == TOKvar && result & WANTinterpret) 362 { 363 FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration(); 364 if (fd) 365 { 366 Expression *eresult = fd->interpret(NULL, arguments); 367 if (eresult && eresult != EXP_VOID_INTERPRET) 368 e = eresult; 369 else if (result & WANTinterpret) 370 error("cannot evaluate %s at compile time", toChars()); 371 } 363 if (result & WANTinterpret) 364 { 365 Expression *eresult = interpret(NULL); 366 if (eresult == EXP_CANT_INTERPRET) 367 return e; 368 if (eresult && eresult != EXP_VOID_INTERPRET) 369 e = eresult; 370 else 371 error("cannot evaluate %s at compile time", toChars()); 372 372 } 373 373 return e; … … 625 625 626 626 //printf("CommaExp::optimize(result = %d) %s\n", result, toChars()); 627 // Comma needs special treatment, because it may 628 // contain compiler-generated declarations. We can interpret them, but 629 // otherwise we must NOT attempt to constant-fold them. 630 // In particular, if the comma returns a temporary variable, it needs 631 // to be an lvalue (this is particularly important for struct constructors) 632 633 if (result & WANTinterpret) 634 { // Interpreting comma needs special treatment, because it may 635 // contain compiler-generated declarations. 636 e = interpret(NULL); 637 return (e == EXP_CANT_INTERPRET) ? this : e; 638 } 639 // Don't constant fold if it is a compiler-generated temporary. 640 if (e1->op == TOKdeclaration) 641 return this; 642 627 643 e1 = e1->optimize(result & WANTinterpret); 628 644 e2 = e2->optimize(result); … … 710 726 { // Convert slice of string literal into dynamic array 711 727 Type *t = e1->type->toBasetype(); 712 if (t->next )713 e = e1->castTo(NULL, t->next ->arrayOf());728 if (t->nextOf()) 729 e = e1->castTo(NULL, t->nextOf()->arrayOf()); 714 730 } 715 731 return e; dmd/statement.c
r1607 r1630 2484 2484 2485 2485 e = e->semantic(sc); 2486 #if 1 2486 2487 e = e->optimize(WANTvalue | WANTinterpret); 2488 #else 2489 e = e->interpret(NULL); 2490 if (e == EXP_CANT_INTERPRET) 2491 fprintf(stdmsg, ((Expression *)args->data[i])->toChars()); 2492 else 2493 #endif 2487 2494 if (e->op == TOKstring) 2488 2495 { dmd/statement.h
r1607 r1630 55 55 56 56 enum TOK; 57 57 #if IN_LLVM 58 58 namespace llvm 59 59 { … … 62 62 class ConstantInt; 63 63 } 64 #endif 64 65 65 66 // Back end … … 142 143 virtual CaseStatement* isCaseStatement() { return NULL; } 143 144 144 // LDC 145 #if IN_LLVM 145 146 virtual void toNakedIR(IRState *irs); 146 147 virtual AsmBlockStatement* endsWithAsm(); 148 #endif 147 149 }; 148 150 … … 173 175 void toIR(IRState *irs); 174 176 175 // LDC 177 #if IN_LLVM 176 178 void toNakedIR(IRState *irs); 179 #endif 177 180 }; 178 181 dmd/struct.c
r1628 r1630 20 20 #include "id.h" 21 21 #include "statement.h" 22 #include "template.h" 22 23 23 24 /********************************* AggregateDeclaration ****************************/ … … 269 270 scope = NULL; 270 271 } 272 273 unsigned dprogress_save = Module::dprogress; 271 274 272 275 parent = sc->parent; … … 418 421 scope->setNoFree(); 419 422 scope->module->addDeferredSemantic(this); 423 424 Module::dprogress = dprogress_save; 420 425 //printf("\tdeferring %s\n", toChars()); 421 426 return; dmd/template.c
r1618 r1630 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-20 09by Digital Mars3 // Copyright (c) 1999-2010 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 3540 3540 if (tinst) 3541 3541 { tinst->printInstantiationTrace(); 3542 fatal(); 3542 if (!global.gag) 3543 fatal(); 3543 3544 } 3544 3545 errors = 1;

