comparison dmd/func.c @ 1587:def7a1d494fd

Merge DMD 1.051
author Christian Kamm <kamm incasoftware de>
date Fri, 06 Nov 2009 23:58:01 +0100
parents 05c235309d6f
children a413ae7329bf
comparison
equal deleted inserted replaced
1586:7f728c52e63c 1587:def7a1d494fd
1 // Compiler implementation of the D programming language 1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2008 by Digital Mars 2 // Copyright (c) 1999-2009 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.
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;
43 frequire = NULL; 44 frequire = NULL;
45 fdrequire = NULL;
46 fdensure = NULL;
44 outId = NULL; 47 outId = NULL;
45 vresult = NULL; 48 vresult = NULL;
46 returnLabel = NULL; 49 returnLabel = NULL;
47 fensure = NULL; 50 fensure = NULL;
48 fbody = NULL; 51 fbody = NULL;
61 inlineStatus = ILSuninitialized; 64 inlineStatus = ILSuninitialized;
62 inlineNest = 0; 65 inlineNest = 0;
63 inlineAsm = 0; 66 inlineAsm = 0;
64 cantInterpret = 0; 67 cantInterpret = 0;
65 semanticRun = 0; 68 semanticRun = 0;
69 #if DMDV1
66 nestedFrameRef = 0; 70 nestedFrameRef = 0;
71 #endif
67 fes = NULL; 72 fes = NULL;
68 introducing = 0; 73 introducing = 0;
69 tintro = NULL; 74 tintro = NULL;
70 /* The type given for "infer the return type" is a TypeFunction with 75 /* The type given for "infer the return type" is a TypeFunction with
71 * NULL for the return type. 76 * NULL for the return type.
72 */ 77 */
73 inferRetType = (type && type->nextOf() == NULL); 78 inferRetType = (type && type->nextOf() == NULL);
74 scope = NULL;
75 hasReturnExp = 0; 79 hasReturnExp = 0;
76 nrvo_can = 1; 80 nrvo_can = 1;
77 nrvo_var = NULL; 81 nrvo_var = NULL;
78 #if IN_DMD 82 #if IN_DMD
79 shidden = NULL; 83 shidden = NULL;
84 #endif
85
86 #if DMDV2
87 builtin = BUILTINunknown;
88 tookAddressOf = 0;
80 #endif 89 #endif
81 90
82 #if IN_LLVM 91 #if IN_LLVM
83 // LDC 92 // LDC
84 isArrayOp = false; 93 isArrayOp = false;
140 149
141 #if 0 150 #if 0
142 printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage); 151 printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage);
143 if (isFuncLiteralDeclaration()) 152 if (isFuncLiteralDeclaration())
144 printf("\tFuncLiteralDeclaration()\n"); 153 printf("\tFuncLiteralDeclaration()\n");
145 printf("sc->parent = %s\n", sc->parent->toChars()); 154 printf("sc->parent = %s, parent = %s\n", sc->parent->toChars(), parent ? parent->toChars() : "");
146 printf("type: %p, %s\n", type, type->toChars()); 155 printf("type: %p, %s\n", type, type->toChars());
147 #endif 156 #endif
148 157
149 if (semanticRun && isFuncLiteralDeclaration()) 158 if (semanticRun && isFuncLiteralDeclaration())
150 { 159 {
156 return; 165 return;
157 } 166 }
158 assert(semanticRun <= 1); 167 assert(semanticRun <= 1);
159 semanticRun = 1; 168 semanticRun = 1;
160 169
161 if (type->nextOf()) 170 if (!type->deco)
171 {
162 type = type->semantic(loc, sc); 172 type = type->semantic(loc, sc);
173 }
163 //type->print(); 174 //type->print();
164 if (type->ty != Tfunction) 175 if (type->ty != Tfunction)
165 { 176 {
166 error("%s must be a function", toChars()); 177 error("%s must be a function", toChars());
167 return; 178 return;
247 if (id) 258 if (id)
248 { 259 {
249 storage_class |= STCabstract; 260 storage_class |= STCabstract;
250 261
251 if (isCtorDeclaration() || 262 if (isCtorDeclaration() ||
263 #if DMDV2
264 isPostBlitDeclaration() ||
265 #endif
252 isDtorDeclaration() || 266 isDtorDeclaration() ||
253 isInvariantDeclaration() || 267 isInvariantDeclaration() ||
254 isUnitTestDeclaration() || isNewDeclaration() || isDelete()) 268 isUnitTestDeclaration() || isNewDeclaration() || isDelete())
255 error("special function not allowed in interface %s", id->toChars()); 269 error("special function not allowed in interface %s", id->toChars());
256 if (fbody) 270 if (fbody)
395 error("multiple overrides of same function"); 409 error("multiple overrides of same function");
396 } 410 }
397 cd->vtbl.data[vi] = (void *)this; 411 cd->vtbl.data[vi] = (void *)this;
398 vtblIndex = vi; 412 vtblIndex = vi;
399 413
414 /* Remember which functions this overrides
415 */
416 foverrides.push(fdv);
417
400 /* This works by whenever this function is called, 418 /* This works by whenever this function is called,
401 * it actually returns tintro, which gets dynamically 419 * it actually returns tintro, which gets dynamically
402 * cast to type. But we know that tintro is a base 420 * cast to type. But we know that tintro is a base
403 * of type, so we could optimize it by not doing a 421 * of type, so we could optimize it by not doing a
404 * dynamic cast, but just subtracting the isBaseOf() 422 * dynamic cast, but just subtracting the isBaseOf()
441 return; 459 return;
442 460
443 default: 461 default:
444 { FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi]; 462 { FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi];
445 Type *ti = NULL; 463 Type *ti = NULL;
464
465 /* Remember which functions this overrides
466 */
467 foverrides.push(fdv);
446 468
447 if (fdv->tintro) 469 if (fdv->tintro)
448 ti = fdv->tintro; 470 ti = fdv->tintro;
449 else if (!type->equals(fdv->type)) 471 else if (!type->equals(fdv->type))
450 { 472 {
598 620
599 default: 621 default:
600 goto Lmainerr; 622 goto Lmainerr;
601 } 623 }
602 624
603 if (f->nextOf()->ty != Tint32 && f->nextOf()->ty != Tvoid) 625 if (!f->nextOf())
626 error("must return int or void");
627 else if (f->nextOf()->ty != Tint32 && f->nextOf()->ty != Tvoid)
604 error("must return int or void, not %s", f->nextOf()->toChars()); 628 error("must return int or void, not %s", f->nextOf()->toChars());
605 if (f->varargs) 629 if (f->varargs)
606 { 630 {
607 Lmainerr: 631 Lmainerr:
608 error("parameters must be main() or main(char[][] args)"); 632 error("parameters must be main() or main(char[][] args)");
633 goto Lassignerr; 657 goto Lassignerr;
634 } 658 }
635 } 659 }
636 } 660 }
637 661
662 if (isVirtual())
663 {
664 /* Rewrite contracts as nested functions, then call them.
665 * Doing it as nested functions means that overriding functions
666 * can call them.
667 */
668 if (frequire)
669 { /* in { ... }
670 * becomes:
671 * void __require() { ... }
672 * __require();
673 */
674 Loc loc = frequire->loc;
675 TypeFunction *tf = new TypeFunction(NULL, Type::tvoid, 0, LINKd);
676 FuncDeclaration *fd = new FuncDeclaration(loc, loc,
677 Id::require, STCundefined, tf);
678 fd->fbody = frequire;
679 Statement *s1 = new DeclarationStatement(loc, fd);
680 Expression *e = new CallExp(loc, new VarExp(loc, fd), (Expressions *)NULL);
681 Statement *s2 = new ExpStatement(loc, e);
682 frequire = new CompoundStatement(loc, s1, s2);
683 fdrequire = fd;
684 }
685
686 if (fensure)
687 { /* out (result) { ... }
688 * becomes:
689 * tret __ensure(ref tret result) { ... }
690 * __ensure(result);
691 */
692 if (!outId && f->nextOf()->toBasetype()->ty != Tvoid)
693 outId = Id::result; // provide a default
694
695 Loc loc = fensure->loc;
696 Arguments *arguments = new Arguments();
697 Argument *a = NULL;
698 if (outId)
699 { a = new Argument(STCref, f->nextOf(), outId, NULL);
700 arguments->push(a);
701 }
702 TypeFunction *tf = new TypeFunction(arguments, Type::tvoid, 0, LINKd);
703 FuncDeclaration *fd = new FuncDeclaration(loc, loc,
704 Id::ensure, STCundefined, tf);
705 fd->fbody = fensure;
706 Statement *s1 = new DeclarationStatement(loc, fd);
707 Expression *eresult = NULL;
708 if (outId)
709 eresult = new IdentifierExp(loc, outId);
710 Expression *e = new CallExp(loc, new VarExp(loc, fd), eresult);
711 Statement *s2 = new ExpStatement(loc, e);
712 fensure = new CompoundStatement(loc, s1, s2);
713 fdensure = fd;
714 }
715 }
716
638 Ldone: 717 Ldone:
639 /* Save scope for possible later use (if we need the 718 /* Save scope for possible later use (if we need the
640 * function internals) 719 * function internals)
641 */ 720 */
642 scope = new Scope(*sc); 721 scope = new Scope(*sc);
653 732
654 // Do the semantic analysis on the internals of the function. 733 // Do the semantic analysis on the internals of the function.
655 734
656 void FuncDeclaration::semantic3(Scope *sc) 735 void FuncDeclaration::semantic3(Scope *sc)
657 { TypeFunction *f; 736 { TypeFunction *f;
658 AggregateDeclaration *ad;
659 VarDeclaration *argptr = NULL; 737 VarDeclaration *argptr = NULL;
660 VarDeclaration *_arguments = NULL; 738 VarDeclaration *_arguments = NULL;
661 739
662 if (!parent) 740 if (!parent)
663 { 741 {
666 //printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc); 744 //printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
667 assert(0); 745 assert(0);
668 } 746 }
669 //printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars()); 747 //printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
670 //fflush(stdout); 748 //fflush(stdout);
749 //printf("storage class = x%x %x\n", sc->stc, storage_class);
671 //{ static int x; if (++x == 2) *(char*)0=0; } 750 //{ static int x; if (++x == 2) *(char*)0=0; }
672 //printf("\tlinkage = %d\n", sc->linkage); 751 //printf("\tlinkage = %d\n", sc->linkage);
673 752
674 //printf(" sc->incontract = %d\n", sc->incontract); 753 //printf(" sc->incontract = %d\n", sc->incontract);
675 if (semanticRun >= 3) 754 if (semanticRun >= 3)
681 availableExternally = false; 760 availableExternally = false;
682 761
683 if (!type || type->ty != Tfunction) 762 if (!type || type->ty != Tfunction)
684 return; 763 return;
685 f = (TypeFunction *)(type); 764 f = (TypeFunction *)(type);
686 size_t nparams = Argument::dim(f->parameters);
687 765
688 // Check the 'throws' clause 766 // Check the 'throws' clause
689 if (fthrows) 767 if (fthrows)
690 { 768 {
691 for (int i = 0; i < fthrows->dim; i++) 769 for (int i = 0; i < fthrows->dim; i++)
695 t = t->semantic(loc, sc); 773 t = t->semantic(loc, sc);
696 if (!t->isClassHandle()) 774 if (!t->isClassHandle())
697 error("can only throw classes, not %s", t->toChars()); 775 error("can only throw classes, not %s", t->toChars());
698 } 776 }
699 } 777 }
778
779 frequire = mergeFrequire(frequire);
780 fensure = mergeFensure(fensure);
700 781
701 if (fbody || frequire) 782 if (fbody || frequire)
702 { 783 {
703 /* Symbol table into which we place parameters and nested functions, 784 /* Symbol table into which we place parameters and nested functions,
704 * solely to diagnose name collisions. 785 * solely to diagnose name collisions.
725 sc2->enclosingFinally = NULL; 806 sc2->enclosingFinally = NULL;
726 sc2->enclosingScopeExit = NULL; 807 sc2->enclosingScopeExit = NULL;
727 sc2->noctor = 0; 808 sc2->noctor = 0;
728 809
729 // Declare 'this' 810 // Declare 'this'
730 ad = isThis(); 811 AggregateDeclaration *ad = isThis();
731 if (ad) 812 if (ad)
732 { VarDeclaration *v; 813 { VarDeclaration *v;
733 814
734 if (isFuncLiteralDeclaration() && isNested()) 815 if (isFuncLiteralDeclaration() && isNested())
735 { 816 {
764 vthis = v; 845 vthis = v;
765 } 846 }
766 847
767 // Declare hidden variable _arguments[] and _argptr 848 // Declare hidden variable _arguments[] and _argptr
768 if (f->varargs == 1) 849 if (f->varargs == 1)
769 { Type *t; 850 {
851 #if TARGET_NET
852 varArgs(sc2, f, argptr, _arguments);
853 #else
854 Type *t;
770 855
771 if (f->linkage == LINKd) 856 if (f->linkage == LINKd)
772 { // Declare _arguments[] 857 { // Declare _arguments[]
773 #if BREAKABI 858 #if BREAKABI
774 v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL); 859 v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
801 argptr = new VarDeclaration(0, t, Id::_argptr, NULL); 886 argptr = new VarDeclaration(0, t, Id::_argptr, NULL);
802 argptr->semantic(sc2); 887 argptr->semantic(sc2);
803 sc2->insert(argptr); 888 sc2->insert(argptr);
804 argptr->parent = this; 889 argptr->parent = this;
805 } 890 }
891 #endif
806 } 892 }
807 893
808 #if IN_LLVM 894 #if IN_LLVM
809 // LDC make sure argument type is semanticed. 895 // LDC make sure argument type is semanticed.
810 // Turns TypeTuple!(int, int) into two int parameters, for instance. 896 // Turns TypeTuple!(int, int) into two int parameters, for instance.
822 // FIXME: Maybe we only need to do this for tuples, 908 // FIXME: Maybe we only need to do this for tuples,
823 // and can add tuple.length after decrement? 909 // and can add tuple.length after decrement?
824 i--; 910 i--;
825 } 911 }
826 } 912 }
827 // update nparams to include expanded tuples
828 nparams = Argument::dim(f->parameters);
829 } 913 }
830 #endif 914 #endif
831 915
832 // Propagate storage class from tuple parameters to their element-parameters. 916 // Propagate storage class from tuple parameters to their element-parameters.
833 if (f->parameters) 917 if (f->parameters)
834 { 918 {
835 for (size_t i = 0; i < f->parameters->dim; i++) 919 for (size_t i = 0; i < f->parameters->dim; i++)
836 { Argument *arg = (Argument *)f->parameters->data[i]; 920 { Argument *arg = (Argument *)f->parameters->data[i];
837 921
922 //printf("[%d] arg->type->ty = %d %s\n", i, arg->type->ty, arg->type->toChars());
838 if (arg->type->ty == Ttuple) 923 if (arg->type->ty == Ttuple)
839 { TypeTuple *t = (TypeTuple *)arg->type; 924 { TypeTuple *t = (TypeTuple *)arg->type;
840 size_t dim = Argument::dim(t->arguments); 925 size_t dim = Argument::dim(t->arguments);
841 for (size_t j = 0; j < dim; j++) 926 for (size_t j = 0; j < dim; j++)
842 { Argument *narg = Argument::getNth(t->arguments, j); 927 { Argument *narg = Argument::getNth(t->arguments, j);
844 } 929 }
845 } 930 }
846 } 931 }
847 } 932 }
848 933
849 // Declare all the function parameters as variables 934 /* Declare all the function parameters as variables
935 * and install them in parameters[]
936 */
937 size_t nparams = Argument::dim(f->parameters);
850 if (nparams) 938 if (nparams)
851 { /* parameters[] has all the tuples removed, as the back end 939 { /* parameters[] has all the tuples removed, as the back end
852 * doesn't know about tuples 940 * doesn't know about tuples
853 */ 941 */
854 parameters = new Dsymbols(); 942 parameters = new Dsymbols();
862 /* Generate identifier for un-named parameter, 950 /* Generate identifier for un-named parameter,
863 * because we need it later on. 951 * because we need it later on.
864 */ 952 */
865 arg->ident = id = Identifier::generateId("_param_", i); 953 arg->ident = id = Identifier::generateId("_param_", i);
866 } 954 }
867 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL); 955 Type *vtype = arg->type;
956 VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL);
868 //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars()); 957 //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars());
869 v->storage_class |= STCparameter; 958 v->storage_class |= STCparameter;
870 if (f->varargs == 2 && i + 1 == nparams) 959 if (f->varargs == 2 && i + 1 == nparams)
871 v->storage_class |= STCvariadic; 960 v->storage_class |= STCvariadic;
872 v->storage_class |= arg->storageClass & (STCin | STCout | STCref | STClazy); 961 v->storage_class |= arg->storageClass & (STCin | STCout | STCref | STClazy);
933 } 1022 }
934 1023
935 if (fensure || addPostInvariant()) 1024 if (fensure || addPostInvariant())
936 { /* fensure is composed of the [out] contracts 1025 { /* fensure is composed of the [out] contracts
937 */ 1026 */
1027 if (!type->nextOf())
1028 { // Have to do semantic() on fbody first
1029 error("post conditions are not supported if the return type is inferred");
1030 return;
1031 }
1032
938 ScopeDsymbol *sym = new ScopeDsymbol(); 1033 ScopeDsymbol *sym = new ScopeDsymbol();
939 sym->parent = sc2->scopesym; 1034 sym->parent = sc2->scopesym;
940 sc2 = sc2->push(sym); 1035 sc2 = sc2->push(sym);
941 1036
942 assert(type->nextOf()); 1037 assert(type->nextOf());
959 if (fensure) 1054 if (fensure)
960 loc = fensure->loc; 1055 loc = fensure->loc;
961 1056
962 v = new VarDeclaration(loc, type->nextOf(), outId, NULL); 1057 v = new VarDeclaration(loc, type->nextOf(), outId, NULL);
963 v->noscope = 1; 1058 v->noscope = 1;
1059 #if DMDV2
1060 if (f->isref)
1061 {
1062 v->storage_class |= STCref | STCforeach;
1063 }
1064 #endif
964 sc2->incontract--; 1065 sc2->incontract--;
965 v->semantic(sc2); 1066 v->semantic(sc2);
966 sc2->incontract++; 1067 sc2->incontract++;
967 if (!sc2->insert(v)) 1068 if (!sc2->insert(v))
968 error("out result %s is already defined", v->toChars()); 1069 error("out result %s is already defined", v->toChars());
1009 e = e->semantic(sc2); 1110 e = e->semantic(sc2);
1010 } 1111 }
1011 } 1112 }
1012 else 1113 else
1013 { // Call invariant virtually 1114 { // Call invariant virtually
1014 ThisExp *v = new ThisExp(0); 1115 Expression *v = new ThisExp(0);
1015 v->type = vthis->type; 1116 v->type = vthis->type;
1117 #if STRUCTTHISREF
1118 if (ad->isStructDeclaration())
1119 v = v->addressOf(sc);
1120 #endif
1016 e = new AssertExp(0, v); 1121 e = new AssertExp(0, v);
1017 } 1122 }
1018 if (e) 1123 if (e)
1019 { 1124 {
1020 ExpStatement *s = new ExpStatement(0, e); 1125 ExpStatement *s = new ExpStatement(0, e);
1132 } 1237 }
1133 else if (!hasReturnExp && type->nextOf()->ty != Tvoid) 1238 else if (!hasReturnExp && type->nextOf()->ty != Tvoid)
1134 error("expected to return a value of type %s", type->nextOf()->toChars()); 1239 error("expected to return a value of type %s", type->nextOf()->toChars());
1135 else if (!inlineAsm) 1240 else if (!inlineAsm)
1136 { 1241 {
1242 #if DMDV2
1243 int blockexit = fbody ? fbody->blockExit() : BEfallthru;
1244 if (f->isnothrow && blockexit & BEthrow)
1245 error("'%s' is nothrow yet may throw", toChars());
1246
1247 int offend = blockexit & BEfallthru;
1248 #endif
1137 if (type->nextOf()->ty == Tvoid) 1249 if (type->nextOf()->ty == Tvoid)
1138 { 1250 {
1139 if (offend && isMain()) 1251 if (offend && isMain())
1140 { // Add a return 0; statement 1252 { // Add a return 0; statement
1141 Statement *s = new ReturnStatement(0, new IntegerExp(0)); 1253 Statement *s = new ReturnStatement(0, new IntegerExp(0));
1144 } 1256 }
1145 else 1257 else
1146 { 1258 {
1147 if (offend) 1259 if (offend)
1148 { Expression *e; 1260 { Expression *e;
1149 1261 #if DMDV1
1150 warning(loc, "no return at end of function"); 1262 warning(loc, "no return exp; or assert(0); at end of function");
1151 1263 #else
1264 error("no return exp; or assert(0); at end of function");
1265 #endif
1152 if (global.params.useAssert && 1266 if (global.params.useAssert &&
1153 !global.params.useInline) 1267 !global.params.useInline)
1154 { /* Add an assert(0, msg); where the missing return 1268 { /* Add an assert(0, msg); where the missing return
1155 * should be. 1269 * should be.
1156 */ 1270 */
1207 e1 = new VarExp(0, argptr); 1321 e1 = new VarExp(0, argptr);
1208 if (parameters && parameters->dim) 1322 if (parameters && parameters->dim)
1209 p = (VarDeclaration *)parameters->data[parameters->dim - 1]; 1323 p = (VarDeclaration *)parameters->data[parameters->dim - 1];
1210 else 1324 else
1211 p = v_arguments; // last parameter is _arguments[] 1325 p = v_arguments; // last parameter is _arguments[]
1212 offset = p->type->size(); 1326 if (p->storage_class & STClazy)
1327 // If the last parameter is lazy, it's the size of a delegate
1328 offset = PTRSIZE * 2;
1329 else
1330 offset = p->type->size();
1213 offset = (offset + 3) & ~3; // assume stack aligns on 4 1331 offset = (offset + 3) & ~3; // assume stack aligns on 4
1214 e = new SymOffExp(0, p, offset); 1332 e = new SymOffExp(0, p, offset);
1215 e = new AssignExp(0, e1, e); 1333 e = new AssignExp(0, e1, e);
1216 e->type = t; 1334 e->type = t;
1217 a->push(new ExpStatement(0, e)); 1335 a->push(new ExpStatement(0, e));
1225 */ 1343 */
1226 Expression *e = new VarExp(0, v_arguments); 1344 Expression *e = new VarExp(0, v_arguments);
1227 e = new DotIdExp(0, e, Id::elements); 1345 e = new DotIdExp(0, e, Id::elements);
1228 Expression *e1 = new VarExp(0, _arguments); 1346 Expression *e1 = new VarExp(0, _arguments);
1229 e = new AssignExp(0, e1, e); 1347 e = new AssignExp(0, e1, e);
1230 e = e->semantic(sc); 1348 e->op = TOKconstruct;
1349 e = e->semantic(sc2);
1231 a->push(new ExpStatement(0, e)); 1350 a->push(new ExpStatement(0, e));
1232 } 1351 }
1233 1352
1234 #endif // !IN_LLVM 1353 #endif // !IN_LLVM
1235 1354
1282 } 1401 }
1283 1402
1284 // LDC: check for null this 1403 // LDC: check for null this
1285 ThisExp* v = new ThisExp(0); 1404 ThisExp* v = new ThisExp(0);
1286 v->type = vthis->type; 1405 v->type = vthis->type;
1406 #if STRUCTTHISREF
1407 if (ad->isStructDeclaration())
1408 v = v->addressOf(sc);
1409 #endif
1287 v->var = vthis; 1410 v->var = vthis;
1288 1411
1289 NullExp *nv = new NullExp(0); 1412 NullExp *nv = new NullExp(0);
1290 nv->type = v->type; 1413 nv->type = v->type;
1291 1414
1330 a->push(s); 1453 a->push(s);
1331 } 1454 }
1332 } 1455 }
1333 1456
1334 fbody = new CompoundStatement(0, a); 1457 fbody = new CompoundStatement(0, a);
1458 #if DMDV2
1459 /* Append destructor calls for parameters as finally blocks.
1460 */
1461 if (parameters)
1462 { for (size_t i = 0; i < parameters->dim; i++)
1463 {
1464 VarDeclaration *v = (VarDeclaration *)parameters->data[i];
1465
1466 if (v->storage_class & (STCref | STCout))
1467 continue;
1468
1469 /* Don't do this for static arrays, since static
1470 * arrays are called by reference. Remove this
1471 * when we change them to call by value.
1472 */
1473 if (v->type->toBasetype()->ty == Tsarray)
1474 continue;
1475
1476 Expression *e = v->callAutoDtor(sc);
1477 if (e)
1478 { Statement *s = new ExpStatement(0, e);
1479 s = s->semantic(sc);
1480 if (fbody->blockExit() == BEfallthru)
1481 fbody = new CompoundStatement(0, fbody, s);
1482 else
1483 fbody = new TryFinallyStatement(0, fbody, s);
1484 }
1485 }
1486 }
1487 #endif
1335 1488
1336 // wrap body of synchronized functions in a synchronized statement 1489 // wrap body of synchronized functions in a synchronized statement
1337 if (isSynchronized()) 1490 if (isSynchronized())
1338 { 1491 {
1339 ClassDeclaration *cd = parent->isClassDeclaration(); 1492 ClassDeclaration *cd = parent->isClassDeclaration();
1428 buf->writenl(); 1581 buf->writenl();
1429 } 1582 }
1430 } 1583 }
1431 1584
1432 /**************************************************** 1585 /****************************************************
1586 * Merge into this function the 'in' contracts of all it overrides.
1587 * 'in's are OR'd together, i.e. only one of them needs to pass.
1588 */
1589
1590 Statement *FuncDeclaration::mergeFrequire(Statement *sf)
1591 {
1592 /* Implementing this is done by having the overriding function call
1593 * nested functions (the fdrequire functions) nested inside the overridden
1594 * function. This requires that the stack layout of the calling function's
1595 * parameters and 'this' pointer be in the same place (as the nested
1596 * function refers to them).
1597 * This is easy for the parameters, as they are all on the stack in the same
1598 * place by definition, since it's an overriding function. The problem is
1599 * getting the 'this' pointer in the same place, since it is a local variable.
1600 * We did some hacks in the code generator to make this happen:
1601 * 1. always generate exception handler frame, or at least leave space for it
1602 * in the frame (Windows 32 SEH only)
1603 * 2. always generate an EBP style frame
1604 * 3. since 'this' is passed in a register that is subsequently copied into
1605 * a stack local, allocate that local immediately following the exception
1606 * handler block, so it is always at the same offset from EBP.
1607 */
1608 for (int i = 0; i < foverrides.dim; i++)
1609 {
1610 FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i];
1611 sf = fdv->mergeFrequire(sf);
1612 if (fdv->fdrequire)
1613 {
1614 //printf("fdv->frequire: %s\n", fdv->frequire->toChars());
1615 /* Make the call:
1616 * try { __require(); }
1617 * catch { frequire; }
1618 */
1619 Expression *eresult = NULL;
1620 Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdrequire), eresult);
1621 Statement *s2 = new ExpStatement(loc, e);
1622
1623 if (sf)
1624 { Catch *c = new Catch(loc, NULL, NULL, sf);
1625 Array *catches = new Array();
1626 catches->push(c);
1627 sf = new TryCatchStatement(loc, s2, catches);
1628 }
1629 else
1630 sf = s2;
1631 }
1632 }
1633 return sf;
1634 }
1635
1636 /****************************************************
1637 * Merge into this function the 'out' contracts of all it overrides.
1638 * 'out's are AND'd together, i.e. all of them need to pass.
1639 */
1640
1641 Statement *FuncDeclaration::mergeFensure(Statement *sf)
1642 {
1643 /* Same comments as for mergeFrequire(), except that we take care
1644 * of generating a consistent reference to the 'result' local by
1645 * explicitly passing 'result' to the nested function as a reference
1646 * argument.
1647 * This won't work for the 'this' parameter as it would require changing
1648 * the semantic code for the nested function so that it looks on the parameter
1649 * list for the 'this' pointer, something that would need an unknown amount
1650 * of tweaking of various parts of the compiler that I'd rather leave alone.
1651 */
1652 for (int i = 0; i < foverrides.dim; i++)
1653 {
1654 FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i];
1655 sf = fdv->mergeFensure(sf);
1656 if (fdv->fdensure)
1657 {
1658 //printf("fdv->fensure: %s\n", fdv->fensure->toChars());
1659 // Make the call: __ensure(result)
1660 Expression *eresult = NULL;
1661 if (outId)
1662 eresult = new IdentifierExp(loc, outId);
1663 Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdensure), eresult);
1664 Statement *s2 = new ExpStatement(loc, e);
1665
1666 if (sf)
1667 {
1668 sf = new CompoundStatement(fensure->loc, s2, sf);
1669 }
1670 else
1671 sf = s2;
1672 }
1673 }
1674 return sf;
1675 }
1676
1677 /****************************************************
1433 * Determine if 'this' overrides fd. 1678 * Determine if 'this' overrides fd.
1434 * Return !=0 if it does. 1679 * Return !=0 if it does.
1435 */ 1680 */
1436 1681
1437 int FuncDeclaration::overrides(FuncDeclaration *fd) 1682 int FuncDeclaration::overrides(FuncDeclaration *fd)
1602 } 1847 }
1603 return 0; 1848 return 0;
1604 } 1849 }
1605 1850
1606 /******************************************** 1851 /********************************************
1852 * If there are no overloads of function f, return that function,
1853 * otherwise return NULL.
1854 */
1855
1856 static int fpunique(void *param, FuncDeclaration *f)
1857 { FuncDeclaration **pf = (FuncDeclaration **)param;
1858
1859 if (*pf)
1860 { *pf = NULL;
1861 return 1; // ambiguous, done
1862 }
1863 else
1864 { *pf = f;
1865 return 0;
1866 }
1867 }
1868
1869 FuncDeclaration *FuncDeclaration::isUnique()
1870 { FuncDeclaration *result = NULL;
1871
1872 overloadApply(getModule(), this, &fpunique, &result);
1873 return result;
1874 }
1875
1876 /********************************************
1607 * Find function in overload list that exactly matches t. 1877 * Find function in overload list that exactly matches t.
1608 */ 1878 */
1609 1879
1610 struct Param1 1880 struct Param1
1611 { 1881 {
1745 } 2015 }
1746 return 0; 2016 return 0;
1747 } 2017 }
1748 2018
1749 2019
1750 void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments, Module* from) 2020 void overloadResolveX(Match *m, FuncDeclaration *fstart,
2021 Expression *ethis, Expressions *arguments, Module *from)
1751 { 2022 {
1752 Param2 p; 2023 Param2 p;
1753 p.m = m; 2024 p.m = m;
1754 p.arguments = arguments; 2025 p.arguments = arguments;
1755 overloadApply(from, fstart, &fp2, &p); 2026 overloadApply(from, fstart, &fp2, &p);
1771 AliasDeclaration *a; 2042 AliasDeclaration *a;
1772 2043
1773 fa = d->isFuncAliasDeclaration(); 2044 fa = d->isFuncAliasDeclaration();
1774 if (fa) 2045 if (fa)
1775 { 2046 {
1776 overloadResolveX(m, fa->funcalias, arguments); 2047 overloadResolveX(m, fa->funcalias, NULL, arguments);
1777 next = fa->overnext; 2048 next = fa->overnext;
1778 } 2049 }
1779 else if ((f = d->isFuncDeclaration()) != NULL) 2050 else if ((f = d->isFuncDeclaration()) != NULL)
1780 { 2051 {
1781 next = f->overnext; 2052 next = f->overnext;
1835 } 2106 }
1836 } 2107 }
1837 } 2108 }
1838 #endif 2109 #endif
1839 2110
1840 FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expressions *arguments, Module* from) 2111 FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, Module *from, int flags)
1841 { 2112 {
1842 TypeFunction *tf; 2113 TypeFunction *tf;
1843 Match m; 2114 Match m;
1844 2115
1845 #if 0 2116 #if 0
1858 } 2129 }
1859 #endif 2130 #endif
1860 2131
1861 memset(&m, 0, sizeof(m)); 2132 memset(&m, 0, sizeof(m));
1862 m.last = MATCHnomatch; 2133 m.last = MATCHnomatch;
1863 overloadResolveX(&m, this, arguments, from); 2134 overloadResolveX(&m, this, NULL, arguments, from);
1864 2135
1865 if (m.count == 1) // exactly one match 2136 if (m.count == 1) // exactly one match
1866 { 2137 {
1867 return m.lastf; 2138 return m.lastf;
1868 } 2139 }
2037 } 2308 }
2038 cs = fbody->isCompoundStatement(); 2309 cs = fbody->isCompoundStatement();
2039 cs->statements->push(s); 2310 cs->statements->push(s);
2040 } 2311 }
2041 2312
2313 const char *FuncDeclaration::toPrettyChars()
2314 {
2315 if (isMain())
2316 return "D main";
2317 else
2318 return Dsymbol::toPrettyChars();
2319 }
2042 2320
2043 int FuncDeclaration::isMain() 2321 int FuncDeclaration::isMain()
2044 { 2322 {
2045 return ident == Id::main && 2323 return ident == Id::main &&
2046 linkage != LINKc && !isMember() && !isNested(); 2324 linkage != LINKc && !isMember() && !isNested();
2402 tret = Type::tvoid; 2680 tret = Type::tvoid;
2403 } 2681 }
2404 else 2682 else
2405 tret = cd->type; //->referenceTo(); 2683 tret = cd->type; //->referenceTo();
2406 type = new TypeFunction(arguments, tret, varargs, LINKd); 2684 type = new TypeFunction(arguments, tret, varargs, LINKd);
2685 #if STRUCTTHISREF
2686 if (ad && ad->isStructDeclaration())
2687 ((TypeFunction *)type)->isref = 1;
2688 #endif
2407 if (!originalType) 2689 if (!originalType)
2408 originalType = type; 2690 originalType = type;
2409 2691
2410 sc->flags |= SCOPEctor; 2692 sc->flags |= SCOPEctor;
2411 type = type->semantic(loc, sc); 2693 type = type->semantic(loc, sc);
2413 2695
2414 // Append: 2696 // Append:
2415 // return this; 2697 // return this;
2416 // to the function body 2698 // to the function body
2417 if (fbody) 2699 if (fbody)
2418 { Expression *e; 2700 {
2419 Statement *s; 2701 Expression *e = new ThisExp(loc);
2420 2702 Statement *s = new ReturnStatement(loc, e);
2421 e = new ThisExp(0); 2703 fbody = new CompoundStatement(loc, fbody, s);
2422 s = new ReturnStatement(0, e);
2423 fbody = new CompoundStatement(0, fbody, s);
2424 } 2704 }
2425 2705
2426 FuncDeclaration::semantic(sc); 2706 FuncDeclaration::semantic(sc);
2427 2707
2428 sc->pop(); 2708 sc->pop();
2463 buf->writestring("this"); 2743 buf->writestring("this");
2464 Argument::argsToCBuffer(buf, hgs, arguments, varargs); 2744 Argument::argsToCBuffer(buf, hgs, arguments, varargs);
2465 bodyToCBuffer(buf, hgs); 2745 bodyToCBuffer(buf, hgs);
2466 } 2746 }
2467 2747
2748 /********************************* PostBlitDeclaration ****************************/
2749
2750 #if DMDV2
2751 PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc)
2752 : FuncDeclaration(loc, endloc, Id::_postblit, STCundefined, NULL)
2753 {
2754 }
2755
2756 PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc, Identifier *id)
2757 : FuncDeclaration(loc, endloc, id, STCundefined, NULL)
2758 {
2759 }
2760
2761 Dsymbol *PostBlitDeclaration::syntaxCopy(Dsymbol *s)
2762 {
2763 assert(!s);
2764 PostBlitDeclaration *dd = new PostBlitDeclaration(loc, endloc, ident);
2765 return FuncDeclaration::syntaxCopy(dd);
2766 }
2767
2768
2769 void PostBlitDeclaration::semantic(Scope *sc)
2770 {
2771 //printf("PostBlitDeclaration::semantic() %s\n", toChars());
2772 //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor);
2773 parent = sc->parent;
2774 Dsymbol *parent = toParent();
2775 StructDeclaration *ad = parent->isStructDeclaration();
2776 if (!ad)
2777 {
2778 error("post blits are only for struct/union definitions, not %s %s", parent->kind(), parent->toChars());
2779 }
2780 else if (ident == Id::_postblit)
2781 ad->postblits.push(this);
2782 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
2783
2784 sc = sc->push();
2785 sc->stc &= ~STCstatic; // not static
2786 sc->linkage = LINKd;
2787
2788 FuncDeclaration::semantic(sc);
2789
2790 sc->pop();
2791 }
2792
2793 int PostBlitDeclaration::overloadInsert(Dsymbol *s)
2794 {
2795 return FALSE; // cannot overload postblits
2796 }
2797
2798 int PostBlitDeclaration::addPreInvariant()
2799 {
2800 return FALSE;
2801 }
2802
2803 int PostBlitDeclaration::addPostInvariant()
2804 {
2805 return (isThis() && vthis && global.params.useInvariants);
2806 }
2807
2808 int PostBlitDeclaration::isVirtual()
2809 {
2810 return FALSE;
2811 }
2812
2813 void PostBlitDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2814 {
2815 if (hgs->hdrgen)
2816 return;
2817 buf->writestring("=this()");
2818 bodyToCBuffer(buf, hgs);
2819 }
2820 #endif
2821
2468 /********************************* DtorDeclaration ****************************/ 2822 /********************************* DtorDeclaration ****************************/
2469 2823
2470 DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc) 2824 DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc)
2471 : FuncDeclaration(loc, endloc, Id::dtor, STCundefined, NULL) 2825 : FuncDeclaration(loc, endloc, Id::dtor, STCundefined, NULL)
2472 { 2826 {
2485 } 2839 }
2486 2840
2487 2841
2488 void DtorDeclaration::semantic(Scope *sc) 2842 void DtorDeclaration::semantic(Scope *sc)
2489 { 2843 {
2490 ClassDeclaration *cd; 2844 //printf("DtorDeclaration::semantic() %s\n", toChars());
2491 2845 //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor);
2492 parent = sc->parent; 2846 parent = sc->parent;
2493 Dsymbol *parent = toParent(); 2847 Dsymbol *parent = toParent();
2494 cd = parent->isClassDeclaration(); 2848 ClassDeclaration *cd = parent->isClassDeclaration();
2495 if (!cd) 2849 if (!cd)
2496 { 2850 {
2497 error("destructors only are for class definitions"); 2851 error("destructors are only for class/struct/union definitions, not %s %s", parent->kind(), parent->toChars());
2498 fatal(); 2852 fatal();
2499 } 2853 }
2500 else 2854 else
2501 cd->dtors.push(this); 2855 cd->dtors.push(this);
2502 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2856 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
2521 } 2875 }
2522 2876
2523 int DtorDeclaration::addPostInvariant() 2877 int DtorDeclaration::addPostInvariant()
2524 { 2878 {
2525 return FALSE; 2879 return FALSE;
2880 }
2881
2882 const char *DtorDeclaration::kind()
2883 {
2884 return "destructor";
2885 }
2886
2887 char *DtorDeclaration::toChars()
2888 {
2889 return (char *)"~this";
2526 } 2890 }
2527 2891
2528 int DtorDeclaration::isVirtual() 2892 int DtorDeclaration::isVirtual()
2529 { 2893 {
2530 /* This should be FALSE so that dtor's don't get put into the vtbl[], 2894 /* This should be FALSE so that dtor's don't get put into the vtbl[],
2861 sc2->linkage = LINKd; 3225 sc2->linkage = LINKd;
2862 FuncDeclaration::semantic(sc2); 3226 FuncDeclaration::semantic(sc2);
2863 sc2->pop(); 3227 sc2->pop();
2864 } 3228 }
2865 3229
3230 #if 0
2866 // We're going to need ModuleInfo even if the unit tests are not 3231 // We're going to need ModuleInfo even if the unit tests are not
2867 // compiled in, because other modules may import this module and refer 3232 // compiled in, because other modules may import this module and refer
2868 // to this ModuleInfo. 3233 // to this ModuleInfo.
3234 // (This doesn't make sense to me?)
2869 Module *m = getModule(); 3235 Module *m = getModule();
2870 if (!m) 3236 if (!m)
2871 m = sc->module; 3237 m = sc->module;
2872 if (m) 3238 if (m)
3239 {
3240 //printf("module3 %s needs moduleinfo\n", m->toChars());
2873 m->needmoduleinfo = 1; 3241 m->needmoduleinfo = 1;
3242 }
3243 #endif
2874 } 3244 }
2875 3245
2876 AggregateDeclaration *UnitTestDeclaration::isThis() 3246 AggregateDeclaration *UnitTestDeclaration::isThis()
2877 { 3247 {
2878 return NULL; 3248 return NULL;