Mercurial > projects > ldc
comparison dmd/func.c @ 1630:44b145be2ef5
Merge dmd 1.056.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 06 Feb 2010 15:53:52 +0000 |
parents | 6820110de311 |
children | 9bf06e02070b |
comparison
equal
deleted
inserted
replaced
1629:b07d683ba4d0 | 1630:44b145be2ef5 |
---|---|
1 // Compiler implementation of the D programming language | 1 // Compiler implementation of the D programming language |
2 // Copyright (c) 1999-2009 by Digital Mars | 2 // Copyright (c) 1999-2010 by Digital Mars |
3 // All Rights Reserved | 3 // All Rights Reserved |
4 // written by Walter Bright | 4 // written by Walter Bright |
5 // http://www.digitalmars.com | 5 // http://www.digitalmars.com |
6 // License for redistribution is by either the Artistic License | 6 // License for redistribution is by either the Artistic License |
7 // in artistic.txt, or the GNU General Public License in gnu.txt. | 7 // in artistic.txt, or the GNU General Public License in gnu.txt. |
63 naked = 0; | 63 naked = 0; |
64 inlineStatus = ILSuninitialized; | 64 inlineStatus = ILSuninitialized; |
65 inlineNest = 0; | 65 inlineNest = 0; |
66 inlineAsm = 0; | 66 inlineAsm = 0; |
67 cantInterpret = 0; | 67 cantInterpret = 0; |
68 semanticRun = 0; | 68 semanticRun = PASSinit; |
69 #if DMDV1 | 69 #if DMDV1 |
70 nestedFrameRef = 0; | 70 nestedFrameRef = 0; |
71 #endif | 71 #endif |
72 fes = NULL; | 72 fes = NULL; |
73 introducing = 0; | 73 introducing = 0; |
129 f->frequire = frequire ? frequire->syntaxCopy() : NULL; | 129 f->frequire = frequire ? frequire->syntaxCopy() : NULL; |
130 f->fensure = fensure ? fensure->syntaxCopy() : NULL; | 130 f->fensure = fensure ? fensure->syntaxCopy() : NULL; |
131 f->fbody = fbody ? fbody->syntaxCopy() : NULL; | 131 f->fbody = fbody ? fbody->syntaxCopy() : NULL; |
132 assert(!fthrows); // deprecated | 132 assert(!fthrows); // deprecated |
133 | 133 |
134 // LDC | 134 #if IN_LLVM |
135 f->intrinsicName = intrinsicName; | 135 f->intrinsicName = intrinsicName; |
136 #endif | |
136 | 137 |
137 return f; | 138 return f; |
138 } | 139 } |
139 | 140 |
140 | 141 |
153 printf("\tFuncLiteralDeclaration()\n"); | 154 printf("\tFuncLiteralDeclaration()\n"); |
154 printf("sc->parent = %s, parent = %s\n", sc->parent->toChars(), parent ? parent->toChars() : ""); | 155 printf("sc->parent = %s, parent = %s\n", sc->parent->toChars(), parent ? parent->toChars() : ""); |
155 printf("type: %p, %s\n", type, type->toChars()); | 156 printf("type: %p, %s\n", type, type->toChars()); |
156 #endif | 157 #endif |
157 | 158 |
158 if (semanticRun && isFuncLiteralDeclaration()) | 159 if (semanticRun != PASSinit && isFuncLiteralDeclaration()) |
159 { | 160 { |
160 /* Member functions that have return types that are | 161 /* Member functions that have return types that are |
161 * forward references can have semantic() run more than | 162 * forward references can have semantic() run more than |
162 * once on them. | 163 * once on them. |
163 * See test\interface2.d, test20 | 164 * See test\interface2.d, test20 |
164 */ | 165 */ |
165 return; | 166 return; |
166 } | 167 } |
167 assert(semanticRun <= 1); | 168 parent = sc->parent; |
168 semanticRun = 1; | 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 if (!type->deco) | 187 if (!type->deco) |
171 { | 188 { |
172 type = type->semantic(loc, sc); | 189 type = type->semantic(loc, sc); |
173 } | 190 } |
179 } | 196 } |
180 f = (TypeFunction *)(type); | 197 f = (TypeFunction *)(type); |
181 size_t nparams = Parameter::dim(f->parameters); | 198 size_t nparams = Parameter::dim(f->parameters); |
182 | 199 |
183 linkage = sc->linkage; | 200 linkage = sc->linkage; |
184 // if (!parent) | |
185 { | |
186 //parent = sc->scopesym; | |
187 parent = sc->parent; | |
188 } | |
189 protection = sc->protection; | 201 protection = sc->protection; |
190 storage_class |= sc->stc; | 202 storage_class |= sc->stc; |
191 //printf("function storage_class = x%x\n", storage_class); | 203 //printf("function storage_class = x%x\n", storage_class); |
192 Dsymbol *parent = toParent(); | |
193 | 204 |
194 if (ident == Id::ctor && !isCtorDeclaration()) | 205 if (ident == Id::ctor && !isCtorDeclaration()) |
195 error("_ctor is reserved for constructors"); | 206 error("_ctor is reserved for constructors"); |
196 | 207 |
197 if (isConst() || isAuto() || isScope()) | 208 if (isConst() || isAuto() || isScope()) |
265 #endif | 276 #endif |
266 isDtorDeclaration() || | 277 isDtorDeclaration() || |
267 isInvariantDeclaration() || | 278 isInvariantDeclaration() || |
268 isUnitTestDeclaration() || isNewDeclaration() || isDelete()) | 279 isUnitTestDeclaration() || isNewDeclaration() || isDelete()) |
269 error("special function not allowed in interface %s", id->toChars()); | 280 error("special function not allowed in interface %s", id->toChars()); |
270 if (fbody) | 281 if (fbody && isVirtual()) |
271 error("function body is not abstract in interface %s", id->toChars()); | 282 error("function body is not abstract in interface %s", id->toChars()); |
272 } | 283 } |
273 | 284 |
274 /* Template member functions aren't virtual: | 285 /* Template member functions aren't virtual: |
275 * interface TestInterface { void tpl(T)(); } | 286 * interface TestInterface { void tpl(T)(); } |
335 { | 346 { |
336 //printf("\tnot virtual\n"); | 347 //printf("\tnot virtual\n"); |
337 goto Ldone; | 348 goto Ldone; |
338 } | 349 } |
339 | 350 |
340 // Find index of existing function in vtbl[] to override | 351 /* Find index of existing function in base class's vtbl[] to override |
341 vi = findVtblIndex(&cd->vtbl, cd->baseClass ? cd->baseClass->vtbl.dim : 0); | 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 switch (vi) | 357 switch (vi) |
343 { | 358 { |
344 case -1: | 359 case -1: |
345 /* Didn't find one, so | 360 /* Didn't find one, so |
346 * This is an 'introducing' function which gets a new | 361 * This is an 'introducing' function which gets a new |
376 } | 391 } |
377 break; | 392 break; |
378 | 393 |
379 case -2: // can't determine because of fwd refs | 394 case -2: // can't determine because of fwd refs |
380 cd->sizeok = 2; // can't finish due to forward reference | 395 cd->sizeok = 2; // can't finish due to forward reference |
396 Module::dprogress = dprogress_save; | |
381 return; | 397 return; |
382 | 398 |
383 default: | 399 default: |
384 { FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi]; | 400 { FuncDeclaration *fdv = (FuncDeclaration *)cd->baseClass->vtbl.data[vi]; |
385 // This function is covariant with fdv | 401 // This function is covariant with fdv |
386 if (fdv->isFinal()) | 402 if (fdv->isFinal()) |
387 error("cannot override final function %s", fdv->toPrettyChars()); | 403 error("cannot override final function %s", fdv->toPrettyChars()); |
388 | 404 |
389 #if DMDV2 | 405 #if DMDV2 |
453 case -1: | 469 case -1: |
454 break; | 470 break; |
455 | 471 |
456 case -2: | 472 case -2: |
457 cd->sizeok = 2; // can't finish due to forward reference | 473 cd->sizeok = 2; // can't finish due to forward reference |
474 Module::dprogress = dprogress_save; | |
458 return; | 475 return; |
459 | 476 |
460 default: | 477 default: |
461 { FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi]; | 478 { FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi]; |
462 Type *ti = NULL; | 479 Type *ti = NULL; |
470 else if (!type->equals(fdv->type)) | 487 else if (!type->equals(fdv->type)) |
471 { | 488 { |
472 /* Only need to have a tintro if the vptr | 489 /* Only need to have a tintro if the vptr |
473 * offsets differ | 490 * offsets differ |
474 */ | 491 */ |
492 unsigned errors = global.errors; | |
493 global.gag++; // suppress printing of error messages | |
475 int offset; | 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 ti = fdv->type; | 507 ti = fdv->type; |
479 #if 0 | |
480 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 #endif | |
488 } | 508 } |
489 } | 509 } |
490 if (ti) | 510 if (ti) |
491 { | 511 { |
492 if (tintro && !tintro->equals(ti)) | 512 if (tintro && !tintro->equals(ti)) |
594 goto Lassignerr; | 614 goto Lassignerr; |
595 } | 615 } |
596 } | 616 } |
597 } | 617 } |
598 | 618 |
599 if (isVirtual()) | 619 if (isVirtual() && semanticRun != PASSsemanticdone) |
600 { | 620 { |
601 /* Rewrite contracts as nested functions, then call them. | 621 /* Rewrite contracts as nested functions, then call them. |
602 * Doing it as nested functions means that overriding functions | 622 * Doing it as nested functions means that overriding functions |
603 * can call them. | 623 * can call them. |
604 */ | 624 */ |
650 fdensure = fd; | 670 fdensure = fd; |
651 } | 671 } |
652 } | 672 } |
653 | 673 |
654 Ldone: | 674 Ldone: |
675 Module::dprogress++; | |
676 semanticRun = PASSsemanticdone; | |
677 | |
655 /* Save scope for possible later use (if we need the | 678 /* Save scope for possible later use (if we need the |
656 * function internals) | 679 * function internals) |
657 */ | 680 */ |
658 scope = new Scope(*sc); | 681 scope = new Scope(*sc); |
659 scope->setNoFree(); | 682 scope->setNoFree(); |
686 //printf("storage class = x%x %x\n", sc->stc, storage_class); | 709 //printf("storage class = x%x %x\n", sc->stc, storage_class); |
687 //{ static int x; if (++x == 2) *(char*)0=0; } | 710 //{ static int x; if (++x == 2) *(char*)0=0; } |
688 //printf("\tlinkage = %d\n", sc->linkage); | 711 //printf("\tlinkage = %d\n", sc->linkage); |
689 | 712 |
690 //printf(" sc->incontract = %d\n", sc->incontract); | 713 //printf(" sc->incontract = %d\n", sc->incontract); |
691 if (semanticRun >= 3) | 714 if (semanticRun >= PASSsemantic3) |
692 return; | 715 return; |
693 semanticRun = 3; | 716 semanticRun = PASSsemantic3; |
694 | 717 |
695 // LDC | 718 #if IN_LLVM |
696 if (!global.params.useAvailableExternally) | 719 if (!global.params.useAvailableExternally) |
697 availableExternally = false; | 720 availableExternally = false; |
698 | 721 #endif |
699 if (!type || type->ty != Tfunction) | 722 if (!type || type->ty != Tfunction) |
700 return; | 723 return; |
701 f = (TypeFunction *)(type); | 724 f = (TypeFunction *)(type); |
702 | 725 |
703 // Check the 'throws' clause | 726 // Check the 'throws' clause |
1464 } | 1487 } |
1465 | 1488 |
1466 sc2->callSuper = 0; | 1489 sc2->callSuper = 0; |
1467 sc2->pop(); | 1490 sc2->pop(); |
1468 } | 1491 } |
1469 semanticRun = 4; | 1492 semanticRun = PASSsemantic3done; |
1470 } | 1493 } |
1471 | 1494 |
1472 void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 1495 void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
1473 { | 1496 { |
1474 //printf("FuncDeclaration::toCBuffer() '%s'\n", toChars()); | 1497 //printf("FuncDeclaration::toCBuffer() '%s'\n", toChars()); |
1636 } | 1659 } |
1637 | 1660 |
1638 /************************************************* | 1661 /************************************************* |
1639 * Find index of function in vtbl[0..dim] that | 1662 * Find index of function in vtbl[0..dim] that |
1640 * this function overrides. | 1663 * this function overrides. |
1664 * Prefer an exact match to a covariant one. | |
1641 * Returns: | 1665 * Returns: |
1642 * -1 didn't find one | 1666 * -1 didn't find one |
1643 * -2 can't determine because of forward references | 1667 * -2 can't determine because of forward references |
1644 */ | 1668 */ |
1645 | 1669 |
1646 int FuncDeclaration::findVtblIndex(Array *vtbl, int dim) | 1670 int FuncDeclaration::findVtblIndex(Array *vtbl, int dim) |
1647 { | 1671 { |
1672 FuncDeclaration *mismatch = NULL; | |
1673 int bestvi = -1; | |
1648 for (int vi = 0; vi < dim; vi++) | 1674 for (int vi = 0; vi < dim; vi++) |
1649 { | 1675 { |
1650 FuncDeclaration *fdv = ((Dsymbol *)vtbl->data[vi])->isFuncDeclaration(); | 1676 FuncDeclaration *fdv = ((Dsymbol *)vtbl->data[vi])->isFuncDeclaration(); |
1651 if (fdv && fdv->ident == ident) | 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 int cov = type->covariant(fdv->type); | 1682 int cov = type->covariant(fdv->type); |
1654 //printf("\tbaseclass cov = %d\n", cov); | 1683 //printf("\tbaseclass cov = %d\n", cov); |
1655 switch (cov) | 1684 switch (cov) |
1656 { | 1685 { |
1657 case 0: // types are distinct | 1686 case 0: // types are distinct |
1658 break; | 1687 break; |
1659 | 1688 |
1660 case 1: | 1689 case 1: |
1661 return vi; | 1690 bestvi = vi; // covariant, but not identical |
1691 break; // keep looking for an exact match | |
1662 | 1692 |
1663 case 2: | 1693 case 2: |
1664 //type->print(); | 1694 mismatch = fdv; // overrides, but is not covariant |
1665 //fdv->type->print(); | 1695 break; // keep looking for an exact match |
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; | |
1670 | 1696 |
1671 case 3: | 1697 case 3: |
1672 return -2; // forward references | 1698 return -2; // forward references |
1673 | 1699 |
1674 default: | 1700 default: |
1675 assert(0); | 1701 assert(0); |
1676 } | 1702 } |
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 |
1682 /**************************************************** | 1716 /**************************************************** |
1683 * Overload this FuncDeclaration with the new one f. | 1717 * Overload this FuncDeclaration with the new one f. |
1684 * Return !=0 if successful; i.e. no conflict. | 1718 * Return !=0 if successful; i.e. no conflict. |
2552 id = "__foreachbody"; | 2586 id = "__foreachbody"; |
2553 else if (tok == TOKdelegate) | 2587 else if (tok == TOKdelegate) |
2554 id = "__dgliteral"; | 2588 id = "__dgliteral"; |
2555 else | 2589 else |
2556 id = "__funcliteral"; | 2590 id = "__funcliteral"; |
2557 this->ident = Identifier::generateId(id); | 2591 this->ident = Lexer::uniqueId(id); |
2558 this->tok = tok; | 2592 this->tok = tok; |
2559 this->fes = fes; | 2593 this->fes = fes; |
2560 //printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars()); | 2594 //printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars()); |
2561 } | 2595 } |
2562 | 2596 |
2566 | 2600 |
2567 //printf("FuncLiteralDeclaration::syntaxCopy('%s')\n", toChars()); | 2601 //printf("FuncLiteralDeclaration::syntaxCopy('%s')\n", toChars()); |
2568 if (s) | 2602 if (s) |
2569 f = (FuncLiteralDeclaration *)s; | 2603 f = (FuncLiteralDeclaration *)s; |
2570 else | 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 FuncDeclaration::syntaxCopy(f); | 2608 FuncDeclaration::syntaxCopy(f); |
2573 return f; | 2609 return f; |
2574 } | 2610 } |
2575 | 2611 |
2576 int FuncLiteralDeclaration::isNested() | 2612 int FuncLiteralDeclaration::isNested() |
2632 } | 2668 } |
2633 | 2669 |
2634 | 2670 |
2635 void CtorDeclaration::semantic(Scope *sc) | 2671 void CtorDeclaration::semantic(Scope *sc) |
2636 { | 2672 { |
2637 ClassDeclaration *cd; | 2673 //printf("CtorDeclaration::semantic() %s\n", toChars()); |
2638 Type *tret; | |
2639 | |
2640 //printf("CtorDeclaration::semantic()\n"); | |
2641 if (type) | |
2642 return; | |
2643 | |
2644 sc = sc->push(); | 2674 sc = sc->push(); |
2645 sc->stc &= ~STCstatic; // not a static constructor | 2675 sc->stc &= ~STCstatic; // not a static constructor |
2646 | 2676 |
2647 parent = sc->parent; | 2677 parent = sc->parent; |
2648 Dsymbol *parent = toParent(); | 2678 Dsymbol *parent = toParent(); |
2649 cd = parent->isClassDeclaration(); | 2679 Type *tret; |
2680 ClassDeclaration *cd = parent->isClassDeclaration(); | |
2650 if (!cd) | 2681 if (!cd) |
2651 { | 2682 { |
2652 error("constructors are only for class definitions"); | 2683 error("constructors are only for class definitions"); |
2653 fatal(); | 2684 fatal(); |
2654 tret = Type::tvoid; | 2685 tret = Type::tvoid; |
2655 } | 2686 } |
2656 else | 2687 else |
2657 tret = cd->type; //->referenceTo(); | 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 #if STRUCTTHISREF | 2691 #if STRUCTTHISREF |
2660 if (ad && ad->isStructDeclaration()) | 2692 if (ad && ad->isStructDeclaration()) |
2661 ((TypeFunction *)type)->isref = 1; | 2693 ((TypeFunction *)type)->isref = 1; |
2662 #endif | 2694 #endif |
2663 if (!originalType) | 2695 if (!originalType) |
2668 sc->flags &= ~SCOPEctor; | 2700 sc->flags &= ~SCOPEctor; |
2669 | 2701 |
2670 // Append: | 2702 // Append: |
2671 // return this; | 2703 // return this; |
2672 // to the function body | 2704 // to the function body |
2673 if (fbody) | 2705 if (fbody && semanticRun < PASSsemantic) |
2674 { | 2706 { |
2675 Expression *e = new ThisExp(loc); | 2707 Expression *e = new ThisExp(loc); |
2676 Statement *s = new ReturnStatement(loc, e); | 2708 Statement *s = new ReturnStatement(loc, e); |
2677 fbody = new CompoundStatement(loc, fbody, s); | 2709 fbody = new CompoundStatement(loc, fbody, s); |
2678 } | 2710 } |
2742 | 2774 |
2743 void PostBlitDeclaration::semantic(Scope *sc) | 2775 void PostBlitDeclaration::semantic(Scope *sc) |
2744 { | 2776 { |
2745 //printf("PostBlitDeclaration::semantic() %s\n", toChars()); | 2777 //printf("PostBlitDeclaration::semantic() %s\n", toChars()); |
2746 //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor); | 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 parent = sc->parent; | 2780 parent = sc->parent; |
2748 Dsymbol *parent = toParent(); | 2781 Dsymbol *parent = toParent(); |
2749 StructDeclaration *ad = parent->isStructDeclaration(); | 2782 StructDeclaration *ad = parent->isStructDeclaration(); |
2750 if (!ad) | 2783 if (!ad) |
2751 { | 2784 { |
2752 error("post blits are only for struct/union definitions, not %s %s", parent->kind(), parent->toChars()); | 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 ad->postblits.push(this); | 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 sc = sc->push(); | 2793 sc = sc->push(); |
2759 sc->stc &= ~STCstatic; // not static | 2794 sc->stc &= ~STCstatic; // not static |
2760 sc->linkage = LINKd; | 2795 sc->linkage = LINKd; |
2761 | 2796 |
2784 return FALSE; | 2819 return FALSE; |
2785 } | 2820 } |
2786 | 2821 |
2787 void PostBlitDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 2822 void PostBlitDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
2788 { | 2823 { |
2789 if (hgs->hdrgen) | 2824 buf->writestring("this(this)"); |
2790 return; | |
2791 buf->writestring("=this()"); | |
2792 bodyToCBuffer(buf, hgs); | 2825 bodyToCBuffer(buf, hgs); |
2793 } | 2826 } |
2794 #endif | 2827 #endif |
2795 | 2828 |
2796 /********************************* DtorDeclaration ****************************/ | 2829 /********************************* DtorDeclaration ****************************/ |
2823 if (!cd) | 2856 if (!cd) |
2824 { | 2857 { |
2825 error("destructors are only for class/struct/union definitions, not %s %s", parent->kind(), parent->toChars()); | 2858 error("destructors are only for class/struct/union definitions, not %s %s", parent->kind(), parent->toChars()); |
2826 fatal(); | 2859 fatal(); |
2827 } | 2860 } |
2828 else | 2861 else if (semanticRun < PASSsemantic) |
2829 cd->dtors.push(this); | 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 sc = sc->push(); | 2867 sc = sc->push(); |
2833 sc->stc &= ~STCstatic; // not a static destructor | 2868 sc->stc &= ~STCstatic; // not a static destructor |
2834 sc->linkage = LINKd; | 2869 sc->linkage = LINKd; |
2835 | 2870 |
2891 { | 2926 { |
2892 } | 2927 } |
2893 | 2928 |
2894 Dsymbol *StaticCtorDeclaration::syntaxCopy(Dsymbol *s) | 2929 Dsymbol *StaticCtorDeclaration::syntaxCopy(Dsymbol *s) |
2895 { | 2930 { |
2896 StaticCtorDeclaration *scd; | |
2897 | |
2898 assert(!s); | 2931 assert(!s); |
2899 scd = new StaticCtorDeclaration(loc, endloc); | 2932 StaticCtorDeclaration *scd = new StaticCtorDeclaration(loc, endloc); |
2900 return FuncDeclaration::syntaxCopy(scd); | 2933 return FuncDeclaration::syntaxCopy(scd); |
2901 } | 2934 } |
2902 | 2935 |
2903 | 2936 |
2904 void StaticCtorDeclaration::semantic(Scope *sc) | 2937 void StaticCtorDeclaration::semantic(Scope *sc) |
2905 { | 2938 { |
2906 //printf("StaticCtorDeclaration::semantic()\n"); | 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 /* If the static ctor appears within a template instantiation, | 2944 /* If the static ctor appears within a template instantiation, |
2911 * it could get called multiple times by the module constructors | 2945 * it could get called multiple times by the module constructors |
2912 * for different modules. Thus, protect it with a gate. | 2946 * for different modules. Thus, protect it with a gate. |
2913 */ | 2947 */ |
2914 if (inTemplateInstance()) | 2948 if (inTemplateInstance() && semanticRun < PASSsemantic) |
2915 { | 2949 { |
2916 /* Add this prefix to the function: | 2950 /* Add this prefix to the function: |
2917 * static int gate; | 2951 * static int gate; |
2918 * if (++gate != 1) return; | 2952 * if (++gate != 1) return; |
2919 * Note that this is not thread safe; should not have threads | 2953 * Note that this is not thread safe; should not have threads |
2941 Module *m = getModule(); | 2975 Module *m = getModule(); |
2942 if (!m) | 2976 if (!m) |
2943 m = sc->module; | 2977 m = sc->module; |
2944 if (m) | 2978 if (m) |
2945 { m->needmoduleinfo = 1; | 2979 { m->needmoduleinfo = 1; |
2980 //printf("module1 %s needs moduleinfo\n", m->toChars()); | |
2946 #ifdef IN_GCC | 2981 #ifdef IN_GCC |
2947 m->strictlyneedmoduleinfo = 1; | 2982 m->strictlyneedmoduleinfo = 1; |
2948 #endif | 2983 #endif |
2949 } | 2984 } |
2950 } | 2985 } |
3003 } | 3038 } |
3004 | 3039 |
3005 | 3040 |
3006 void StaticDtorDeclaration::semantic(Scope *sc) | 3041 void StaticDtorDeclaration::semantic(Scope *sc) |
3007 { | 3042 { |
3008 ClassDeclaration *cd; | 3043 ClassDeclaration *cd = sc->scopesym->isClassDeclaration(); |
3009 Type *tret; | 3044 |
3010 | 3045 if (!type) |
3011 cd = sc->scopesym->isClassDeclaration(); | 3046 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); |
3012 if (!cd) | |
3013 { | |
3014 } | |
3015 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); | |
3016 | 3047 |
3017 /* If the static ctor appears within a template instantiation, | 3048 /* If the static ctor appears within a template instantiation, |
3018 * it could get called multiple times by the module constructors | 3049 * it could get called multiple times by the module constructors |
3019 * for different modules. Thus, protect it with a gate. | 3050 * for different modules. Thus, protect it with a gate. |
3020 */ | 3051 */ |
3021 if (inTemplateInstance()) | 3052 if (inTemplateInstance() && semanticRun < PASSsemantic) |
3022 { | 3053 { |
3023 /* Add this prefix to the function: | 3054 /* Add this prefix to the function: |
3024 * static int gate; | 3055 * static int gate; |
3025 * if (--gate != 0) return; | 3056 * if (--gate != 0) return; |
3026 * Increment gate during constructor execution. | 3057 * Increment gate during constructor execution. |
3110 } | 3141 } |
3111 | 3142 |
3112 | 3143 |
3113 void InvariantDeclaration::semantic(Scope *sc) | 3144 void InvariantDeclaration::semantic(Scope *sc) |
3114 { | 3145 { |
3115 AggregateDeclaration *ad; | |
3116 Type *tret; | |
3117 | |
3118 parent = sc->parent; | 3146 parent = sc->parent; |
3119 Dsymbol *parent = toParent(); | 3147 Dsymbol *parent = toParent(); |
3120 ad = parent->isAggregateDeclaration(); | 3148 AggregateDeclaration *ad = parent->isAggregateDeclaration(); |
3121 if (!ad) | 3149 if (!ad) |
3122 { | 3150 { |
3123 error("invariants are only for struct/union/class definitions"); | 3151 error("invariants are only for struct/union/class definitions"); |
3124 return; | 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 error("more than one invariant for %s", ad->toChars()); | 3156 error("more than one invariant for %s", ad->toChars()); |
3129 } | 3157 } |
3130 ad->inv = this; | 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 sc = sc->push(); | 3162 sc = sc->push(); |
3134 sc->stc &= ~STCstatic; // not a static invariant | 3163 sc->stc &= ~STCstatic; // not a static invariant |
3135 sc->incontract++; | 3164 sc->incontract++; |
3136 sc->linkage = LINKd; | 3165 sc->linkage = LINKd; |
3193 | 3222 |
3194 void UnitTestDeclaration::semantic(Scope *sc) | 3223 void UnitTestDeclaration::semantic(Scope *sc) |
3195 { | 3224 { |
3196 if (global.params.useUnitTests) | 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 Scope *sc2 = sc->push(); | 3229 Scope *sc2 = sc->push(); |
3200 sc2->linkage = LINKd; | 3230 sc2->linkage = LINKd; |
3201 FuncDeclaration::semantic(sc2); | 3231 FuncDeclaration::semantic(sc2); |
3202 sc2->pop(); | 3232 sc2->pop(); |
3203 } | 3233 } |
3269 } | 3299 } |
3270 | 3300 |
3271 | 3301 |
3272 void NewDeclaration::semantic(Scope *sc) | 3302 void NewDeclaration::semantic(Scope *sc) |
3273 { | 3303 { |
3274 ClassDeclaration *cd; | |
3275 Type *tret; | |
3276 | |
3277 //printf("NewDeclaration::semantic()\n"); | 3304 //printf("NewDeclaration::semantic()\n"); |
3278 | 3305 |
3279 parent = sc->parent; | 3306 parent = sc->parent; |
3280 Dsymbol *parent = toParent(); | 3307 Dsymbol *parent = toParent(); |
3281 cd = parent->isClassDeclaration(); | 3308 ClassDeclaration *cd = parent->isClassDeclaration(); |
3282 if (!cd && !parent->isStructDeclaration()) | 3309 if (!cd && !parent->isStructDeclaration()) |
3283 { | 3310 { |
3284 error("new allocators only are for class or struct definitions"); | 3311 error("new allocators only are for class or struct definitions"); |
3285 } | 3312 } |
3286 tret = Type::tvoid->pointerTo(); | 3313 Type *tret = Type::tvoid->pointerTo(); |
3287 type = new TypeFunction(arguments, tret, varargs, LINKd); | 3314 if (!type) |
3315 type = new TypeFunction(arguments, tret, varargs, LINKd); | |
3288 | 3316 |
3289 type = type->semantic(loc, sc); | 3317 type = type->semantic(loc, sc); |
3290 assert(type->ty == Tfunction); | 3318 assert(type->ty == Tfunction); |
3291 | 3319 |
3292 // Check that there is at least one argument of type size_t | 3320 // Check that there is at least one argument of type size_t |
3355 } | 3383 } |
3356 | 3384 |
3357 | 3385 |
3358 void DeleteDeclaration::semantic(Scope *sc) | 3386 void DeleteDeclaration::semantic(Scope *sc) |
3359 { | 3387 { |
3360 ClassDeclaration *cd; | |
3361 | |
3362 //printf("DeleteDeclaration::semantic()\n"); | 3388 //printf("DeleteDeclaration::semantic()\n"); |
3363 | 3389 |
3364 parent = sc->parent; | 3390 parent = sc->parent; |
3365 Dsymbol *parent = toParent(); | 3391 Dsymbol *parent = toParent(); |
3366 cd = parent->isClassDeclaration(); | 3392 ClassDeclaration *cd = parent->isClassDeclaration(); |
3367 if (!cd && !parent->isStructDeclaration()) | 3393 if (!cd && !parent->isStructDeclaration()) |
3368 { | 3394 { |
3369 error("new allocators only are for class or struct definitions"); | 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 type = type->semantic(loc, sc); | 3400 type = type->semantic(loc, sc); |
3374 assert(type->ty == Tfunction); | 3401 assert(type->ty == Tfunction); |
3375 | 3402 |
3376 // Check that there is only one argument of type void* | 3403 // Check that there is only one argument of type void* |