comparison dmd2/func.c @ 1452:638d16625da2

LDC 2 compiles again.
author Robert Clipsham <robert@octarineparrot.com>
date Sat, 30 May 2009 17:23:32 +0100
parents 03d7c4aac654
children 7d1e815b4f76
comparison
equal deleted inserted replaced
1423:42bd767ec5a4 1452:638d16625da2
33 33
34 FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type) 34 FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type)
35 : Declaration(id) 35 : Declaration(id)
36 { 36 {
37 //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type); 37 //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
38 //printf("storage_class = x%x\n", storage_class);
38 this->storage_class = storage_class; 39 this->storage_class = storage_class;
39 this->type = type; 40 this->type = type;
40 this->loc = loc; 41 this->loc = loc;
41 this->endloc = endloc; 42 this->endloc = endloc;
42 fthrows = NULL; 43 fthrows = NULL;
72 inferRetType = (type && type->nextOf() == NULL); 73 inferRetType = (type && type->nextOf() == NULL);
73 scope = NULL; 74 scope = NULL;
74 hasReturnExp = 0; 75 hasReturnExp = 0;
75 nrvo_can = 1; 76 nrvo_can = 1;
76 nrvo_var = NULL; 77 nrvo_var = NULL;
78 #if IN_DMD
77 shidden = NULL; 79 shidden = NULL;
80 #endif
81
78 builtin = BUILTINunknown; 82 builtin = BUILTINunknown;
79 tookAddressOf = 0; 83 tookAddressOf = 0;
80 84
85 #if IN_LLVM
81 // LDC 86 // LDC
82 isArrayOp = false; 87 isArrayOp = false;
83 allowInlining = false; 88 allowInlining = false;
89
90 // function types in ldc don't merge if the context parameter differs
91 // so we actually don't care about the function declaration, but only
92 // what kind of context parameter it has.
93 // however, this constructor is usually called from the parser, which
94 // unfortunately doesn't provide the information needed to get to the
95 // aggregate type. So we have to stick with the FuncDeclaration and
96 // just be sure we don't actually rely on the symbol it points to,
97 // but rather just the type of its context parameter.
98 // this means some function might have a function type pointing to
99 // another function declaration
100
101 if (type)
102 {
103 assert(type->ty == Tfunction && "invalid function type");
104 TypeFunction* tf = (TypeFunction*)type;
105 if (tf->funcdecl == NULL)
106 tf->funcdecl = this;
107 }
108 #endif
84 } 109 }
85 110
86 Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s) 111 Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
87 { 112 {
88 FuncDeclaration *f; 113 FuncDeclaration *f;
116 141
117 #if 0 142 #if 0
118 printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage); 143 printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage);
119 if (isFuncLiteralDeclaration()) 144 if (isFuncLiteralDeclaration())
120 printf("\tFuncLiteralDeclaration()\n"); 145 printf("\tFuncLiteralDeclaration()\n");
121 printf("sc->parent = %s\n", sc->parent->toChars()); 146 printf("sc->parent = %s, parent = %s\n", sc->parent->toChars(), parent ? parent->toChars() : "");
122 printf("type: %p, %s\n", type, type->toChars()); 147 printf("type: %p, %s\n", type, type->toChars());
123 #endif 148 #endif
149
150 if (semanticRun && isFuncLiteralDeclaration())
151 {
152 /* Member functions that have return types that are
153 * forward references can have semantic() run more than
154 * once on them.
155 * See test\interface2.d, test20
156 */
157 return;
158 }
159 assert(semanticRun <= 1);
160 semanticRun = 1;
124 161
125 storage_class |= sc->stc & ~STCref; 162 storage_class |= sc->stc & ~STCref;
126 //printf("function storage_class = x%x\n", storage_class); 163 //printf("function storage_class = x%x\n", storage_class);
127 164
128 if (!originalType) 165 if (!originalType)
129 originalType = type; 166 originalType = type;
130 if (!type->deco && type->nextOf()) 167 if (!type->deco && type->nextOf())
131 { 168 {
132 #if 1
133 /* Apply const and invariant storage class 169 /* Apply const and invariant storage class
134 * to the function type 170 * to the function type
135 */ 171 */
136 type = type->semantic(loc, sc); 172 type = type->semantic(loc, sc);
137 if (storage_class & STCinvariant) 173 unsigned stc = storage_class;
138 { // Don't use toInvariant(), as that will do a merge() 174 if (type->isInvariant())
139 type = type->makeInvariant(); 175 stc |= STCimmutable;
140 type->deco = type->merge()->deco; 176 if (type->isConst())
141 } 177 stc |= STCconst;
142 else if (storage_class & STCconst) 178 if (type->isShared())
143 { 179 stc |= STCshared;
144 if (!type->isInvariant()) 180 switch (stc & STC_TYPECTOR)
145 { // Don't use toConst(), as that will do a merge() 181 {
182 case STCimmutable:
183 case STCimmutable | STCconst:
184 case STCimmutable | STCconst | STCshared:
185 case STCimmutable | STCshared:
186 // Don't use toInvariant(), as that will do a merge()
187 type = type->makeInvariant();
188 type->deco = type->merge()->deco;
189 break;
190
191 case STCconst:
146 type = type->makeConst(); 192 type = type->makeConst();
147 type->deco = type->merge()->deco; 193 type->deco = type->merge()->deco;
148 } 194 break;
149 } 195
150 #else 196 case STCshared | STCconst:
151 if (storage_class & (STCconst | STCinvariant)) 197 type = type->makeSharedConst();
152 { 198 type->deco = type->merge()->deco;
153 /* Apply const and invariant storage class 199 break;
154 * to the function's return type 200
155 */ 201 case STCshared:
156 Type *tn = type->nextOf(); 202 type = type->makeShared();
157 if (storage_class & STCconst) 203 type->deco = type->merge()->deco;
158 tn = tn->makeConst(); 204 break;
159 if (storage_class & STCinvariant) 205
160 tn = tn->makeInvariant(); 206 case 0:
161 ((TypeNext *)type)->next = tn; 207 break;
162 } 208
163 209 default:
164 type = type->semantic(loc, sc); 210 assert(0);
165 #endif 211 }
166 } 212 }
167 //type->print(); 213 //type->print();
168 if (type->ty != Tfunction) 214 if (type->ty != Tfunction)
169 { 215 {
170 error("%s must be a function", toChars()); 216 error("%s must be a function", toChars());
188 234
189 if (isAbstract() && !isVirtual()) 235 if (isAbstract() && !isVirtual())
190 error("non-virtual functions cannot be abstract"); 236 error("non-virtual functions cannot be abstract");
191 237
192 if ((f->isConst() || f->isInvariant()) && !isThis()) 238 if ((f->isConst() || f->isInvariant()) && !isThis())
193 error("without 'this' cannot be const/invariant"); 239 error("without 'this' cannot be const/immutable");
194 240
195 if (isAbstract() && isFinal()) 241 if (isAbstract() && isFinal())
196 error("cannot be both final and abstract"); 242 error("cannot be both final and abstract");
197 #if 0 243 #if 0
198 if (isAbstract() && fbody) 244 if (isAbstract() && fbody)
345 if (cd->baseClass) 391 if (cd->baseClass)
346 { Dsymbol *s = cd->baseClass->search(loc, ident, 0); 392 { Dsymbol *s = cd->baseClass->search(loc, ident, 0);
347 if (s) 393 if (s)
348 { 394 {
349 FuncDeclaration *f = s->isFuncDeclaration(); 395 FuncDeclaration *f = s->isFuncDeclaration();
350 f = f->overloadExactMatch(type); 396 f = f->overloadExactMatch(type, getModule());
351 if (f && f->isFinal() && f->prot() != PROTprivate) 397 if (f && f->isFinal() && f->prot() != PROTprivate)
352 error("cannot override final function %s", f->toPrettyChars()); 398 error("cannot override final function %s", f->toPrettyChars());
353 } 399 }
354 } 400 }
355 401
356 if (isFinal()) 402 if (isFinal())
357 { 403 {
404 if (isOverride())
405 error("does not override any function");
358 cd->vtblFinal.push(this); 406 cd->vtblFinal.push(this);
359 } 407 }
360 else 408 else
361 { 409 {
362 // Append to end of vtbl[] 410 // Append to end of vtbl[]
377 // This function is covariant with fdv 425 // This function is covariant with fdv
378 if (fdv->isFinal()) 426 if (fdv->isFinal())
379 error("cannot override final function %s", fdv->toPrettyChars()); 427 error("cannot override final function %s", fdv->toPrettyChars());
380 428
381 #if DMDV2 429 #if DMDV2
382 if (!isOverride() && global.params.warnings) 430 if (!isOverride())
383 warning("%s: overrides base class function %s, but is not marked with 'override'", locToChars(), fdv->toPrettyChars()); 431 warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars());
384 #endif 432 #endif
385 433
386 if (fdv->toParent() == parent) 434 if (fdv->toParent() == parent)
387 { 435 {
388 // If both are mixins, then error. 436 // If both are mixins, then error.
601 649
602 // Do the semantic analysis on the internals of the function. 650 // Do the semantic analysis on the internals of the function.
603 651
604 void FuncDeclaration::semantic3(Scope *sc) 652 void FuncDeclaration::semantic3(Scope *sc)
605 { TypeFunction *f; 653 { TypeFunction *f;
606 AggregateDeclaration *ad;
607 VarDeclaration *argptr = NULL; 654 VarDeclaration *argptr = NULL;
608 VarDeclaration *_arguments = NULL; 655 VarDeclaration *_arguments = NULL;
609 656
610 if (!parent) 657 if (!parent)
611 { 658 {
614 //printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc); 661 //printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
615 assert(0); 662 assert(0);
616 } 663 }
617 //printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars()); 664 //printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
618 //fflush(stdout); 665 //fflush(stdout);
666 //printf("storage class = x%x %x\n", sc->stc, storage_class);
619 //{ static int x; if (++x == 2) *(char*)0=0; } 667 //{ static int x; if (++x == 2) *(char*)0=0; }
620 //printf("\tlinkage = %d\n", sc->linkage); 668 //printf("\tlinkage = %d\n", sc->linkage);
621 669
622 //printf(" sc->incontract = %d\n", sc->incontract); 670 //printf(" sc->incontract = %d\n", sc->incontract);
623 if (semanticRun) 671 if (semanticRun >= 3)
624 return; 672 return;
625 semanticRun = 1; 673 semanticRun = 3;
626 674
627 if (!type || type->ty != Tfunction) 675 if (!type || type->ty != Tfunction)
628 return; 676 return;
629 f = (TypeFunction *)(type); 677 f = (TypeFunction *)(type);
678 size_t nparams = Argument::dim(f->parameters);
630 679
631 // Check the 'throws' clause 680 // Check the 'throws' clause
632 if (fthrows) 681 if (fthrows)
633 { 682 {
634 for (int i = 0; i < fthrows->dim; i++) 683 for (int i = 0; i < fthrows->dim; i++)
658 sc2->sbreak = NULL; 707 sc2->sbreak = NULL;
659 sc2->scontinue = NULL; 708 sc2->scontinue = NULL;
660 sc2->sw = NULL; 709 sc2->sw = NULL;
661 sc2->fes = fes; 710 sc2->fes = fes;
662 sc2->linkage = LINKd; 711 sc2->linkage = LINKd;
663 sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCconst | STCfinal | STCinvariant | STCtls); 712 sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STC_TYPECTOR | STCfinal | STCtls | STCgshared | STCref);
664 sc2->protection = PROTpublic; 713 sc2->protection = PROTpublic;
665 sc2->explicitProtection = 0; 714 sc2->explicitProtection = 0;
666 sc2->structalign = 8; 715 sc2->structalign = 8;
667 sc2->incontract = 0; 716 sc2->incontract = 0;
717 #if !IN_LLVM
668 sc2->tf = NULL; 718 sc2->tf = NULL;
669 sc2->tfOfTry = NULL; 719 #else
720 sc2->enclosingFinally = NULL;
721 sc2->enclosingScopeExit = NULL;
722 #endif
670 sc2->noctor = 0; 723 sc2->noctor = 0;
671 724
672 // Declare 'this' 725 // Declare 'this'
673 ad = isThis(); 726 AggregateDeclaration *ad = isThis();
674 if (ad) 727 if (ad)
675 { VarDeclaration *v; 728 { VarDeclaration *v;
676 729
677 if (isFuncLiteralDeclaration() && isNested()) 730 if (isFuncLiteralDeclaration() && isNested())
678 { 731 {
682 else 735 else
683 { 736 {
684 assert(!isNested()); // can't be both member and nested 737 assert(!isNested()); // can't be both member and nested
685 assert(ad->handle); 738 assert(ad->handle);
686 Type *thandle = ad->handle; 739 Type *thandle = ad->handle;
740 #if STRUCTTHISREF
741 thandle = thandle->addMod(type->mod);
742 thandle = thandle->addStorageClass(storage_class);
743 if (isPure())
744 thandle = thandle->addMod(MODconst);
745 #else
687 if (storage_class & STCconst || type->isConst()) 746 if (storage_class & STCconst || type->isConst())
688 { 747 {
689 #if STRUCTTHISREF 748 assert(0); // BUG: shared not handled
690 thandle = thandle->constOf();
691 #else
692 if (thandle->ty == Tclass) 749 if (thandle->ty == Tclass)
693 thandle = thandle->constOf(); 750 thandle = thandle->constOf();
694 else 751 else
695 { assert(thandle->ty == Tpointer); 752 { assert(thandle->ty == Tpointer);
696 thandle = thandle->nextOf()->constOf()->pointerTo(); 753 thandle = thandle->nextOf()->constOf()->pointerTo();
697 } 754 }
698 #endif
699 } 755 }
700 else if (storage_class & STCinvariant || type->isInvariant()) 756 else if (storage_class & STCimmutable || type->isInvariant())
701 { 757 {
702 #if STRUCTTHISREF
703 thandle = thandle->invariantOf();
704 #else
705 if (thandle->ty == Tclass) 758 if (thandle->ty == Tclass)
706 thandle = thandle->invariantOf(); 759 thandle = thandle->invariantOf();
707 else 760 else
708 { assert(thandle->ty == Tpointer); 761 { assert(thandle->ty == Tpointer);
709 thandle = thandle->nextOf()->invariantOf()->pointerTo(); 762 thandle = thandle->nextOf()->invariantOf()->pointerTo();
710 } 763 }
711 #endif
712 } 764 }
713 v = new ThisDeclaration(thandle); 765 else if (storage_class & STCshared || type->isShared())
766 {
767 assert(0); // not implemented
768 }
769 #endif
770 v = new ThisDeclaration(loc, thandle);
714 v->storage_class |= STCparameter; 771 v->storage_class |= STCparameter;
715 #if STRUCTTHISREF 772 #if STRUCTTHISREF
716 if (thandle->ty == Tstruct) 773 if (thandle->ty == Tstruct)
717 v->storage_class |= STCref; 774 v->storage_class |= STCref;
718 #endif 775 #endif
727 { 784 {
728 /* The 'this' for a nested function is the link to the 785 /* The 'this' for a nested function is the link to the
729 * enclosing function's stack frame. 786 * enclosing function's stack frame.
730 * Note that nested functions and member functions are disjoint. 787 * Note that nested functions and member functions are disjoint.
731 */ 788 */
732 VarDeclaration *v = new ThisDeclaration(Type::tvoid->pointerTo()); 789 VarDeclaration *v = new ThisDeclaration(loc, Type::tvoid->pointerTo());
733 v->storage_class |= STCparameter; 790 v->storage_class |= STCparameter;
734 v->semantic(sc2); 791 v->semantic(sc2);
735 if (!sc2->insert(v)) 792 if (!sc2->insert(v))
736 assert(0); 793 assert(0);
737 v->parent = this; 794 v->parent = this;
738 vthis = v; 795 vthis = v;
739 } 796 }
740 797
741 // Declare hidden variable _arguments[] and _argptr 798 // Declare hidden variable _arguments[] and _argptr
742 if (f->varargs == 1) 799 if (f->varargs == 1)
743 { Type *t; 800 {
801 #if TARGET_NET
802 varArgs(sc2, f, argptr, _arguments);
803 #else
804 Type *t;
744 805
745 if (f->linkage == LINKd) 806 if (f->linkage == LINKd)
746 { // Declare _arguments[] 807 { // Declare _arguments[]
747 #if BREAKABI 808 #if BREAKABI
748 v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL); 809 v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
776 argptr = new VarDeclaration(0, t, Id::_argptr, NULL); 837 argptr = new VarDeclaration(0, t, Id::_argptr, NULL);
777 argptr->semantic(sc2); 838 argptr->semantic(sc2);
778 sc2->insert(argptr); 839 sc2->insert(argptr);
779 argptr->parent = this; 840 argptr->parent = this;
780 } 841 }
781 } 842 #endif
843 }
844
845 #if IN_LLVM
846 // LDC make sure argument type is semanticed.
847 // Turns TypeTuple!(int, int) into two int parameters, for instance.
848 if (f->parameters)
849 {
850 for (size_t i = 0; i < Argument::dim(f->parameters); i++)
851 { Argument *arg = (Argument *)Argument::getNth(f->parameters, i);
852 Type* nw = arg->type->semantic(0, sc);
853 if (arg->type != nw) {
854 arg->type = nw;
855 // Examine this index again.
856 // This is important if it turned into a tuple.
857 // In particular, the empty tuple should be handled or the
858 // next parameter will be skipped.
859 // FIXME: Maybe we only need to do this for tuples,
860 // and can add tuple.length after decrement?
861 i--;
862 }
863 }
864 // update nparams to include expanded tuples
865 nparams = Argument::dim(f->parameters);
866 }
867 #endif
782 868
783 // Propagate storage class from tuple parameters to their element-parameters. 869 // Propagate storage class from tuple parameters to their element-parameters.
784 if (f->parameters) 870 if (f->parameters)
785 { 871 {
786 for (size_t i = 0; i < f->parameters->dim; i++) 872 for (size_t i = 0; i < f->parameters->dim; i++)
816 /* Generate identifier for un-named parameter, 902 /* Generate identifier for un-named parameter,
817 * because we need it later on. 903 * because we need it later on.
818 */ 904 */
819 arg->ident = id = Identifier::generateId("_param_", i); 905 arg->ident = id = Identifier::generateId("_param_", i);
820 } 906 }
821 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL); 907 Type *vtype = arg->type;
908 if (isPure())
909 vtype = vtype->addMod(MODconst);
910 VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL);
822 //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars()); 911 //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars());
823 v->storage_class |= STCparameter; 912 v->storage_class |= STCparameter;
824 if (f->varargs == 2 && i + 1 == nparams) 913 if (f->varargs == 2 && i + 1 == nparams)
825 v->storage_class |= STCvariadic; 914 v->storage_class |= STCvariadic;
826 v->storage_class |= arg->storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STCconst | STCinvariant | STCnodtor); 915 v->storage_class |= arg->storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
827 v->semantic(sc2); 916 v->semantic(sc2);
828 if (!sc2->insert(v)) 917 if (!sc2->insert(v))
829 error("parameter %s.%s is already defined", toChars(), v->toChars()); 918 error("parameter %s.%s is already defined", toChars(), v->toChars());
830 else 919 else
831 parameters->push(v); 920 parameters->push(v);
1064 1153
1065 // Insert implicit super() at start of fbody 1154 // Insert implicit super() at start of fbody
1066 Expression *e1 = new SuperExp(0); 1155 Expression *e1 = new SuperExp(0);
1067 Expression *e = new CallExp(0, e1); 1156 Expression *e = new CallExp(0, e1);
1068 1157
1069 unsigned errors = global.errors; 1158 e = e->trySemantic(sc2);
1070 global.gag++; 1159 if (!e)
1071 e = e->semantic(sc2);
1072 global.gag--;
1073 if (errors != global.errors)
1074 error("no match for implicit super() call in constructor"); 1160 error("no match for implicit super() call in constructor");
1075 1161 else
1076 Statement *s = new ExpStatement(0, e); 1162 {
1077 fbody = new CompoundStatement(0, s, fbody); 1163 Statement *s = new ExpStatement(0, e);
1164 fbody = new CompoundStatement(0, s, fbody);
1165 }
1078 } 1166 }
1079 } 1167 }
1080 else if (fes) 1168 else if (fes)
1081 { // For foreach(){} body, append a return 0; 1169 { // For foreach(){} body, append a return 0;
1082 Expression *e = new IntegerExp(0); 1170 Expression *e = new IntegerExp(0);
1086 } 1174 }
1087 else if (!hasReturnExp && type->nextOf()->ty != Tvoid) 1175 else if (!hasReturnExp && type->nextOf()->ty != Tvoid)
1088 error("expected to return a value of type %s", type->nextOf()->toChars()); 1176 error("expected to return a value of type %s", type->nextOf()->toChars());
1089 else if (!inlineAsm) 1177 else if (!inlineAsm)
1090 { 1178 {
1091 int offend = fbody ? fbody->blockExit() & BEfallthru : TRUE; 1179 int blockexit = fbody ? fbody->blockExit() : 0;
1092 //int offend = fbody ? fbody->fallOffEnd() : TRUE; 1180 if (f->isnothrow && blockexit & BEthrow)
1181 error("'%s' is nothrow yet may throw", toChars());
1182
1183 int offend = blockexit & BEfallthru;
1093 1184
1094 if (type->nextOf()->ty == Tvoid) 1185 if (type->nextOf()->ty == Tvoid)
1095 { 1186 {
1096 if (offend && isMain()) 1187 if (offend && isMain())
1097 { // Add a return 0; statement 1188 { // Add a return 0; statement
1102 else 1193 else
1103 { 1194 {
1104 if (offend) 1195 if (offend)
1105 { Expression *e; 1196 { Expression *e;
1106 1197
1107 if (global.params.warnings) 1198 warning(loc, "no return at end of function");
1108 { warning("%s: no return at end of function", locToChars());
1109 }
1110 1199
1111 if (global.params.useAssert && 1200 if (global.params.useAssert &&
1112 !global.params.useInline) 1201 !global.params.useInline)
1113 { /* Add an assert(0, msg); where the missing return 1202 { /* Add an assert(0, msg); where the missing return
1114 * should be. 1203 * should be.
1185 Expression *e = new VarExp(0, v_arguments); 1274 Expression *e = new VarExp(0, v_arguments);
1186 e = new DotIdExp(0, e, Id::elements); 1275 e = new DotIdExp(0, e, Id::elements);
1187 Expression *e1 = new VarExp(0, _arguments); 1276 Expression *e1 = new VarExp(0, _arguments);
1188 e = new AssignExp(0, e1, e); 1277 e = new AssignExp(0, e1, e);
1189 e->op = TOKconstruct; 1278 e->op = TOKconstruct;
1190 e = e->semantic(sc); 1279 e = e->semantic(sc2);
1191 a->push(new ExpStatement(0, e)); 1280 a->push(new ExpStatement(0, e));
1192 } 1281 }
1193 1282
1194 #endif // !IN_LLVM 1283 #endif // !IN_LLVM
1195 1284
1207 1296
1208 // Precondition invariant 1297 // Precondition invariant
1209 if (addPreInvariant()) 1298 if (addPreInvariant())
1210 { 1299 {
1211 Expression *e = NULL; 1300 Expression *e = NULL;
1301 Expression *ee = NULL;
1212 if (isDtorDeclaration()) 1302 if (isDtorDeclaration())
1213 { 1303 {
1214 // Call invariant directly only if it exists 1304 // Call invariant directly only if it exists
1215 InvariantDeclaration *inv = ad->inv; 1305 InvariantDeclaration *inv = ad->inv;
1216 ClassDeclaration *cd = ad->isClassDeclaration(); 1306 ClassDeclaration *cd = ad->isClassDeclaration();
1235 v->type = vthis->type; 1325 v->type = vthis->type;
1236 #if STRUCTTHISREF 1326 #if STRUCTTHISREF
1237 if (ad->isStructDeclaration()) 1327 if (ad->isStructDeclaration())
1238 v = v->addressOf(sc); 1328 v = v->addressOf(sc);
1239 #endif 1329 #endif
1330 #if IN_LLVM
1331 //e = new AssertExp(loc, v, NULL);
1332
1333 // LDC: check for null this
1334 //v = new ThisExp(0);
1335 //v->type = vthis->type;
1336 //v->var = vthis; // Error: Expression has no property var... in D1 typeof(v) == ThisExp
1337
1338 //NullExp *nv = new NullExp(0);
1339 //nv->type = v->type;
1340
1341 //IdentityExp *ie = new IdentityExp(TOKnotidentity, 0, v, nv);
1342 //ie->type = Type::tbool;
1343 #endif
1240 Expression *se = new StringExp(0, (char *)"null this"); 1344 Expression *se = new StringExp(0, (char *)"null this");
1241 se = se->semantic(sc); 1345 se = se->semantic(sc);
1242 se->type = Type::tchar->arrayOf(); 1346 se->type = Type::tchar->arrayOf();
1347 //#if IN_LLVM
1348 // ee = new AssertExp(loc, ie, se);
1349 //#else
1243 e = new AssertExp(loc, v, se); 1350 e = new AssertExp(loc, v, se);
1351 //#endif
1244 } 1352 }
1353 if (ee)
1354 {
1355 ExpStatement *s = new ExpStatement(0, ee);
1356 a->push(s);
1357 }
1245 if (e) 1358 if (e)
1246 { 1359 {
1247 ExpStatement *s = new ExpStatement(0, e); 1360 ExpStatement *s = new ExpStatement(0, e);
1248 a->push(s); 1361 a->push(s);
1249 } 1362 }
1270 } 1383 }
1271 } 1384 }
1272 1385
1273 fbody = new CompoundStatement(0, a); 1386 fbody = new CompoundStatement(0, a);
1274 1387
1388 #if IN_LLVM
1389 // wrap body of synchronized functions in a synchronized statement
1390 if (isSynchronized())
1391 {
1392 ClassDeclaration *cd = parent->isClassDeclaration();
1393 if (!cd)
1394 error("synchronized function %s must be a member of a class", toChars());
1395
1396 Expression *sync;
1397 if (isStatic())
1398 {
1399 // static member functions synchronize on classinfo
1400 sync = cd->type->dotExp(sc2, new TypeExp(loc, cd->type), Id::classinfo);
1401 }
1402 else
1403 {
1404 // non-static member functions synchronize on this
1405 sync = new VarExp(loc, vthis);
1406 }
1407
1408 // we do not want to rerun semantics on the whole function, so we
1409 // manually adjust all labels in the function that currently don't
1410 // have an enclosingScopeExit to use the new SynchronizedStatement
1411 SynchronizedStatement* s = new SynchronizedStatement(loc, sync, NULL);
1412 s->semantic(sc2);
1413 s->body = fbody;
1414
1415 // LDC
1416 LabelMap::iterator it, end = labmap.end();
1417 for (it = labmap.begin(); it != end; ++it)
1418 if (it->second->enclosingScopeExit == NULL)
1419 it->second->enclosingScopeExit = s;
1420
1421 a = new Statements;
1422 a->push(s);
1423 fbody = new CompoundStatement(0, a);
1424 }
1425 #endif
1426
1275 /* Append destructor calls for parameters as finally blocks. 1427 /* Append destructor calls for parameters as finally blocks.
1276 */ 1428 */
1277 if (parameters) 1429 if (parameters)
1278 { for (size_t i = 0; i < parameters->dim; i++) 1430 { for (size_t i = 0; i < parameters->dim; i++)
1279 { 1431 {
1303 } 1455 }
1304 1456
1305 sc2->callSuper = 0; 1457 sc2->callSuper = 0;
1306 sc2->pop(); 1458 sc2->pop();
1307 } 1459 }
1308 semanticRun = 2; 1460 semanticRun = 4;
1309 } 1461 }
1310 1462
1311 void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 1463 void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1312 { 1464 {
1313 //printf("FuncDeclaration::toCBuffer() '%s'\n", toChars()); 1465 //printf("FuncDeclaration::toCBuffer() '%s'\n", toChars());
1314 1466
1467 StorageClassDeclaration::stcToCBuffer(buf, storage_class);
1315 type->toCBuffer(buf, ident, hgs); 1468 type->toCBuffer(buf, ident, hgs);
1316 bodyToCBuffer(buf, hgs); 1469 bodyToCBuffer(buf, hgs);
1317 } 1470 }
1318 1471
1319 1472
1493 * Returns: 1646 * Returns:
1494 * 0 continue 1647 * 0 continue
1495 * 1 done 1648 * 1 done
1496 */ 1649 */
1497 1650
1498 int overloadApply(FuncDeclaration *fstart, 1651 int overloadApply(Module* from, FuncDeclaration *fstart,
1499 int (*fp)(void *, FuncDeclaration *), 1652 int (*fp)(void *, FuncDeclaration *),
1500 void *param) 1653 void *param)
1501 { 1654 {
1502 FuncDeclaration *f; 1655 FuncDeclaration *f;
1503 Declaration *d; 1656 Declaration *d;
1506 for (d = fstart; d; d = next) 1659 for (d = fstart; d; d = next)
1507 { FuncAliasDeclaration *fa = d->isFuncAliasDeclaration(); 1660 { FuncAliasDeclaration *fa = d->isFuncAliasDeclaration();
1508 1661
1509 if (fa) 1662 if (fa)
1510 { 1663 {
1511 if (overloadApply(fa->funcalias, fp, param)) 1664 if (fa->getModule() == from || fa->importprot != PROTprivate)
1512 return 1; 1665 if (overloadApply(from, fa->funcalias, fp, param))
1666 return 1;
1513 next = fa->overnext; 1667 next = fa->overnext;
1514 } 1668 }
1515 else 1669 else
1516 { 1670 {
1517 AliasDeclaration *a = d->isAliasDeclaration(); 1671 AliasDeclaration *a = d->isAliasDeclaration();
1522 next = s->isDeclaration(); 1676 next = s->isDeclaration();
1523 if (next == a) 1677 if (next == a)
1524 break; 1678 break;
1525 if (next == fstart) 1679 if (next == fstart)
1526 break; 1680 break;
1681 #if IN_LLVM
1682 if (a->importprot == PROTprivate && a->getModule() != from)
1683 if (FuncDeclaration* fd = next->isFuncDeclaration())
1684 next = fd->overnext;
1685 #endif
1527 } 1686 }
1528 else 1687 else
1529 { 1688 {
1530 f = d->isFuncDeclaration(); 1689 f = d->isFuncDeclaration();
1531 if (!f) 1690 if (!f)
1561 } 1720 }
1562 1721
1563 FuncDeclaration *FuncDeclaration::isUnique() 1722 FuncDeclaration *FuncDeclaration::isUnique()
1564 { FuncDeclaration *result = NULL; 1723 { FuncDeclaration *result = NULL;
1565 1724
1566 overloadApply(this, &fpunique, &result); 1725 overloadApply(getModule(), this, &fpunique, &result);
1567 return result; 1726 return result;
1568 } 1727 }
1569 1728
1570 /******************************************** 1729 /********************************************
1571 * Find function in overload list that exactly matches t. 1730 * Find function in overload list that exactly matches t.
1601 } 1760 }
1602 #endif 1761 #endif
1603 return 0; 1762 return 0;
1604 } 1763 }
1605 1764
1606 FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t) 1765 FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t, Module* from)
1607 { 1766 {
1608 Param1 p; 1767 Param1 p;
1609 p.t = t; 1768 p.t = t;
1610 p.f = NULL; 1769 p.f = NULL;
1611 overloadApply(this, &fp1, &p); 1770 overloadApply(from, this, &fp1, &p);
1612 return p.f; 1771 return p.f;
1613 } 1772 }
1614 1773
1615 1774
1616 /******************************************** 1775 /********************************************
1683 } 1842 }
1684 return 0; 1843 return 0;
1685 } 1844 }
1686 1845
1687 void overloadResolveX(Match *m, FuncDeclaration *fstart, 1846 void overloadResolveX(Match *m, FuncDeclaration *fstart,
1688 Expression *ethis, Expressions *arguments) 1847 Expression *ethis, Expressions *arguments, Module* from)
1689 { 1848 {
1690 Param2 p; 1849 Param2 p;
1691 p.m = m; 1850 p.m = m;
1692 p.ethis = ethis; 1851 p.ethis = ethis;
1693 p.arguments = arguments; 1852 p.arguments = arguments;
1694 overloadApply(fstart, &fp2, &p); 1853 overloadApply(from, fstart, &fp2, &p);
1695 } 1854 }
1696 1855
1697 1856
1698 FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags) 1857 FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags, Module* from)
1699 { 1858 {
1700 TypeFunction *tf; 1859 TypeFunction *tf;
1701 Match m; 1860 Match m;
1702 1861
1703 #if 0 1862 #if 0
1716 } 1875 }
1717 #endif 1876 #endif
1718 1877
1719 memset(&m, 0, sizeof(m)); 1878 memset(&m, 0, sizeof(m));
1720 m.last = MATCHnomatch; 1879 m.last = MATCHnomatch;
1721 overloadResolveX(&m, this, ethis, arguments); 1880 overloadResolveX(&m, this, ethis, arguments, from);
1722 1881
1723 if (m.count == 1) // exactly one match 1882 if (m.count == 1) // exactly one match
1724 { 1883 {
1725 return m.lastf; 1884 return m.lastf;
1726 } 1885 }
1847 printf(" doesn't match, so is not as specialized\n"); 2006 printf(" doesn't match, so is not as specialized\n");
1848 #endif 2007 #endif
1849 return MATCHnomatch; 2008 return MATCHnomatch;
1850 } 2009 }
1851 2010
2011 /*******************************************
2012 * Given a symbol that could be either a FuncDeclaration or
2013 * a function template, resolve it to a function symbol.
2014 * sc instantiation scope
2015 * loc instantiation location
2016 * targsi initial list of template arguments
2017 * ethis if !NULL, the 'this' pointer argument
2018 * fargs arguments to function
2019 * flags 1: do not issue error message on no match, just return NULL
2020 */
2021
2022 FuncDeclaration *resolveFuncCall(Scope *sc, Loc loc, Dsymbol *s,
2023 Objects *tiargs,
2024 Expression *ethis,
2025 Expressions *arguments,
2026 int flags)
2027 {
2028 if (!s)
2029 return NULL; // no match
2030 FuncDeclaration *f = s->isFuncDeclaration();
2031 if (f)
2032 f = f->overloadResolve(loc, ethis, arguments);
2033 else
2034 { TemplateDeclaration *td = s->isTemplateDeclaration();
2035 assert(td);
2036 f = td->deduceFunctionTemplate(sc, loc, tiargs, NULL, arguments, flags);
2037 }
2038 return f;
2039 }
2040
1852 /******************************** 2041 /********************************
1853 * Labels are in a separate scope, one per function. 2042 * Labels are in a separate scope, one per function.
1854 */ 2043 */
1855 2044
1856 LabelDsymbol *FuncDeclaration::searchLabel(Identifier *ident) 2045 LabelDsymbol *FuncDeclaration::searchLabel(Identifier *ident)
1938 { if (!thisfd->isNested() && !thisfd->vthis) 2127 { if (!thisfd->isNested() && !thisfd->vthis)
1939 goto Lerr; 2128 goto Lerr;
1940 } 2129 }
1941 else 2130 else
1942 { 2131 {
1943 ClassDeclaration *thiscd = s->isClassDeclaration(); 2132 AggregateDeclaration *thiscd = s->isAggregateDeclaration();
1944 if (thiscd) 2133 if (thiscd)
1945 { if (!thiscd->isNested()) 2134 { if (!thiscd->isNested())
1946 goto Lerr; 2135 goto Lerr;
1947 } 2136 }
1948 else 2137 else
2066 int FuncDeclaration::isOverloadable() 2255 int FuncDeclaration::isOverloadable()
2067 { 2256 {
2068 return 1; // functions can be overloaded 2257 return 1; // functions can be overloaded
2069 } 2258 }
2070 2259
2260 int FuncDeclaration::isPure()
2261 {
2262 //printf("FuncDeclaration::isPure() '%s'\n", toChars());
2263 assert(type->ty == Tfunction);
2264 return ((TypeFunction *)this->type)->ispure;
2265 }
2266
2071 // Determine if function needs 2267 // Determine if function needs
2072 // a static frame pointer to its lexically enclosing function 2268 // a static frame pointer to its lexically enclosing function
2073 2269
2074 int FuncDeclaration::isNested() 2270 int FuncDeclaration::isNested()
2075 { 2271 {
2076 //if (!toParent()) 2272 //if (!toParent())
2077 //printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent); 2273 //printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent);
2078 //printf("\ttoParent2() = '%s'\n", toParent2()->toChars()); 2274 //printf("\ttoParent2() = '%s'\n", toParent2()->toChars());
2079 return ((storage_class & STCstatic) == 0) && 2275 return ((storage_class & STCstatic) == 0) && toParent2() &&
2080 (toParent2()->isFuncDeclaration() != NULL); 2276 (toParent2()->isFuncDeclaration() != NULL);
2081 } 2277 }
2082 2278
2083 int FuncDeclaration::needThis() 2279 int FuncDeclaration::needThis()
2084 { 2280 {
2194 2390
2195 for (int j = 0; j < v->nestedrefs.dim; j++) 2391 for (int j = 0; j < v->nestedrefs.dim; j++)
2196 { FuncDeclaration *f = (FuncDeclaration *)v->nestedrefs.data[j]; 2392 { FuncDeclaration *f = (FuncDeclaration *)v->nestedrefs.data[j];
2197 assert(f != this); 2393 assert(f != this);
2198 2394
2199 //printf("\t\tf = %s, %d, %d\n", f->toChars(), f->isVirtual(), f->tookAddressOf); 2395 //printf("\t\tf = %s, %d, %p, %d\n", f->toChars(), f->isVirtual(), f->isThis(), f->tookAddressOf);
2200 if (f->isThis() || f->tookAddressOf) 2396 if (f->isThis() || f->tookAddressOf)
2201 goto Lyes; // assume f escapes this function's scope 2397 goto Lyes; // assume f escapes this function's scope
2202 2398
2203 // Look to see if any parents of f that are below this escape 2399 // Look to see if any parents of f that are below this escape
2204 for (Dsymbol *s = f->parent; s && s != this; s = s->parent) 2400 for (Dsymbol *s = f->parent; s && s != this; s = s->parent)
2225 : FuncDeclaration(funcalias->loc, funcalias->endloc, funcalias->ident, 2421 : FuncDeclaration(funcalias->loc, funcalias->endloc, funcalias->ident,
2226 (enum STC)funcalias->storage_class, funcalias->type) 2422 (enum STC)funcalias->storage_class, funcalias->type)
2227 { 2423 {
2228 assert(funcalias != this); 2424 assert(funcalias != this);
2229 this->funcalias = funcalias; 2425 this->funcalias = funcalias;
2426 #if IN_LLVM
2427 importprot = PROTundefined;
2428 #endif
2230 } 2429 }
2231 2430
2232 const char *FuncAliasDeclaration::kind() 2431 const char *FuncAliasDeclaration::kind()
2233 { 2432 {
2234 return "function alias"; 2433 return "function alias";
2247 id = "__foreachbody"; 2446 id = "__foreachbody";
2248 else if (tok == TOKdelegate) 2447 else if (tok == TOKdelegate)
2249 id = "__dgliteral"; 2448 id = "__dgliteral";
2250 else 2449 else
2251 id = "__funcliteral"; 2450 id = "__funcliteral";
2252 this->ident = Identifier::generateId(id); 2451 this->ident = Lexer::uniqueId(id);
2253 this->tok = tok; 2452 this->tok = tok;
2254 this->fes = fes; 2453 this->fes = fes;
2255 //printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars()); 2454 //printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars());
2256 } 2455 }
2257 2456
2261 2460
2262 //printf("FuncLiteralDeclaration::syntaxCopy('%s')\n", toChars()); 2461 //printf("FuncLiteralDeclaration::syntaxCopy('%s')\n", toChars());
2263 if (s) 2462 if (s)
2264 f = (FuncLiteralDeclaration *)s; 2463 f = (FuncLiteralDeclaration *)s;
2265 else 2464 else
2266 f = new FuncLiteralDeclaration(loc, endloc, type->syntaxCopy(), tok, fes); 2465 { f = new FuncLiteralDeclaration(loc, endloc, type->syntaxCopy(), tok, fes);
2466 f->ident = ident; // keep old identifier
2467 }
2267 FuncDeclaration::syntaxCopy(f); 2468 FuncDeclaration::syntaxCopy(f);
2268 return f; 2469 return f;
2269 } 2470 }
2270 2471
2271 int FuncLiteralDeclaration::isNested() 2472 int FuncLiteralDeclaration::isNested()
2330 void CtorDeclaration::semantic(Scope *sc) 2531 void CtorDeclaration::semantic(Scope *sc)
2331 { 2532 {
2332 AggregateDeclaration *ad; 2533 AggregateDeclaration *ad;
2333 Type *tret; 2534 Type *tret;
2334 2535
2335 //printf("CtorDeclaration::semantic()\n"); 2536 //printf("CtorDeclaration::semantic() %s\n", toChars());
2336 if (type) 2537 if (type)
2337 return; 2538 return;
2338 2539
2339 sc = sc->push(); 2540 sc = sc->push();
2340 sc->stc &= ~STCstatic; // not a static constructor 2541 sc->stc &= ~STCstatic; // not a static constructor
2341 2542
2342 parent = sc->parent; 2543 parent = sc->parent;
2343 Dsymbol *parent = toParent(); 2544 Dsymbol *parent = toParent2();
2344 ad = parent->isAggregateDeclaration(); 2545 ad = parent->isAggregateDeclaration();
2345 if (!ad || parent->isUnionDeclaration()) 2546 if (!ad || parent->isUnionDeclaration())
2346 { 2547 {
2347 error("constructors are only for class or struct definitions"); 2548 error("constructors are only for class or struct definitions");
2348 fatal(); 2549 fatal();
2349 tret = Type::tvoid; 2550 tret = Type::tvoid;
2350 } 2551 }
2351 else 2552 else
2352 { tret = ad->handle; 2553 { tret = ad->handle;
2353 assert(tret); 2554 assert(tret);
2367 // Append: 2568 // Append:
2368 // return this; 2569 // return this;
2369 // to the function body 2570 // to the function body
2370 if (fbody) 2571 if (fbody)
2371 { 2572 {
2372 Expression *e = new ThisExp(0); 2573 Expression *e = new ThisExp(loc);
2373 Statement *s = new ReturnStatement(0, e); 2574 Statement *s = new ReturnStatement(loc, e);
2374 fbody = new CompoundStatement(0, fbody, s); 2575 fbody = new CompoundStatement(loc, fbody, s);
2375 } 2576 }
2376 2577
2377 FuncDeclaration::semantic(sc); 2578 FuncDeclaration::semantic(sc);
2378 2579
2379 sc->pop(); 2580 sc->pop();
2407 return FALSE; 2608 return FALSE;
2408 } 2609 }
2409 2610
2410 int CtorDeclaration::addPostInvariant() 2611 int CtorDeclaration::addPostInvariant()
2411 { 2612 {
2412 return (vthis && global.params.useInvariants); 2613 return (isThis() && vthis && global.params.useInvariants);
2413 } 2614 }
2414 2615
2415 2616
2416 void CtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2617 void CtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2417 { 2618 {
2474 return FALSE; 2675 return FALSE;
2475 } 2676 }
2476 2677
2477 int PostBlitDeclaration::addPostInvariant() 2678 int PostBlitDeclaration::addPostInvariant()
2478 { 2679 {
2479 return (vthis && global.params.useInvariants); 2680 return (isThis() && vthis && global.params.useInvariants);
2480 } 2681 }
2481 2682
2482 int PostBlitDeclaration::isVirtual() 2683 int PostBlitDeclaration::isVirtual()
2483 { 2684 {
2484 return FALSE; 2685 return FALSE;
2520 Dsymbol *parent = toParent(); 2721 Dsymbol *parent = toParent();
2521 AggregateDeclaration *ad = parent->isAggregateDeclaration(); 2722 AggregateDeclaration *ad = parent->isAggregateDeclaration();
2522 if (!ad) 2723 if (!ad)
2523 { 2724 {
2524 error("destructors are only for class/struct/union definitions, not %s %s", parent->kind(), parent->toChars()); 2725 error("destructors are only for class/struct/union definitions, not %s %s", parent->kind(), parent->toChars());
2525 fatal(); 2726 fatal();
2526 } 2727 }
2527 else if (ident == Id::dtor) 2728 else if (ident == Id::dtor)
2528 ad->dtors.push(this); 2729 ad->dtors.push(this);
2529 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2730 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
2530 2731
2542 return FALSE; // cannot overload destructors 2743 return FALSE; // cannot overload destructors
2543 } 2744 }
2544 2745
2545 int DtorDeclaration::addPreInvariant() 2746 int DtorDeclaration::addPreInvariant()
2546 { 2747 {
2547 return (vthis && global.params.useInvariants); 2748 return (isThis() && vthis && global.params.useInvariants);
2548 } 2749 }
2549 2750
2550 int DtorDeclaration::addPostInvariant() 2751 int DtorDeclaration::addPostInvariant()
2551 { 2752 {
2552 return FALSE; 2753 return FALSE;
2754 }
2755
2756 const char *DtorDeclaration::kind()
2757 {
2758 return "destructor";
2759 }
2760
2761 char *DtorDeclaration::toChars()
2762 {
2763 return (char *)"~this";
2553 } 2764 }
2554 2765
2555 int DtorDeclaration::isVirtual() 2766 int DtorDeclaration::isVirtual()
2556 { 2767 {
2557 /* This should be FALSE so that dtor's don't get put into the vtbl[], 2768 /* This should be FALSE so that dtor's don't get put into the vtbl[],
2806 parent = sc->parent; 3017 parent = sc->parent;
2807 Dsymbol *parent = toParent(); 3018 Dsymbol *parent = toParent();
2808 ad = parent->isAggregateDeclaration(); 3019 ad = parent->isAggregateDeclaration();
2809 if (!ad) 3020 if (!ad)
2810 { 3021 {
2811 error("invariants only are for struct/union/class definitions"); 3022 error("invariants are only for struct/union/class definitions");
2812 return; 3023 return;
2813 } 3024 }
2814 else if (ad->inv && ad->inv != this) 3025 else if (ad->inv && ad->inv != this)
2815 { 3026 {
2816 error("more than one invariant for %s", ad->toChars()); 3027 error("more than one invariant for %s", ad->toChars());
2969 type = new TypeFunction(arguments, tret, varargs, LINKd); 3180 type = new TypeFunction(arguments, tret, varargs, LINKd);
2970 3181
2971 type = type->semantic(loc, sc); 3182 type = type->semantic(loc, sc);
2972 assert(type->ty == Tfunction); 3183 assert(type->ty == Tfunction);
2973 3184
2974 // Check that there is at least one argument of type uint 3185 // Check that there is at least one argument of type size_t
2975 TypeFunction *tf = (TypeFunction *)type; 3186 TypeFunction *tf = (TypeFunction *)type;
2976 if (Argument::dim(tf->parameters) < 1) 3187 if (Argument::dim(tf->parameters) < 1)
2977 { 3188 {
2978 error("at least one argument of type size_t expected"); 3189 error("at least one argument of type size_t expected");
2979 } 3190 }