Mercurial > projects > ldc
comparison dmd/template.c @ 1615:3da302cc4966
Merge DMD r294: bugzilla 2816 Sudden-death static assert is not...
bugzilla 2816 Sudden-death static assert is not very useful.
---
dmd/expression.h | 12 ++++++
dmd/staticassert.c | 10 +---
dmd/template.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++----
dmd/template.h | 2 +
4 files changed, 117 insertions(+), 15 deletions(-)
author | Leandro Lucarella <llucax@gmail.com> |
---|---|
date | Wed, 06 Jan 2010 15:18:21 -0300 |
parents | 4f63d530861f |
children | a87f1d6ff48e |
comparison
equal
deleted
inserted
replaced
1614:dbf7b54f542f | 1615:3da302cc4966 |
---|---|
3495 */ | 3495 */ |
3496 semantic2(sc2); | 3496 semantic2(sc2); |
3497 | 3497 |
3498 if (sc->func || dosemantic3) | 3498 if (sc->func || dosemantic3) |
3499 { | 3499 { |
3500 semantic3(sc2); | 3500 #if WINDOWS_SEH |
3501 __try | |
3502 { | |
3503 #endif | |
3504 static int nest; | |
3505 if (++nest > 300) | |
3506 { | |
3507 global.gag = 0; // ensure error message gets printed | |
3508 error("recursive expansion"); | |
3509 fatal(); | |
3510 } | |
3511 semantic3(sc2); | |
3512 --nest; | |
3513 #if WINDOWS_SEH | |
3514 } | |
3515 __except (__ehfilter(GetExceptionInformation())) | |
3516 { | |
3517 global.gag = 0; // ensure error message gets printed | |
3518 error("recursive expansion"); | |
3519 fatal(); | |
3520 } | |
3521 #endif | |
3501 } | 3522 } |
3502 | 3523 |
3503 Laftersemantic: | 3524 Laftersemantic: |
3504 sc2->pop(); | 3525 sc2->pop(); |
3505 | 3526 |
3507 | 3528 |
3508 // Give additional context info if error occurred during instantiation | 3529 // Give additional context info if error occurred during instantiation |
3509 if (global.errors != errorsave) | 3530 if (global.errors != errorsave) |
3510 { | 3531 { |
3511 error("error instantiating"); | 3532 error("error instantiating"); |
3512 if (tinst && !global.gag) | 3533 if (tinst) |
3513 { tinst->printInstantiationTrace(); | 3534 { tinst->printInstantiationTrace(); |
3514 fatal(); | 3535 fatal(); |
3515 } | 3536 } |
3516 errors = 1; | 3537 errors = 1; |
3517 if (global.gag) | 3538 if (global.gag) |
3670 int i; | 3691 int i; |
3671 | 3692 |
3672 id = name; | 3693 id = name; |
3673 s = sc->search(loc, id, &scopesym); | 3694 s = sc->search(loc, id, &scopesym); |
3674 if (!s) | 3695 if (!s) |
3675 { error("identifier '%s' is not defined", id->toChars()); | 3696 { error("template '%s' is not defined", id->toChars()); |
3676 return NULL; | 3697 return NULL; |
3677 } | 3698 } |
3678 #if LOG | 3699 #if LOG |
3679 printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind()); | 3700 printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind()); |
3680 if (s->parent) | 3701 if (s->parent) |
3976 * the type signature for it. | 3997 * the type signature for it. |
3977 */ | 3998 */ |
3978 | 3999 |
3979 Identifier *TemplateInstance::genIdent() | 4000 Identifier *TemplateInstance::genIdent() |
3980 { OutBuffer buf; | 4001 { OutBuffer buf; |
3981 char *id; | |
3982 Objects *args; | |
3983 | 4002 |
3984 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); | 4003 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); |
3985 id = tempdecl->ident->toChars(); | 4004 char *id = tempdecl->ident->toChars(); |
3986 buf.printf("__T%zu%s", strlen(id), id); | 4005 buf.printf("__T%zu%s", strlen(id), id); |
3987 args = tiargs; | 4006 Objects *args = tiargs; |
3988 for (int i = 0; i < args->dim; i++) | 4007 for (int i = 0; i < args->dim; i++) |
3989 { Object *o = (Object *)args->data[i]; | 4008 { Object *o = (Object *)args->data[i]; |
3990 Type *ta = isType(o); | 4009 Type *ta = isType(o); |
3991 Expression *ea = isExpression(o); | 4010 Expression *ea = isExpression(o); |
3992 Dsymbol *sa = isDsymbol(o); | 4011 Dsymbol *sa = isDsymbol(o); |
3993 Tuple *va = isTuple(o); | 4012 Tuple *va = isTuple(o); |
3994 //printf("\to %p ta %p ea %p sa %p va %p\n", o, ta, ea, sa, va); | 4013 //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va); |
3995 if (ta) | 4014 if (ta) |
3996 { | 4015 { |
3997 buf.writeByte('T'); | 4016 buf.writeByte('T'); |
3998 if (ta->deco) | 4017 if (ta->deco) |
3999 buf.writestring(ta->deco); | 4018 buf.writestring(ta->deco); |
4189 } | 4208 } |
4190 } | 4209 } |
4191 | 4210 |
4192 #if IN_DMD | 4211 #if IN_DMD |
4193 | 4212 |
4213 /************************************** | |
4214 * Given an error instantiating the TemplateInstance, | |
4215 * give the nested TemplateInstance instantiations that got | |
4216 * us here. Those are a list threaded into the nested scopes. | |
4217 */ | |
4194 void TemplateInstance::printInstantiationTrace() | 4218 void TemplateInstance::printInstantiationTrace() |
4195 { | 4219 { |
4196 if (global.gag) | 4220 if (global.gag) |
4197 return; | 4221 return; |
4222 | |
4223 const int max_shown = 6; | |
4224 const char format[] = "%s: instantiated from here: %s\n"; | |
4225 | |
4226 // determine instantiation depth and number of recursive instantiations | |
4227 int n_instantiations = 1; | |
4228 int n_totalrecursions = 0; | |
4229 for (TemplateInstance *cur = this; cur; cur = cur->tinst) | |
4230 { | |
4231 ++n_instantiations; | |
4232 // If two instantiations use the same declaration, they are recursive. | |
4233 // (this works even if they are instantiated from different places in the | |
4234 // same template). | |
4235 // In principle, we could also check for multiple-template recursion, but it's | |
4236 // probably not worthwhile. | |
4237 if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl | |
4238 && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) | |
4239 ++n_totalrecursions; | |
4240 } | |
4241 | |
4242 // show full trace only if it's short or verbose is on | |
4243 if (n_instantiations <= max_shown || global.params.verbose) | |
4244 { | |
4245 for (TemplateInstance *cur = this; cur; cur = cur->tinst) | |
4246 { | |
4247 fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); | |
4248 } | |
4249 } | |
4250 else if (n_instantiations - n_totalrecursions <= max_shown) | |
4251 { | |
4252 // By collapsing recursive instantiations into a single line, | |
4253 // we can stay under the limit. | |
4254 int recursionDepth=0; | |
4255 for (TemplateInstance *cur = this; cur; cur = cur->tinst) | |
4256 { | |
4257 if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl | |
4258 && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) | |
4259 { | |
4260 ++recursionDepth; | |
4261 } | |
4262 else | |
4263 { | |
4264 if (recursionDepth) | |
4265 fprintf(stdmsg, "%s: %d recursive instantiations from here: %s\n", cur->loc.toChars(), recursionDepth+2, cur->toChars()); | |
4266 else | |
4267 fprintf(stdmsg,format, cur->loc.toChars(), cur->toChars()); | |
4268 recursionDepth = 0; | |
4269 } | |
4270 } | |
4271 } | |
4272 else | |
4273 { | |
4274 // Even after collapsing the recursions, the depth is too deep. | |
4275 // Just display the first few and last few instantiations. | |
4276 size_t i = 0; | |
4277 for (TemplateInstance *cur = this; cur; cur = cur->tinst) | |
4278 { | |
4279 if (i == max_shown / 2) | |
4280 fprintf(stdmsg," ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown); | |
4281 | |
4282 if (i < max_shown / 2 || | |
4283 i >= n_instantiations - max_shown + max_shown / 2) | |
4284 fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); | |
4285 ++i; | |
4286 } | |
4287 } | |
4198 } | 4288 } |
4199 | 4289 |
4200 void TemplateInstance::toObjFile(int multiobj) | 4290 void TemplateInstance::toObjFile(int multiobj) |
4201 { | 4291 { |
4202 #if LOG | 4292 #if LOG |
4275 | 4365 |
4276 if (inst != this) | 4366 if (inst != this) |
4277 return inst->toAlias(); | 4367 return inst->toAlias(); |
4278 | 4368 |
4279 if (aliasdecl) | 4369 if (aliasdecl) |
4370 { | |
4280 return aliasdecl->toAlias(); | 4371 return aliasdecl->toAlias(); |
4372 } | |
4281 | 4373 |
4282 return inst; | 4374 return inst; |
4283 } | 4375 } |
4284 | 4376 |
4285 AliasDeclaration *TemplateInstance::isAliasDeclaration() | 4377 AliasDeclaration *TemplateInstance::isAliasDeclaration() |