comparison dmd/template.c @ 561:d4e95db0e62b

Introducing template instantiation traces for static asserts and errors within templates.
author Christian Kamm <kamm incasoftware de>
date Sat, 30 Aug 2008 10:30:57 +0200
parents cecfee2d01a8
children eef8ac26c66c
comparison
equal deleted inserted replaced
559:5d6ef6e6805d 561:d4e95db0e62b
2773 this->withsym = NULL; 2773 this->withsym = NULL;
2774 this->nest = 0; 2774 this->nest = 0;
2775 this->havetempdecl = 0; 2775 this->havetempdecl = 0;
2776 this->isnested = NULL; 2776 this->isnested = NULL;
2777 this->errors = 0; 2777 this->errors = 0;
2778 this->tinst = NULL;
2778 } 2779 }
2779 2780
2780 2781
2781 TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs) 2782 TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs)
2782 : ScopeDsymbol(NULL) 2783 : ScopeDsymbol(NULL)
2796 this->withsym = NULL; 2797 this->withsym = NULL;
2797 this->nest = 0; 2798 this->nest = 0;
2798 this->havetempdecl = 1; 2799 this->havetempdecl = 1;
2799 this->isnested = NULL; 2800 this->isnested = NULL;
2800 this->errors = 0; 2801 this->errors = 0;
2802 this->tinst = NULL;
2801 2803
2802 assert((size_t)tempdecl->scope > 0x10000); 2804 assert((size_t)tempdecl->scope > 0x10000);
2803 } 2805 }
2804 2806
2805 2807
2872 // inst = this; 2874 // inst = this;
2873 return; 2875 return;
2874 } 2876 }
2875 semanticdone = 1; 2877 semanticdone = 1;
2876 2878
2879 // get the enclosing template instance from the scope tinst
2880 tinst = sc->tinst;
2881
2877 #if LOG 2882 #if LOG
2878 printf("\tdo semantic\n"); 2883 printf("\tdo semantic\n");
2879 #endif 2884 #endif
2880 if (havetempdecl) 2885 if (havetempdecl)
2881 { 2886 {
3060 #endif 3065 #endif
3061 Scope *sc2; 3066 Scope *sc2;
3062 sc2 = scope->push(this); 3067 sc2 = scope->push(this);
3063 //printf("isnested = %d, sc->parent = %s\n", isnested, sc->parent->toChars()); 3068 //printf("isnested = %d, sc->parent = %s\n", isnested, sc->parent->toChars());
3064 sc2->parent = /*isnested ? sc->parent :*/ this; 3069 sc2->parent = /*isnested ? sc->parent :*/ this;
3070 sc2->tinst = this;
3065 3071
3066 #if !IN_LLVM 3072 #if !IN_LLVM
3067 #if _WIN32 3073 #if _WIN32
3068 __try 3074 __try
3069 { 3075 {
3128 3134
3129 // Give additional context info if error occurred during instantiation 3135 // Give additional context info if error occurred during instantiation
3130 if (global.errors != errorsave) 3136 if (global.errors != errorsave)
3131 { 3137 {
3132 error("error instantiating"); 3138 error("error instantiating");
3139 if(tinst)
3140 tinst->printInstantiationTrace();
3133 errors = 1; 3141 errors = 1;
3134 if (global.gag) 3142 if (global.gag)
3135 tempdecl->instances.remove(tempdecl_instance_idx); 3143 tempdecl->instances.remove(tempdecl_instance_idx);
3136 } 3144 }
3137 3145
3685 { 3693 {
3686 sc = tempdecl->scope; 3694 sc = tempdecl->scope;
3687 assert(sc); 3695 assert(sc);
3688 sc = sc->push(argsym); 3696 sc = sc->push(argsym);
3689 sc = sc->push(this); 3697 sc = sc->push(this);
3698 sc->tinst = this;
3690 for (i = 0; i < members->dim; i++) 3699 for (i = 0; i < members->dim; i++)
3691 { 3700 {
3692 Dsymbol *s = (Dsymbol *)members->data[i]; 3701 Dsymbol *s = (Dsymbol *)members->data[i];
3693 #if LOG 3702 #if LOG
3694 printf("\tmember '%s', kind = '%s'\n", s->toChars(), s->kind()); 3703 printf("\tmember '%s', kind = '%s'\n", s->toChars(), s->kind());
3715 if (!errors && members) 3724 if (!errors && members)
3716 { 3725 {
3717 sc = tempdecl->scope; 3726 sc = tempdecl->scope;
3718 sc = sc->push(argsym); 3727 sc = sc->push(argsym);
3719 sc = sc->push(this); 3728 sc = sc->push(this);
3729 sc->tinst = this;
3720 for (int i = 0; i < members->dim; i++) 3730 for (int i = 0; i < members->dim; i++)
3721 { 3731 {
3722 Dsymbol *s = (Dsymbol *)members->data[i]; 3732 Dsymbol *s = (Dsymbol *)members->data[i];
3723 s->semantic3(sc); 3733 s->semantic3(sc);
3724 } 3734 }
3833 3843
3834 toCBuffer(&buf, &hgs); 3844 toCBuffer(&buf, &hgs);
3835 s = buf.toChars(); 3845 s = buf.toChars();
3836 buf.data = NULL; 3846 buf.data = NULL;
3837 return s; 3847 return s;
3848 }
3849
3850 void TemplateInstance::printInstantiationTrace()
3851 {
3852 if(global.gag)
3853 return;
3854
3855 const int max_shown = 6;
3856
3857 // determine instantiation depth
3858 int n_instantiations = 1;
3859 TemplateInstance* cur = this;
3860 while(cur = cur->tinst)
3861 ++n_instantiations;
3862
3863 // show full trace only if it's short or verbose is on
3864 if(n_instantiations <= max_shown || global.params.verbose)
3865 {
3866 cur = this;
3867 while(cur)
3868 {
3869 fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars());
3870 cur = cur->tinst;
3871 }
3872 }
3873 else
3874 {
3875 cur = this;
3876 size_t i = 0;
3877 for(; i < max_shown/2; ++i, cur = cur->tinst)
3878 fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars());
3879 fprintf(stdmsg," ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown);
3880 for(; i < n_instantiations - max_shown + max_shown/2; ++i, cur = cur->tinst)
3881 {}
3882 for(; i < n_instantiations; ++i, cur = cur->tinst)
3883 fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars());
3884 }
3838 } 3885 }
3839 3886
3840 /* ======================== TemplateMixin ================================ */ 3887 /* ======================== TemplateMixin ================================ */
3841 3888
3842 TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual, 3889 TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual,