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 {