Mercurial > projects > ldc
comparison dmd/template.c @ 1587:def7a1d494fd
Merge DMD 1.051
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Fri, 06 Nov 2009 23:58:01 +0100 |
parents | 4dca8ed9d8b7 |
children | 207a8a438dea |
comparison
equal
deleted
inserted
replaced
1586:7f728c52e63c | 1587:def7a1d494fd |
---|---|
308 this->origParameters = parameters; | 308 this->origParameters = parameters; |
309 this->constraint = constraint; | 309 this->constraint = constraint; |
310 this->members = decldefs; | 310 this->members = decldefs; |
311 this->overnext = NULL; | 311 this->overnext = NULL; |
312 this->overroot = NULL; | 312 this->overroot = NULL; |
313 this->scope = NULL; | 313 this->semanticRun = 0; |
314 this->onemember = NULL; | 314 this->onemember = NULL; |
315 } | 315 } |
316 | 316 |
317 Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) | 317 Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) |
318 { | 318 { |
348 void TemplateDeclaration::semantic(Scope *sc) | 348 void TemplateDeclaration::semantic(Scope *sc) |
349 { | 349 { |
350 #if LOG | 350 #if LOG |
351 printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars()); | 351 printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars()); |
352 #endif | 352 #endif |
353 if (scope) | 353 if (semanticRun) |
354 return; // semantic() already run | 354 return; // semantic() already run |
355 semanticRun = 1; | |
355 | 356 |
356 if (sc->func) | 357 if (sc->func) |
357 { | 358 { |
358 #if DMDV1 | 359 #if DMDV1 |
359 error("cannot declare template at function scope %s", sc->func->toChars()); | 360 error("cannot declare template at function scope %s", sc->func->toChars()); |
801 nargsi = 0; | 802 nargsi = 0; |
802 if (targsi) | 803 if (targsi) |
803 { // Set initial template arguments | 804 { // Set initial template arguments |
804 | 805 |
805 nargsi = targsi->dim; | 806 nargsi = targsi->dim; |
806 if (nargsi > parameters->dim) | 807 size_t n = parameters->dim; |
808 if (nargsi > n) | |
807 { if (!tp) | 809 { if (!tp) |
808 goto Lnomatch; | 810 goto Lnomatch; |
809 dedargs->setDim(nargsi); | 811 dedargs->setDim(nargsi); |
810 dedargs->zero(); | 812 dedargs->zero(); |
811 } | 813 } |
812 | 814 else |
813 memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data)); | 815 n = nargsi; |
814 | 816 |
815 for (size_t i = 0; i < nargsi; i++) | 817 memcpy(dedargs->data, targsi->data, n * sizeof(*dedargs->data)); |
818 | |
819 for (size_t i = 0; i < n; i++) | |
816 { assert(i < parameters->dim); | 820 { assert(i < parameters->dim); |
817 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; | 821 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; |
818 MATCH m; | 822 MATCH m; |
819 Declaration *sparam = NULL; | 823 Declaration *sparam = NULL; |
820 | 824 |
842 | 846 |
843 assert(fd->type->ty == Tfunction); | 847 assert(fd->type->ty == Tfunction); |
844 fdtype = (TypeFunction *)fd->type; | 848 fdtype = (TypeFunction *)fd->type; |
845 | 849 |
846 nfparams = Argument::dim(fdtype->parameters); // number of function parameters | 850 nfparams = Argument::dim(fdtype->parameters); // number of function parameters |
847 nfargs = fargs->dim; // number of function arguments | 851 nfargs = fargs ? fargs->dim : 0; // number of function arguments |
848 | 852 |
849 /* Check for match of function arguments with variadic template | 853 /* Check for match of function arguments with variadic template |
850 * parameter, such as: | 854 * parameter, such as: |
851 * | 855 * |
852 * template Foo(T, A...) { void Foo(T t, A a); } | 856 * template Foo(T, A...) { void Foo(T t, A a); } |
853 * void main() { Foo(1,2,3); } | 857 * void main() { Foo(1,2,3); } |
854 */ | 858 */ |
855 if (tp) // if variadic | 859 if (tp) // if variadic |
856 { | 860 { |
857 if (nfparams == 0) // if no function parameters | 861 if (nfparams == 0 && nfargs != 0) // if no function parameters |
858 { | 862 { |
859 Tuple *t = new Tuple(); | 863 Tuple *t = new Tuple(); |
860 //printf("t = %p\n", t); | 864 //printf("t = %p\n", t); |
861 dedargs->data[parameters->dim - 1] = (void *)t; | 865 dedargs->data[parameters->dim - 1] = (void *)t; |
862 declareParameter(paramscope, tp, t); | 866 declareParameter(paramscope, tp, t); |
1291 } | 1295 } |
1292 #endif | 1296 #endif |
1293 | 1297 |
1294 for (TemplateDeclaration *td = this; td; td = td->overnext) | 1298 for (TemplateDeclaration *td = this; td; td = td->overnext) |
1295 { | 1299 { |
1296 if (!td->scope) | 1300 if (!td->semanticRun) |
1297 { | 1301 { |
1298 error("forward reference to template %s", td->toChars()); | 1302 error("forward reference to template %s", td->toChars()); |
1299 goto Lerror; | 1303 goto Lerror; |
1300 } | 1304 } |
1301 if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration()) | 1305 if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration()) |
1899 else if (tempinst->tempdecl != tp->tempinst->tempdecl) | 1903 else if (tempinst->tempdecl != tp->tempinst->tempdecl) |
1900 goto Lnomatch; | 1904 goto Lnomatch; |
1901 | 1905 |
1902 L2: | 1906 L2: |
1903 | 1907 |
1904 for (int i = 0; i < tempinst->tiargs->dim; i++) | 1908 for (int i = 0; 1; i++) |
1905 { | 1909 { |
1906 //printf("\ttest: tempinst->tiargs[%d]\n", i); | 1910 //printf("\ttest: tempinst->tiargs[%d]\n", i); |
1911 Object *o1; | |
1912 if (i < tempinst->tiargs->dim) | |
1913 o1 = (Object *)tempinst->tiargs->data[i]; | |
1914 else if (i < tempinst->tdtypes.dim && i < tp->tempinst->tiargs->dim) | |
1915 // Pick up default arg | |
1916 o1 = (Object *)tempinst->tdtypes.data[i]; | |
1917 else | |
1918 break; | |
1919 | |
1907 if (i >= tp->tempinst->tiargs->dim) | 1920 if (i >= tp->tempinst->tiargs->dim) |
1908 goto Lnomatch; | 1921 goto Lnomatch; |
1909 | 1922 |
1910 int j; | |
1911 Object *o1 = (Object *)tempinst->tiargs->data[i]; | |
1912 Object *o2 = (Object *)tp->tempinst->tiargs->data[i]; | 1923 Object *o2 = (Object *)tp->tempinst->tiargs->data[i]; |
1913 | 1924 |
1914 Type *t1 = isType(o1); | 1925 Type *t1 = isType(o1); |
1915 Type *t2 = isType(o2); | 1926 Type *t2 = isType(o2); |
1916 | 1927 |
1932 if (v1) printf("v1 = %s\n", v1->toChars()); | 1943 if (v1) printf("v1 = %s\n", v1->toChars()); |
1933 if (v2) printf("v2 = %s\n", v2->toChars()); | 1944 if (v2) printf("v2 = %s\n", v2->toChars()); |
1934 #endif | 1945 #endif |
1935 | 1946 |
1936 TemplateTupleParameter *ttp; | 1947 TemplateTupleParameter *ttp; |
1948 int j; | |
1937 if (t2 && | 1949 if (t2 && |
1938 t2->ty == Tident && | 1950 t2->ty == Tident && |
1939 i == tp->tempinst->tiargs->dim - 1 && | 1951 i == tp->tempinst->tiargs->dim - 1 && |
1940 i == tempinst->tempdecl->parameters->dim - 1 && | 1952 i == tempinst->tempdecl->parameters->dim - 1 && |
1941 (ttp = tempinst->tempdecl->isVariadic()) != NULL) | 1953 (ttp = tempinst->tempdecl->isVariadic()) != NULL) |
3060 this->tempdecl = NULL; | 3072 this->tempdecl = NULL; |
3061 this->inst = NULL; | 3073 this->inst = NULL; |
3062 this->tinst = NULL; | 3074 this->tinst = NULL; |
3063 this->argsym = NULL; | 3075 this->argsym = NULL; |
3064 this->aliasdecl = NULL; | 3076 this->aliasdecl = NULL; |
3065 this->semanticdone = 0; | 3077 this->semanticRun = 0; |
3066 this->semantictiargsdone = 0; | 3078 this->semantictiargsdone = 0; |
3067 this->withsym = NULL; | 3079 this->withsym = NULL; |
3068 this->nest = 0; | 3080 this->nest = 0; |
3069 this->havetempdecl = 0; | 3081 this->havetempdecl = 0; |
3070 this->isnested = NULL; | 3082 this->isnested = NULL; |
3094 this->tempdecl = td; | 3106 this->tempdecl = td; |
3095 this->inst = NULL; | 3107 this->inst = NULL; |
3096 this->tinst = NULL; | 3108 this->tinst = NULL; |
3097 this->argsym = NULL; | 3109 this->argsym = NULL; |
3098 this->aliasdecl = NULL; | 3110 this->aliasdecl = NULL; |
3099 this->semanticdone = 0; | 3111 this->semanticRun = 0; |
3100 this->semantictiargsdone = 1; | 3112 this->semantictiargsdone = 1; |
3101 this->withsym = NULL; | 3113 this->withsym = NULL; |
3102 this->nest = 0; | 3114 this->nest = 0; |
3103 this->havetempdecl = 1; | 3115 this->havetempdecl = 1; |
3104 this->isnested = NULL; | 3116 this->isnested = NULL; |
3177 } | 3189 } |
3178 | 3190 |
3179 // get the enclosing template instance from the scope tinst | 3191 // get the enclosing template instance from the scope tinst |
3180 tinst = sc->tinst; | 3192 tinst = sc->tinst; |
3181 | 3193 |
3182 if (semanticdone != 0) | 3194 if (semanticRun != 0) |
3183 { | 3195 { |
3184 error(loc, "recursive template expansion"); | 3196 error(loc, "recursive template expansion"); |
3185 // inst = this; | 3197 // inst = this; |
3186 return; | 3198 return; |
3187 } | 3199 } |
3188 semanticdone = 1; | 3200 semanticRun = 1; |
3189 | 3201 |
3190 // get the enclosing template instance from the scope tinst | 3202 // get the enclosing template instance from the scope tinst |
3191 tinst = sc->tinst; | 3203 tinst = sc->tinst; |
3192 | 3204 |
3193 // get the module of the outermost enclosing instantiation | 3205 // get the module of the outermost enclosing instantiation |
3321 } | 3333 } |
3322 else | 3334 else |
3323 { Module *m = sc->module->importedFrom; | 3335 { Module *m = sc->module->importedFrom; |
3324 //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); | 3336 //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); |
3325 a = m->members; | 3337 a = m->members; |
3326 if (m->semanticdone >= 3) | 3338 if (m->semanticRun >= 3) |
3327 dosemantic3 = 1; | 3339 dosemantic3 = 1; |
3328 } | 3340 } |
3329 for (int i = 0; 1; i++) | 3341 for (int i = 0; 1; i++) |
3330 { | 3342 { |
3331 if (i == a->dim) | 3343 if (i == a->dim) |
3342 // Copy the syntax trees from the TemplateDeclaration | 3354 // Copy the syntax trees from the TemplateDeclaration |
3343 members = Dsymbol::arraySyntaxCopy(tempdecl->members); | 3355 members = Dsymbol::arraySyntaxCopy(tempdecl->members); |
3344 | 3356 |
3345 // Create our own scope for the template parameters | 3357 // Create our own scope for the template parameters |
3346 Scope *scope = tempdecl->scope; | 3358 Scope *scope = tempdecl->scope; |
3347 if (!scope) | 3359 if (!tempdecl->semanticRun) |
3348 { | 3360 { |
3349 error("forward reference to template declaration %s\n", tempdecl->toChars()); | 3361 error("template instantiation %s forward references template declaration %s\n", toChars(), tempdecl->toChars()); |
3350 return; | 3362 return; |
3351 } | 3363 } |
3352 | 3364 |
3353 #if LOG | 3365 #if LOG |
3354 printf("\tcreate scope for template parameters '%s'\n", toChars()); | 3366 printf("\tcreate scope for template parameters '%s'\n", toChars()); |
3557 j--; | 3569 j--; |
3558 } | 3570 } |
3559 } | 3571 } |
3560 else if (ta) | 3572 else if (ta) |
3561 { | 3573 { |
3574 Ltype: | |
3562 if (ta->ty == Ttuple) | 3575 if (ta->ty == Ttuple) |
3563 { // Expand tuple | 3576 { // Expand tuple |
3564 TypeTuple *tt = (TypeTuple *)ta; | 3577 TypeTuple *tt = (TypeTuple *)ta; |
3565 size_t dim = tt->arguments->dim; | 3578 size_t dim = tt->arguments->dim; |
3566 tiargs->remove(j); | 3579 tiargs->remove(j); |
3591 assert(ea); | 3604 assert(ea); |
3592 ea = ea->semantic(sc); | 3605 ea = ea->semantic(sc); |
3593 ea = ea->optimize(WANTvalue | WANTinterpret); | 3606 ea = ea->optimize(WANTvalue | WANTinterpret); |
3594 tiargs->data[j] = ea; | 3607 tiargs->data[j] = ea; |
3595 if (ea->op == TOKtype) | 3608 if (ea->op == TOKtype) |
3596 tiargs->data[j] = ea->type; | 3609 { ta = ea->type; |
3610 goto Ltype; | |
3611 } | |
3612 if (ea->op == TOKtuple) | |
3613 { // Expand tuple | |
3614 TupleExp *te = (TupleExp *)ea; | |
3615 size_t dim = te->exps->dim; | |
3616 tiargs->remove(j); | |
3617 if (dim) | |
3618 { tiargs->reserve(dim); | |
3619 for (size_t i = 0; i < dim; i++) | |
3620 tiargs->insert(j + i, te->exps->data[i]); | |
3621 } | |
3622 j--; | |
3623 } | |
3597 } | 3624 } |
3598 else if (sa) | 3625 else if (sa) |
3599 { | 3626 { |
3600 } | 3627 } |
3601 else | 3628 else |
3734 Objects dedtypes; | 3761 Objects dedtypes; |
3735 | 3762 |
3736 #if LOG | 3763 #if LOG |
3737 printf("TemplateInstance::findBestMatch()\n"); | 3764 printf("TemplateInstance::findBestMatch()\n"); |
3738 #endif | 3765 #endif |
3766 // First look for forward references | |
3767 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) | |
3768 { | |
3769 if (!td->semanticRun) | |
3770 { | |
3771 if (td->scope) | |
3772 { // Try to fix forward reference | |
3773 td->semantic(td->scope); | |
3774 } | |
3775 if (!td->semanticRun) | |
3776 { | |
3777 error("%s forward references template declaration %s\n", toChars(), td->toChars()); | |
3778 return NULL; | |
3779 } | |
3780 } | |
3781 } | |
3782 | |
3739 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) | 3783 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) |
3740 { | 3784 { |
3741 MATCH m; | 3785 MATCH m; |
3742 | 3786 |
3743 //if (tiargs->dim) printf("2: tiargs->dim = %d, data[0] = %p\n", tiargs->dim, tiargs->data[0]); | 3787 //if (tiargs->dim) printf("2: tiargs->dim = %d, data[0] = %p\n", tiargs->dim, tiargs->data[0]); |
3750 continue; | 3794 continue; |
3751 } | 3795 } |
3752 | 3796 |
3753 dedtypes.setDim(td->parameters->dim); | 3797 dedtypes.setDim(td->parameters->dim); |
3754 dedtypes.zero(); | 3798 dedtypes.zero(); |
3755 if (!td->scope) | 3799 assert(td->semanticRun); |
3756 { | |
3757 error("forward reference to template declaration %s", td->toChars()); | |
3758 return NULL; | |
3759 } | |
3760 m = td->matchWithInstance(this, &dedtypes, 0); | 3800 m = td->matchWithInstance(this, &dedtypes, 0); |
3761 //printf("matchWithInstance = %d\n", m); | 3801 //printf("matchWithInstance = %d\n", m); |
3762 if (!m) // no match at all | 3802 if (!m) // no match at all |
3763 continue; | 3803 continue; |
3764 | 3804 |
3962 } | 4002 } |
3963 else if (ea) | 4003 else if (ea) |
3964 { sinteger_t v; | 4004 { sinteger_t v; |
3965 real_t r; | 4005 real_t r; |
3966 | 4006 |
4007 ea = ea->optimize(WANTvalue | WANTinterpret); | |
3967 if (ea->op == TOKvar) | 4008 if (ea->op == TOKvar) |
3968 { | 4009 { |
3969 sa = ((VarExp *)ea)->var; | 4010 sa = ((VarExp *)ea)->var; |
3970 ea = NULL; | 4011 ea = NULL; |
3971 goto Lsa; | 4012 goto Lsa; |
4028 /**************************************************** | 4069 /**************************************************** |
4029 * Declare parameters of template instance, initialize them with the | 4070 * Declare parameters of template instance, initialize them with the |
4030 * template instance arguments. | 4071 * template instance arguments. |
4031 */ | 4072 */ |
4032 | 4073 |
4033 void TemplateInstance::declareParameters(Scope *scope) | 4074 void TemplateInstance::declareParameters(Scope *sc) |
4034 { | 4075 { |
4035 //printf("TemplateInstance::declareParameters()\n"); | 4076 //printf("TemplateInstance::declareParameters()\n"); |
4036 for (int i = 0; i < tdtypes.dim; i++) | 4077 for (int i = 0; i < tdtypes.dim; i++) |
4037 { | 4078 { |
4038 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; | 4079 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; |
4039 //Object *o = (Object *)tiargs->data[i]; | 4080 //Object *o = (Object *)tiargs->data[i]; |
4040 Object *o = (Object *)tdtypes.data[i]; // initializer for tp | 4081 Object *o = (Object *)tdtypes.data[i]; // initializer for tp |
4041 | 4082 |
4042 //printf("\ttdtypes[%d] = %p\n", i, o); | 4083 //printf("\ttdtypes[%d] = %p\n", i, o); |
4043 tempdecl->declareParameter(scope, tp, o); | 4084 tempdecl->declareParameter(sc, tp, o); |
4044 } | 4085 } |
4045 } | 4086 } |
4046 | 4087 |
4047 | 4088 |
4048 void TemplateInstance::semantic2(Scope *sc) | 4089 void TemplateInstance::semantic2(Scope *sc) |
4049 { int i; | 4090 { int i; |
4050 | 4091 |
4051 if (semanticdone >= 2) | 4092 if (semanticRun >= 2) |
4052 return; | 4093 return; |
4053 semanticdone = 2; | 4094 semanticRun = 2; |
4054 #if LOG | 4095 #if LOG |
4055 printf("+TemplateInstance::semantic2('%s')\n", toChars()); | 4096 printf("+TemplateInstance::semantic2('%s')\n", toChars()); |
4056 #endif | 4097 #endif |
4057 if (!errors && members) | 4098 if (!errors && members) |
4058 { | 4099 { |
4078 } | 4119 } |
4079 | 4120 |
4080 void TemplateInstance::semantic3(Scope *sc) | 4121 void TemplateInstance::semantic3(Scope *sc) |
4081 { | 4122 { |
4082 #if LOG | 4123 #if LOG |
4083 printf("TemplateInstance::semantic3('%s'), semanticdone = %d\n", toChars(), semanticdone); | 4124 printf("TemplateInstance::semantic3('%s'), semanticRun = %d\n", toChars(), semanticRun); |
4084 #endif | 4125 #endif |
4085 //if (toChars()[0] == 'D') *(char*)0=0; | 4126 //if (toChars()[0] == 'D') *(char*)0=0; |
4086 if (semanticdone >= 3) | 4127 if (semanticRun >= 3) |
4087 return; | 4128 return; |
4088 semanticdone = 3; | 4129 semanticRun = 3; |
4089 if (!errors && members) | 4130 if (!errors && members) |
4090 { | 4131 { |
4091 sc = tempdecl->scope; | 4132 sc = tempdecl->scope; |
4092 sc = sc->push(argsym); | 4133 sc = sc->push(argsym); |
4093 sc = sc->push(this); | 4134 sc = sc->push(this); |
4180 #if LOG | 4221 #if LOG |
4181 printf("TemplateInstance::toAlias()\n"); | 4222 printf("TemplateInstance::toAlias()\n"); |
4182 #endif | 4223 #endif |
4183 if (!inst) | 4224 if (!inst) |
4184 { error("cannot resolve forward reference"); | 4225 { error("cannot resolve forward reference"); |
4226 errors = 1; | |
4185 return this; | 4227 return this; |
4186 } | 4228 } |
4187 | 4229 |
4188 if (inst != this) | 4230 if (inst != this) |
4189 return inst->toAlias(); | 4231 return inst->toAlias(); |
4272 //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : ""); | 4314 //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : ""); |
4273 this->ident = ident; | 4315 this->ident = ident; |
4274 this->tqual = tqual; | 4316 this->tqual = tqual; |
4275 this->idents = idents; | 4317 this->idents = idents; |
4276 this->tiargs = tiargs ? tiargs : new Objects(); | 4318 this->tiargs = tiargs ? tiargs : new Objects(); |
4277 this->scope = NULL; | |
4278 } | 4319 } |
4279 | 4320 |
4280 Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s) | 4321 Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s) |
4281 { TemplateMixin *tm; | 4322 { TemplateMixin *tm; |
4282 | 4323 |
4306 { | 4347 { |
4307 #if LOG | 4348 #if LOG |
4308 printf("+TemplateMixin::semantic('%s', this=%p)\n", toChars(), this); | 4349 printf("+TemplateMixin::semantic('%s', this=%p)\n", toChars(), this); |
4309 fflush(stdout); | 4350 fflush(stdout); |
4310 #endif | 4351 #endif |
4311 if (semanticdone && | 4352 if (semanticRun) |
4353 { | |
4312 // This for when a class/struct contains mixin members, and | 4354 // This for when a class/struct contains mixin members, and |
4313 // is done over because of forward references | 4355 // is done over because of forward references |
4314 (!parent || !toParent()->isAggregateDeclaration())) | 4356 if (parent && toParent()->isAggregateDeclaration()) |
4315 { | 4357 semanticRun = 1; // do over |
4358 else | |
4359 { | |
4316 #if LOG | 4360 #if LOG |
4317 printf("\tsemantic done\n"); | 4361 printf("\tsemantic done\n"); |
4318 #endif | 4362 #endif |
4319 return; | 4363 return; |
4320 } | 4364 } |
4321 if (!semanticdone) | 4365 } |
4322 semanticdone = 1; | 4366 if (!semanticRun) |
4367 semanticRun = 1; | |
4323 #if LOG | 4368 #if LOG |
4324 printf("\tdo semantic\n"); | 4369 printf("\tdo semantic\n"); |
4325 #endif | 4370 #endif |
4326 | 4371 |
4327 #if !IN_LLVM | 4372 #if !IN_LLVM |
4392 | 4437 |
4393 // Look for forward reference | 4438 // Look for forward reference |
4394 assert(tempdecl); | 4439 assert(tempdecl); |
4395 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) | 4440 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) |
4396 { | 4441 { |
4397 if (!td->scope) | 4442 if (!td->semanticRun) |
4398 { | 4443 { |
4399 /* Cannot handle forward references if mixin is a struct member, | 4444 /* Cannot handle forward references if mixin is a struct member, |
4400 * because addField must happen during struct's semantic, not | 4445 * because addField must happen during struct's semantic, not |
4401 * during the mixin semantic. | 4446 * during the mixin semantic. |
4402 * runDeferred will re-run mixin's semantic outside of the struct's | 4447 * runDeferred will re-run mixin's semantic outside of the struct's |
4403 * semantic. | 4448 * semantic. |
4404 */ | 4449 */ |
4405 semanticdone = 0; | 4450 semanticRun = 0; |
4406 AggregateDeclaration *ad = toParent()->isAggregateDeclaration(); | 4451 AggregateDeclaration *ad = toParent()->isAggregateDeclaration(); |
4407 if (ad) | 4452 if (ad) |
4408 ad->sizeok = 2; | 4453 ad->sizeok = 2; |
4409 else | 4454 else |
4410 { | 4455 { |
4418 } | 4463 } |
4419 } | 4464 } |
4420 | 4465 |
4421 // Run semantic on each argument, place results in tiargs[] | 4466 // Run semantic on each argument, place results in tiargs[] |
4422 semanticTiargs(sc); | 4467 semanticTiargs(sc); |
4468 if (errors) | |
4469 return; | |
4423 | 4470 |
4424 tempdecl = findBestMatch(sc); | 4471 tempdecl = findBestMatch(sc); |
4425 if (!tempdecl) | 4472 if (!tempdecl) |
4426 { inst = this; | 4473 { inst = this; |
4427 return; // error recovery | 4474 return; // error recovery |
4506 scy = sc->push(this); | 4553 scy = sc->push(this); |
4507 scy->parent = this; | 4554 scy->parent = this; |
4508 | 4555 |
4509 argsym = new ScopeDsymbol(); | 4556 argsym = new ScopeDsymbol(); |
4510 argsym->parent = scy->parent; | 4557 argsym->parent = scy->parent; |
4511 Scope *scope = scy->push(argsym); | 4558 Scope *argscope = scy->push(argsym); |
4512 | 4559 |
4513 unsigned errorsave = global.errors; | 4560 unsigned errorsave = global.errors; |
4514 | 4561 |
4515 // Declare each template parameter as an alias for the argument type | 4562 // Declare each template parameter as an alias for the argument type |
4516 declareParameters(scope); | 4563 declareParameters(argscope); |
4517 | 4564 |
4518 // Add members to enclosing scope, as well as this scope | 4565 // Add members to enclosing scope, as well as this scope |
4519 for (unsigned i = 0; i < members->dim; i++) | 4566 for (unsigned i = 0; i < members->dim; i++) |
4520 { Dsymbol *s; | 4567 { Dsymbol *s; |
4521 | 4568 |
4522 s = (Dsymbol *)members->data[i]; | 4569 s = (Dsymbol *)members->data[i]; |
4523 s->addMember(scope, this, i); | 4570 s->addMember(argscope, this, i); |
4524 //sc->insert(s); | 4571 //sc->insert(s); |
4525 //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym); | 4572 //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym); |
4526 //printf("s->parent = %s\n", s->parent->toChars()); | 4573 //printf("s->parent = %s\n", s->parent->toChars()); |
4527 } | 4574 } |
4528 | 4575 |
4529 // Do semantic() analysis on template instance members | 4576 // Do semantic() analysis on template instance members |
4530 #if LOG | 4577 #if LOG |
4531 printf("\tdo semantic() on template instance members '%s'\n", toChars()); | 4578 printf("\tdo semantic() on template instance members '%s'\n", toChars()); |
4532 #endif | 4579 #endif |
4533 Scope *sc2; | 4580 Scope *sc2; |
4534 sc2 = scope->push(this); | 4581 sc2 = argscope->push(this); |
4535 sc2->offset = sc->offset; | 4582 sc2->offset = sc->offset; |
4536 | 4583 |
4537 static int nest; | 4584 static int nest; |
4538 //printf("%d\n", nest); | 4585 //printf("%d\n", nest); |
4539 if (++nest > 500) | 4586 if (++nest > 500) |
4572 error("error instantiating"); | 4619 error("error instantiating"); |
4573 } | 4620 } |
4574 | 4621 |
4575 sc2->pop(); | 4622 sc2->pop(); |
4576 | 4623 |
4577 scope->pop(); | 4624 argscope->pop(); |
4578 | 4625 |
4579 // if (!isAnonymous()) | 4626 // if (!isAnonymous()) |
4580 { | 4627 { |
4581 scy->pop(); | 4628 scy->pop(); |
4582 } | 4629 } |
4586 } | 4633 } |
4587 | 4634 |
4588 void TemplateMixin::semantic2(Scope *sc) | 4635 void TemplateMixin::semantic2(Scope *sc) |
4589 { int i; | 4636 { int i; |
4590 | 4637 |
4591 if (semanticdone >= 2) | 4638 if (semanticRun >= 2) |
4592 return; | 4639 return; |
4593 semanticdone = 2; | 4640 semanticRun = 2; |
4594 #if LOG | 4641 #if LOG |
4595 printf("+TemplateMixin::semantic2('%s')\n", toChars()); | 4642 printf("+TemplateMixin::semantic2('%s')\n", toChars()); |
4596 #endif | 4643 #endif |
4597 if (members) | 4644 if (members) |
4598 { | 4645 { |
4616 } | 4663 } |
4617 | 4664 |
4618 void TemplateMixin::semantic3(Scope *sc) | 4665 void TemplateMixin::semantic3(Scope *sc) |
4619 { int i; | 4666 { int i; |
4620 | 4667 |
4621 if (semanticdone >= 3) | 4668 if (semanticRun >= 3) |
4622 return; | 4669 return; |
4623 semanticdone = 3; | 4670 semanticRun = 3; |
4624 #if LOG | 4671 #if LOG |
4625 printf("TemplateMixin::semantic3('%s')\n", toChars()); | 4672 printf("TemplateMixin::semantic3('%s')\n", toChars()); |
4626 #endif | 4673 #endif |
4627 if (members) | 4674 if (members) |
4628 { | 4675 { |