Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 294

Show
Ignore:
Timestamp:
12/15/09 05:53:21 (15 years ago)
Author:
walter
Message:

bugzilla 2816 Sudden-death static assert is not very useful

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/expression.h

    r253 r294  
    12231223 
    12241224    elem *toElem(IRState *irs); 
    12251225}; 
    12261226 
    12271227struct ModExp : BinExp 
    12281228{ 
    12291229    ModExp(Loc loc, Expression *e1, Expression *e2); 
    12301230    Expression *semantic(Scope *sc); 
    12311231    Expression *optimize(int result); 
    12321232    Expression *interpret(InterState *istate); 
    12331233    void buildArrayIdent(OutBuffer *buf, Expressions *arguments); 
    12341234    Expression *buildArrayLoop(Parameters *fparams); 
    12351235 
    12361236    // For operator overloading 
    12371237    Identifier *opId(); 
    12381238    Identifier *opId_r(); 
    12391239 
    12401240    elem *toElem(IRState *irs); 
    12411241}; 
    12421242 
     1243#if DMDV2 
     1244struct PowExp : BinExp 
     1245{ 
     1246    PowExp(Loc loc, Expression *e1, Expression *e2); 
     1247    Expression *semantic(Scope *sc); 
     1248 
     1249    // For operator overloading 
     1250    Identifier *opId(); 
     1251    Identifier *opId_r(); 
     1252}; 
     1253#endif 
     1254 
    12431255struct ShlExp : BinExp 
    12441256{ 
    12451257    ShlExp(Loc loc, Expression *e1, Expression *e2); 
    12461258    Expression *semantic(Scope *sc); 
    12471259    Expression *optimize(int result); 
    12481260    Expression *interpret(InterState *istate); 
    12491261 
    12501262    // For operator overloading 
    12511263    Identifier *opId(); 
    12521264    Identifier *opId_r(); 
    12531265 
    12541266    elem *toElem(IRState *irs); 
    12551267}; 
    12561268 
    12571269struct ShrExp : BinExp 
    12581270{ 
    12591271    ShrExp(Loc loc, Expression *e1, Expression *e2); 
    12601272    Expression *semantic(Scope *sc); 
    12611273    Expression *optimize(int result); 
    12621274    Expression *interpret(InterState *istate); 
  • branches/dmd-1.x/src/staticassert.c

    r189 r294  
    11 
    22// Copyright (c) 1999-2007 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010#include <stdio.h> 
    1111#include <string.h> 
    1212#include <assert.h> 
    1313 
    1414#include "dsymbol.h" 
    1515#include "staticassert.h" 
    1616#include "expression.h" 
    1717#include "id.h" 
    1818#include "hdrgen.h" 
    1919#include "scope.h" 
    2020#include "template.h" 
     21#include "declaration.h" 
    2122 
    2223 
    2324/********************************* AttribDeclaration ****************************/ 
    2425 
    2526StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg) 
    2627    : Dsymbol(Id::empty) 
    2728{ 
    2829    this->loc = loc; 
    2930    this->exp = exp; 
    3031    this->msg = msg; 
    3132} 
    3233 
    3334Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s) 
    3435{ 
    3536    StaticAssert *sa; 
    3637 
    3738    assert(!s); 
    3839    sa = new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL); 
    3940    return sa; 
    4041} 
    4142 
    4243int StaticAssert::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) 
    4344{ 
    4445    return 0;       // we didn't add anything 
    4546} 
    4647 
    4748void StaticAssert::semantic(Scope *sc) 
    4849{ 
    4950} 
    5051 
    51 #include "scope.h" 
    52 #include "template.h" 
    53 #include "declaration.h" 
    54  
    5552void StaticAssert::semantic2(Scope *sc) 
    5653{ 
    5754    Expression *e; 
    5855 
    5956    //printf("StaticAssert::semantic2() %s\n", toChars()); 
    6057    e = exp->semantic(sc); 
    6158    e = e->optimize(WANTvalue | WANTinterpret); 
    6259    if (e->isBool(FALSE)) 
    6360    { 
    6461    if (msg) 
    6562    {   HdrGenState hgs; 
    6663        OutBuffer buf; 
    6764 
    6865        msg = msg->semantic(sc); 
    6966        msg = msg->optimize(WANTvalue | WANTinterpret); 
    7067        hgs.console = 1; 
    7168        msg->toCBuffer(&buf, &hgs); 
    7269        error("%s", buf.toChars()); 
    7370    } 
    7471    else 
    7572        error("(%s) is false", exp->toChars()); 
    76        if(sc->tinst) 
     73    if (sc->tinst) 
    7774        sc->tinst->printInstantiationTrace(); 
    78       if (!global.gag) { 
     75    if (!global.gag) 
    7976          fatal(); 
    80       } 
    8177    } 
    8278    else if (!e->isBool(TRUE)) 
    8379    { 
    8480    error("(%s) is not evaluatable at compile time", exp->toChars()); 
    8581    } 
    8682} 
    8783 
    8884int StaticAssert::oneMember(Dsymbol **ps) 
    8985{ 
    9086    //printf("StaticAssert::oneMember())\n"); 
    9187    *ps = NULL; 
    9288    return TRUE; 
    9389} 
    9490 
    9591void StaticAssert::inlineScan() 
    9692{ 
    9793} 
    9894 
    9995void StaticAssert::toObjFile(int multiobj) 
    10096{ 
  • branches/dmd-1.x/src/template.c

    r276 r294  
    34383438    {   Dsymbol *sd = (Dsymbol *)Module::deferred.data[i]; 
    34393439 
    34403440    if (sd->parent == this) 
    34413441        goto Laftersemantic; 
    34423442    } 
    34433443 
    34443444    /* The problem is when to parse the initializer for a variable. 
    34453445     * Perhaps VarDeclaration::semantic() should do it like it does 
    34463446     * for initializers inside a function. 
    34473447     */ 
    34483448//    if (sc->parent->isFuncDeclaration()) 
    34493449 
    34503450    /* BUG 782: this has problems if the classes this depends on 
    34513451     * are forward referenced. Find a way to defer semantic() 
    34523452     * on this template. 
    34533453     */ 
    34543454    semantic2(sc2); 
    34553455 
    34563456    if (sc->func || dosemantic3) 
    34573457    { 
    3458     semantic3(sc2); 
     3458#if WINDOWS_SEH 
     3459    __try 
     3460    { 
     3461#endif 
     3462        static int nest; 
     3463        if (++nest > 300) 
     3464        { 
     3465        global.gag = 0;            // ensure error message gets printed 
     3466        error("recursive expansion"); 
     3467        fatal(); 
     3468        } 
     3469        semantic3(sc2); 
     3470        --nest; 
     3471#if WINDOWS_SEH 
     3472    } 
     3473    __except (__ehfilter(GetExceptionInformation())) 
     3474    { 
     3475        global.gag = 0;            // ensure error message gets printed 
     3476        error("recursive expansion"); 
     3477        fatal(); 
     3478    } 
     3479#endif 
    34593480    } 
    34603481 
    34613482  Laftersemantic: 
    34623483    sc2->pop(); 
    34633484 
    34643485    scope->pop(); 
    34653486 
    34663487    // Give additional context info if error occurred during instantiation 
    34673488    if (global.errors != errorsave) 
    34683489    { 
    34693490    error("error instantiating"); 
    3470     if (tinst && !global.gag
     3491    if (tinst
    34713492    {   tinst->printInstantiationTrace(); 
    34723493        fatal(); 
    34733494    } 
    34743495    errors = 1; 
    34753496    if (global.gag) 
    34763497        tempdecl->instances.remove(tempdecl_instance_idx); 
    34773498    } 
    34783499 
    34793500#if LOG 
    34803501    printf("-TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); 
    34813502#endif 
    34823503} 
    34833504 
    34843505 
    34853506void TemplateInstance::semanticTiargs(Scope *sc) 
    34863507{ 
    34873508    //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); 
    34883509    if (semantictiargsdone) 
    34893510    return; 
    34903511    semantictiargsdone = 1; 
     
    36133634 * Find template declaration corresponding to template instance. 
    36143635 */ 
    36153636 
    36163637TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc) 
    36173638{ 
    36183639    //printf("TemplateInstance::findTemplateDeclaration() %s\n", toChars()); 
    36193640    if (!tempdecl) 
    36203641    { 
    36213642    /* Given: 
    36223643     *    foo!( ... ) 
    36233644     * figure out which TemplateDeclaration foo refers to. 
    36243645     */ 
    36253646    Dsymbol *s; 
    36263647    Dsymbol *scopesym; 
    36273648    Identifier *id; 
    36283649    int i; 
    36293650 
    36303651    id = name; 
    36313652    s = sc->search(loc, id, &scopesym); 
    36323653    if (!s) 
    3633     {   error("identifier '%s' is not defined", id->toChars()); 
     3654    {   error("template '%s' is not defined", id->toChars()); 
    36343655        return NULL; 
    36353656    } 
    36363657#if LOG 
    36373658    printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind()); 
    36383659    if (s->parent) 
    36393660        printf("s->parent = '%s'\n", s->parent->toChars()); 
    36403661#endif 
    36413662    withsym = scopesym->isWithScopeSymbol(); 
    36423663 
    36433664    /* We might have found an alias within a template when 
    36443665     * we really want the template. 
    36453666     */ 
    36463667    TemplateInstance *ti; 
    36473668    if (s->parent && 
    36483669        (ti = s->parent->isTemplateInstance()) != NULL) 
    36493670    { 
    36503671        if ( 
    36513672        (ti->name == id || 
    36523673         ti->toAlias()->ident == id) 
    36533674        && 
     
    39193940        else 
    39203941            error("cannot use local '%s' as parameter to non-global template %s", d->toChars(), tempdecl->toChars()); 
    39213942        } 
    39223943    } 
    39233944    else if (va) 
    39243945    { 
    39253946        nested |= hasNestedArgs(&va->objects); 
    39263947    } 
    39273948    } 
    39283949    return nested; 
    39293950} 
    39303951 
    39313952/**************************************** 
    39323953 * This instance needs an identifier for name mangling purposes. 
    39333954 * Create one by taking the template declaration name and adding 
    39343955 * the type signature for it. 
    39353956 */ 
    39363957 
    39373958Identifier *TemplateInstance::genIdent() 
    39383959{   OutBuffer buf; 
    3939     char *id; 
    3940     Objects *args; 
    39413960 
    39423961    //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); 
    3943     id = tempdecl->ident->toChars(); 
     3962    char *id = tempdecl->ident->toChars(); 
    39443963    buf.printf("__T%zu%s", strlen(id), id); 
    3945     args = tiargs; 
     3964    Objects *args = tiargs; 
    39463965    for (int i = 0; i < args->dim; i++) 
    39473966    {   Object *o = (Object *)args->data[i]; 
    39483967    Type *ta = isType(o); 
    39493968    Expression *ea = isExpression(o); 
    39503969    Dsymbol *sa = isDsymbol(o); 
    39513970    Tuple *va = isTuple(o); 
    3952     //printf("\to %p ta %p ea %p sa %p va %p\n", o, ta, ea, sa, va); 
     3971    //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va); 
    39533972    if (ta) 
    39543973    { 
    39553974        buf.writeByte('T'); 
    39563975        if (ta->deco) 
    39573976        buf.writestring(ta->deco); 
    39583977        else 
    39593978        { 
    39603979#ifdef DEBUG 
    39613980        printf("ta = %d, %s\n", ta->ty, ta->toChars()); 
    39623981#endif 
    39633982        assert(global.errors); 
    39643983        } 
    39653984    } 
    39663985    else if (ea) 
    39673986    {   sinteger_t v; 
    39683987        real_t r; 
    39693988 
    39703989        ea = ea->optimize(WANTvalue | WANTinterpret); 
    39713990        if (ea->op == TOKvar) 
    39723991        { 
     
    41304149//if (toChars()[0] == 'D') *(char*)0=0; 
    41314150    if (semanticRun >= 3) 
    41324151    return; 
    41334152    semanticRun = 3; 
    41344153    if (!errors && members) 
    41354154    { 
    41364155    sc = tempdecl->scope; 
    41374156    sc = sc->push(argsym); 
    41384157    sc = sc->push(this); 
    41394158    sc->tinst = this; 
    41404159    for (int i = 0; i < members->dim; i++) 
    41414160    { 
    41424161        Dsymbol *s = (Dsymbol *)members->data[i]; 
    41434162        s->semantic3(sc); 
    41444163    } 
    41454164    sc = sc->pop(); 
    41464165    sc->pop(); 
    41474166    } 
    41484167} 
    41494168 
     4169/************************************** 
     4170 * Given an error instantiating the TemplateInstance, 
     4171 * give the nested TemplateInstance instantiations that got 
     4172 * us here. Those are a list threaded into the nested scopes. 
     4173 */ 
    41504174void TemplateInstance::printInstantiationTrace() 
    41514175{ 
    41524176    if (global.gag) 
    41534177    return; 
     4178 
     4179    const int max_shown = 6; 
     4180    const char format[] = "%s:        instantiated from here: %s\n"; 
     4181 
     4182    // determine instantiation depth and number of recursive instantiations 
     4183    int n_instantiations = 1; 
     4184    int n_totalrecursions = 0; 
     4185    for (TemplateInstance *cur = this; cur; cur = cur->tinst) 
     4186    { 
     4187    ++n_instantiations; 
     4188    // If two instantiations use the same declaration, they are recursive. 
     4189    // (this works even if they are instantiated from different places in the 
     4190    // same template). 
     4191    // In principle, we could also check for multiple-template recursion, but it's 
     4192    // probably not worthwhile. 
     4193    if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl 
     4194        && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) 
     4195        ++n_totalrecursions; 
     4196    } 
     4197 
     4198    // show full trace only if it's short or verbose is on 
     4199    if (n_instantiations <= max_shown || global.params.verbose) 
     4200    { 
     4201    for (TemplateInstance *cur = this; cur; cur = cur->tinst) 
     4202    { 
     4203        fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); 
     4204    } 
     4205    } 
     4206    else if (n_instantiations - n_totalrecursions <= max_shown) 
     4207    { 
     4208    // By collapsing recursive instantiations into a single line, 
     4209    // we can stay under the limit. 
     4210    int recursionDepth=0; 
     4211    for (TemplateInstance *cur = this; cur; cur = cur->tinst) 
     4212    { 
     4213        if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl 
     4214            && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) 
     4215        { 
     4216        ++recursionDepth; 
     4217        } 
     4218        else 
     4219        { 
     4220        if (recursionDepth) 
     4221            fprintf(stdmsg, "%s:        %d recursive instantiations from here: %s\n", cur->loc.toChars(), recursionDepth+2, cur->toChars()); 
     4222        else  
     4223            fprintf(stdmsg,format, cur->loc.toChars(), cur->toChars()); 
     4224        recursionDepth = 0; 
     4225        } 
     4226    } 
     4227    } 
     4228    else 
     4229    { 
     4230    // Even after collapsing the recursions, the depth is too deep. 
     4231    // Just display the first few and last few instantiations. 
     4232    size_t i = 0; 
     4233    for (TemplateInstance *cur = this; cur; cur = cur->tinst) 
     4234    { 
     4235        if (i == max_shown / 2) 
     4236        fprintf(stdmsg,"    ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown); 
     4237 
     4238        if (i < max_shown / 2 || 
     4239        i >= n_instantiations - max_shown + max_shown / 2) 
     4240        fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); 
     4241        ++i; 
     4242    } 
     4243    } 
    41544244} 
    41554245 
    41564246void TemplateInstance::toObjFile(int multiobj) 
    41574247{ 
    41584248#if LOG 
    41594249    printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this); 
    41604250#endif 
    41614251    if (!errors && members) 
    41624252    { 
    41634253    if (multiobj) 
    41644254        // Append to list of object files to be written later 
    41654255        obj_append(this); 
    41664256    else 
    41674257    { 
    41684258        for (int i = 0; i < members->dim; i++) 
    41694259        { 
    41704260        Dsymbol *s = (Dsymbol *)members->data[i]; 
    41714261        s->toObjFile(multiobj); 
    41724262        } 
    41734263    } 
     
    42134303    } 
    42144304    buf->writeByte(')'); 
    42154305} 
    42164306 
    42174307 
    42184308Dsymbol *TemplateInstance::toAlias() 
    42194309{ 
    42204310#if LOG 
    42214311    printf("TemplateInstance::toAlias()\n"); 
    42224312#endif 
    42234313    if (!inst) 
    42244314    {   error("cannot resolve forward reference"); 
    42254315    errors = 1; 
    42264316    return this; 
    42274317    } 
    42284318 
    42294319    if (inst != this) 
    42304320    return inst->toAlias(); 
    42314321 
    42324322    if (aliasdecl) 
     4323    { 
    42334324    return aliasdecl->toAlias(); 
     4325    } 
    42344326 
    42354327    return inst; 
    42364328} 
    42374329 
    42384330AliasDeclaration *TemplateInstance::isAliasDeclaration() 
    42394331{ 
    42404332    return aliasdecl; 
    42414333} 
    42424334 
    42434335const char *TemplateInstance::kind() 
    42444336{ 
    42454337    return "template instance"; 
    42464338} 
    42474339 
    42484340int TemplateInstance::oneMember(Dsymbol **ps) 
    42494341{ 
    42504342    *ps = NULL; 
    42514343    return TRUE; 
    42524344} 
    42534345 
  • branches/dmd-1.x/src/template.h

    r274 r294  
    6868    int overloadInsert(Dsymbol *s); 
    6969    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    7070    const char *kind(); 
    7171    char *toChars(); 
    7272 
    7373    void emitComment(Scope *sc); 
    7474    void toJsonBuffer(OutBuffer *buf); 
    7575//    void toDocBuffer(OutBuffer *buf); 
    7676 
    7777    MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag); 
    7878    MATCH leastAsSpecialized(TemplateDeclaration *td2); 
    7979 
    8080    MATCH deduceFunctionTemplateMatch(Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, Objects *dedargs); 
    8181    FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, int flags = 0); 
    8282    void declareParameter(Scope *sc, TemplateParameter *tp, Object *o); 
    8383 
    8484    TemplateDeclaration *isTemplateDeclaration() { return this; } 
    8585 
    8686    TemplateTupleParameter *isVariadic(); 
    8787    int isOverloadable(); 
     88 
     89    void makeParamNamesVisibleInConstraint(Scope *paramscope); 
    8890}; 
    8991 
    9092struct TemplateParameter 
    9193{ 
    9294    /* For type-parameter: 
    9395     *  template Foo(ident)     // specType is set to NULL 
    9496     *  template Foo(ident : specType) 
    9597     * For value-parameter: 
    9698     *  template Foo(valType ident) // specValue is set to NULL 
    9799     *  template Foo(valType ident : specValue) 
    98100     * For alias-parameter: 
    99101     *  template Foo(alias ident) 
    100102     * For this-parameter: 
    101103     *  template Foo(this ident) 
    102104     */ 
    103105 
    104106    Loc loc; 
    105107    Identifier *ident; 
    106108 
    107109    Declaration *sparam; 
  • trunk/src/staticassert.c

    r189 r294  
    11 
    22// Copyright (c) 1999-2007 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010#include <stdio.h> 
    1111#include <string.h> 
    1212#include <assert.h> 
    1313 
    1414#include "dsymbol.h" 
    1515#include "staticassert.h" 
    1616#include "expression.h" 
    1717#include "id.h" 
    1818#include "hdrgen.h" 
    1919#include "scope.h" 
    2020#include "template.h" 
     21#include "declaration.h" 
    2122 
    2223 
    2324/********************************* AttribDeclaration ****************************/ 
    2425 
    2526StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg) 
    2627    : Dsymbol(Id::empty) 
    2728{ 
    2829    this->loc = loc; 
    2930    this->exp = exp; 
    3031    this->msg = msg; 
    3132} 
    3233 
    3334Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s) 
    3435{ 
    3536    StaticAssert *sa; 
    3637 
    3738    assert(!s); 
    3839    sa = new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL); 
    3940    return sa; 
    4041} 
    4142 
    4243int StaticAssert::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) 
    4344{ 
    4445    return 0;       // we didn't add anything 
    4546} 
    4647 
    4748void StaticAssert::semantic(Scope *sc) 
    4849{ 
    4950} 
    5051 
    51 #include "scope.h" 
    52 #include "template.h" 
    53 #include "declaration.h" 
    54  
    5552void StaticAssert::semantic2(Scope *sc) 
    5653{ 
    5754    Expression *e; 
    5855 
    5956    //printf("StaticAssert::semantic2() %s\n", toChars()); 
    6057    e = exp->semantic(sc); 
    6158    e = e->optimize(WANTvalue | WANTinterpret); 
    6259    if (e->isBool(FALSE)) 
    6360    { 
    6461    if (msg) 
    6562    {   HdrGenState hgs; 
    6663        OutBuffer buf; 
    6764 
    6865        msg = msg->semantic(sc); 
    6966        msg = msg->optimize(WANTvalue | WANTinterpret); 
    7067        hgs.console = 1; 
    7168        msg->toCBuffer(&buf, &hgs); 
    7269        error("%s", buf.toChars()); 
    7370    } 
    7471    else 
    7572        error("(%s) is false", exp->toChars()); 
    76        if(sc->tinst) 
     73    if (sc->tinst) 
    7774        sc->tinst->printInstantiationTrace(); 
    78       if (!global.gag) { 
     75    if (!global.gag) 
    7976          fatal(); 
    80       } 
    8177    } 
    8278    else if (!e->isBool(TRUE)) 
    8379    { 
    8480    error("(%s) is not evaluatable at compile time", exp->toChars()); 
    8581    } 
    8682} 
    8783 
    8884int StaticAssert::oneMember(Dsymbol **ps) 
    8985{ 
    9086    //printf("StaticAssert::oneMember())\n"); 
    9187    *ps = NULL; 
    9288    return TRUE; 
    9389} 
    9490 
    9591void StaticAssert::inlineScan() 
    9692{ 
    9793} 
    9894 
    9995void StaticAssert::toObjFile(int multiobj) 
    10096{ 
  • trunk/src/template.c

    r287 r294  
    37343734#if WINDOWS_SEH 
    37353735    } 
    37363736    __except (__ehfilter(GetExceptionInformation())) 
    37373737    { 
    37383738        global.gag = 0;            // ensure error message gets printed 
    37393739        error("recursive expansion"); 
    37403740        fatal(); 
    37413741    } 
    37423742#endif 
    37433743    } 
    37443744 
    37453745  Laftersemantic: 
    37463746    sc2->pop(); 
    37473747 
    37483748    scope->pop(); 
    37493749 
    37503750    // Give additional context info if error occurred during instantiation 
    37513751    if (global.errors != errorsave) 
    37523752    { 
    37533753    error("error instantiating"); 
    3754     if (tinst && !global.gag
     3754    if (tinst
    37553755    {   tinst->printInstantiationTrace(); 
    37563756        fatal(); 
    37573757    } 
    37583758    errors = 1; 
    37593759    if (global.gag) 
    37603760        tempdecl->instances.remove(tempdecl_instance_idx); 
    37613761    } 
    37623762 
    37633763#if LOG 
    37643764    printf("-TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); 
    37653765#endif 
    37663766} 
    37673767 
    37683768 
    37693769void TemplateInstance::semanticTiargs(Scope *sc) 
    37703770{ 
    37713771    //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); 
    37723772    if (semantictiargsdone) 
    37733773    return; 
    37743774    semantictiargsdone = 1; 
     
    44574457//if (toChars()[0] == 'D') *(char*)0=0; 
    44584458    if (semanticRun >= 3) 
    44594459    return; 
    44604460    semanticRun = 3; 
    44614461    if (!errors && members) 
    44624462    { 
    44634463    sc = tempdecl->scope; 
    44644464    sc = sc->push(argsym); 
    44654465    sc = sc->push(this); 
    44664466    sc->tinst = this; 
    44674467    for (int i = 0; i < members->dim; i++) 
    44684468    { 
    44694469        Dsymbol *s = (Dsymbol *)members->data[i]; 
    44704470        s->semantic3(sc); 
    44714471    } 
    44724472    sc = sc->pop(); 
    44734473    sc->pop(); 
    44744474    } 
    44754475} 
    44764476 
     4477/************************************** 
     4478 * Given an error instantiating the TemplateInstance, 
     4479 * give the nested TemplateInstance instantiations that got 
     4480 * us here. Those are a list threaded into the nested scopes. 
     4481 */ 
    44774482void TemplateInstance::printInstantiationTrace() 
    44784483{ 
    44794484    if (global.gag) 
    44804485    return; 
     4486 
     4487    const int max_shown = 6; 
     4488    const char format[] = "%s:        instantiated from here: %s\n"; 
     4489 
     4490    // determine instantiation depth and number of recursive instantiations 
     4491    int n_instantiations = 1; 
     4492    int n_totalrecursions = 0; 
     4493    for (TemplateInstance *cur = this; cur; cur = cur->tinst) 
     4494    { 
     4495    ++n_instantiations; 
     4496    // If two instantiations use the same declaration, they are recursive. 
     4497    // (this works even if they are instantiated from different places in the 
     4498    // same template). 
     4499    // In principle, we could also check for multiple-template recursion, but it's 
     4500    // probably not worthwhile. 
     4501    if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl 
     4502        && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) 
     4503        ++n_totalrecursions; 
     4504    } 
     4505 
     4506    // show full trace only if it's short or verbose is on 
     4507    if (n_instantiations <= max_shown || global.params.verbose) 
     4508    { 
     4509    for (TemplateInstance *cur = this; cur; cur = cur->tinst) 
     4510    { 
     4511        fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); 
     4512    } 
     4513    } 
     4514    else if (n_instantiations - n_totalrecursions <= max_shown) 
     4515    { 
     4516    // By collapsing recursive instantiations into a single line, 
     4517    // we can stay under the limit. 
     4518    int recursionDepth=0; 
     4519    for (TemplateInstance *cur = this; cur; cur = cur->tinst) 
     4520    { 
     4521        if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl 
     4522            && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) 
     4523        { 
     4524        ++recursionDepth; 
     4525        } 
     4526        else 
     4527        { 
     4528        if (recursionDepth) 
     4529            fprintf(stdmsg, "%s:        %d recursive instantiations from here: %s\n", cur->loc.toChars(), recursionDepth+2, cur->toChars()); 
     4530        else  
     4531            fprintf(stdmsg,format, cur->loc.toChars(), cur->toChars()); 
     4532        recursionDepth = 0; 
     4533        } 
     4534    } 
     4535    } 
     4536    else 
     4537    { 
     4538    // Even after collapsing the recursions, the depth is too deep. 
     4539    // Just display the first few and last few instantiations. 
     4540    size_t i = 0; 
     4541    for (TemplateInstance *cur = this; cur; cur = cur->tinst) 
     4542    { 
     4543        if (i == max_shown / 2) 
     4544        fprintf(stdmsg,"    ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown); 
     4545 
     4546        if (i < max_shown / 2 || 
     4547        i >= n_instantiations - max_shown + max_shown / 2) 
     4548        fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); 
     4549        ++i; 
     4550    } 
     4551    } 
    44814552} 
    44824553 
    44834554void TemplateInstance::toObjFile(int multiobj) 
    44844555{ 
    44854556#if LOG 
    44864557    printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this); 
    44874558#endif 
    44884559    if (!errors && members) 
    44894560    { 
    44904561    if (multiobj) 
    44914562        // Append to list of object files to be written later 
    44924563        obj_append(this); 
    44934564    else 
    44944565    { 
    44954566        for (int i = 0; i < members->dim; i++) 
    44964567        { 
    44974568        Dsymbol *s = (Dsymbol *)members->data[i]; 
    44984569        s->toObjFile(multiobj); 
    44994570        } 
    45004571    }