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

Changeset 801

Show
Ignore:
Timestamp:
12/12/10 08:43:49 (14 years ago)
Author:
walter
Message:

improve template arg match

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/template.c

    r784 r801  
    196196    } 
    197197    else if (e1) 
    198198    { 
    199199#if 0 
    200200        if (e1 && e2) 
    201201        { 
    202202            printf("match %d\n", e1->equals(e2)); 
    203203            e1->print(); 
    204204            e2->print(); 
    205205            e1->type->print(); 
    206206            e2->type->print(); 
    207207        } 
    208208#endif 
    209209        if (!e2) 
    210210            goto Lnomatch; 
    211211        if (!e1->equals(e2)) 
    212212            goto Lnomatch; 
    213213    } 
    214214    else if (s1) 
    215215    { 
    216         //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars()); 
    217         if (!s2 || !s1->equals(s2) || s1->parent != s2->parent
     216        //printf("%p %s %s, %p %s %s\n", s1, s1->kind(), s1->toChars(), s2, s2->kind(), s2->toChars()); 
     217        if (!s2
    218218        { 
    219219            goto Lnomatch; 
    220220        } 
     221        if (!s1->equals(s2)) 
     222        { 
    221223#if DMDV2 
    222         VarDeclaration *v1 = s1->isVarDeclaration(); 
    223         VarDeclaration *v2 = s2->isVarDeclaration(); 
    224         if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) 
    225         {   ExpInitializer *ei1 = v1->init->isExpInitializer(); 
    226             ExpInitializer *ei2 = v2->init->isExpInitializer(); 
    227             if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) 
     224            VarDeclaration *v1 = s1->isVarDeclaration(); 
     225            VarDeclaration *v2 = s2->isVarDeclaration(); 
     226            if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) 
     227            {   ExpInitializer *ei1 = v1->init->isExpInitializer(); 
     228                ExpInitializer *ei2 = v2->init->isExpInitializer(); 
     229                if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) 
     230                    goto Lnomatch; 
     231                goto Lmatch; 
     232            } 
     233            else 
     234#endif 
    228235                goto Lnomatch; 
    229236        } 
    230 #endif 
     237        if (s1->parent != s2->parent) 
     238        { 
     239            goto Lnomatch; 
     240        } 
    231241    } 
    232242    else if (v1) 
    233243    { 
    234244        if (!v2) 
    235245            goto Lnomatch; 
    236246        if (v1->objects.dim != v2->objects.dim) 
    237247            goto Lnomatch; 
    238248        for (size_t i = 0; i < v1->objects.dim; i++) 
    239249        { 
    240250            if (!match((Object *)v1->objects.data[i], 
    241251                       (Object *)v2->objects.data[i], 
    242252                       tempdecl, sc)) 
    243253                goto Lnomatch; 
    244254        } 
    245255    } 
     256Lmatch: 
    246257    //printf("match\n"); 
    247258    return 1;   // match 
    248259Lnomatch: 
    249260    //printf("nomatch\n"); 
    250261    return 0;   // nomatch; 
     262} 
     263 
     264 
     265/************************************ 
     266 * Match an array of them. 
     267 * This should match what genIdent() does. 
     268 */ 
     269int arrayObjectMatch(Objects *oa1, Objects *oa2, TemplateDeclaration *tempdecl, Scope *sc) 
     270{ 
     271    if (oa1 == oa2) 
     272        return 1; 
     273    if (oa1->dim != oa2->dim) 
     274        return 0; 
     275    for (size_t j = 0; j < oa1->dim; j++) 
     276    {   Object *o1 = (Object *)oa1->data[j]; 
     277        Object *o2 = (Object *)oa2->data[j]; 
     278        if (!match(o1, o2, tempdecl, sc)) 
     279        { 
     280            return 0; 
     281        } 
     282    } 
     283    return 1; 
    251284} 
    252285 
    253286/**************************************** 
    254287 */ 
    255288 
    256289void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg) 
    257290{ 
    258291    //printf("ObjectToCBuffer()\n"); 
    259292    Type *t = isType(oarg); 
    260293    Expression *e = isExpression(oarg); 
    261294    Dsymbol *s = isDsymbol(oarg); 
    262295    Tuple *v = isTuple(oarg); 
    263296    if (t) 
    264297    {   //printf("\tt: %s ty = %d\n", t->toChars(), t->ty); 
    265298        t->toCBuffer(buf, NULL, hgs); 
    266299    } 
    267300    else if (e) 
    268301        e->toCBuffer(buf, hgs); 
    269302    else if (s) 
    270303    { 
     
    332365                printf("\tparameter[%d] = %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : ""); 
    333366            } 
    334367        } 
    335368#endif 
    336369    this->loc = loc; 
    337370    this->parameters = parameters; 
    338371    this->origParameters = parameters; 
    339372    this->constraint = constraint; 
    340373    this->members = decldefs; 
    341374    this->overnext = NULL; 
    342375    this->overroot = NULL; 
    343376    this->semanticRun = 0; 
    344377    this->onemember = NULL; 
    345378} 
    346379 
    347380Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) 
    348381{ 
    349382    //printf("TemplateDeclaration::syntaxCopy()\n"); 
    350383    TemplateDeclaration *td; 
    351384    TemplateParameters *p; 
    352     Array *d; 
    353385 
    354386    p = NULL; 
    355387    if (parameters) 
    356388    { 
    357389        p = new TemplateParameters(); 
    358390        p->setDim(parameters->dim); 
    359391        for (int i = 0; i < p->dim; i++) 
    360392        {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    361393            p->data[i] = (void *)tp->syntaxCopy(); 
    362394        } 
    363395    } 
    364396    Expression *e = NULL; 
    365397    if (constraint) 
    366398        e = constraint->syntaxCopy(); 
    367     d = Dsymbol::arraySyntaxCopy(members); 
     399    Array *d = Dsymbol::arraySyntaxCopy(members); 
    368400    td = new TemplateDeclaration(loc, ident, p, e, d); 
    369401    return td; 
    370402} 
    371403 
    372404void TemplateDeclaration::semantic(Scope *sc) 
    373405{ 
    374406#if LOG 
    375407    printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars()); 
     408    printf("sc->stc = %llx\n", sc->stc); 
     409    printf("sc->module = %s\n", sc->module->toChars()); 
    376410#endif 
    377411    if (semanticRun) 
    378412        return;         // semantic() already run 
    379413    semanticRun = 1; 
    380414 
    381415    if (sc->func) 
    382416    { 
    383417#if DMDV1 
    384418        error("cannot declare template at function scope %s", sc->func->toChars()); 
    385419#endif 
    386420    } 
    387421 
    388422    if (/*global.params.useArrayBounds &&*/ sc->module) 
    389423    { 
    390424        // Generate this function as it may be used 
    391425        // when template is instantiated in other modules 
    392426        sc->module->toModuleArray(); 
    393427    } 
    394428 
    395429    if (/*global.params.useAssert &&*/ sc->module) 
     
    928962                } 
    929963                declareParameter(paramscope, tp, t); 
    930964                goto L2; 
    931965            } 
    932966            fptupindex = -1; 
    933967        } 
    934968    } 
    935969 
    936970L1: 
    937971    if (nfparams == nfargs) 
    938972        ; 
    939973    else if (nfargs > nfparams) 
    940974    { 
    941975        if (fvarargs == 0) 
    942976            goto Lnomatch;              // too many args, no match 
    943977        match = MATCHconvert;           // match ... with a conversion 
    944978    } 
    945979 
    946980L2: 
    947981#if DMDV2 
    948     // Match 'ethis' to any TemplateThisParameter's 
    949982    if (ethis) 
    950983    { 
     984        // Match 'ethis' to any TemplateThisParameter's 
    951985        for (size_t i = 0; i < parameters->dim; i++) 
    952986        {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    953987            TemplateThisParameter *ttp = tp->isTemplateThisParameter(); 
    954988            if (ttp) 
    955989            {   MATCH m; 
    956990 
    957991                Type *t = new TypeIdentifier(0, ttp->ident); 
    958992                m = ethis->type->deduceType(paramscope, t, parameters, &dedtypes); 
    959993                if (!m) 
    960994                    goto Lnomatch; 
    961995                if (m < match) 
    962996                    match = m;          // pick worst match 
     997            } 
     998        } 
     999 
     1000        // Match attributes of ethis against attributes of fd 
     1001        if (fd->type) 
     1002        { 
     1003            Type *tthis = ethis->type; 
     1004            unsigned mod = fd->type->mod; 
     1005            StorageClass stc = scope->stc; 
     1006            if (stc & (STCshared | STCsynchronized)) 
     1007                mod |= MODshared; 
     1008            if (stc & STCimmutable) 
     1009                mod |= MODimmutable; 
     1010            if (stc & STCconst) 
     1011                mod |= MODconst; 
     1012            if (stc & STCwild) 
     1013                mod |= MODwild; 
     1014            // Fix mod 
     1015            if (mod & MODimmutable) 
     1016                mod = MODimmutable; 
     1017            if (mod & MODconst) 
     1018                mod &= ~STCwild; 
     1019            if (tthis->mod != mod) 
     1020            { 
     1021                if (!MODimplicitConv(tthis->mod, mod)) 
     1022                    goto Lnomatch; 
     1023                if (MATCHconst < match) 
     1024                    match = MATCHconst; 
    9631025            } 
    9641026        } 
    9651027    } 
    9661028#endif 
    9671029 
    9681030    // Loop through the function parameters 
    9691031    for (size_t parami = 0; parami < nfparams; parami++) 
    9701032    { 
    9711033        /* Skip over function parameters which wound up 
    9721034         * as part of a template tuple parameter. 
    9731035         */ 
    9741036        if (parami == fptupindex) 
    9751037            continue; 
    9761038        /* Set i = index into function arguments 
    9771039         * Function parameters correspond to function arguments as follows. 
    9781040         * Note that tuple_dim may be zero, and there may be default or 
    9791041         * variadic arguments at the end. 
    9801042         *  arg [0..fptupindex] == param[0..fptupindex] 
    9811043         *  arg [fptupindex..fptupindex+tuple_dim] == param[fptupindex] 
    9821044         *  arg[fputupindex+dim.. ] == param[fptupindex+1.. ] 
     
    13111373    TemplateDeclaration *td_best = NULL; 
    13121374    Objects *tdargs = new Objects(); 
    13131375    TemplateInstance *ti; 
    13141376    FuncDeclaration *fd; 
    13151377 
    13161378#if 0 
    13171379    printf("TemplateDeclaration::deduceFunctionTemplate() %s\n", toChars()); 
    13181380    printf("    targsi:\n"); 
    13191381    if (targsi) 
    13201382    {   for (int i = 0; i < targsi->dim; i++) 
    13211383        {   Object *arg = (Object *)targsi->data[i]; 
    13221384            printf("\t%s\n", arg->toChars()); 
    13231385        } 
    13241386    } 
    13251387    printf("    fargs:\n"); 
    13261388    for (int i = 0; i < fargs->dim; i++) 
    13271389    {   Expression *arg = (Expression *)fargs->data[i]; 
    13281390        printf("\t%s %s\n", arg->type->toChars(), arg->toChars()); 
    13291391        //printf("\tty = %d\n", arg->type->ty); 
    13301392    } 
     1393    printf("stc = %llx\n", scope->stc); 
    13311394#endif 
    13321395 
    13331396    for (TemplateDeclaration *td = this; td; td = td->overnext) 
    13341397    { 
    13351398        if (!td->semanticRun) 
    13361399        { 
    13371400            error("forward reference to template %s", td->toChars()); 
    13381401            goto Lerror; 
    13391402        } 
    13401403        if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration()) 
    13411404        { 
    13421405            error("is not a function template"); 
    13431406            goto Lerror; 
    13441407        } 
    13451408 
    13461409        MATCH m; 
    13471410        Objects dedargs; 
    13481411 
    13491412        m = td->deduceFunctionTemplateMatch(loc, targsi, ethis, fargs, &dedargs); 
    13501413        //printf("deduceFunctionTemplateMatch = %d\n", m); 
     
    16051668        { 
    16061669            dedtypes->data[i] = (void *)this; 
    16071670            goto Lexact; 
    16081671        } 
    16091672        if (equals(at)) 
    16101673            goto Lexact; 
    16111674        else if (ty == Tclass && at->ty == Tclass) 
    16121675        { 
    16131676            return (MATCH) implicitConvTo(at); 
    16141677        } 
    16151678        else if (ty == Tsarray && at->ty == Tarray && 
    16161679            nextOf()->equals(at->nextOf())) 
    16171680        { 
    16181681            goto Lexact; 
    16191682        } 
    16201683        else 
    16211684            goto Lnomatch; 
    16221685    } 
    16231686 
    16241687    if (ty != tparam->ty) 
    1625         return implicitConvTo(tparam); 
    1626 //      goto Lnomatch; 
     1688    { 
     1689#if DMDV2 
     1690        // Can't instantiate AssociativeArray!() without a scope 
     1691        if (tparam->ty == Taarray && !((TypeAArray*)tparam)->sc) 
     1692            ((TypeAArray*)tparam)->sc = sc; 
     1693#endif 
     1694       return implicitConvTo(tparam); 
     1695    } 
    16271696 
    16281697    if (nextOf()) 
    16291698        return nextOf()->deduceType(sc, tparam->nextOf(), parameters, dedtypes); 
    16301699 
    16311700Lexact: 
    16321701    return MATCHexact; 
    16331702 
    16341703Lnomatch: 
    16351704    return MATCHnomatch; 
    16361705 
    16371706#if DMDV2 
    16381707Lconst: 
    16391708    return MATCHconst; 
    16401709#endif 
    16411710} 
    16421711 
    16431712#if DMDV2 
    16441713MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, 
    16451714        Objects *dedtypes) 
    16461715{ 
     
    17751844 
    17761845    // Extra check that function characteristics must match 
    17771846    if (tparam && tparam->ty == Tfunction) 
    17781847    { 
    17791848        TypeFunction *tp = (TypeFunction *)tparam; 
    17801849        if (varargs != tp->varargs || 
    17811850            linkage != tp->linkage) 
    17821851            return MATCHnomatch; 
    17831852 
    17841853        size_t nfargs = Parameter::dim(this->parameters); 
    17851854        size_t nfparams = Parameter::dim(tp->parameters); 
    17861855 
    17871856        /* See if tuple match 
    17881857         */ 
    17891858        if (nfparams > 0 && nfargs >= nfparams - 1) 
    17901859        { 
    17911860            /* See if 'A' of the template parameter matches 'A' 
    17921861             * of the type of the last function parameter. 
    17931862             */ 
    17941863            Parameter *fparam = Parameter::getNth(tp->parameters, nfparams - 1); 
     1864            assert(fparam); 
     1865            assert(fparam->type); 
    17951866            if (fparam->type->ty != Tident) 
    17961867                goto L1; 
    17971868            TypeIdentifier *tid = (TypeIdentifier *)fparam->type; 
    17981869            if (tid->idents.dim) 
    17991870                goto L1; 
    18001871 
    18011872            /* Look through parameters to find tuple matching tid->ident 
    18021873             */ 
    18031874            size_t tupi = 0; 
    18041875            for (; 1; tupi++) 
    18051876            {   if (tupi == parameters->dim) 
    18061877                    goto L1; 
    18071878                TemplateParameter *t = (TemplateParameter *)parameters->data[tupi]; 
    18081879                TemplateTupleParameter *tup = t->isTemplateTupleParameter(); 
    18091880                if (tup && tup->ident->equals(tid->ident)) 
    18101881                    break; 
    18111882            } 
    18121883 
    18131884            /* The types of the function arguments [nfparams - 1 .. nfargs] 
    18141885             * now form the tuple argument. 
     
    20802151                        goto Lnomatch; 
    20812152                } 
    20822153                else 
    20832154                { 
    20842155                    dedtypes->data[j] = s1; 
    20852156                } 
    20862157            } 
    20872158            else if (s1 && s2) 
    20882159            { 
    20892160                if (!s1->equals(s2)) 
    20902161                    goto Lnomatch; 
    20912162            } 
    20922163            // BUG: Need to handle tuple parameters 
    20932164            else 
    20942165                goto Lnomatch; 
    20952166        } 
    20962167    } 
    20972168    return Type::deduceType(sc, tparam, parameters, dedtypes); 
    20982169 
    20992170Lnomatch: 
     2171    //printf("no match\n"); 
    21002172    return MATCHnomatch; 
    21012173} 
    21022174 
    21032175MATCH TypeStruct::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes) 
    21042176{ 
    21052177    //printf("TypeStruct::deduceType()\n"); 
    21062178    //printf("\tthis->parent   = %s, ", sym->parent->toChars()); print(); 
    21072179    //printf("\ttparam = %d, ", tparam->ty); tparam->print(); 
    21082180 
    21092181    /* If this struct is a template struct, and we're matching 
    21102182     * it against a template instance, convert the struct type 
    21112183     * to a template instance, too, and try again. 
    21122184     */ 
    21132185    TemplateInstance *ti = sym->parent->isTemplateInstance(); 
    21142186 
    21152187    if (tparam && tparam->ty == Tinstance) 
    21162188    { 
    21172189        if (ti && ti->toAlias() == sym) 
    21182190        { 
    21192191            TypeInstance *t = new TypeInstance(0, ti); 
     
    24382510            goto Lnomatch; 
    24392511 
    24402512        if (specType && !specType->equals(ttp->specType)) 
    24412513            goto Lnomatch; 
    24422514 
    24432515        return 1;                       // match 
    24442516    } 
    24452517 
    24462518Lnomatch: 
    24472519    return 0; 
    24482520} 
    24492521 
    24502522/******************************************* 
    24512523 * Match to a particular TemplateParameter. 
    24522524 * Input: 
    24532525 *      i               i'th argument 
    24542526 *      tiargs[]        actual arguments to template instance 
    24552527 *      parameters[]    template parameters 
    24562528 *      dedtypes[]      deduced arguments to template instance 
    24572529 *      *psparam        set to symbol declared and initialized to dedtypes[i] 
     2530 *      flags           1: don't do 'toHeadMutable()' 
    24582531 */ 
    24592532 
    24602533MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs, 
    24612534        int i, TemplateParameters *parameters, Objects *dedtypes, 
    24622535        Declaration **psparam, int flags) 
    24632536{ 
    24642537    //printf("TemplateTypeParameter::matchArg()\n"); 
    24652538    Type *t; 
    24662539    Object *oarg; 
    24672540    MATCH m = MATCHexact; 
    24682541    Type *ta; 
    24692542 
    24702543    if (i < tiargs->dim) 
    24712544        oarg = (Object *)tiargs->data[i]; 
    24722545    else 
    24732546    {   // Get default argument instead 
    24742547        oarg = defaultArg(loc, sc); 
    24752548        if (!oarg) 
    24762549        {   assert(i < dedtypes->dim); 
    24772550            // It might have already been deduced 
     
    33063379            fatal(); 
    33073380        } 
    33083381        return; 
    33093382    } 
    33103383#if LOG 
    33113384    printf("\n+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); 
    33123385#endif 
    33133386    if (inst)           // if semantic() was already run 
    33143387    { 
    33153388#if LOG 
    33163389        printf("-TemplateInstance::semantic('%s', this=%p) already run\n", inst->toChars(), inst); 
    33173390#endif 
    33183391        return; 
    33193392    } 
    33203393 
    33213394    // get the enclosing template instance from the scope tinst 
    33223395    tinst = sc->tinst; 
    33233396 
    33243397    if (semanticRun != 0) 
    33253398    { 
     3399#if LOG 
     3400        printf("Recursive template expansion\n"); 
     3401#endif 
    33263402        error(loc, "recursive template expansion"); 
    33273403//      inst = this; 
    33283404        return; 
    33293405    } 
    33303406    semanticRun = 1; 
    33313407 
    33323408#if LOG 
    33333409    printf("\tdo semantic\n"); 
    33343410#endif 
    33353411    if (havetempdecl) 
    33363412    { 
    33373413        assert((size_t)tempdecl->scope > 0x10000); 
    33383414        // Deduce tdtypes 
    33393415        tdtypes.setDim(tempdecl->parameters->dim); 
    33403416        if (!tempdecl->matchWithInstance(this, &tdtypes, 0)) 
    33413417        { 
    33423418            error("incompatible arguments for template instantiation"); 
    33433419            inst = this; 
    33443420            return; 
    33453421        } 
  • trunk/src/template.c

    r784 r801  
    197197    } 
    198198    else if (e1) 
    199199    { 
    200200#if 0 
    201201        if (e1 && e2) 
    202202        { 
    203203            printf("match %d\n", e1->equals(e2)); 
    204204            e1->print(); 
    205205            e2->print(); 
    206206            e1->type->print(); 
    207207            e2->type->print(); 
    208208        } 
    209209#endif 
    210210        if (!e2) 
    211211            goto Lnomatch; 
    212212        if (!e1->equals(e2)) 
    213213            goto Lnomatch; 
    214214    } 
    215215    else if (s1) 
    216216    { 
    217         //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars()); 
    218217        if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) 
    219218        { 
     219            if (s2) 
     220            { 
     221                VarDeclaration *v1 = s1->isVarDeclaration(); 
     222                VarDeclaration *v2 = s2->isVarDeclaration(); 
     223                if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) 
     224                {   ExpInitializer *ei1 = v1->init->isExpInitializer(); 
     225                    ExpInitializer *ei2 = v2->init->isExpInitializer(); 
     226                    if (ei1 && ei2 && ei1->exp->equals(ei2->exp)) 
     227                        goto Lmatch; 
     228                } 
     229            } 
    220230            goto Lnomatch; 
    221231        } 
    222232#if DMDV2 
    223233        VarDeclaration *v1 = s1->isVarDeclaration(); 
    224234        VarDeclaration *v2 = s2->isVarDeclaration(); 
    225235        if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) 
    226236        {   ExpInitializer *ei1 = v1->init->isExpInitializer(); 
    227237            ExpInitializer *ei2 = v2->init->isExpInitializer(); 
    228238            if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) 
    229239                goto Lnomatch; 
    230240        } 
    231241#endif 
    232242    } 
    233243    else if (v1) 
    234244    { 
    235245        if (!v2) 
    236246            goto Lnomatch; 
    237247        if (v1->objects.dim != v2->objects.dim) 
    238248            goto Lnomatch; 
    239249        for (size_t i = 0; i < v1->objects.dim; i++) 
    240250        { 
    241251            if (!match((Object *)v1->objects.data[i], 
    242252                       (Object *)v2->objects.data[i], 
    243253                       tempdecl, sc)) 
    244254                goto Lnomatch; 
    245255        } 
    246256    } 
     257Lmatch: 
    247258    //printf("match\n"); 
    248259    return 1;   // match 
    249260Lnomatch: 
    250261    //printf("nomatch\n"); 
    251262    return 0;   // nomatch; 
    252263} 
    253264 
    254265 
    255266/************************************ 
    256267 * Match an array of them. 
    257268 */ 
    258269int arrayObjectMatch(Objects *oa1, Objects *oa2, TemplateDeclaration *tempdecl, Scope *sc) 
    259270{ 
    260271    if (oa1 == oa2) 
    261272        return 1; 
    262273    if (oa1->dim != oa2->dim) 
    263274        return 0; 
    264275    for (size_t j = 0; j < oa1->dim; j++) 
    265276    {   Object *o1 = (Object *)oa1->data[j]; 
    266277        Object *o2 = (Object *)oa2->data[j]; 
     
    46864697            /* Bugzilla 3043: if the first character of p is a digit this 
    46874698             * causes ambiguity issues because the digits of the two numbers are adjacent. 
    46884699             * Current demanglers resolve this by trying various places to separate the 
    46894700             * numbers until one gets a successful demangle. 
    46904701             * Unfortunately, fixing this ambiguity will break existing binary 
    46914702             * compatibility and the demanglers, so we'll leave it as is. 
    46924703             */ 
    46934704            buf.printf("%zu%s", strlen(p), p); 
    46944705        } 
    46954706        else if (va) 
    46964707        { 
    46974708            assert(i + 1 == args->dim);         // must be last one 
    46984709            args = &va->objects; 
    46994710            i = -1; 
    47004711        } 
    47014712        else 
    47024713            assert(0); 
    47034714    } 
    47044715    buf.writeByte('Z'); 
    47054716    id = buf.toChars(); 
    4706     buf.data = NULL; 
     4717    //buf.data = NULL;                          // we can free the string after call to idPool() 
    47074718    //printf("\tgenIdent = %s\n", id); 
    4708     return new Identifier(id, TOKidentifier); 
     4719    return Lexer::idPool(id); 
    47094720} 
    47104721 
    47114722 
    47124723/**************************************************** 
    47134724 * Declare parameters of template instance, initialize them with the 
    47144725 * template instance arguments. 
    47154726 */ 
    47164727 
    47174728void TemplateInstance::declareParameters(Scope *sc) 
    47184729{ 
    47194730    //printf("TemplateInstance::declareParameters()\n"); 
    47204731    for (int i = 0; i < tdtypes.dim; i++) 
    47214732    { 
    47224733        TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; 
    47234734        //Object *o = (Object *)tiargs->data[i]; 
    47244735        Object *o = (Object *)tdtypes.data[i];          // initializer for tp 
    47254736 
    47264737        //printf("\ttdtypes[%d] = %p\n", i, o); 
    47274738        tempdecl->declareParameter(sc, tp, o); 
    47284739    }