comparison dmd/template.c @ 875:330f999ade44

Merged DMD 1.038
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 06 Jan 2009 16:33:51 +0100
parents eef8ac26c66c
children 27a379f288bf
comparison
equal deleted inserted replaced
874:2ddee23bd70e 875:330f999ade44
199 (Object *)v2->objects.data[i], 199 (Object *)v2->objects.data[i],
200 tempdecl, sc)) 200 tempdecl, sc))
201 goto Lnomatch; 201 goto Lnomatch;
202 } 202 }
203 } 203 }
204 //printf("match\n");
204 return 1; // match 205 return 1; // match
205 Lnomatch: 206 Lnomatch:
207 //printf("nomatch\n");
206 return 0; // nomatch; 208 return 0; // nomatch;
207 } 209 }
208 210
209 /**************************************** 211 /****************************************
210 */ 212 */
318 if (scope) 320 if (scope)
319 return; // semantic() already run 321 return; // semantic() already run
320 322
321 if (sc->func) 323 if (sc->func)
322 { 324 {
325 #if DMDV1
323 error("cannot declare template at function scope %s", sc->func->toChars()); 326 error("cannot declare template at function scope %s", sc->func->toChars());
327 #endif
324 } 328 }
325 329
326 if (/*global.params.useArrayBounds &&*/ sc->module) 330 if (/*global.params.useArrayBounds &&*/ sc->module)
327 { 331 {
328 // Generate this function as it may be used 332 // Generate this function as it may be used
549 goto Lnomatch; 553 goto Lnomatch;
550 } 554 }
551 555
552 if (!flag) 556 if (!flag)
553 { 557 {
554 // Any parameter left without a type gets the type of its corresponding arg 558 /* Any parameter left without a type gets the type of
559 * its corresponding arg
560 */
555 for (int i = 0; i < dedtypes_dim; i++) 561 for (int i = 0; i < dedtypes_dim; i++)
556 { 562 {
557 if (!dedtypes->data[i]) 563 if (!dedtypes->data[i])
558 { assert(i < ti->tiargs->dim); 564 { assert(i < ti->tiargs->dim);
559 dedtypes->data[i] = ti->tiargs->data[i]; 565 dedtypes->data[i] = ti->tiargs->data[i];
560 } 566 }
561 } 567 }
562 } 568 }
569
570 #if DMDV2
571 if (m && constraint && !(flag & 1))
572 { /* Check to see if constraint is satisfied.
573 */
574 Expression *e = constraint->syntaxCopy();
575 paramscope->flags |= SCOPEstaticif;
576 e = e->semantic(paramscope);
577 e = e->optimize(WANTvalue | WANTinterpret);
578 if (e->isBool(TRUE))
579 ;
580 else if (e->isBool(FALSE))
581 goto Lnomatch;
582 else
583 {
584 e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars());
585 }
586 }
587 #endif
563 588
564 #if LOGM 589 #if LOGM
565 // Print out the results 590 // Print out the results
566 printf("--------------------------\n"); 591 printf("--------------------------\n");
567 printf("template %s\n", toChars()); 592 printf("template %s\n", toChars());
672 697
673 698
674 /************************************************* 699 /*************************************************
675 * Match function arguments against a specific template function. 700 * Match function arguments against a specific template function.
676 * Input: 701 * Input:
702 * loc instantiation location
677 * targsi Expression/Type initial list of template arguments 703 * targsi Expression/Type initial list of template arguments
704 * ethis 'this' argument if !NULL
678 * fargs arguments to function 705 * fargs arguments to function
679 * Output: 706 * Output:
680 * dedargs Expression/Type deduced template arguments 707 * dedargs Expression/Type deduced template arguments
681 * Returns: 708 * Returns:
682 * match level 709 * match level
683 */ 710 */
684 711
685 MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, 712 MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
713 Expression *ethis, Expressions *fargs,
686 Objects *dedargs) 714 Objects *dedargs)
687 { 715 {
688 size_t i; 716 size_t i;
689 size_t nfparams; 717 size_t nfparams;
690 size_t nfargs; 718 size_t nfargs;
822 goto Lnomatch; // too many args, no match 850 goto Lnomatch; // too many args, no match
823 match = MATCHconvert; // match ... with a conversion 851 match = MATCHconvert; // match ... with a conversion
824 } 852 }
825 853
826 L2: 854 L2:
855 #if DMDV2
856 // Match 'ethis' to any TemplateThisParameter's
857 if (ethis)
858 {
859 for (size_t i = 0; i < parameters->dim; i++)
860 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
861 TemplateThisParameter *ttp = tp->isTemplateThisParameter();
862 if (ttp)
863 { MATCH m;
864
865 Type *t = new TypeIdentifier(0, ttp->ident);
866 m = ethis->type->deduceType(scope, t, parameters, &dedtypes);
867 if (!m)
868 goto Lnomatch;
869 if (m < match)
870 match = m; // pick worst match
871 }
872 }
873 }
874 #endif
875
827 // Loop through the function parameters 876 // Loop through the function parameters
828 for (i = 0; i < nfparams; i++) 877 for (i = 0; i < nfparams; i++)
829 { 878 {
830 /* Skip over function parameters which wound up 879 /* Skip over function parameters which wound up
831 * as part of a template tuple parameter. 880 * as part of a template tuple parameter.
980 if (dedtypes.data[i] != oded) 1029 if (dedtypes.data[i] != oded)
981 error("specialization not allowed for deduced parameter %s", tp->ident->toChars()); 1030 error("specialization not allowed for deduced parameter %s", tp->ident->toChars());
982 } 1031 }
983 } 1032 }
984 else 1033 else
985 { oded = tp->defaultArg(paramscope); 1034 { oded = tp->defaultArg(loc, paramscope);
986 if (!oded) 1035 if (!oded)
987 goto Lnomatch; 1036 goto Lnomatch;
988 } 1037 }
989 declareParameter(paramscope, tp, oded); 1038 declareParameter(paramscope, tp, oded);
990 dedargs->data[i] = (void *)oded; 1039 dedargs->data[i] = (void *)oded;
991 } 1040 }
992 } 1041 }
1042
1043 #if DMDV2
1044 if (constraint)
1045 { /* Check to see if constraint is satisfied.
1046 */
1047 Expression *e = constraint->syntaxCopy();
1048 paramscope->flags |= SCOPEstaticif;
1049 e = e->semantic(paramscope);
1050 e = e->optimize(WANTvalue | WANTinterpret);
1051 if (e->isBool(TRUE))
1052 ;
1053 else if (e->isBool(FALSE))
1054 goto Lnomatch;
1055 else
1056 {
1057 e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars());
1058 }
1059 }
1060 #endif
993 1061
994 #if 0 1062 #if 0
995 for (i = 0; i < dedargs->dim; i++) 1063 for (i = 0; i < dedargs->dim; i++)
996 { Type *t = (Type *)dedargs->data[i]; 1064 { Type *t = (Type *)dedargs->data[i];
997 printf("\tdedargs[%d] = %d, %s\n", i, t->dyncast(), t->toChars()); 1065 printf("\tdedargs[%d] = %d, %s\n", i, t->dyncast(), t->toChars());
1094 * If no match, give error message and return NULL. 1162 * If no match, give error message and return NULL.
1095 * Input: 1163 * Input:
1096 * sc instantiation scope 1164 * sc instantiation scope
1097 * loc instantiation location 1165 * loc instantiation location
1098 * targsi initial list of template arguments 1166 * targsi initial list of template arguments
1167 * ethis if !NULL, the 'this' pointer argument
1099 * fargs arguments to function 1168 * fargs arguments to function
1169 * flags 1: do not issue error message on no match, just return NULL
1100 */ 1170 */
1101 1171
1102 FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, 1172 FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
1103 Objects *targsi, Expressions *fargs) 1173 Objects *targsi, Expression *ethis, Expressions *fargs, int flags)
1104 { 1174 {
1105 MATCH m_best = MATCHnomatch; 1175 MATCH m_best = MATCHnomatch;
1106 TemplateDeclaration *td_ambig = NULL; 1176 TemplateDeclaration *td_ambig = NULL;
1107 TemplateDeclaration *td_best = NULL; 1177 TemplateDeclaration *td_best = NULL;
1108 Objects *tdargs = new Objects(); 1178 Objects *tdargs = new Objects();
1140 } 1210 }
1141 1211
1142 MATCH m; 1212 MATCH m;
1143 Objects dedargs; 1213 Objects dedargs;
1144 1214
1145 m = td->deduceFunctionTemplateMatch(targsi, fargs, &dedargs); 1215 m = td->deduceFunctionTemplateMatch(loc, targsi, ethis, fargs, &dedargs);
1146 //printf("deduceFunctionTemplateMatch = %d\n", m); 1216 //printf("deduceFunctionTemplateMatch = %d\n", m);
1147 if (!m) // if no match 1217 if (!m) // if no match
1148 continue; 1218 continue;
1149 1219
1150 if (m < m_best) 1220 if (m < m_best)
1205 goto Lerror; 1275 goto Lerror;
1206 return fd; 1276 return fd;
1207 1277
1208 Lerror: 1278 Lerror:
1209 { 1279 {
1280 HdrGenState hgs;
1281
1282 OutBuffer bufa;
1283 Objects *args = targsi;
1284 if (args)
1285 { for (int i = 0; i < args->dim; i++)
1286 {
1287 if (i)
1288 bufa.writeByte(',');
1289 Object *oarg = (Object *)args->data[i];
1290 ObjectToCBuffer(&bufa, &hgs, oarg);
1291 }
1292 }
1293
1210 OutBuffer buf; 1294 OutBuffer buf;
1211 HdrGenState hgs;
1212
1213 argExpTypesToCBuffer(&buf, fargs, &hgs); 1295 argExpTypesToCBuffer(&buf, fargs, &hgs);
1214 error(loc, "cannot deduce template function from argument types (%s)", 1296 error(loc, "cannot deduce template function from argument types !(%s)(%s)",
1215 buf.toChars()); 1297 bufa.toChars(), buf.toChars());
1216 return NULL; 1298 }
1217 } 1299 return NULL;
1218 } 1300 }
1219 1301
1220 void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 1302 void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1221 { 1303 {
1222 #if 0 // Should handle template functions 1304 #if 0 // Should handle template functions
1235 if (i) 1317 if (i)
1236 buf->writeByte(','); 1318 buf->writeByte(',');
1237 tp->toCBuffer(buf, hgs); 1319 tp->toCBuffer(buf, hgs);
1238 } 1320 }
1239 buf->writeByte(')'); 1321 buf->writeByte(')');
1322 #if DMDV2
1323 if (constraint)
1324 { buf->writestring(" if (");
1325 constraint->toCBuffer(buf, hgs);
1326 buf->writeByte(')');
1327 }
1328 #endif
1240 1329
1241 if (hgs->hdrgen) 1330 if (hgs->hdrgen)
1242 { 1331 {
1243 hgs->tpltMember++; 1332 hgs->tpltMember++;
1244 buf->writenl(); 1333 buf->writenl();
1269 if (i) 1358 if (i)
1270 buf.writeByte(','); 1359 buf.writeByte(',');
1271 tp->toCBuffer(&buf, &hgs); 1360 tp->toCBuffer(&buf, &hgs);
1272 } 1361 }
1273 buf.writeByte(')'); 1362 buf.writeByte(')');
1363 #if DMDV2
1364 if (constraint)
1365 { buf.writestring(" if (");
1366 constraint->toCBuffer(&buf, &hgs);
1367 buf.writeByte(')');
1368 }
1369 #endif
1274 buf.writeByte(0); 1370 buf.writeByte(0);
1275 return (char *)buf.extractData(); 1371 return (char *)buf.extractData();
1276 } 1372 }
1277 1373
1278 /* ======================== Type ============================================ */ 1374 /* ======================== Type ============================================ */
1321 */ 1417 */
1322 1418
1323 MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, 1419 MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
1324 Objects *dedtypes) 1420 Objects *dedtypes)
1325 { 1421 {
1326 //printf("Type::deduceType()\n"); 1422 #if 0
1327 //printf("\tthis = %d, ", ty); print(); 1423 printf("Type::deduceType()\n");
1328 //printf("\ttparam = %d, ", tparam->ty); tparam->print(); 1424 printf("\tthis = %d, ", ty); print();
1425 printf("\ttparam = %d, ", tparam->ty); tparam->print();
1426 #endif
1329 if (!tparam) 1427 if (!tparam)
1330 goto Lnomatch; 1428 goto Lnomatch;
1331 1429
1332 if (this == tparam) 1430 if (this == tparam)
1333 goto Lexact; 1431 goto Lexact;
2025 2123
2026 if (i < tiargs->dim) 2124 if (i < tiargs->dim)
2027 oarg = (Object *)tiargs->data[i]; 2125 oarg = (Object *)tiargs->data[i];
2028 else 2126 else
2029 { // Get default argument instead 2127 { // Get default argument instead
2030 oarg = defaultArg(sc); 2128 oarg = defaultArg(loc, sc);
2031 if (!oarg) 2129 if (!oarg)
2032 { assert(i < dedtypes->dim); 2130 { assert(i < dedtypes->dim);
2033 // It might have already been deduced 2131 // It might have already been deduced
2034 oarg = (Object *)dedtypes->data[i]; 2132 oarg = (Object *)dedtypes->data[i];
2035 if (!oarg) 2133 if (!oarg)
2139 { 2237 {
2140 return specType; 2238 return specType;
2141 } 2239 }
2142 2240
2143 2241
2144 Object *TemplateTypeParameter::defaultArg(Scope *sc) 2242 Object *TemplateTypeParameter::defaultArg(Loc loc, Scope *sc)
2145 { 2243 {
2146 Type *t; 2244 Type *t;
2147 2245
2148 t = defaultType; 2246 t = defaultType;
2149 if (t) 2247 if (t)
2269 2367
2270 if (i < tiargs->dim) 2368 if (i < tiargs->dim)
2271 oarg = (Object *)tiargs->data[i]; 2369 oarg = (Object *)tiargs->data[i];
2272 else 2370 else
2273 { // Get default argument instead 2371 { // Get default argument instead
2274 oarg = defaultArg(sc); 2372 oarg = defaultArg(loc, sc);
2275 if (!oarg) 2373 if (!oarg)
2276 { assert(i < dedtypes->dim); 2374 { assert(i < dedtypes->dim);
2277 // It might have already been deduced 2375 // It might have already been deduced
2278 oarg = (Object *)dedtypes->data[i]; 2376 oarg = (Object *)dedtypes->data[i];
2279 if (!oarg) 2377 if (!oarg)
2355 { 2453 {
2356 return specAliasT; 2454 return specAliasT;
2357 } 2455 }
2358 2456
2359 2457
2360 Object *TemplateAliasParameter::defaultArg(Scope *sc) 2458 Object *TemplateAliasParameter::defaultArg(Loc loc, Scope *sc)
2361 { 2459 {
2362 Dsymbol *s = NULL; 2460 Dsymbol *s = NULL;
2363 2461
2364 if (defaultAlias) 2462 if (defaultAlias)
2365 { 2463 {
2483 2581
2484 if (i < tiargs->dim) 2582 if (i < tiargs->dim)
2485 oarg = (Object *)tiargs->data[i]; 2583 oarg = (Object *)tiargs->data[i];
2486 else 2584 else
2487 { // Get default argument instead 2585 { // Get default argument instead
2488 oarg = defaultArg(sc); 2586 oarg = defaultArg(loc, sc);
2489 if (!oarg) 2587 if (!oarg)
2490 { assert(i < dedtypes->dim); 2588 { assert(i < dedtypes->dim);
2491 // It might have already been deduced 2589 // It might have already been deduced
2492 oarg = (Object *)dedtypes->data[i]; 2590 oarg = (Object *)dedtypes->data[i];
2493 if (!oarg) 2591 if (!oarg)
2600 { 2698 {
2601 return specValue; 2699 return specValue;
2602 } 2700 }
2603 2701
2604 2702
2605 Object *TemplateValueParameter::defaultArg(Scope *sc) 2703 Object *TemplateValueParameter::defaultArg(Loc loc, Scope *sc)
2606 { 2704 {
2607 Expression *e = defaultValue; 2705 Expression *e = defaultValue;
2608 if (e) 2706 if (e)
2609 { 2707 {
2610 e = e->syntaxCopy(); 2708 e = e->syntaxCopy();
2746 { 2844 {
2747 return NULL; 2845 return NULL;
2748 } 2846 }
2749 2847
2750 2848
2751 Object *TemplateTupleParameter::defaultArg(Scope *sc) 2849 Object *TemplateTupleParameter::defaultArg(Loc loc, Scope *sc)
2752 { 2850 {
2753 return NULL; 2851 return NULL;
2754 } 2852 }
2755 2853
2756 /* ======================== TemplateInstance ================================ */ 2854 /* ======================== TemplateInstance ================================ */
2776 this->isnested = NULL; 2874 this->isnested = NULL;
2777 this->errors = 0; 2875 this->errors = 0;
2778 this->tinst = NULL; 2876 this->tinst = NULL;
2779 } 2877 }
2780 2878
2879 /*****************
2880 * This constructor is only called when we figured out which function
2881 * template to instantiate.
2882 */
2781 2883
2782 TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs) 2884 TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs)
2783 : ScopeDsymbol(NULL) 2885 : ScopeDsymbol(NULL)
2784 { 2886 {
2785 #if LOG 2887 #if LOG
2828 } 2930 }
2829 2931
2830 Dsymbol *TemplateInstance::syntaxCopy(Dsymbol *s) 2932 Dsymbol *TemplateInstance::syntaxCopy(Dsymbol *s)
2831 { 2933 {
2832 TemplateInstance *ti; 2934 TemplateInstance *ti;
2833 int i;
2834 2935
2835 if (s) 2936 if (s)
2836 ti = (TemplateInstance *)s; 2937 ti = (TemplateInstance *)s;
2837 else 2938 else
2838 ti = new TemplateInstance(loc, name); 2939 ti = new TemplateInstance(loc, name);
2894 return; 2995 return;
2895 } 2996 }
2896 } 2997 }
2897 else 2998 else
2898 { 2999 {
2899 // Run semantic on each argument, place results in tiargs[] 3000 /* Run semantic on each argument, place results in tiargs[]
3001 * (if we havetempdecl, then tiargs is already evaluated)
3002 */
2900 semanticTiargs(sc); 3003 semanticTiargs(sc);
2901 3004
2902 tempdecl = findTemplateDeclaration(sc); 3005 tempdecl = findTemplateDeclaration(sc);
2903 if (tempdecl) 3006 if (tempdecl)
2904 tempdecl = findBestMatch(sc); 3007 tempdecl = findBestMatch(sc);
2972 // Add 'this' to the enclosing scope's members[] so the semantic routines 3075 // Add 'this' to the enclosing scope's members[] so the semantic routines
2973 // will get called on the instance members 3076 // will get called on the instance members
2974 #if 1 3077 #if 1
2975 int dosemantic3 = 0; 3078 int dosemantic3 = 0;
2976 { Array *a; 3079 { Array *a;
2977 int i; 3080
2978 3081 Scope *scx = sc;
2979 if (sc->scopesym && sc->scopesym->members && !sc->scopesym->isTemplateMixin()) 3082 #if 0
2980 { 3083 for (scx = sc; scx; scx = scx->enclosing)
2981 //printf("\t1: adding to %s %s\n", sc->scopesym->kind(), sc->scopesym->toChars()); 3084 if (scx->scopesym)
2982 a = sc->scopesym->members; 3085 break;
3086 #endif
3087
3088 //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
3089 if (scx && scx->scopesym &&
3090 scx->scopesym->members && !scx->scopesym->isTemplateMixin() &&
3091 /* The following test should really be if scx->module recursively
3092 * imports itself. Because if it does, see bugzilla 2500.
3093 */
3094 //scx->module == tempdecl->getModule()
3095 !scx->module->imports(scx->module)
3096 )
3097 {
3098 //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
3099 a = scx->scopesym->members;
2983 } 3100 }
2984 else 3101 else
2985 { Module *m = sc->module->importedFrom; 3102 { Module *m = sc->module->importedFrom;
2986 //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); 3103 //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars());
2987 a = m->members; 3104 a = m->members;
3393 { 3510 {
3394 error("forward reference to template declaration %s", td->toChars()); 3511 error("forward reference to template declaration %s", td->toChars());
3395 return NULL; 3512 return NULL;
3396 } 3513 }
3397 m = td->matchWithInstance(this, &dedtypes, 0); 3514 m = td->matchWithInstance(this, &dedtypes, 0);
3398 //printf("m = %d\n", m); 3515 //printf("matchWithInstance = %d\n", m);
3399 if (!m) // no match at all 3516 if (!m) // no match at all
3400 continue; 3517 continue;
3401 3518
3402 #if 1
3403 if (m < m_best) 3519 if (m < m_best)
3404 goto Ltd_best; 3520 goto Ltd_best;
3405 if (m > m_best) 3521 if (m > m_best)
3406 goto Ltd; 3522 goto Ltd;
3407 #else 3523
3408 if (!m_best)
3409 goto Ltd;
3410 #endif
3411 { 3524 {
3412 // Disambiguate by picking the most specialized TemplateDeclaration 3525 // Disambiguate by picking the most specialized TemplateDeclaration
3413 int c1 = td->leastAsSpecialized(td_best); 3526 int c1 = td->leastAsSpecialized(td_best);
3414 int c2 = td_best->leastAsSpecialized(td); 3527 int c2 = td_best->leastAsSpecialized(td);
3415 //printf("c1 = %d, c2 = %d\n", c1, c2); 3528 //printf("c1 = %d, c2 = %d\n", c1, c2);
3654 assert(0); 3767 assert(0);
3655 } 3768 }
3656 buf.writeByte('Z'); 3769 buf.writeByte('Z');
3657 id = buf.toChars(); 3770 id = buf.toChars();
3658 buf.data = NULL; 3771 buf.data = NULL;
3772 //printf("\tgenIdent = %s\n", id);
3659 return new Identifier(id, TOKidentifier); 3773 return new Identifier(id, TOKidentifier);
3660 } 3774 }
3661 3775
3662 3776
3663 /**************************************************** 3777 /****************************************************
3670 //printf("TemplateInstance::declareParameters()\n"); 3784 //printf("TemplateInstance::declareParameters()\n");
3671 for (int i = 0; i < tdtypes.dim; i++) 3785 for (int i = 0; i < tdtypes.dim; i++)
3672 { 3786 {
3673 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; 3787 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i];
3674 //Object *o = (Object *)tiargs->data[i]; 3788 //Object *o = (Object *)tiargs->data[i];
3675 Object *o = (Object *)tdtypes.data[i]; 3789 Object *o = (Object *)tdtypes.data[i]; // initializer for tp
3676 3790
3677 //printf("\ttdtypes[%d] = %p\n", i, o); 3791 //printf("\ttdtypes[%d] = %p\n", i, o);
3678 tempdecl->declareParameter(scope, tp, o); 3792 tempdecl->declareParameter(scope, tp, o);
3679 } 3793 }
3680 } 3794 }