# HG changeset patch # User Tomas Lindquist Olsen # Date 1220196592 -7200 # Node ID 4b1b0d262c9a5c15431e94af9c9e9319e47a1431 # Parent 394e72cbbb46f8135795fcabe16c96dfc089801f# Parent 1ada9c6865df9d43a3f3781e0cef4c87e5f4cc0b merge diff -r 394e72cbbb46 -r 4b1b0d262c9a dmd/scope.c --- a/dmd/scope.c Fri Aug 29 16:59:12 2008 +0200 +++ b/dmd/scope.c Sun Aug 31 17:29:52 2008 +0200 @@ -54,6 +54,7 @@ this->sw = NULL; this->tf = NULL; this->tfOfTry = NULL; + this->tinst = NULL; this->sbreak = NULL; this->scontinue = NULL; this->fes = NULL; @@ -92,6 +93,7 @@ this->sw = enclosing->sw; this->tf = enclosing->tf; this->tfOfTry = enclosing->tfOfTry; + this->tinst = enclosing->tinst; this->sbreak = enclosing->sbreak; this->scontinue = enclosing->scontinue; this->fes = enclosing->fes; diff -r 394e72cbbb46 -r 4b1b0d262c9a dmd/scope.h --- a/dmd/scope.h Fri Aug 29 16:59:12 2008 +0200 +++ b/dmd/scope.h Sun Aug 31 17:29:52 2008 +0200 @@ -47,6 +47,7 @@ SwitchStatement *sw; // enclosing switch statement TryFinallyStatement *tf; // enclosing try finally statement; set inside its finally block EnclosingHandler *tfOfTry; // enclosing try-finally, volatile or synchronized statement; set inside its try or body block + TemplateInstance *tinst; // enclosing template instance Statement *sbreak; // enclosing statement that supports "break" Statement *scontinue; // enclosing statement that supports "continue" ForeachStatement *fes; // if nested function for ForeachStatement, this is it diff -r 394e72cbbb46 -r 4b1b0d262c9a dmd/staticassert.c --- a/dmd/staticassert.c Fri Aug 29 16:59:12 2008 +0200 +++ b/dmd/staticassert.c Sun Aug 31 17:29:52 2008 +0200 @@ -16,6 +16,8 @@ #include "expression.h" #include "id.h" #include "hdrgen.h" +#include "scope.h" +#include "template.h" /********************************* AttribDeclaration ****************************/ @@ -66,6 +68,8 @@ } else error("is false"); + if(sc->tinst) + sc->tinst->printInstantiationTrace(); if (!global.gag) fatal(); } diff -r 394e72cbbb46 -r 4b1b0d262c9a dmd/template.c --- a/dmd/template.c Fri Aug 29 16:59:12 2008 +0200 +++ b/dmd/template.c Sun Aug 31 17:29:52 2008 +0200 @@ -2775,6 +2775,7 @@ this->havetempdecl = 0; this->isnested = NULL; this->errors = 0; + this->tinst = NULL; } @@ -2798,6 +2799,7 @@ this->havetempdecl = 1; this->isnested = NULL; this->errors = 0; + this->tinst = NULL; assert((size_t)tempdecl->scope > 0x10000); } @@ -2874,6 +2876,9 @@ } semanticdone = 1; + // get the enclosing template instance from the scope tinst + tinst = sc->tinst; + #if LOG printf("\tdo semantic\n"); #endif @@ -3062,6 +3067,7 @@ sc2 = scope->push(this); //printf("isnested = %d, sc->parent = %s\n", isnested, sc->parent->toChars()); sc2->parent = /*isnested ? sc->parent :*/ this; + sc2->tinst = this; #if !IN_LLVM #if _WIN32 @@ -3130,6 +3136,8 @@ if (global.errors != errorsave) { error("error instantiating"); + if(tinst) + tinst->printInstantiationTrace(); errors = 1; if (global.gag) tempdecl->instances.remove(tempdecl_instance_idx); @@ -3687,6 +3695,7 @@ assert(sc); sc = sc->push(argsym); sc = sc->push(this); + sc->tinst = this; for (i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; @@ -3717,6 +3726,7 @@ sc = tempdecl->scope; sc = sc->push(argsym); sc = sc->push(this); + sc->tinst = this; for (int i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; @@ -3837,6 +3847,43 @@ return s; } +void TemplateInstance::printInstantiationTrace() +{ + if(global.gag) + return; + + const int max_shown = 6; + + // determine instantiation depth + int n_instantiations = 1; + TemplateInstance* cur = this; + while(cur = cur->tinst) + ++n_instantiations; + + // show full trace only if it's short or verbose is on + if(n_instantiations <= max_shown || global.params.verbose) + { + cur = this; + while(cur) + { + fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars()); + cur = cur->tinst; + } + } + else + { + cur = this; + size_t i = 0; + for(; i < max_shown/2; ++i, cur = cur->tinst) + fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars()); + fprintf(stdmsg," ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown); + for(; i < n_instantiations - max_shown + max_shown/2; ++i, cur = cur->tinst) + {} + for(; i < n_instantiations; ++i, cur = cur->tinst) + fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars()); + } +} + /* ======================== TemplateMixin ================================ */ TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual, diff -r 394e72cbbb46 -r 4b1b0d262c9a dmd/template.h --- a/dmd/template.h Fri Aug 29 16:59:12 2008 +0200 +++ b/dmd/template.h Sun Aug 31 17:29:52 2008 +0200 @@ -314,6 +314,10 @@ TemplateInstance *isTemplateInstance() { return this; } AliasDeclaration *isAliasDeclaration(); + + // LLVMDC + TemplateInstance *tinst; // enclosing template instance + void printInstantiationTrace(); }; struct TemplateMixin : TemplateInstance