Mercurial > projects > ldc
comparison dmd2/template.c @ 1526:54b3c1394d62
Merged dmdfe 2.031.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Tue, 07 Jul 2009 02:26:11 +0100 |
parents | 638d16625da2 |
children | e4f7b5d9c68a |
comparison
equal
deleted
inserted
replaced
1525:d28cd7c45267 | 1526:54b3c1394d62 |
---|---|
306 this->origParameters = parameters; | 306 this->origParameters = parameters; |
307 this->constraint = constraint; | 307 this->constraint = constraint; |
308 this->members = decldefs; | 308 this->members = decldefs; |
309 this->overnext = NULL; | 309 this->overnext = NULL; |
310 this->overroot = NULL; | 310 this->overroot = NULL; |
311 this->scope = NULL; | 311 this->semanticRun = 0; |
312 this->onemember = NULL; | 312 this->onemember = NULL; |
313 this->literal = 0; | 313 this->literal = 0; |
314 } | 314 } |
315 | 315 |
316 Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) | 316 Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) |
335 e = constraint->syntaxCopy(); | 335 e = constraint->syntaxCopy(); |
336 d = Dsymbol::arraySyntaxCopy(members); | 336 d = Dsymbol::arraySyntaxCopy(members); |
337 td = new TemplateDeclaration(loc, ident, p, e, d); | 337 td = new TemplateDeclaration(loc, ident, p, e, d); |
338 | 338 |
339 #if IN_LLVM | 339 #if IN_LLVM |
340 // LDC | |
341 td->intrinsicName = intrinsicName; | 340 td->intrinsicName = intrinsicName; |
342 #endif | 341 #endif |
343 | 342 |
344 return td; | 343 return td; |
345 } | 344 } |
347 void TemplateDeclaration::semantic(Scope *sc) | 346 void TemplateDeclaration::semantic(Scope *sc) |
348 { | 347 { |
349 #if LOG | 348 #if LOG |
350 printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars()); | 349 printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars()); |
351 #endif | 350 #endif |
352 if (scope) | 351 if (semanticRun) |
353 return; // semantic() already run | 352 return; // semantic() already run |
353 semanticRun = 1; | |
354 | 354 |
355 if (sc->func) | 355 if (sc->func) |
356 { | 356 { |
357 #if DMDV1 | 357 #if DMDV1 |
358 error("cannot declare template at function scope %s", sc->func->toChars()); | 358 error("cannot declare template at function scope %s", sc->func->toChars()); |
876 assert(fctor); | 876 assert(fctor); |
877 fparameters = fctor->arguments; | 877 fparameters = fctor->arguments; |
878 fvarargs = fctor->varargs; | 878 fvarargs = fctor->varargs; |
879 } | 879 } |
880 | 880 |
881 nfparams = Argument::dim(fparameters); // number of function parameters | 881 nfparams = Argument::dim(fparameters); // number of function parameters |
882 nfargs = fargs->dim; // number of function arguments | 882 nfargs = fargs ? fargs->dim : 0; // number of function arguments |
883 | 883 |
884 /* Check for match of function arguments with variadic template | 884 /* Check for match of function arguments with variadic template |
885 * parameter, such as: | 885 * parameter, such as: |
886 * | 886 * |
887 * template Foo(T, A...) { void Foo(T t, A a); } | 887 * template Foo(T, A...) { void Foo(T t, A a); } |
1327 } | 1327 } |
1328 #endif | 1328 #endif |
1329 | 1329 |
1330 for (TemplateDeclaration *td = this; td; td = td->overnext) | 1330 for (TemplateDeclaration *td = this; td; td = td->overnext) |
1331 { | 1331 { |
1332 if (!td->scope) | 1332 if (!td->semanticRun) |
1333 { | 1333 { |
1334 error("forward reference to template %s", td->toChars()); | 1334 error("forward reference to template %s", td->toChars()); |
1335 goto Lerror; | 1335 goto Lerror; |
1336 } | 1336 } |
1337 if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration()) | 1337 if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration()) |
3213 this->tempdecl = NULL; | 3213 this->tempdecl = NULL; |
3214 this->inst = NULL; | 3214 this->inst = NULL; |
3215 this->tinst = NULL; | 3215 this->tinst = NULL; |
3216 this->argsym = NULL; | 3216 this->argsym = NULL; |
3217 this->aliasdecl = NULL; | 3217 this->aliasdecl = NULL; |
3218 this->semanticdone = 0; | 3218 this->semanticRun = 0; |
3219 this->semantictiargsdone = 0; | 3219 this->semantictiargsdone = 0; |
3220 this->withsym = NULL; | 3220 this->withsym = NULL; |
3221 this->nest = 0; | 3221 this->nest = 0; |
3222 this->havetempdecl = 0; | 3222 this->havetempdecl = 0; |
3223 this->isnested = NULL; | 3223 this->isnested = NULL; |
3247 this->tempdecl = td; | 3247 this->tempdecl = td; |
3248 this->inst = NULL; | 3248 this->inst = NULL; |
3249 this->tinst = NULL; | 3249 this->tinst = NULL; |
3250 this->argsym = NULL; | 3250 this->argsym = NULL; |
3251 this->aliasdecl = NULL; | 3251 this->aliasdecl = NULL; |
3252 this->semanticdone = 0; | 3252 this->semanticRun = 0; |
3253 this->semantictiargsdone = 1; | 3253 this->semantictiargsdone = 1; |
3254 this->withsym = NULL; | 3254 this->withsym = NULL; |
3255 this->nest = 0; | 3255 this->nest = 0; |
3256 this->havetempdecl = 1; | 3256 this->havetempdecl = 1; |
3257 this->isnested = NULL; | 3257 this->isnested = NULL; |
3322 } | 3322 } |
3323 | 3323 |
3324 // get the enclosing template instance from the scope tinst | 3324 // get the enclosing template instance from the scope tinst |
3325 tinst = sc->tinst; | 3325 tinst = sc->tinst; |
3326 | 3326 |
3327 if (semanticdone != 0) | 3327 if (semanticRun != 0) |
3328 { | 3328 { |
3329 error(loc, "recursive template expansion"); | 3329 error(loc, "recursive template expansion"); |
3330 // inst = this; | 3330 // inst = this; |
3331 return; | 3331 return; |
3332 } | 3332 } |
3333 semanticdone = 1; | 3333 semanticRun = 1; |
3334 #if IN_LLVM | 3334 #if IN_LLVM |
3335 // get the enclosing template instance from the scope tinst | 3335 // get the enclosing template instance from the scope tinst |
3336 tinst = sc->tinst; | 3336 tinst = sc->tinst; |
3337 | 3337 |
3338 // get the module of the outermost enclosing instantiation | 3338 // get the module of the outermost enclosing instantiation |
3472 } | 3472 } |
3473 else | 3473 else |
3474 { Module *m = sc->module->importedFrom; | 3474 { Module *m = sc->module->importedFrom; |
3475 //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); | 3475 //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); |
3476 a = m->members; | 3476 a = m->members; |
3477 if (m->semanticdone >= 3) | 3477 if (m->semanticRun >= 3) |
3478 dosemantic3 = 1; | 3478 dosemantic3 = 1; |
3479 } | 3479 } |
3480 for (int i = 0; 1; i++) | 3480 for (int i = 0; 1; i++) |
3481 { | 3481 { |
3482 if (i == a->dim) | 3482 if (i == a->dim) |
3493 // Copy the syntax trees from the TemplateDeclaration | 3493 // Copy the syntax trees from the TemplateDeclaration |
3494 members = Dsymbol::arraySyntaxCopy(tempdecl->members); | 3494 members = Dsymbol::arraySyntaxCopy(tempdecl->members); |
3495 | 3495 |
3496 // Create our own scope for the template parameters | 3496 // Create our own scope for the template parameters |
3497 Scope *scope = tempdecl->scope; | 3497 Scope *scope = tempdecl->scope; |
3498 if (!scope) | 3498 if (!tempdecl->semanticRun) |
3499 { | 3499 { |
3500 error("forward reference to template declaration %s\n", tempdecl->toChars()); | 3500 error("template instantiation %s forward references template declaration %s\n", toChars(), tempdecl->toChars()); |
3501 return; | 3501 return; |
3502 } | 3502 } |
3503 | 3503 |
3504 #if LOG | 3504 #if LOG |
3505 printf("\tcreate scope for template parameters '%s'\n", toChars()); | 3505 printf("\tcreate scope for template parameters '%s'\n", toChars()); |
3715 j--; | 3715 j--; |
3716 } | 3716 } |
3717 } | 3717 } |
3718 else if (ta) | 3718 else if (ta) |
3719 { | 3719 { |
3720 Ltype: | |
3720 if (ta->ty == Ttuple) | 3721 if (ta->ty == Ttuple) |
3721 { // Expand tuple | 3722 { // Expand tuple |
3722 TypeTuple *tt = (TypeTuple *)ta; | 3723 TypeTuple *tt = (TypeTuple *)ta; |
3723 size_t dim = tt->arguments->dim; | 3724 size_t dim = tt->arguments->dim; |
3724 tiargs->remove(j); | 3725 tiargs->remove(j); |
3750 ea = ea->semantic(sc); | 3751 ea = ea->semantic(sc); |
3751 if (ea->op != TOKvar || flags & 1) | 3752 if (ea->op != TOKvar || flags & 1) |
3752 ea = ea->optimize(WANTvalue | WANTinterpret); | 3753 ea = ea->optimize(WANTvalue | WANTinterpret); |
3753 tiargs->data[j] = ea; | 3754 tiargs->data[j] = ea; |
3754 if (ea->op == TOKtype) | 3755 if (ea->op == TOKtype) |
3755 tiargs->data[j] = ea->type; | 3756 { ta = ea->type; |
3757 goto Ltype; | |
3758 } | |
3759 if (ea->op == TOKtuple) | |
3760 { // Expand tuple | |
3761 TupleExp *te = (TupleExp *)ea; | |
3762 size_t dim = te->exps->dim; | |
3763 tiargs->remove(j); | |
3764 if (dim) | |
3765 { tiargs->reserve(dim); | |
3766 for (size_t i = 0; i < dim; i++) | |
3767 tiargs->insert(j + i, te->exps->data[i]); | |
3768 } | |
3769 j--; | |
3770 } | |
3756 } | 3771 } |
3757 else if (sa) | 3772 else if (sa) |
3758 { | 3773 { |
3759 TemplateDeclaration *td = sa->isTemplateDeclaration(); | 3774 TemplateDeclaration *td = sa->isTemplateDeclaration(); |
3760 if (td && !td->scope && td->literal) | 3775 if (td && !td->semanticRun && td->literal) |
3761 td->semantic(sc); | 3776 td->semantic(sc); |
3762 } | 3777 } |
3763 else | 3778 else |
3764 { | 3779 { |
3765 assert(0); | 3780 assert(0); |
3896 Objects dedtypes; | 3911 Objects dedtypes; |
3897 | 3912 |
3898 #if LOG | 3913 #if LOG |
3899 printf("TemplateInstance::findBestMatch()\n"); | 3914 printf("TemplateInstance::findBestMatch()\n"); |
3900 #endif | 3915 #endif |
3916 // First look for forward references | |
3917 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) | |
3918 { | |
3919 if (!td->semanticRun) | |
3920 { | |
3921 if (td->scope) | |
3922 { // Try to fix forward reference | |
3923 td->semantic(td->scope); | |
3924 } | |
3925 if (!td->semanticRun) | |
3926 { | |
3927 error("%s forward references template declaration %s\n", toChars(), td->toChars()); | |
3928 return NULL; | |
3929 } | |
3930 } | |
3931 } | |
3932 | |
3901 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) | 3933 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) |
3902 { | 3934 { |
3903 MATCH m; | 3935 MATCH m; |
3904 | 3936 |
3905 //if (tiargs->dim) printf("2: tiargs->dim = %d, data[0] = %p\n", tiargs->dim, tiargs->data[0]); | 3937 //if (tiargs->dim) printf("2: tiargs->dim = %d, data[0] = %p\n", tiargs->dim, tiargs->data[0]); |
3912 continue; | 3944 continue; |
3913 } | 3945 } |
3914 | 3946 |
3915 dedtypes.setDim(td->parameters->dim); | 3947 dedtypes.setDim(td->parameters->dim); |
3916 dedtypes.zero(); | 3948 dedtypes.zero(); |
3917 if (!td->scope) | 3949 assert(td->semanticRun); |
3918 { | |
3919 error("forward reference to template declaration %s", td->toChars()); | |
3920 return NULL; | |
3921 } | |
3922 m = td->matchWithInstance(this, &dedtypes, 0); | 3950 m = td->matchWithInstance(this, &dedtypes, 0); |
3923 //printf("matchWithInstance = %d\n", m); | 3951 //printf("matchWithInstance = %d\n", m); |
3924 if (!m) // no match at all | 3952 if (!m) // no match at all |
3925 continue; | 3953 continue; |
3926 | 3954 |
4210 /**************************************************** | 4238 /**************************************************** |
4211 * Declare parameters of template instance, initialize them with the | 4239 * Declare parameters of template instance, initialize them with the |
4212 * template instance arguments. | 4240 * template instance arguments. |
4213 */ | 4241 */ |
4214 | 4242 |
4215 void TemplateInstance::declareParameters(Scope *scope) | 4243 void TemplateInstance::declareParameters(Scope *sc) |
4216 { | 4244 { |
4217 //printf("TemplateInstance::declareParameters()\n"); | 4245 //printf("TemplateInstance::declareParameters()\n"); |
4218 for (int i = 0; i < tdtypes.dim; i++) | 4246 for (int i = 0; i < tdtypes.dim; i++) |
4219 { | 4247 { |
4220 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; | 4248 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; |
4221 //Object *o = (Object *)tiargs->data[i]; | 4249 //Object *o = (Object *)tiargs->data[i]; |
4222 Object *o = (Object *)tdtypes.data[i]; // initializer for tp | 4250 Object *o = (Object *)tdtypes.data[i]; // initializer for tp |
4223 | 4251 |
4224 //printf("\ttdtypes[%d] = %p\n", i, o); | 4252 //printf("\ttdtypes[%d] = %p\n", i, o); |
4225 tempdecl->declareParameter(scope, tp, o); | 4253 tempdecl->declareParameter(sc, tp, o); |
4226 } | 4254 } |
4227 } | 4255 } |
4228 | 4256 |
4229 | 4257 |
4230 void TemplateInstance::semantic2(Scope *sc) | 4258 void TemplateInstance::semantic2(Scope *sc) |
4231 { int i; | 4259 { int i; |
4232 | 4260 |
4233 if (semanticdone >= 2) | 4261 if (semanticRun >= 2) |
4234 return; | 4262 return; |
4235 semanticdone = 2; | 4263 semanticRun = 2; |
4236 #if LOG | 4264 #if LOG |
4237 printf("+TemplateInstance::semantic2('%s')\n", toChars()); | 4265 printf("+TemplateInstance::semantic2('%s')\n", toChars()); |
4238 #endif | 4266 #endif |
4239 if (!errors && members) | 4267 if (!errors && members) |
4240 { | 4268 { |
4260 } | 4288 } |
4261 | 4289 |
4262 void TemplateInstance::semantic3(Scope *sc) | 4290 void TemplateInstance::semantic3(Scope *sc) |
4263 { | 4291 { |
4264 #if LOG | 4292 #if LOG |
4265 printf("TemplateInstance::semantic3('%s'), semanticdone = %d\n", toChars(), semanticdone); | 4293 printf("TemplateInstance::semantic3('%s'), semanticRun = %d\n", toChars(), semanticRun); |
4266 #endif | 4294 #endif |
4267 //if (toChars()[0] == 'D') *(char*)0=0; | 4295 //if (toChars()[0] == 'D') *(char*)0=0; |
4268 if (semanticdone >= 3) | 4296 if (semanticRun >= 3) |
4269 return; | 4297 return; |
4270 semanticdone = 3; | 4298 semanticRun = 3; |
4271 if (!errors && members) | 4299 if (!errors && members) |
4272 { | 4300 { |
4273 sc = tempdecl->scope; | 4301 sc = tempdecl->scope; |
4274 sc = sc->push(argsym); | 4302 sc = sc->push(argsym); |
4275 sc = sc->push(this); | 4303 sc = sc->push(this); |
4455 //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : ""); | 4483 //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : ""); |
4456 this->ident = ident; | 4484 this->ident = ident; |
4457 this->tqual = tqual; | 4485 this->tqual = tqual; |
4458 this->idents = idents; | 4486 this->idents = idents; |
4459 this->tiargs = tiargs ? tiargs : new Objects(); | 4487 this->tiargs = tiargs ? tiargs : new Objects(); |
4460 this->scope = NULL; | |
4461 } | 4488 } |
4462 | 4489 |
4463 Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s) | 4490 Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s) |
4464 { TemplateMixin *tm; | 4491 { TemplateMixin *tm; |
4465 | 4492 |
4489 { | 4516 { |
4490 #if LOG | 4517 #if LOG |
4491 printf("+TemplateMixin::semantic('%s', this=%p)\n", toChars(), this); | 4518 printf("+TemplateMixin::semantic('%s', this=%p)\n", toChars(), this); |
4492 fflush(stdout); | 4519 fflush(stdout); |
4493 #endif | 4520 #endif |
4494 if (semanticdone && | 4521 if (semanticRun && |
4495 // This for when a class/struct contains mixin members, and | 4522 // This for when a class/struct contains mixin members, and |
4496 // is done over because of forward references | 4523 // is done over because of forward references |
4497 (!parent || !toParent()->isAggregateDeclaration())) | 4524 (!parent || !toParent()->isAggregateDeclaration())) |
4498 { | 4525 { |
4499 #if LOG | 4526 #if LOG |
4500 printf("\tsemantic done\n"); | 4527 printf("\tsemantic done\n"); |
4501 #endif | 4528 #endif |
4502 return; | 4529 return; |
4503 } | 4530 } |
4504 if (!semanticdone) | 4531 if (!semanticRun) |
4505 semanticdone = 1; | 4532 semanticRun = 1; |
4506 #if LOG | 4533 #if LOG |
4507 printf("\tdo semantic\n"); | 4534 printf("\tdo semantic\n"); |
4508 #endif | 4535 #endif |
4509 | 4536 |
4510 #if !IN_LLVM | 4537 #if !IN_LLVM |
4575 | 4602 |
4576 // Look for forward reference | 4603 // Look for forward reference |
4577 assert(tempdecl); | 4604 assert(tempdecl); |
4578 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) | 4605 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) |
4579 { | 4606 { |
4580 if (!td->scope) | 4607 if (!td->semanticRun) |
4581 { | 4608 { |
4582 /* Cannot handle forward references if mixin is a struct member, | 4609 /* Cannot handle forward references if mixin is a struct member, |
4583 * because addField must happen during struct's semantic, not | 4610 * because addField must happen during struct's semantic, not |
4584 * during the mixin semantic. | 4611 * during the mixin semantic. |
4585 * runDeferred will re-run mixin's semantic outside of the struct's | 4612 * runDeferred will re-run mixin's semantic outside of the struct's |
4586 * semantic. | 4613 * semantic. |
4587 */ | 4614 */ |
4588 semanticdone = 0; | 4615 semanticRun = 0; |
4589 AggregateDeclaration *ad = toParent()->isAggregateDeclaration(); | 4616 AggregateDeclaration *ad = toParent()->isAggregateDeclaration(); |
4590 if (ad) | 4617 if (ad) |
4591 ad->sizeok = 2; | 4618 ad->sizeok = 2; |
4592 else | 4619 else |
4593 { | 4620 { |
4689 scy = sc->push(this); | 4716 scy = sc->push(this); |
4690 scy->parent = this; | 4717 scy->parent = this; |
4691 | 4718 |
4692 argsym = new ScopeDsymbol(); | 4719 argsym = new ScopeDsymbol(); |
4693 argsym->parent = scy->parent; | 4720 argsym->parent = scy->parent; |
4694 Scope *scope = scy->push(argsym); | 4721 Scope *argscope = scy->push(argsym); |
4695 | 4722 |
4696 unsigned errorsave = global.errors; | 4723 unsigned errorsave = global.errors; |
4697 | 4724 |
4698 // Declare each template parameter as an alias for the argument type | 4725 // Declare each template parameter as an alias for the argument type |
4699 declareParameters(scope); | 4726 declareParameters(argscope); |
4700 | 4727 |
4701 // Add members to enclosing scope, as well as this scope | 4728 // Add members to enclosing scope, as well as this scope |
4702 for (unsigned i = 0; i < members->dim; i++) | 4729 for (unsigned i = 0; i < members->dim; i++) |
4703 { Dsymbol *s; | 4730 { Dsymbol *s; |
4704 | 4731 |
4705 s = (Dsymbol *)members->data[i]; | 4732 s = (Dsymbol *)members->data[i]; |
4706 s->addMember(scope, this, i); | 4733 s->addMember(argscope, this, i); |
4707 //sc->insert(s); | 4734 //sc->insert(s); |
4708 //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym); | 4735 //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym); |
4709 //printf("s->parent = %s\n", s->parent->toChars()); | 4736 //printf("s->parent = %s\n", s->parent->toChars()); |
4710 } | 4737 } |
4711 | 4738 |
4712 // Do semantic() analysis on template instance members | 4739 // Do semantic() analysis on template instance members |
4713 #if LOG | 4740 #if LOG |
4714 printf("\tdo semantic() on template instance members '%s'\n", toChars()); | 4741 printf("\tdo semantic() on template instance members '%s'\n", toChars()); |
4715 #endif | 4742 #endif |
4716 Scope *sc2; | 4743 Scope *sc2; |
4717 sc2 = scope->push(this); | 4744 sc2 = argscope->push(this); |
4718 sc2->offset = sc->offset; | 4745 sc2->offset = sc->offset; |
4719 | 4746 |
4720 static int nest; | 4747 static int nest; |
4721 //printf("%d\n", nest); | 4748 //printf("%d\n", nest); |
4722 if (++nest > 500) | 4749 if (++nest > 500) |
4755 error("error instantiating"); | 4782 error("error instantiating"); |
4756 } | 4783 } |
4757 | 4784 |
4758 sc2->pop(); | 4785 sc2->pop(); |
4759 | 4786 |
4760 scope->pop(); | 4787 argscope->pop(); |
4761 | 4788 |
4762 // if (!isAnonymous()) | 4789 // if (!isAnonymous()) |
4763 { | 4790 { |
4764 scy->pop(); | 4791 scy->pop(); |
4765 } | 4792 } |
4769 } | 4796 } |
4770 | 4797 |
4771 void TemplateMixin::semantic2(Scope *sc) | 4798 void TemplateMixin::semantic2(Scope *sc) |
4772 { int i; | 4799 { int i; |
4773 | 4800 |
4774 if (semanticdone >= 2) | 4801 if (semanticRun >= 2) |
4775 return; | 4802 return; |
4776 semanticdone = 2; | 4803 semanticRun = 2; |
4777 #if LOG | 4804 #if LOG |
4778 printf("+TemplateMixin::semantic2('%s')\n", toChars()); | 4805 printf("+TemplateMixin::semantic2('%s')\n", toChars()); |
4779 #endif | 4806 #endif |
4780 if (members) | 4807 if (members) |
4781 { | 4808 { |
4799 } | 4826 } |
4800 | 4827 |
4801 void TemplateMixin::semantic3(Scope *sc) | 4828 void TemplateMixin::semantic3(Scope *sc) |
4802 { int i; | 4829 { int i; |
4803 | 4830 |
4804 if (semanticdone >= 3) | 4831 if (semanticRun >= 3) |
4805 return; | 4832 return; |
4806 semanticdone = 3; | 4833 semanticRun = 3; |
4807 #if LOG | 4834 #if LOG |
4808 printf("TemplateMixin::semantic3('%s')\n", toChars()); | 4835 printf("TemplateMixin::semantic3('%s')\n", toChars()); |
4809 #endif | 4836 #endif |
4810 if (members) | 4837 if (members) |
4811 { | 4838 { |