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()